From 419c80e6dc2cd83372a77dfaf6f04e446d1f0267 Mon Sep 17 00:00:00 2001 From: DeHackEd Date: Mon, 12 Jun 2017 14:41:03 -0400 Subject: [PATCH] Reduce stack usage of dsl_dir_tempreserve_impl Buildbots and zfs-tests regularly see 7 kilobytes of stack usage with this function. Convert self-calls to iterations Reviewed-by: Brian Behlendorf Signed-off-by: DHE Closes #6219 --- module/zfs/dsl_dir.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/module/zfs/dsl_dir.c b/module/zfs/dsl_dir.c index 98aeff5dc..a3ef5896a 100644 --- a/module/zfs/dsl_dir.c +++ b/module/zfs/dsl_dir.c @@ -1119,11 +1119,16 @@ dsl_dir_tempreserve_impl(dsl_dir_t *dd, uint64_t asize, boolean_t netfree, boolean_t ignorequota, list_t *tr_list, dmu_tx_t *tx, boolean_t first) { - uint64_t txg = tx->tx_txg; + uint64_t txg; uint64_t quota; struct tempreserve *tr; - int retval = EDQUOT; - uint64_t ref_rsrv = 0; + int retval; + uint64_t ref_rsrv; + +top_of_function: + txg = tx->tx_txg; + retval = EDQUOT; + ref_rsrv = 0; ASSERT3U(txg, !=, 0); ASSERT3S(asize, >, 0); @@ -1220,10 +1225,18 @@ dsl_dir_tempreserve_impl(dsl_dir_t *dd, uint64_t asize, boolean_t netfree, /* see if it's OK with our parent */ if (dd->dd_parent != NULL && parent_rsrv != 0) { - boolean_t ismos = (dsl_dir_phys(dd)->dd_head_dataset_obj == 0); + /* + * Recurse on our parent without recursion. This has been + * observed to be potentially large stack usage even within + * the test suite. Largest seen stack was 7632 bytes on linux. + */ + + dd = dd->dd_parent; + asize = parent_rsrv; + ignorequota = (dsl_dir_phys(dd)->dd_head_dataset_obj == 0); + first = B_FALSE; + goto top_of_function; - return (dsl_dir_tempreserve_impl(dd->dd_parent, - parent_rsrv, netfree, ismos, tr_list, tx, B_FALSE)); } else { return (0); }