]> granicus.if.org Git - zfs/commitdiff
Fix stack noinline
authorBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 26 Aug 2010 17:58:36 +0000 (10:58 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 31 Aug 2010 15:38:49 +0000 (08:38 -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've found as 'noinline' to prevent gcc from making
the optimization.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
lib/libzpool/include/sys/zfs_context.h
module/zfs/dbuf.c
module/zfs/dmu_send.c

index 55b117c218a1f767ac438d5b960b606ec5557dd8..f2776566c07606620b384e4df8dcc75a2bbac4c7 100644 (file)
@@ -75,6 +75,12 @@ extern "C" {
 #include <sys/sysevent/dev.h>
 #include <sys/sunddi.h>
 
+/*
+ * Stack
+ */
+
+#define  noinline      __attribute__((noinline))
+
 /*
  * Debugging
  */
index add2bc36d3d9be08e4e38beef1ee5e43b1a2df16..c1b27d4ef3386078f66be8be3605469aa3c795dc 100644 (file)
@@ -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;
index dc93dea853e0317588bdf05424cb1fb514af46d9..f13cfd316f909f99fc80f5cfed1c9665e3653df4 100644 (file)
@@ -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)
 {