Index: vm/vm_pager.c =================================================================== --- vm/vm_pager.c (revision 255404) +++ vm/vm_pager.c (working copy) @@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -176,9 +177,8 @@ static const int npagers = sizeof(pagertab) / size * (MAXPHYS == 64k) if you want to get the most efficiency. */ struct mtx_padalign pbuf_mtx; -static TAILQ_HEAD(swqueue, buf) bswlist; -static int bswneeded; vm_offset_t swapbkva; /* swap buffers kva */ +static vmem_t *pbuf_vmem; void vm_pager_init() @@ -185,7 +185,6 @@ vm_pager_init() { struct pagerops **pgops; - TAILQ_INIT(&bswlist); /* * Initialize known pagers */ @@ -206,7 +205,6 @@ vm_pager_bufferinit() * Now set up swap and physical I/O buffer headers. */ for (i = 0; i < nswbuf; i++, bp++) { - TAILQ_INSERT_HEAD(&bswlist, bp, b_freelist); BUF_LOCKINIT(bp); LIST_INIT(&bp->b_dep); bp->b_rcred = bp->b_wcred = NOCRED; @@ -215,6 +213,8 @@ vm_pager_bufferinit() cluster_pbuf_freecnt = nswbuf / 2; vnode_pbuf_freecnt = nswbuf / 2 + 1; + + pbuf_vmem = vmem_create("pbuf", 1, nswbuf, 1, 1, M_WAITOK | M_FIRSTFIT); } /* @@ -327,31 +327,22 @@ struct buf * getpbuf(int *pfreecnt) { struct buf *bp; + vmem_addr_t i; - mtx_lock(&pbuf_mtx); - - for (;;) { - if (pfreecnt) { - while (*pfreecnt == 0) { - msleep(pfreecnt, &pbuf_mtx, PVM, "wswbuf0", 0); - } + if (pfreecnt) { + mtx_lock(&pbuf_mtx); + while (*pfreecnt == 0) { + msleep(pfreecnt, &pbuf_mtx, PVM, "wswbuf0", 0); } - - /* get a bp from the swap buffer header pool */ - if ((bp = TAILQ_FIRST(&bswlist)) != NULL) - break; - - bswneeded = 1; - msleep(&bswneeded, &pbuf_mtx, PVM, "wswbuf1", 0); - /* loop in case someone else grabbed one */ + --*pfreecnt; + mtx_unlock(&pbuf_mtx); } - TAILQ_REMOVE(&bswlist, bp, b_freelist); - if (pfreecnt) - --*pfreecnt; - mtx_unlock(&pbuf_mtx); + /* get a bp from the swap buffer header pool */ + vmem_alloc(pbuf_vmem, 1, M_WAITOK | M_BESTFIT, &i); + bp = &swbuf[i - 1]; initpbuf(bp); - return bp; + return (bp); } /* @@ -364,21 +355,22 @@ struct buf * trypbuf(int *pfreecnt) { struct buf *bp; + vmem_addr_t i; mtx_lock(&pbuf_mtx); - if (*pfreecnt == 0 || (bp = TAILQ_FIRST(&bswlist)) == NULL) { + if (*pfreecnt == 0) { mtx_unlock(&pbuf_mtx); + return (NULL); + } + if (vmem_alloc(pbuf_vmem, 1, M_NOWAIT | M_BESTFIT, &i) != 0) { + mtx_unlock(&pbuf_mtx); return NULL; } - TAILQ_REMOVE(&bswlist, bp, b_freelist); - --*pfreecnt; - mtx_unlock(&pbuf_mtx); - + bp = &swbuf[i - 1]; initpbuf(bp); - - return bp; + return (bp); } /* @@ -405,18 +397,13 @@ relpbuf(struct buf *bp, int *pfreecnt) BUF_UNLOCK(bp); - mtx_lock(&pbuf_mtx); - TAILQ_INSERT_HEAD(&bswlist, bp, b_freelist); - - if (bswneeded) { - bswneeded = 0; - wakeup(&bswneeded); - } + vmem_free(pbuf_vmem, bp - swbuf + 1, 1); if (pfreecnt) { + mtx_lock(&pbuf_mtx); if (++*pfreecnt == 1) wakeup(pfreecnt); + mtx_unlock(&pbuf_mtx); } - mtx_unlock(&pbuf_mtx); } /*