Annotation of researchv10no/sys/vm/vmdrum.c, revision 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.