Annotation of researchv10no/sys/vm/vmdrum.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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