summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2010-08-26 10:58:36 -0700
committerBrian Behlendorf <[email protected]>2010-08-31 08:38:49 -0700
commit60948de1ef976aabaa3630707bcc8b5867508507 (patch)
tree12d5530b229402e5b9f939f52eff043e84d3da76
parent18a89ba43d3e5e8a31d50838c93ec26d1cb27429 (diff)
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 <[email protected]>
-rw-r--r--lib/libzpool/include/sys/zfs_context.h6
-rw-r--r--module/zfs/dbuf.c12
-rw-r--r--module/zfs/dmu_send.c10
3 files changed, 21 insertions, 7 deletions
diff --git a/lib/libzpool/include/sys/zfs_context.h b/lib/libzpool/include/sys/zfs_context.h
index 55b117c21..f2776566c 100644
--- a/lib/libzpool/include/sys/zfs_context.h
+++ b/lib/libzpool/include/sys/zfs_context.h
@@ -76,6 +76,12 @@ extern "C" {
#include <sys/sunddi.h>
/*
+ * Stack
+ */
+
+#define noinline __attribute__((noinline))
+
+/*
* Debugging
*/
diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c
index add2bc36d..c1b27d4ef 100644
--- a/module/zfs/dbuf.c
+++ b/module/zfs/dbuf.c
@@ -2291,7 +2291,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;
@@ -2334,7 +2338,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 dc93dea85..f13cfd316 100644
--- a/module/zfs/dmu_send.c
+++ b/module/zfs/dmu_send.c
@@ -937,7 +937,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))
@@ -1019,7 +1019,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;
@@ -1103,7 +1103,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)
{
@@ -1127,7 +1127,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)
{
@@ -1273,7 +1273,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)
{