Module Name: src Committed By: jdolecek Date: Wed Jun 24 16:29:34 UTC 2020
Modified Files: src/external/cddl/osnet/dist/uts/common/fs/zfs: dsl_scan.c Log Message: reduce stack usage in dsl_scan_recurse() - allocate memory for temporary zbookmark_phys_t using kmem_alloc() rather than stack; this recuses several times usually, and this saves 2x sizeof(zbookmark_phys_t) == 64 bytes per recursion part of fix for PR kern/55402 by Frank Kardel To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 \ src/external/cddl/osnet/dist/uts/common/fs/zfs/dsl_scan.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/dsl_scan.c diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/dsl_scan.c:1.2 src/external/cddl/osnet/dist/uts/common/fs/zfs/dsl_scan.c:1.3 --- src/external/cddl/osnet/dist/uts/common/fs/zfs/dsl_scan.c:1.2 Wed Jun 24 16:23:16 2020 +++ src/external/cddl/osnet/dist/uts/common/fs/zfs/dsl_scan.c Wed Jun 24 16:29:34 2020 @@ -397,7 +397,7 @@ static void dsl_scan_visitbp(blkptr_t *b dmu_objset_type_t ostype, dmu_tx_t *tx); static void dsl_scan_visitdnode(dsl_scan_t *, dsl_dataset_t *ds, dmu_objset_type_t ostype, - dnode_phys_t *dnp, uint64_t object, dmu_tx_t *tx); + dnode_phys_t *dnp, uint64_t object, dmu_tx_t *tx, zbookmark_phys_t *); void dsl_free(dsl_pool_t *dp, uint64_t txg, const blkptr_t *bp) @@ -585,9 +585,8 @@ dsl_scan_zil(dsl_pool_t *dp, zil_header_ /* ARGSUSED */ static void dsl_scan_prefetch(dsl_scan_t *scn, arc_buf_t *buf, blkptr_t *bp, - uint64_t objset, uint64_t object, uint64_t blkid) + uint64_t objset, uint64_t object, uint64_t blkid, zbookmark_phys_t *czb) { - zbookmark_phys_t czb; arc_flags_t flags = ARC_FLAG_NOWAIT | ARC_FLAG_PREFETCH; if (zfs_no_scrub_prefetch) @@ -597,11 +596,11 @@ dsl_scan_prefetch(dsl_scan_t *scn, arc_b (BP_GET_LEVEL(bp) == 0 && BP_GET_TYPE(bp) != DMU_OT_DNODE)) return; - SET_BOOKMARK(&czb, objset, object, BP_GET_LEVEL(bp), blkid); + SET_BOOKMARK(czb, objset, object, BP_GET_LEVEL(bp), blkid); (void) arc_read(scn->scn_zio_root, scn->scn_dp->dp_spa, bp, NULL, NULL, ZIO_PRIORITY_ASYNC_READ, - ZIO_FLAG_CANFAIL | ZIO_FLAG_SCAN_THREAD, &flags, &czb); + ZIO_FLAG_CANFAIL | ZIO_FLAG_SCAN_THREAD, &flags, czb); } static boolean_t @@ -659,6 +658,7 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_da blkptr_t *cbp; int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT; arc_buf_t *buf; + zbookmark_phys_t *czb; err = arc_read(NULL, dp->dp_spa, bp, arc_getbuf_func, &buf, ZIO_PRIORITY_ASYNC_READ, zio_flags, &flags, zb); @@ -666,19 +666,19 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_da scn->scn_phys.scn_errors++; return (err); } + czb = kmem_alloc(sizeof (*czb), KM_SLEEP); for (i = 0, cbp = buf->b_data; i < epb; i++, cbp++) { dsl_scan_prefetch(scn, buf, cbp, zb->zb_objset, - zb->zb_object, zb->zb_blkid * epb + i); + zb->zb_object, zb->zb_blkid * epb + i, czb); } for (i = 0, cbp = buf->b_data; i < epb; i++, cbp++) { - zbookmark_phys_t czb; - - SET_BOOKMARK(&czb, zb->zb_objset, zb->zb_object, + SET_BOOKMARK(czb, zb->zb_objset, zb->zb_object, zb->zb_level - 1, zb->zb_blkid * epb + i); - dsl_scan_visitbp(cbp, &czb, dnp, + dsl_scan_visitbp(cbp, czb, dnp, ds, scn, ostype, tx); } + kmem_free(czb, sizeof (*czb)); arc_buf_destroy(buf, &buf); } else if (BP_GET_TYPE(bp) == DMU_OT_DNODE) { arc_flags_t flags = ARC_FLAG_WAIT; @@ -686,6 +686,7 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_da int i, j; int epb = BP_GET_LSIZE(bp) >> DNODE_SHIFT; arc_buf_t *buf; + zbookmark_phys_t *czb; err = arc_read(NULL, dp->dp_spa, bp, arc_getbuf_func, &buf, ZIO_PRIORITY_ASYNC_READ, zio_flags, &flags, zb); @@ -693,23 +694,27 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_da scn->scn_phys.scn_errors++; return (err); } + czb = kmem_alloc(sizeof (*czb), KM_SLEEP); for (i = 0, cdnp = buf->b_data; i < epb; i++, cdnp++) { for (j = 0; j < cdnp->dn_nblkptr; j++) { blkptr_t *cbp = &cdnp->dn_blkptr[j]; dsl_scan_prefetch(scn, buf, cbp, - zb->zb_objset, zb->zb_blkid * epb + i, j); + zb->zb_objset, zb->zb_blkid * epb + i, j, + czb); } } for (i = 0, cdnp = buf->b_data; i < epb; i++, cdnp++) { dsl_scan_visitdnode(scn, ds, ostype, - cdnp, zb->zb_blkid * epb + i, tx); + cdnp, zb->zb_blkid * epb + i, tx, czb); } + kmem_free(czb, sizeof (*czb)); arc_buf_destroy(buf, &buf); } else if (BP_GET_TYPE(bp) == DMU_OT_OBJSET) { arc_flags_t flags = ARC_FLAG_WAIT; objset_phys_t *osp; arc_buf_t *buf; + zbookmark_phys_t *czb; err = arc_read(NULL, dp->dp_spa, bp, arc_getbuf_func, &buf, ZIO_PRIORITY_ASYNC_READ, zio_flags, &flags, zb); @@ -720,8 +725,9 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_da osp = buf->b_data; + czb = kmem_alloc(sizeof (*czb), KM_SLEEP); dsl_scan_visitdnode(scn, ds, osp->os_type, - &osp->os_meta_dnode, DMU_META_DNODE_OBJECT, tx); + &osp->os_meta_dnode, DMU_META_DNODE_OBJECT, tx, czb); if (OBJSET_BUF_HAS_USERUSED(buf)) { /* @@ -732,11 +738,12 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_da */ dsl_scan_visitdnode(scn, ds, osp->os_type, &osp->os_groupused_dnode, - DMU_GROUPUSED_OBJECT, tx); + DMU_GROUPUSED_OBJECT, tx, czb); dsl_scan_visitdnode(scn, ds, osp->os_type, &osp->os_userused_dnode, - DMU_USERUSED_OBJECT, tx); + DMU_USERUSED_OBJECT, tx, czb); } + kmem_free(czb, sizeof (*czb)); arc_buf_destroy(buf, &buf); } @@ -746,25 +753,22 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_da static void dsl_scan_visitdnode(dsl_scan_t *scn, dsl_dataset_t *ds, dmu_objset_type_t ostype, dnode_phys_t *dnp, - uint64_t object, dmu_tx_t *tx) + uint64_t object, dmu_tx_t *tx, zbookmark_phys_t *czb) { int j; for (j = 0; j < dnp->dn_nblkptr; j++) { - zbookmark_phys_t czb; - - SET_BOOKMARK(&czb, ds ? ds->ds_object : 0, object, + SET_BOOKMARK(czb, ds ? ds->ds_object : 0, object, dnp->dn_nlevels - 1, j); dsl_scan_visitbp(&dnp->dn_blkptr[j], - &czb, dnp, ds, scn, ostype, tx); + czb, dnp, ds, scn, ostype, tx); } if (dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) { - zbookmark_phys_t czb; - SET_BOOKMARK(&czb, ds ? ds->ds_object : 0, object, + SET_BOOKMARK(czb, ds ? ds->ds_object : 0, object, 0, DMU_SPILL_BLKID); dsl_scan_visitbp(&dnp->dn_spill, - &czb, dnp, ds, scn, ostype, tx); + czb, dnp, ds, scn, ostype, tx); } }