Annotation of researchv9/sys.vax/sys/vmdrum.c, revision 1.1.1.1

1.1       root        1: /*     vmdrum.c        4.3     81/03/08        */
                      2: 
                      3: #include "../h/param.h"
                      4: #include "../h/systm.h"
                      5: #include "../h/dir.h"
                      6: #include "../h/user.h"
                      7: #include "../h/proc.h"
                      8: #include "../h/buf.h"
                      9: #include "../h/text.h"
                     10: #include "../h/map.h"
                     11: #include "../h/pte.h"
                     12: #include "../h/vm.h"
                     13: #include "../h/cmap.h"
                     14: 
                     15: /*
                     16:  * Expand the swap area for both the data and stack segments.
                     17:  * If space is not available for both, retract and return 0.
                     18:  */
                     19: swpexpand(ds, ss, dmp, smp)
                     20:        size_t ds, ss;
                     21:        register struct dmap *dmp, *smp;
                     22: {
                     23:        register struct dmap *tmp;
                     24:        register int ts;
                     25:        size_t ods;
                     26: 
                     27:        /*
                     28:         * If dmap isn't growing, do smap first.
                     29:         * This avoids anomalies if smap will try to grow and
                     30:         * fail, which otherwise would shrink ds without expanding
                     31:         * ss, a rather curious side effect!
                     32:         */
                     33:        if (dmp->dm_alloc > ds) {
                     34:                tmp = dmp; ts = ds;
                     35:                dmp = smp; ds = ss;
                     36:                smp = tmp; ss = ts;
                     37:        }
                     38:        ods = dmp->dm_size;
                     39:        if (vsexpand(ds, dmp, 0) == 0)
                     40:                goto bad;
                     41:        if (vsexpand(ss, smp, 0) == 0) {
                     42:                (void) vsexpand(ods, dmp, 1);
                     43:                goto bad;
                     44:        }
                     45:        return (1);
                     46: 
                     47: bad:
                     48:        u.u_error = ENOMEM;
                     49:        return (0);
                     50: }
                     51: 
                     52: /*
                     53:  * Expand or contract the virtual swap segment mapped
                     54:  * by the argument diskmap so as to just allow the given size.
                     55:  *
                     56:  * FOR NOW CANT RELEASE UNLESS SHRINKING TO ZERO, SINCE PAGEOUTS MAY
                     57:  * BE IN PROGRESS... TYPICALLY NEVER SHRINK ANYWAYS, SO DOESNT MATTER MUCH
                     58:  */
                     59: vsexpand(vssize, dmp, canshrink)
                     60:        register size_t vssize;
                     61:        register struct dmap *dmp;
                     62: {
                     63:        register int blk = DMMIN;
                     64:        register int vsbase = 0;
                     65:        register swblk_t *ip = dmp->dm_map;
                     66:        size_t oldsize = dmp->dm_size;
                     67:        size_t oldalloc = dmp->dm_alloc;
                     68: 
                     69:        while (vsbase < oldalloc || vsbase < vssize) {
                     70:                if (vsbase >= oldalloc) {
                     71:                        *ip = rmalloc(swapmap, ctod(blk));
                     72:                        if (*ip == 0) {
                     73:                                dmp->dm_size = vsbase;
                     74:                                if (vsexpand(oldsize, dmp, 1) == 0)
                     75:                                        panic("vsexpand");
                     76:                                return (0);
                     77:                        }
                     78:                        dmp->dm_alloc += blk;
                     79:                } else if (vssize == 0 ||
                     80:                    vsbase >= vssize && canshrink) {
                     81:                        rmfree(swapmap, ctod(blk), *ip);
                     82:                        *ip = 0;
                     83:                        dmp->dm_alloc -= blk;
                     84:                }
                     85:                vsbase += blk;
                     86:                if (blk < DMMAX)
                     87:                        blk *= 2;
                     88:                ip++;
                     89:                if (ip - dmp->dm_map > NDMAP)
                     90:                        panic("vmdrum NDMAP");
                     91:        }
                     92:        dmp->dm_size = vssize;
                     93:        return (1);
                     94: }
                     95: 
                     96: /*
                     97:  * Allocate swap space for a text segment,
                     98:  * in chunks of at most DMTEXT pages.
                     99:  */
                    100: vsxalloc(xp)
                    101:        struct text *xp;
                    102: {
                    103:        register int blk;
                    104:        register swblk_t *dp;
                    105:        swblk_t vsbase;
                    106: 
                    107:        if (xp->x_size > NXDAD * DMTEXT)
                    108:                panic("vsxalloc");
                    109:        dp = xp->x_daddr;
                    110:        for (vsbase = 0; vsbase < xp->x_size; vsbase += DMTEXT) {
                    111:                blk = xp->x_size - vsbase;
                    112:                if (blk > DMTEXT)
                    113:                        blk = DMTEXT;
                    114:                if ((*dp++ = rmalloc(swapmap, blk)) == 0) {
                    115:                        vsxfree(xp, vsbase);
                    116:                        return (0);
                    117:                }
                    118:        }
                    119:        if (xp->x_flag & XPAGI) {
                    120:                xp->x_ptdaddr = rmalloc(swapmap, clrnd(ctopt(xp->x_size)));
                    121:                if (xp->x_ptdaddr == 0) {
                    122:                        vsxfree(xp, xp->x_size);
                    123:                        return (0);
                    124:                }
                    125:        }
                    126:        return (1);
                    127: }
                    128: 
                    129: /*
                    130:  * Free the swap space of a text segment which
                    131:  * has been allocated ts pages.
                    132:  */
                    133: vsxfree(xp, ts)
                    134:        struct text *xp;
                    135:        int ts;
                    136: {
                    137:        register int blk;
                    138:        register swblk_t *dp;
                    139:        swblk_t vsbase;
                    140: 
                    141:        dp = xp->x_daddr;
                    142:        for (vsbase = 0; vsbase < ts; vsbase += DMTEXT) {
                    143:                blk = ts - vsbase;
                    144:                if (blk > DMTEXT)
                    145:                        blk = DMTEXT;
                    146:                rmfree(swapmap, blk, *dp);
                    147:                *dp++ = 0;
                    148:        }
                    149:        if ((xp->x_flag&XPAGI) && xp->x_ptdaddr) {
                    150:                rmfree(swapmap, clrnd(ctopt(xp->x_size)), xp->x_ptdaddr);
                    151:                xp->x_ptdaddr = 0;
                    152:        }
                    153: }
                    154: 
                    155: /*
                    156:  * Swap a segment of virtual memory to disk,
                    157:  * by locating the contiguous dirty pte's
                    158:  * and calling vschunk with each chunk.
                    159:  */
                    160: vsswap(p, pte, type, vsbase, vscount, dmp)
                    161:        struct proc *p;
                    162:        register struct pte *pte;
                    163:        int type;
                    164:        register int vsbase, vscount;
                    165:        struct dmap *dmp;
                    166: {
                    167:        register int size = 0;
                    168: 
                    169:        if (vscount % CLSIZE)
                    170:                panic("vsswap");
                    171:        for (;;) {
                    172:                if (vscount == 0 || !dirtycl(pte)) {
                    173:                        if (size) {
                    174:                                vschunk(p, vsbase, size, type, dmp);
                    175:                                vsbase += size;
                    176:                                size = 0;
                    177:                        }
                    178:                        if (vscount == 0)
                    179:                                return;
                    180:                        vsbase += CLSIZE;
                    181:                        if (pte->pg_fod == 0 && pte->pg_pfnum)
                    182:                                if (type == CTEXT)
                    183:                                        p->p_textp->x_rssize -= vmemfree(pte, CLSIZE);
                    184:                                else
                    185:                                        p->p_rssize -= vmemfree(pte, CLSIZE);
                    186:                } else {
                    187:                        size += CLSIZE;
                    188:                        mwait(pte->pg_pfnum);
                    189:                        if (anycl(pte, pg_m))
                    190:                                zapcl(pte, pg_vreadm) = 1;
                    191:                }
                    192:                vscount -= CLSIZE;
                    193:                if (type == CSTACK)
                    194:                        pte -= CLSIZE;
                    195:                else
                    196:                        pte += CLSIZE;
                    197:        }
                    198: }
                    199: 
                    200: vschunk(p, base, size, type, dmp)
                    201:        register struct proc *p;
                    202:        register int base, size;
                    203:        int type;
                    204:        struct dmap *dmp;
                    205: {
                    206:        register struct pte *pte;
                    207:        struct dblock db;
                    208:        unsigned v;
                    209: 
                    210:        if (type == CTEXT) {
                    211:                while (size > 0) {
                    212:                        db.db_size = DMTEXT - base % DMTEXT;
                    213:                        if (db.db_size > size)
                    214:                                db.db_size = size;
                    215:                        swap(p, p->p_textp->x_daddr[base/DMTEXT] + base%DMTEXT,
                    216:                            ptob(tptov(p, base)), ctob(db.db_size),
                    217:                            B_WRITE, 0, swapdev, 0);
                    218:                        p->p_textp->x_rssize -=
                    219:                            vmemfree(tptopte(p, base), db.db_size);
                    220:                        base += db.db_size;
                    221:                        size -= db.db_size;
                    222:                }
                    223:                return;
                    224:        }
                    225:        do {
                    226:                vstodb(base, size, dmp, &db, type == CSTACK);
                    227:                v = type==CSTACK ? sptov(p, base+db.db_size-1) : dptov(p, base);
                    228:                swap(p, db.db_base, ptob(v), ctob(db.db_size), B_WRITE, 0, swapdev, 0);
                    229:                pte = type==CSTACK ? sptopte(p, base+db.db_size-1) : dptopte(p, base);
                    230:                p->p_rssize -= vmemfree(pte, db.db_size);
                    231:                base += db.db_size;
                    232:                size -= db.db_size;
                    233:        } while (size != 0);
                    234: }
                    235: 
                    236: /*
                    237:  * Given a base/size pair in virtual swap area,
                    238:  * return a physical base/size pair which is the
                    239:  * (largest) initial, physically contiguous block.
                    240:  */
                    241: vstodb(vsbase, vssize, dmp, dbp, rev)
                    242:        register int vsbase, vssize;
                    243:        struct dmap *dmp;
                    244:        register struct dblock *dbp;
                    245: {
                    246:        register int blk = DMMIN;
                    247:        register swblk_t *ip = dmp->dm_map;
                    248:        extern int queueflag;
                    249: 
                    250:        if (vsbase < 0 || vssize < 0 || vsbase + vssize > dmp->dm_size)
                    251:                panic("vstodb");
                    252:        while (vsbase >= blk) {
                    253:                vsbase -= blk;
                    254:                if (blk < DMMAX)
                    255:                        blk *= 2;
                    256:                ip++;
                    257:        }
                    258:        if (*ip + blk > nswap)
                    259:                panic("vstodb *ip");
                    260:        dbp->db_size = imin(vssize, blk - vsbase);
                    261:        dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
                    262: }
                    263: 
                    264: /*
                    265:  * Convert a virtual page number 
                    266:  * to its corresponding disk block number.
                    267:  * Used in pagein/pageout to initiate single page transfers.
                    268:  */
                    269: swblk_t
                    270: vtod(p, v, dmap, smap)
                    271:        register struct proc *p;
                    272:        unsigned v;
                    273:        struct dmap *dmap, *smap;
                    274: {
                    275:        struct dblock db;
                    276:        int tp;
                    277: 
                    278:        if (isatsv(p, v)) {
                    279:                tp = vtotp(p, v);
                    280:                return (p->p_textp->x_daddr[tp/DMTEXT] + tp%DMTEXT);
                    281:        }
                    282:        if (isassv(p, v))
                    283:                vstodb(vtosp(p, v), 1, smap, &db, 1);
                    284:        else
                    285:                vstodb(vtodp(p, v), 1, dmap, &db, 0);
                    286:        return (db.db_base);
                    287: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.