Change the autoflush code to autoflush when a flush group reaches a
authorMatthew Dillon <dillon@dragonflybsd.org>
Tue, 23 Sep 2008 21:03:52 +0000 (21:03 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Tue, 23 Sep 2008 21:03:52 +0000 (21:03 +0000)
certain point rather then trying to do it from the reclaim code.  This
smooths out the flush sequences.  The default is 2000, adjustable via
the vfs.hammer.autoflush sysctl.

Move hammer_inode_waitreclaims() calls.  In particular, remove the calls
in the VOP_CLOSE() path.  The problem with waiting for excessive reclaims to
drop in these paths is that the inode/vnode operation in question is probably
cached.  Thus unrelated programs, even those just opening /dev/null (if /dev
is on a HAMMER filesystem), can wind up blocking in hmrrcm for no good reason.

Instead defer the hammer_inode_waitreclaims() call to the end of the
transaction code if a new inode had to be created during the transaction.
Thus we tend to block on operations that did not have previously cached
vnodes to work with instead of operations on cached vnodes.

Reported-by: Hasso Tepper <hasso@estpak.ee>
sys/vfs/hammer/hammer.h
sys/vfs/hammer/hammer_inode.c
sys/vfs/hammer/hammer_prune.c
sys/vfs/hammer/hammer_transaction.c
sys/vfs/hammer/hammer_vfsops.c
sys/vfs/hammer/hammer_vnops.c

index bb1155f..00cd9db 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.127 2008/08/29 20:19:08 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.128 2008/09/23 21:03:52 dillon Exp $
  */
 /*
  * This header file contains structures used internally by the HAMMERFS
@@ -110,11 +110,14 @@ struct hammer_transaction {
        u_int64_t       time;
        u_int32_t       time32;
        int             sync_lock_refs;
+       int             flags;
        struct hammer_volume *rootvol;
 };
 
 typedef struct hammer_transaction *hammer_transaction_t;
 
+#define HAMMER_TRANSF_NEWINODE 0x0001
+
 /*
  * HAMMER locks
  */
@@ -821,6 +824,7 @@ extern int hammer_bio_count;
 extern int hammer_verify_zone;
 extern int hammer_verify_data;
 extern int hammer_write_mode;
+extern int hammer_autoflush;
 extern int64_t hammer_contention_count;
 
 void   hammer_critical_error(hammer_mount_t hmp, hammer_inode_t ip,
index dac2f06..333b037 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/vfs/hammer/hammer_inode.c,v 1.111 2008/09/17 21:44:20 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_inode.c,v 1.112 2008/09/23 21:03:52 dillon Exp $
  */
 
 #include "hammer.h"
@@ -220,15 +220,6 @@ hammer_vop_reclaim(struct vop_reclaim_args *ap)
                        ++hammer_count_reclaiming;
                        ++hmp->inode_reclaims;
                        ip->flags |= HAMMER_INODE_RECLAIM;
-
-                       /*
-                        * Poke the flusher.  If we don't do this programs
-                        * will start to stall on the reclaiming count.
-                        */
-                       if (hmp->inode_reclaims > HAMMER_RECLAIM_FLUSH &&
-                          (hmp->inode_reclaims & 255) == 0) {
-                              hammer_flusher_async(hmp, NULL);
-                       }
                }
                hammer_rel_inode(ip, 1);
        }
@@ -493,6 +484,7 @@ retry:
                ip = NULL;
        }
        hammer_done_cursor(&cursor);
+       trans->flags |= HAMMER_TRANSF_NEWINODE;
        return (ip);
 }
 
@@ -1665,6 +1657,13 @@ hammer_flush_inode_core(hammer_inode_t ip, hammer_flush_group_t flg, int flags)
        ++hammer_count_iqueued;
        ++flg->total_count;
 
+       /*
+        * If the flush group reaches the autoflush limit we want to signal
+        * the flusher.  This is particularly important for remove()s.
+        */
+       if (flg->total_count == hammer_autoflush)
+               flags |= HAMMER_FLUSH_SIGNAL;
+
        /*
         * We need to be able to vfsync/truncate from the backend.
         */
index 0c807a5..c9baa3a 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/vfs/hammer/hammer_prune.c,v 1.18 2008/07/14 03:20:49 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_prune.c,v 1.19 2008/09/23 21:03:52 dillon Exp $
  */
 
 #include "hammer.h"
@@ -319,6 +319,7 @@ prune_check_nlinks(hammer_cursor_t cursor, hammer_btree_leaf_elm_t elm)
                                elm->base.obj_id);
                }
                hammer_rel_inode(ip, 0);
