swaponsomething() skips the first 2 pages. Subtract these 2 pages from sw_nblcks as well as from swap_pager_avail and swap_total to keep track the correct numbers. Given sw_used and sw_nblcks now keeps track of correct pages, we can use these to check remaining pages blist_alloc(). This improves situation where some of swap devices are filled. Index: sys/vm/swap_pager.c =================================================================== --- sys/vm/swap_pager.c (revision 324645) +++ sys/vm/swap_pager.c (working copy) @@ -131,6 +130,12 @@ #define SWAP_META_PAGES PCTRIE_COUNT /* + * SWAP_DEVICE_START_OFFSET is to skip first two blocks in order to avoid + * overwriting any bsd label at the front of the partition. + */ +#define SWAP_DEVICE_START_OFFSET 2 + +/* * A swblk structure maps each page index within a * SWAP_META_PAGES-aligned and sized range to the address of an * on-disk swap block (or SWAPBLK_NONE). The collection of these @@ -693,7 +753,7 @@ for (i = 0; i < nswapdev; i++) { if (sp == NULL) sp = TAILQ_FIRST(&swtailq); - if (!(sp->sw_flags & SW_CLOSING)) { + if (!(sp->sw_flags & SW_CLOSING) && (sp->sw_nblks - sp->sw_used >= npages)) { blk = blist_alloc(sp->sw_blist, npages); if (blk != SWAPBLK_NONE) { blk += sp->sw_first; @@ -2169,11 +2257,12 @@ } sp = malloc(sizeof *sp, M_VMPGDATA, M_WAITOK | M_ZERO); + /* Can this fail? */ sp->sw_vp = vp; sp->sw_id = id; sp->sw_dev = dev; sp->sw_flags = 0; - sp->sw_nblks = nblks; + sp->sw_nblks = nblks - SWAP_DEVICE_START_OFFSET; sp->sw_used = 0; sp->sw_strategy = strategy; sp->sw_close = close; @@ -2180,11 +2269,12 @@ sp->sw_flags = flags; sp->sw_blist = blist_create(nblks, M_WAITOK); + /* Can thsi fail? */ /* * Do not free the first two block in order to avoid overwriting * any bsd label at the front of the partition */ - blist_free(sp->sw_blist, 2, nblks - 2); + blist_free(sp->sw_blist, SWAP_DEVICE_START_OFFSET, sp->sw_nblks); dvbase = 0; mtx_lock(&sw_dev_mtx); @@ -2202,8 +2296,8 @@ sp->sw_end = dvbase + nblks; TAILQ_INSERT_TAIL(&swtailq, sp, sw_list); nswapdev++; - swap_pager_avail += nblks - 2; - swap_total += (vm_ooffset_t)nblks * PAGE_SIZE; + swap_pager_avail += sp->sw_nblks; + swap_total += (vm_ooffset_t)(sp->sw_nblks) * PAGE_SIZE; swapon_check_swzone(); swp_sizecheck(); mtx_unlock(&sw_dev_mtx); @@ -2298,7 +2393,7 @@ */ mtx_lock(&sw_dev_mtx); sp->sw_flags |= SW_CLOSING; - swap_pager_avail -= blist_fill(sp->sw_blist, 0, nblks); + swap_pager_avail -= blist_fill(sp->sw_blist, SWAP_DEVICE_START_OFFSET, nblks); swap_total -= (vm_ooffset_t)nblks * PAGE_SIZE; mtx_unlock(&sw_dev_mtx);