From 21fde338acc9f79a41d32f22eaa801d5330f34c7 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 23 Sep 2008 21:03:52 +0000 Subject: [PATCH] Change the autoflush code to autoflush when a flush group reaches a 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 --- sys/vfs/hammer/hammer.h | 6 +++++- sys/vfs/hammer/hammer_inode.c | 19 +++++++++---------- sys/vfs/hammer/hammer_prune.c | 3 ++- sys/vfs/hammer/hammer_transaction.c | 7 ++++++- sys/vfs/hammer/hammer_vfsops.c | 5 ++++- sys/vfs/hammer/hammer_vnops.c | 12 ++---------- 6 files changed, 28 insertions(+), 24 deletions(-) diff --git a/sys/vfs/hammer/hammer.h b/sys/vfs/hammer/hammer.h index bb1155feef..00cd9db591 100644 --- a/sys/vfs/hammer/hammer.h +++ b/sys/vfs/hammer/hammer.h @@ -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, diff --git a/sys/vfs/hammer/hammer_inode.c b/sys/vfs/hammer/hammer_inode.c index dac2f06270..333b037a89 100644 --- a/sys/vfs/hammer/hammer_inode.c +++ b/sys/vfs/hammer/hammer_inode.c @@ -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. */ diff --git a/sys/vfs/hammer/hammer_prune.c b/sys/vfs/hammer/hammer_prune.c index 0c807a5ba7..c9baa3a143 100644 --- a/sys/vfs/hammer/hammer_prune.c +++ b/sys/vfs/hammer/hammer_prune.c @@ -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); diff --git a/sys/vfs/hammer/hammer_transaction.c b/sys/vfs/hammer/hammer_transaction.c index 2098b53b55..1f888fc778 100644 --- a/sys/vfs/hammer/hammer_transaction.c +++ b/sys/vfs/hammer/hammer_transaction.c @@ -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); } /* diff --git a/sys/vfs/hammer/hammer_vfsops.c b/sys/vfs/hammer/hammer_vfsops.c index 30f94cafae..ca6a112a16 100644 --- a/sys/vfs/hammer/hammer_vfsops.c +++ b/sys/vfs/hammer/hammer_vfsops.c @@ -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 @@ -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, diff --git a/sys/vfs/hammer/hammer_vnops.c b/sys/vfs/hammer/hammer_vnops.c index 3f725b4723..951a44a2c3 100644 --- a/sys/vfs/hammer/hammer_vnops.c +++ b/sys/vfs/hammer/hammer_vnops.c @@ -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 @@ -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; -- 2.41.0