+               hammer_inode_waitreclaims(cursor->trans->hmp);
        } else {
                kprintf("unable to prune disconnected inode %016llx\n",
                        elm->base.obj_id);
index 2098b53..1f888fc 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/vfs/hammer/hammer_transaction.c,v 1.24 2008/07/19 18:44:49 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_transaction.c,v 1.25 2008/09/23 21:03:52 dillon Exp $
  */
 
 #include "hammer.h"
@@ -55,6 +55,7 @@ hammer_start_transaction(struct hammer_transaction *trans,
        KKASSERT(error == 0);
        trans->tid = 0;
        trans->sync_lock_refs = 0;
+       trans->flags = 0;
 
        getmicrotime(&tv);
        trans->time = (unsigned long)tv.tv_sec * 1000000ULL + tv.tv_usec;
@@ -77,6 +78,7 @@ hammer_simple_transaction(struct hammer_transaction *trans,
        KKASSERT(error == 0);
        trans->tid = 0;
        trans->sync_lock_refs = 0;
+       trans->flags = 0;
 
        getmicrotime(&tv);
        trans->time = (unsigned long)tv.tv_sec * 1000000ULL + tv.tv_usec;
@@ -106,6 +108,7 @@ hammer_start_transaction_fls(struct hammer_transaction *trans,
        KKASSERT(error == 0);
        trans->tid = hammer_alloc_tid(hmp, 1);
        trans->sync_lock_refs = 1;
+       trans->flags = 0;
 
        getmicrotime(&tv);
        trans->time = (unsigned long)tv.tv_sec * 1000000ULL + tv.tv_usec;
@@ -122,6 +125,8 @@ hammer_done_transaction(struct hammer_transaction *trans)
        expected_lock_refs = (trans->type == HAMMER_TRANS_FLS) ? 1 : 0;
        KKASSERT(trans->sync_lock_refs == expected_lock_refs);
        trans->sync_lock_refs = 0;
+       if (trans->flags & HAMMER_TRANSF_NEWINODE)
+               hammer_inode_waitreclaims(trans->hmp);
 }
 
 /*
index 30f94ca..ca6a112 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/vfs/hammer/hammer_vfsops.c,v 1.71 2008/09/17 21:44:20 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_vfsops.c,v 1.72 2008/09/23 21:03:52 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -94,6 +94,7 @@ int hammer_count_io_locked;
 int hammer_limit_dirtybufspace;                /* per-mount */
 int hammer_limit_recs;                 /* as a whole XXX */
 int hammer_limit_iqueued;              /* per-mount */
+int hammer_autoflush = 2000;           /* auto flush */
 int hammer_bio_count;
 int hammer_verify_zone;
 int hammer_verify_data = 1;
@@ -201,6 +202,8 @@ SYSCTL_QUAD(_vfs_hammer, OID_AUTO, zone_limit, CTLFLAG_RW,
           &hammer_zone_limit, 0, "");
 SYSCTL_QUAD(_vfs_hammer, OID_AUTO, contention_count, CTLFLAG_RW,
           &hammer_contention_count, 0, "");
+SYSCTL_INT(_vfs_hammer, OID_AUTO, autoflush, CTLFLAG_RW,
+          &hammer_autoflush, 0, "");
 SYSCTL_INT(_vfs_hammer, OID_AUTO, verify_zone, CTLFLAG_RW,
           &hammer_verify_zone, 0, "");
 SYSCTL_INT(_vfs_hammer, OID_AUTO, verify_data, CTLFLAG_RW,
index 3f725b4..951a44a 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/vfs/hammer/hammer_vnops.c,v 1.97 2008/09/21 02:58:31 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_vnops.c,v 1.98 2008/09/23 21:03:52 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -568,10 +568,7 @@ static
 int
 hammer_vop_close(struct vop_close_args *ap)
 {
-       hammer_inode_t ip = VTOI(ap->a_vp);
-
-       if ((ip->flags | ip->sync_flags) & HAMMER_INODE_MODMASK)
-               hammer_inode_waitreclaims(ip->hmp);
+       /*hammer_inode_t ip = VTOI(ap->a_vp);*/
        return (vop_stdclose(ap));
 }
 
@@ -1041,7 +1038,6 @@ hammer_vop_nlink(struct vop_nlink_args *ap)
                cache_setvp(nch, ap->a_vp);
        }
        hammer_done_transaction(&trans);
-       hammer_inode_waitreclaims(dip->hmp);
        return (error);
 }
 
@@ -1112,7 +1108,6 @@ hammer_vop_nmkdir(struct vop_nmkdir_args *ap)
                }
        }
        hammer_done_transaction(&trans);
-       hammer_inode_waitreclaims(dip->hmp);
        return (error);
 }
 
@@ -1878,8 +1873,6 @@ done:
        if (error == 0)
                hammer_modify_inode(ip, modflags);
        hammer_done_transaction(&trans);
-       if (ap->a_vp->v_opencount == 0)
-               hammer_inode_waitreclaims(ip->hmp);
        return (error);
 }
 
@@ -2772,7 +2765,6 @@ retry:
        } else {
                hammer_done_cursor(&cursor);
        }
-       hammer_inode_waitreclaims(dip->hmp);
        if (error == EDEADLK)
                goto retry;