]> granicus.if.org Git - zfs/commitdiff
Add fix-stack-noinline topic branch
authorBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 16 Jun 2010 21:34:41 +0000 (14:34 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 16 Jun 2010 21:34:41 +0000 (14:34 -0700)
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 [new file with mode: 0644]
.topmsg [new file with mode: 0644]
lib/libzpool/include/sys/zfs_context.h
module/zfs/dbuf.c
module/zfs/dmu_send.c

diff --git a/.topdeps b/.topdeps
new file mode 100644 (file)
index 0000000..1f7391f
--- /dev/null
+++ b/.topdeps
@@ -0,0 +1 @@
+master
diff --git a/.topmsg b/.topmsg
new file mode 100644 (file)
index 0000000..1b1a9cf
--- /dev/null
+++ b/.topmsg
@@ -0,0 +1,9 @@
+From: Brian Behlendorf <behlendorf1@llnl.gov>
+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 <behlendorf1@llnl.gov>
index 9a6d712e53fe9fb11a267a11665c588eec948975..8c16ec1ef7b511b8107606b7f6fdb2deb888ecd1 100644 (file)
@@ -77,6 +77,12 @@ extern "C" {
 #include <sys/sysevent/dev.h>
 #include <sys/sunddi.h>
 
+/*
+ * Stack
+ */
+
+#define  noinline      __attribute__((noinline))
+
 /*
  * Debugging
  */
index 42ae439972e4ce25ebd2ef38692af468bca7e0ac..354114934c9cac43bb4190b036965f5ea84a10a9 100644 (file)
@@ -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;
index 6b00b73b43be124143e7582da4ba1edcefb04f1b..2f837a1e973ca158be86d1862d8b6bcfce1dcdf0 100644 (file)
@@ -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)
 {