diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c --- a/sys/geom/geom_io.c +++ b/sys/geom/geom_io.c @@ -137,12 +137,17 @@ return (bp); } +static int reserved_new_bios = 65536; + struct bio * g_new_bio(void) { struct bio *bp; - bp = uma_zalloc(biozone, M_NOWAIT | M_ZERO); + bp = uma_zalloc(biozone, M_NOWAIT | M_ZERO | + (reserved_new_bios > 0 ? M_USE_RESERVE : 0)); + if (__predict_false(NULL == bp)) + printf("g_new_bio(): failed to allocate\n"); #ifdef KTR if (KTR_GEOM_ENABLED) { struct stack st; @@ -193,7 +198,8 @@ { struct bio *bp2; - bp2 = uma_zalloc(biozone, M_NOWAIT | M_ZERO); + bp2 = uma_zalloc(biozone, M_NOWAIT | M_ZERO | + (reserved_new_bios > 0 ? M_USE_RESERVE : 0)); if (bp2 != NULL) { bp2->bio_parent = bp; bp2->bio_cmd = bp->bio_cmd; @@ -279,6 +285,14 @@ NULL, NULL, NULL, NULL, 0, 0); + /* + * XXX the reservation of a uma(9) zone cannot be altered if it is serving + * any items. + */ + if (reserved_new_bios > 0) { + uma_prealloc(biozone, reserved_new_bios); + uma_zone_reserve(biozone, reserved_new_bios); + } } int @@ -734,6 +748,9 @@ SYSCTL_INT(_kern_geom, OID_AUTO, inflight_transient_maps, CTLFLAG_RD, &inflight_transient_maps, 0, "Current count of the active transient maps"); +SYSCTL_INT(_kern_geom, OID_AUTO, reserved_new_bios, CTLFLAG_RDTUN, + &reserved_new_bios, 0, + "Number of reserved new bios for non-blocking allocation"); static int g_io_transient_map_bio(struct bio *bp)