From d297febad2bf4c02f3de5e223d9e9fcaff48dce4 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 16 Jun 2010 14:30:40 -0700 Subject: [PATCH 1/5] Remove fix-stack dependency from fix-branch --- .topdeps | 1 - 1 file changed, 1 deletion(-) diff --git a/.topdeps b/.topdeps index 903387bf5f..5d5f7ac42b 100644 --- a/.topdeps +++ b/.topdeps @@ -4,7 +4,6 @@ fix-evict-dbufs fix-newlines fix-no-zmod fix-rwlocks -fix-stack fix-taskq fix-list fix-strncat From bbdb8184ec90242ad12239ef0cf7652634345e94 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 16 Jun 2010 14:34:41 -0700 Subject: [PATCH 2/5] Add fix-stack-noinline topic branch Certain function must never be automatically inlined by gcc because they are stack heavy or called recursively. This patch flags all such functions I have found as 'noinline' to prevent gcc from making the optimization. --- .topdeps | 1 + .topmsg | 9 +++++++++ lib/libzpool/include/sys/zfs_context.h | 6 ++++++ module/zfs/dbuf.c | 12 ++++++++++-- module/zfs/dmu_send.c | 10 +++++----- 5 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 .topdeps create mode 100644 .topmsg diff --git a/.topdeps b/.topdeps new file mode 100644 index 0000000000..1f7391f92b --- /dev/null +++ b/.topdeps @@ -0,0 +1 @@ +master diff --git a/.topmsg b/.topmsg new file mode 100644 index 0000000000..1b1a9cfa4a --- /dev/null +++ b/.topmsg @@ -0,0 +1,9 @@ +From: Brian Behlendorf +Subject: [PATCH] fix stack noinline + +Certain function must never be automatically inlined by gcc because +they are stack heavy or called recursively. This patch flags all +such functions I've found as 'noinline' to prevent gcc from making +the optimization. + +Signed-off-by: Brian Behlendorf diff --git a/lib/libzpool/include/sys/zfs_context.h b/lib/libzpool/include/sys/zfs_context.h index 9a6d712e53..8c16ec1ef7 100644 --- a/lib/libzpool/include/sys/zfs_context.h +++ b/lib/libzpool/include/sys/zfs_context.h @@ -77,6 +77,12 @@ extern "C" { #include #include +/* + * Stack + */ + +#define noinline __attribute__((noinline)) + /* * Debugging */ diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 42ae439972..354114934c 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -2085,7 +2085,11 @@ dbuf_check_blkptr(dnode_t *dn, dmu_buf_impl_t *db) } } -static void +/* dbuf_sync_indirect() is called recursively from dbuf_sync_list() so it + * is critical the we not allow the compiler to inline this function in to + * dbuf_sync_list() thereby drastically bloating the stack usage. + */ +noinline static void dbuf_sync_indirect(dbuf_dirty_record_t *dr, dmu_tx_t *tx) { dmu_buf_impl_t *db = dr->dr_dbuf; @@ -2125,7 +2129,11 @@ dbuf_sync_indirect(dbuf_dirty_record_t *dr, dmu_tx_t *tx) zio_nowait(zio); } -static void +/* dbuf_sync_leaf() is called recursively from dbuf_sync_list() so it is + * critical the we not allow the compiler to inline this function in to + * dbuf_sync_list() thereby drastically bloating the stack usage. + */ +noinline static void dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx) { arc_buf_t **datap = &dr->dt.dl.dr_data; diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index 6b00b73b43..2f837a1e97 100644 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@ -921,7 +921,7 @@ restore_read(struct restorearg *ra, int len) return (rv); } -static void +noinline static void backup_byteswap(dmu_replay_record_t *drr) { #define DO64(X) (drr->drr_u.X = BSWAP_64(drr->drr_u.X)) @@ -1001,7 +1001,7 @@ backup_byteswap(dmu_replay_record_t *drr) #undef DO32 } -static int +noinline static int restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro) { int err; @@ -1085,7 +1085,7 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro) } /* ARGSUSED */ -static int +noinline static int restore_freeobjects(struct restorearg *ra, objset_t *os, struct drr_freeobjects *drrfo) { @@ -1109,7 +1109,7 @@ restore_freeobjects(struct restorearg *ra, objset_t *os, return (0); } -static int +noinline static int restore_write(struct restorearg *ra, objset_t *os, struct drr_write *drrw) { @@ -1254,7 +1254,7 @@ restore_spill(struct restorearg *ra, objset_t *os, struct drr_spill *drrs) } /* ARGSUSED */ -static int +noinline static int restore_free(struct restorearg *ra, objset_t *os, struct drr_free *drrf) { From 23d291df442a24fc265e32af3fbdcc4f1308f5d3 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 16 Jun 2010 14:35:11 -0700 Subject: [PATCH 3/5] New TopGit dependency: fix-stack-noinline --- .topdeps | 1 + 1 file changed, 1 insertion(+) diff --git a/.topdeps b/.topdeps index 5d5f7ac42b..4b17552c20 100644 --- a/.topdeps +++ b/.topdeps @@ -17,3 +17,4 @@ fix-kstat-xuio fix-stack-lzjb fix-stack-dsl_dir_open_spa fix-stack-dsl_deleg_get +fix-stack-noinline From e163b08ba3559a348a09774dbadcc3fb75b1b9ad Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 16 Jun 2010 14:39:06 -0700 Subject: [PATCH 4/5] Add fix-stack-dmu_objset_snapshot topic branch Reduce stack usage by 276 bytes by moving the snaparg struct from the stack to the heap. We have limited stack space we must not waste. --- .topdeps | 1 + .topmsg | 7 +++++++ module/zfs/dmu_objset.c | 34 +++++++++++++++++++--------------- 3 files changed, 27 insertions(+), 15 deletions(-) create mode 100644 .topdeps create mode 100644 .topmsg diff --git a/.topdeps b/.topdeps new file mode 100644 index 0000000000..1f7391f92b --- /dev/null +++ b/.topdeps @@ -0,0 +1 @@ +master diff --git a/.topmsg b/.topmsg new file mode 100644 index 0000000000..2290c89c30 --- /dev/null +++ b/.topmsg @@ -0,0 +1,7 @@ +From: Brian Behlendorf +Subject: [PATCH] fix stack dmu_objset_snapshot + +Reduce stack usage by 276 bytes by moving the snaparg struct from the +stack to the heap. We have limited stack space we must not waste. + +Signed-off-by: Brian Behlendorf diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c index 690e6ecdee..32bb614c81 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -878,45 +878,49 @@ dmu_objset_snapshot(char *fsname, char *snapname, nvlist_t *props, boolean_t recursive) { dsl_sync_task_t *dst; - struct snaparg sn; + struct snaparg *sn; spa_t *spa; int err; - (void) strcpy(sn.failed, fsname); + sn = kmem_alloc(sizeof (struct snaparg), KM_SLEEP); + (void) strcpy(sn->failed, fsname); err = spa_open(fsname, &spa, FTAG); - if (err) + if (err) { + kmem_free(sn, sizeof (struct snaparg)); return (err); + } - sn.dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); - sn.snapname = snapname; - sn.props = props; - sn.recursive = recursive; + sn->dstg = dsl_sync_task_group_create(spa_get_dsl(spa)); + sn->snapname = snapname; + sn->props = props; + sn->recursive = recursive; if (recursive) { err = dmu_objset_find(fsname, - dmu_objset_snapshot_one, &sn, DS_FIND_CHILDREN); + dmu_objset_snapshot_one, sn, DS_FIND_CHILDREN); } else { - err = dmu_objset_snapshot_one(fsname, &sn); + err = dmu_objset_snapshot_one(fsname, sn); } if (err == 0) - err = dsl_sync_task_group_wait(sn.dstg); + err = dsl_sync_task_group_wait(sn->dstg); - for (dst = list_head(&sn.dstg->dstg_tasks); dst; - dst = list_next(&sn.dstg->dstg_tasks, dst)) { + for (dst = list_head(&sn->dstg->dstg_tasks); dst; + dst = list_next(&sn->dstg->dstg_tasks, dst)) { objset_t *os = dst->dst_arg1; dsl_dataset_t *ds = os->os_dsl_dataset; if (dst->dst_err) - dsl_dataset_name(ds, sn.failed); + dsl_dataset_name(ds, sn->failed); zil_resume(dmu_objset_zil(os)); dmu_objset_rele(os, &sn); } if (err) - (void) strcpy(fsname, sn.failed); - dsl_sync_task_group_destroy(sn.dstg); + (void) strcpy(fsname, sn->failed); + dsl_sync_task_group_destroy(sn->dstg); spa_close(spa, FTAG); + kmem_free(sn, sizeof (struct snaparg)); return (err); } From bf02bcb6eeb1ed0553293664743b5ab723afe0ea Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Wed, 16 Jun 2010 14:39:39 -0700 Subject: [PATCH 5/5] New TopGit dependency: fix-stack-dmu_objset_snapshot --- .topdeps | 1 + 1 file changed, 1 insertion(+) diff --git a/.topdeps b/.topdeps index 4b17552c20..3ed5fa8b2f 100644 --- a/.topdeps +++ b/.topdeps @@ -18,3 +18,4 @@ fix-stack-lzjb fix-stack-dsl_dir_open_spa fix-stack-dsl_deleg_get fix-stack-noinline +fix-stack-dmu_objset_snapshot