From: Matthew Dillon Date: Mon, 21 Feb 2011 02:26:17 +0000 (-0800) Subject: HAMMER - Fix long stalls when writing out core files X-Git-Tag: v2.10.0~267^2~39 X-Git-Url: http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/a117fbeb5f7e15c128fb94d038d5382d8d03483c HAMMER - Fix long stalls when writing out core files * Fix a long-stall case (hmrwww) due to a broken pipelining algorithm when using large write()s to write out large files. --- diff --git a/sys/vfs/hammer/hammer.h b/sys/vfs/hammer/hammer.h index f85e6c5..a0bb98e 100644 --- a/sys/vfs/hammer/hammer.h +++ b/sys/vfs/hammer/hammer.h @@ -437,7 +437,7 @@ typedef struct hammer_inode *hammer_inode_t; #define HAMMER_INODE_DELETED 0x0080 /* inode delete (backend) */ #define HAMMER_INODE_DELONDISK 0x0100 /* delete synchronized to disk */ #define HAMMER_INODE_RO 0x0200 /* read-only (because of as-of) */ -#define HAMMER_INODE_UNUSED0400 0x0400 +#define HAMMER_INODE_RECSW 0x0400 /* waiting on data record flush */ #define HAMMER_INODE_DONDISK 0x0800 /* data records may be on disk */ #define HAMMER_INODE_BUFS 0x1000 /* dirty high level bps present */ #define HAMMER_INODE_REFLUSH 0x2000 /* flush on dependancy / reflush */ diff --git a/sys/vfs/hammer/hammer_object.c b/sys/vfs/hammer/hammer_object.c index 8786cc8..56b4a97 100644 --- a/sys/vfs/hammer/hammer_object.c +++ b/sys/vfs/hammer/hammer_object.c @@ -447,8 +447,11 @@ hammer_rel_mem_record(struct hammer_record *record) if (RB_EMPTY(&record->ip->rec_tree)) hammer_test_inode(record->ip); - if (ip->rsv_recs == hammer_limit_inode_recs - 1) + if ((ip->flags & HAMMER_INODE_RECSW) && + ip->rsv_recs <= hammer_limit_inode_recs/2) { + ip->flags &= ~HAMMER_INODE_RECSW; wakeup(&ip->rsv_recs); + } } /* diff --git a/sys/vfs/hammer/hammer_vfsops.c b/sys/vfs/hammer/hammer_vfsops.c index fd1e7d1..d83d900 100644 --- a/sys/vfs/hammer/hammer_vfsops.c +++ b/sys/vfs/hammer/hammer_vfsops.c @@ -104,7 +104,7 @@ int hammer_count_io_locked; int hammer_limit_dirtybufspace; /* per-mount */ int hammer_limit_running_io; /* per-mount */ int hammer_limit_recs; /* as a whole XXX */ -int hammer_limit_inode_recs = 1024; /* per inode */ +int hammer_limit_inode_recs = 2048; /* per inode */ int hammer_limit_reclaim; int hammer_live_dedup_cache_size = DEDUP_CACHE_SIZE; int hammer_limit_redo = 4096 * 1024; /* per inode */ diff --git a/sys/vfs/hammer/hammer_vnops.c b/sys/vfs/hammer/hammer_vnops.c index 21e6106..fa1d68b 100644 --- a/sys/vfs/hammer/hammer_vnops.c +++ b/sys/vfs/hammer/hammer_vnops.c @@ -581,15 +581,18 @@ hammer_vop_write(struct vop_write_args *ap) * Control the number of pending records associated with * this inode. If too many have accumulated start a * flush. Try to maintain a pipeline with the flusher. + * + * NOTE: It is possible for other sources to grow the + * records but not necessarily issue another flush, + * so use a timeout and ensure that a re-flush occurs. */ if (ip->rsv_recs >= hammer_limit_inode_recs) { hammer_flush_inode(ip, HAMMER_FLUSH_SIGNAL); - } - if (ip->rsv_recs >= hammer_limit_inode_recs * 2) { - while (ip->rsv_recs >= hammer_limit_inode_recs) { + while (ip->rsv_recs >= hammer_limit_inode_recs * 2) { + ip->flags |= HAMMER_INODE_RECSW; tsleep(&ip->rsv_recs, 0, "hmrwww", hz); + hammer_flush_inode(ip, HAMMER_FLUSH_SIGNAL); } - hammer_flush_inode(ip, HAMMER_FLUSH_SIGNAL); } #if 0