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