Annotation of 43BSDReno/sys/kern/vm_mem.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution is only permitted until one year after the first shipment
        !             6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
        !             7:  * binary forms are permitted provided that: (1) source distributions retain
        !             8:  * this entire copyright notice and comment, and (2) distributions including
        !             9:  * binaries display the following acknowledgement:  This product includes
        !            10:  * software developed by the University of California, Berkeley and its
        !            11:  * contributors'' in the documentation or other materials provided with the
        !            12:  * distribution and in all advertising materials mentioning features or use
        !            13:  * of this software.  Neither the name of the University nor the names of
        !            14:  * its contributors may be used to endorse or promote products derived from
        !            15:  * this software without specific prior written permission.
        !            16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            19:  *
        !            20:  *     @(#)vm_mem.c    7.15 (Berkeley) 6/28/90
        !            21:  */
        !            22: 
        !            23: #include "param.h"
        !            24: #include "systm.h"
        !            25: #include "cmap.h"
        !            26: #include "user.h"
        !            27: #include "proc.h"
        !            28: #include "text.h"
        !            29: #include "vm.h"
        !            30: #include "buf.h"
        !            31: #include "vnode.h"
        !            32: #include "mount.h"
        !            33: #include "trace.h"
        !            34: 
        !            35: #include "machine/pte.h"
        !            36: 
        !            37: /*
        !            38:  * Allocate memory, and always succeed
        !            39:  * by jolting page-out daemon
        !            40:  * so as to obtain page frames.
        !            41:  * To be used in conjunction with vmemfree().
        !            42:  */
        !            43: vmemall(pte, size, p, type)
        !            44:        register struct pte *pte;
        !            45:        int size;
        !            46:        struct proc *p;
        !            47: {
        !            48:        register int m;
        !            49: 
        !            50:        if (size <= 0 || size > maxmem)
        !            51:                panic("vmemall size");
        !            52:        while (size > 0) {
        !            53:                if (freemem < desfree)
        !            54:                        outofmem();
        !            55:                while (freemem == 0)
        !            56:                        sleep((caddr_t)&freemem, PSWP+2);
        !            57:                m = imin(size, freemem);
        !            58:                (void) memall(pte, m, p, type);
        !            59:                size -= m;
        !            60:                pte += m;
        !            61:        }
        !            62:        if (freemem < desfree)
        !            63:                outofmem();
        !            64:        /*
        !            65:         * Always succeeds, but return success for
        !            66:         * vgetu and vgetpt (e.g.) which call either
        !            67:         * memall or vmemall depending on context.
        !            68:         */
        !            69:        return (1);
        !            70: }
        !            71: 
        !            72: /*
        !            73:  * Free valid and reclaimable page frames belonging to the
        !            74:  * count pages starting at pte.  If a page is valid
        !            75:  * or reclaimable and locked (but not a system page), then
        !            76:  * we simply mark the page as c_gone and let the pageout
        !            77:  * daemon free the page when it is through with it.
        !            78:  * If a page is reclaimable, and already in the free list, then
        !            79:  * we mark the page as c_gone, and (of course) don't free it.
        !            80:  *
        !            81:  * Determines the largest contiguous cluster of
        !            82:  * valid pages and frees them in one call to memfree.
        !            83:  */
        !            84: vmemfree(pte, count)
        !            85:        register struct pte *pte;
        !            86:        register int count;
        !            87: {
        !            88:        register struct cmap *c;
        !            89:        register struct pte *spte;
        !            90:        register int j;
        !            91:        int size, pcnt;
        !            92: #ifdef notdef
        !            93:        int fileno;
        !            94: #endif
        !            95: 
        !            96:        if (count % CLSIZE)
        !            97:                panic("vmemfree");
        !            98:        for (size = 0, pcnt = 0; count > 0; pte += CLSIZE, count -= CLSIZE) {
        !            99:                if (pte->pg_fod == 0 && pte->pg_pfnum) {
        !           100:                        c = &cmap[pgtocm(pte->pg_pfnum)];
        !           101:                        pcnt += CLSIZE;
        !           102:                        if (c->c_lock && c->c_type != CSYS) {
        !           103:                                for (j = 0; j < CLSIZE; j++)
        !           104:                                        *(int *)(pte+j) &= PG_PROT;
        !           105:                                c->c_gone = 1;
        !           106:                                goto free;
        !           107:                        }
        !           108:                        if (c->c_free) {
        !           109:                                pcnt -= CLSIZE;
        !           110:                                for (j = 0; j < CLSIZE; j++)
        !           111:                                        *(int *)(pte+j) &= PG_PROT;
        !           112:                                if (c->c_type == CTEXT)
        !           113:                                        distpte(&text[c->c_ndx], c->c_page,
        !           114:                                            pte);
        !           115:                                c->c_gone = 1;
        !           116:                                goto free;
        !           117:                        }
        !           118:                        if (size == 0)
        !           119:                                spte = pte;
        !           120:                        size += CLSIZE;
        !           121:                        continue;
        !           122:                }
        !           123: #ifdef notdef
        !           124:                /* Don't do anything with mapped ptes */
        !           125:                if (pte->pg_fod && pte->pg_v)
        !           126:                        goto free;
        !           127: #endif
        !           128:                if (pte->pg_fod) {
        !           129: #ifdef notdef
        !           130:                        fileno = ((struct fpte *)pte)->pg_fileno;
        !           131:                        if (fileno < NOFILE)
        !           132:                                panic("vmemfree vread");
        !           133: #endif
        !           134:                        for (j = 0; j < CLSIZE; j++)
        !           135:                                *(int *)(pte+j) &= PG_PROT;
        !           136:                }
        !           137: free:
        !           138:                if (size) {
        !           139:                        memfree(spte, size, 1);
        !           140:                        size = 0;
        !           141:                }
        !           142:        }
        !           143:        if (size)
        !           144:                memfree(spte, size, 1);
        !           145:        return (pcnt);
        !           146: }
        !           147: 
        !           148: /*
        !           149:  * Unlink a page frame from the free list -
        !           150:  *
        !           151:  * Performed if the page being reclaimed
        !           152:  * is in the free list.
        !           153:  */
        !           154: munlink(c)
        !           155:        register struct cmap *c;
        !           156: {
        !           157:        register int next, prev;
        !           158: 
        !           159:        next = c->c_next;
        !           160:        prev = c->c_prev;
        !           161:        cmap[prev].c_next = next;
        !           162:        cmap[next].c_prev = prev;
        !           163:        c->c_free = 0;
        !           164:        if (freemem < minfree)
        !           165:                outofmem();
        !           166:        freemem -= CLSIZE;
        !           167: }
        !           168: 
        !           169: /*
        !           170:  * Allocate memory -
        !           171:  *
        !           172:  * The free list appears as a doubly linked list
        !           173:  * in the core map with cmap[0] serving as a header.
        !           174:  */
        !           175: memall(pte, size, p, type)
        !           176:        register struct pte *pte;
        !           177:        int size;
        !           178:        struct proc *p;
        !           179: {
        !           180:        register struct cmap *c;
        !           181:        register struct pte *rpte;
        !           182:        register struct proc *rp;
        !           183:        int i, j, next, curpos;
        !           184:        unsigned pf;
        !           185:        struct cmap *c1, *c2;
        !           186:        int s;
        !           187: 
        !           188:        if (size % CLSIZE)
        !           189:                panic("memall");
        !           190:        s = splimp();
        !           191:        if (size > freemem) {
        !           192:                splx(s);
        !           193:                return (0);
        !           194:        }
        !           195:        trace(TR_MALL, size, u.u_procp->p_pid);
        !           196:        for (i = size; i > 0; i -= CLSIZE) {
        !           197:                curpos = cmap[CMHEAD].c_next;
        !           198:                c = &cmap[curpos];
        !           199:                freemem -= CLSIZE;
        !           200:                next = c->c_next;
        !           201:                cmap[CMHEAD].c_next = next;
        !           202:                cmap[next].c_prev = CMHEAD;
        !           203:                if (c->c_free == 0)
        !           204:                        panic("dup mem alloc");
        !           205:                if (cmtopg(curpos) > maxfree)
        !           206:                        panic("bad mem alloc");
        !           207:                if (c->c_gone == 0 && c->c_type != CSYS) {
        !           208:                        if (c->c_type == CTEXT)
        !           209:                                rp = text[c->c_ndx].x_caddr;
        !           210:                        else
        !           211:                                rp = &proc[c->c_ndx];
        !           212:                        while (rp->p_flag & SNOVM)
        !           213:                                rp = rp->p_xlink;
        !           214:                        switch (c->c_type) {
        !           215: 
        !           216:                        case CTEXT:
        !           217:                                rpte = tptopte(rp, c->c_page);
        !           218:                                break;
        !           219: 
        !           220:                        case CDATA:
        !           221:                                rpte = dptopte(rp, c->c_page);
        !           222:                                break;
        !           223: 
        !           224:                        case CSTACK:
        !           225:                                rpte = sptopte(rp, c->c_page);
        !           226:                                break;
        !           227:                        }
        !           228:                        zapcl(rpte, pg_pfnum) = 0;
        !           229:                        if (c->c_type == CTEXT)
        !           230:                                distpte(&text[c->c_ndx], c->c_page, rpte);
        !           231:                }
        !           232:                switch (type) {
        !           233: 
        !           234:                case CSYS:
        !           235:                        c->c_ndx = p->p_ndx;
        !           236:                        break;
        !           237: 
        !           238:                case CTEXT:
        !           239:                        c->c_page = vtotp(p, ptetov(p, pte));
        !           240:                        c->c_ndx = p->p_textp - &text[0];
        !           241:                        break;
        !           242: 
        !           243:                case CDATA:
        !           244:                        c->c_page = vtodp(p, ptetov(p, pte));
        !           245:                        c->c_ndx = p->p_ndx;
        !           246:                        break;
        !           247: 
        !           248:                case CSTACK:
        !           249:                        c->c_page = vtosp(p, ptetov(p, pte));
        !           250:                        c->c_ndx = p->p_ndx;
        !           251:                        break;
        !           252:                }
        !           253:                if (c->c_blkno) {
        !           254:                        /*
        !           255:                         * This is very like munhash(), except
        !           256:                         * that we really don't want to bother
        !           257:                         * to calculate a vp to pass to it.
        !           258:                         */
        !           259:                        j = CMHASH(c->c_blkno);
        !           260:                        c1 = &cmap[cmhash[j]];
        !           261:                        if (c1 == c)
        !           262:                                cmhash[j] = c1->c_hlink;
        !           263:                        else {
        !           264:                                for (;;) {
        !           265:                                        if (c1 == ecmap)
        !           266:                                                panic("memall ecmap");
        !           267:                                        c2 = c1;
        !           268:                                        c1 = &cmap[c2->c_hlink];
        !           269:                                        if (c1 == c)
        !           270:                                                break;
        !           271:                                }
        !           272:                                c2->c_hlink = c1->c_hlink;
        !           273:                        }
        !           274:                        if (mfind(c->c_vp, (daddr_t)(u_long)c->c_blkno))
        !           275:                                panic("memall mfind");
        !           276:                        HOLDRELE(c1->c_vp);
        !           277:                        c1->c_vp = NULLVP;
        !           278:                        c1->c_blkno = 0;
        !           279:                        c1->c_hlink = 0;
        !           280:                }
        !           281:                pf = cmtopg(curpos);
        !           282:                for (j = 0; j < CLSIZE; j++) {
        !           283:                        *(int *)pte = 0;
        !           284:                        pte++->pg_pfnum = pf++;
        !           285:                }
        !           286:                c->c_free = 0;
        !           287:                c->c_gone = 0;
        !           288:                if (c->c_intrans || c->c_want)
        !           289:                        panic("memall intrans|want");
        !           290:                c->c_lock = 1;
        !           291:                c->c_type = type;
        !           292:        }
        !           293:        splx(s);
        !           294:        return (size);
        !           295: }
        !           296: 
        !           297: /*
        !           298:  * Free memory -
        !           299:  *
        !           300:  * The page frames being returned are inserted
        !           301:  * to the head/tail of the free list depending
        !           302:  * on whether there is any possible future use of them.
        !           303:  *
        !           304:  * If the freemem count had been zero,
        !           305:  * the processes sleeping for memory
        !           306:  * are awakened.
        !           307:  */
        !           308: memfree(pte, size, detach)
        !           309:        register struct pte *pte;
        !           310:        register int size;
        !           311: {
        !           312:        register int i, j, prev, next;
        !           313:        register struct cmap *c;
        !           314:        int s;
        !           315:        
        !           316:        if (size % CLSIZE)
        !           317:                panic("memfree");
        !           318:        if (freemem < CLSIZE * KLMAX)
        !           319:                wakeup((caddr_t)&freemem);
        !           320:        while (size > 0) {
        !           321:                size -= CLSIZE;
        !           322:                i = pte->pg_pfnum;
        !           323:                if (i < firstfree || i > maxfree)
        !           324:                        panic("bad mem free");
        !           325:                i = pgtocm(i);
        !           326:                c = &cmap[i];
        !           327:                if (c->c_free)
        !           328:                        panic("dup mem free");
        !           329:                if (detach && c->c_type != CSYS) {
        !           330:                        for (j = 0; j < CLSIZE; j++)
        !           331:                                *(int *)(pte+j) &= PG_PROT;
        !           332:                        c->c_gone = 1;
        !           333:                }
        !           334:                s = splimp();
        !           335:                if (detach && c->c_blkno == 0) {
        !           336:                        next = cmap[CMHEAD].c_next;
        !           337:                        cmap[next].c_prev = i;
        !           338:                        c->c_prev = CMHEAD;
        !           339:                        c->c_next = next;
        !           340:                        cmap[CMHEAD].c_next = i;
        !           341:                } else {
        !           342:                        prev = cmap[CMHEAD].c_prev;
        !           343:                        cmap[prev].c_next = i;
        !           344:                        c->c_next = CMHEAD;
        !           345:                        c->c_prev = prev;
        !           346:                        cmap[CMHEAD].c_prev = i;
        !           347:                }
        !           348:                c->c_free = 1;
        !           349:                freemem += CLSIZE;
        !           350:                splx(s);
        !           351:                pte += CLSIZE;
        !           352:        }
        !           353: }
        !           354: 
        !           355: /*
        !           356:  * Enter clist block c on the hash chains.
        !           357:  * It contains file system block bn from vnode vp.
        !           358:  */
        !           359: mhash(c, vp, bn)
        !           360:        register struct cmap *c;
        !           361:        struct vnode *vp;
        !           362:        daddr_t bn;
        !           363: {
        !           364:        register int i = CMHASH(bn);
        !           365: 
        !           366:        c->c_hlink = cmhash[i];
        !           367:        cmhash[i] = c - cmap;
        !           368:        c->c_blkno = bn;
        !           369:        c->c_vp = vp;
        !           370:        VHOLD(vp);
        !           371: }
        !           372: 
        !           373: /*
        !           374:  * Pull the clist entry of <vp,bn> off the hash chains
        !           375:  * if present.
        !           376:  */
        !           377: munhash(vp, bn)
        !           378:        struct vnode *vp;
        !           379:        daddr_t bn;
        !           380: {
        !           381:        int i = CMHASH(bn);
        !           382:        register struct cmap *c1, *c2;
        !           383:        int s = splimp();
        !           384: 
        !           385:        c1 = &cmap[cmhash[i]];
        !           386:        if (c1 == ecmap)
        !           387:                goto out;
        !           388:        if (c1->c_blkno == bn && c1->c_vp == vp)
        !           389:                cmhash[i] = c1->c_hlink;
        !           390:        else {
        !           391:                for (;;) {
        !           392:                        c2 = c1;
        !           393:                        c1 = &cmap[c2->c_hlink];
        !           394:                        if (c1 == ecmap)
        !           395:                                goto out;
        !           396:                        if (c1->c_blkno == bn && c1->c_vp == vp)
        !           397:                                break;
        !           398:                }
        !           399:                c2->c_hlink = c1->c_hlink;
        !           400:        }
        !           401:        HOLDRELE(vp);
        !           402:        c1->c_vp = NULLVP;
        !           403:        c1->c_blkno = 0;
        !           404:        c1->c_hlink = 0;
        !           405: out:
        !           406:        splx(s);
        !           407: }
        !           408: 
        !           409: /*
        !           410:  * Look for block bn of vnode vp in the free pool.
        !           411:  * Currently it should not be possible to find it unless it is
        !           412:  * c_free and c_gone, although this may later not be true.
        !           413:  * (This is because active texts are locked against file system
        !           414:  * writes by the system.)
        !           415:  */
        !           416: struct cmap *
        !           417: mfind(vp, bn)
        !           418:        struct vnode *vp;
        !           419:        daddr_t bn;
        !           420: {
        !           421:        register struct cmap *c1 = &cmap[cmhash[CMHASH(bn)]];
        !           422:        int si = splimp();
        !           423: 
        !           424:        while (c1 != ecmap) {
        !           425:                if (c1->c_blkno == bn && c1->c_vp == vp) {
        !           426:                        splx(si);
        !           427:                        return (c1);
        !           428:                }
        !           429:                c1 = &cmap[c1->c_hlink];
        !           430:        }
        !           431:        splx(si);
        !           432:        return ((struct cmap *)0);
        !           433: }
        !           434: 
        !           435: /*
        !           436:  * Purge blocks from vnode vp from incore cache
        !           437:  * before umount().
        !           438:  */
        !           439: mpurge(vp)
        !           440:        struct vnode *vp;
        !           441: {
        !           442:        register struct cmap *c1, *c2;
        !           443:        register int i;
        !           444:        int relcnt = 0, si = splimp();
        !           445: 
        !           446:        for (i = 0; i < CMHSIZ; i++) {
        !           447: more:
        !           448:                c1 = &cmap[cmhash[i]];
        !           449:                if (c1 == ecmap)
        !           450:                        continue;
        !           451:                if (c1->c_vp == vp)
        !           452:                        cmhash[i] = c1->c_hlink;
        !           453:                else {
        !           454:                        for (;;) {
        !           455:                                c2 = c1;
        !           456:                                c1 = &cmap[c1->c_hlink];
        !           457:                                if (c1 == ecmap)
        !           458:                                        goto cont;
        !           459:                                if (c1->c_vp == vp)
        !           460:                                        break;
        !           461:                        }
        !           462:                        c2->c_hlink = c1->c_hlink;
        !           463:                }
        !           464:                relcnt++;
        !           465:                c1->c_vp = NULLVP;
        !           466:                c1->c_blkno = 0;
        !           467:                c1->c_hlink = 0;
        !           468:                goto more;
        !           469: cont:
        !           470:                ;
        !           471:        }
        !           472:        while (relcnt--)
        !           473:                HOLDRELE(vp);
        !           474:        splx(si);
        !           475: }
        !           476: 
        !           477: /*
        !           478:  * Purge blocks for filesystem mp from incore cache
        !           479:  * before umount().
        !           480:  */
        !           481: mpurgemp(mp)
        !           482:        struct mount *mp;
        !           483: {
        !           484:        register struct cmap *c1, *c2;
        !           485:        register int i;
        !           486:        int s = splimp();
        !           487: 
        !           488: more:
        !           489:        for (i = 0; i < CMHSIZ; i++) {
        !           490:                c1 = &cmap[cmhash[i]];
        !           491:                if (c1 == ecmap)
        !           492:                        continue;
        !           493:                if (mp == NULL || c1->c_vp->v_mount == mp)
        !           494:                        cmhash[i] = c1->c_hlink;
        !           495:                else {
        !           496:                        for (;;) {
        !           497:                                c2 = c1;
        !           498:                                c1 = &cmap[c1->c_hlink];
        !           499:                                if (c1 == ecmap)
        !           500:                                        goto cont;
        !           501:                                if (c1->c_vp->v_mount == mp)
        !           502:                                        break;
        !           503:                        }
        !           504:                        c2->c_hlink = c1->c_hlink;
        !           505:                }
        !           506:                (void) splx(s);
        !           507:                HOLDRELE(c1->c_vp);
        !           508:                s = splimp();
        !           509:                c1->c_vp = NULLVP;
        !           510:                c1->c_blkno = 0;
        !           511:                c1->c_hlink = 0;
        !           512:                goto more;
        !           513: cont:
        !           514:                ;
        !           515:        }
        !           516:        (void) splx(s);
        !           517: }
        !           518: 
        !           519: /*
        !           520:  * Initialize core map
        !           521:  */
        !           522: meminit(first, last)
        !           523:        int first, last;
        !           524: {
        !           525:        register int i;
        !           526:        register struct cmap *c;
        !           527: 
        !           528:        firstfree = clrnd(first);
        !           529:        maxfree = clrnd(last - (CLSIZE - 1));
        !           530:        freemem = maxfree - firstfree;
        !           531:        ecmx = ecmap - cmap;
        !           532:        if (ecmx < freemem / CLSIZE)
        !           533:                freemem = ecmx * CLSIZE;
        !           534:        for (i = 1; i <= freemem / CLSIZE; i++) {
        !           535:                cmap[i-1].c_next = i;
        !           536:                c = &cmap[i];
        !           537:                c->c_prev = i-1;
        !           538:                c->c_free = 1;
        !           539:                c->c_gone = 1;
        !           540:                c->c_type = CSYS;
        !           541:                c->c_blkno = 0;
        !           542:        }
        !           543:        cmap[freemem / CLSIZE].c_next = CMHEAD;
        !           544:        for (i = 0; i < CMHSIZ; i++)
        !           545:                cmhash[i] = ecmx;
        !           546:        cmap[CMHEAD].c_prev = freemem / CLSIZE;
        !           547:        cmap[CMHEAD].c_type = CSYS;
        !           548:        avefree = freemem;
        !           549: }
        !           550: 
        !           551: #ifdef notdef
        !           552: /*
        !           553:  * Wait for frame pf to become unlocked
        !           554:  * if it is currently locked.
        !           555:  */
        !           556: mwait(c)
        !           557:        struct cmap *c;
        !           558: {
        !           559: 
        !           560:        mlock(c);
        !           561:        munlock(c);
        !           562: }
        !           563: 
        !           564: /*
        !           565:  * Lock a page frame.
        !           566:  */
        !           567: mlock(c)
        !           568:        register struct cmap *c;
        !           569: {
        !           570: 
        !           571:        while (c->c_lock) {
        !           572:                c->c_want = 1;
        !           573:                sleep((caddr_t)c, PSWP+1);
        !           574:        }
        !           575:        c->c_lock = 1;
        !           576: }
        !           577: 
        !           578: /*
        !           579:  * Unlock a page frame.
        !           580:  */
        !           581: munlock(c)
        !           582:        register struct cmap *c;
        !           583: {
        !           584: 
        !           585:        if (c->c_lock == 0)
        !           586:                panic("dup page unlock");
        !           587:        if (c->c_want) {
        !           588:                wakeup((caddr_t)c);
        !           589:                c->c_want = 0;
        !           590:        }
        !           591:        c->c_lock = 0;
        !           592: }
        !           593: #endif
        !           594: 
        !           595: /* 
        !           596:  * Lock a virtual segment.
        !           597:  *
        !           598:  * For each cluster of pages, if the cluster is not valid,
        !           599:  * touch it to fault it in, otherwise just lock page frame.
        !           600:  * Called from physio to ensure that the pages 
        !           601:  * participating in raw i/o are valid and locked.
        !           602:  */
        !           603: vslock(base, count)
        !           604:        caddr_t base;
        !           605: {
        !           606:        register unsigned v;
        !           607:        register int npf;
        !           608:        register struct pte *pte;
        !           609:        register struct cmap *c;
        !           610: 
        !           611: #if defined(tahoe)
        !           612:        /*
        !           613:         * TAHOE I/O drivers may arrive here on raw I/O,
        !           614:         * base will be a system address in this case
        !           615:         */
        !           616:        if (((int)base & KERNBASE) == KERNBASE)         /* system addresses */
        !           617:                return;
        !           618: #endif
        !           619:        v = clbase(btop(base));
        !           620:        pte = vtopte(u.u_procp, v);
        !           621:        npf = btoc(count + ((int)base & CLOFSET));
        !           622:        for (; npf > 0; pte += CLSIZE, v += CLSIZE, npf -= CLSIZE) {
        !           623: retry:
        !           624:                if (pte->pg_v) {
        !           625: #ifdef MAPMEM
        !           626:                        if (pte->pg_fod)        /* mapped page */
        !           627:                                continue;
        !           628: #endif
        !           629:                        c = &cmap[pgtocm(pte->pg_pfnum)];
        !           630:                        if (c->c_lock) {
        !           631:                                MLOCK(c);
        !           632:                                MUNLOCK(c);
        !           633:                                goto retry;
        !           634:                        }
        !           635:                        MLOCK(c);
        !           636:                } else
        !           637:                        pagein(ctob(v), 1);     /* return it locked */
        !           638:        }
        !           639: }
        !           640: 
        !           641: /* 
        !           642:  * Unlock a virtual segment.
        !           643:  */
        !           644: vsunlock(base, count, rw)
        !           645:        caddr_t base;
        !           646: {
        !           647:        register struct pte *pte;
        !           648:        register struct cmap *c;
        !           649:        unsigned v;
        !           650:        int npf;
        !           651: 
        !           652: #if defined(tahoe)
        !           653:        /*
        !           654:         * TAHOE I/O drivers may arrive here on raw I/O,
        !           655:         * base will be a system address in this case
        !           656:         */
        !           657:        if (((int)base & KERNBASE) == KERNBASE)         /* system addresses */
        !           658:                return;
        !           659: #endif
        !           660:        v = clbase(btop(base));
        !           661:        pte = vtopte(u.u_procp, v);
        !           662:        npf = btoc(count + ((int)base & CLOFSET));
        !           663:        for (; npf > 0; pte += CLSIZE, npf -= CLSIZE) {
        !           664: #ifdef MAPMEM
        !           665:                if (pte->pg_fod && pte->pg_v)   /* mapped page */
        !           666:                        continue;
        !           667: #endif
        !           668:                c = &cmap[pgtocm(pte->pg_pfnum)];
        !           669:                MUNLOCK(c);
        !           670:                if (rw == B_READ)       /* Reading from device writes memory */
        !           671:                        pte->pg_m = 1;
        !           672:        }
        !           673: }

unix.superglobalmegacorp.com

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