diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -154,6 +154,8 @@ static u_long swap_total; static int sysctl_page_shift(SYSCTL_HANDLER_ARGS); +static uma_zone_t __read_mostly swap_biozone; + static SYSCTL_NODE(_vm_stats, OID_AUTO, swap, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "VM swap stats"); @@ -185,6 +187,11 @@ CTLFLAG_RD, &swap_free_completed, "Number of deferred frees completed"); +static int __read_mostly swap_reserved_new_bios = 65536; +SYSCTL_INT(_vm, OID_AUTO, swap_reserved_new_bios, CTLFLAG_RDTUN, + &swap_reserved_new_bios, 0, + "Number of reserved new swap bios for non-blocking allocation"); + static int sysctl_page_shift(SYSCTL_HANDLER_ARGS) { @@ -658,6 +665,13 @@ if (!uma_zone_reserve_kva(swpctrie_zone, n)) printf("Cannot reserve swap pctrie zone, " "reduce kern.maxswzone.\n"); + + /* Initialize the swap bio zone if requested. */ + if (swap_reserved_new_bios > 0) { + swap_biozone = g_io_new_uz("swap_bio"); + uma_prealloc(swap_biozone, swap_reserved_new_bios); + uma_zone_reserve(swap_biozone, swap_reserved_new_bios); + } } bool @@ -2880,20 +2894,20 @@ } swapgeom_acquire(cp); mtx_unlock(&sw_dev_mtx); - if (bp->b_iocmd == BIO_WRITE) - bio = g_new_bio(); - else - bio = g_alloc_bio(); - if (bio == NULL) { - mtx_lock(&sw_dev_mtx); - swapgeom_release(cp, sp); - mtx_unlock(&sw_dev_mtx); - bp->b_error = ENOMEM; - bp->b_ioflags |= BIO_ERROR; - printf("swap_pager: cannot allocate bio\n"); - bufdone(bp); - return; - } + if (bp->b_iocmd == BIO_WRITE) { + bio = g_new_bio_uz(swap_biozone); + if (__predict_false(bio == NULL)) { + mtx_lock(&sw_dev_mtx); + swapgeom_release(cp, sp); + mtx_unlock(&sw_dev_mtx); + bp->b_error = ENOMEM; + bp->b_ioflags |= BIO_ERROR; + printf("swap_pager: cannot allocate bio\n"); + bufdone(bp); + return; + } + } else + bio = g_alloc_bio_uz(swap_biozone); bp->b_caller1 = bio; bio->bio_caller1 = sp;