diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-12-18 15:00:10 -0500 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-01-17 16:07:54 -0500 |
commit | f392e6319a4e9a028b0c8b48f000bb01d660ad53 (patch) | |
tree | 6cf97bebb841da303056b60da087e76cc087af9b /fs | |
parent | 474fce067521a40dbacc722e8ba119e81c2d31bf (diff) |
xfs: replace i_pin_wait with a bit waitqueue
Replace i_pin_wait, which is only used during synchronous inode flushing
with a bit waitqueue. This trades off a much smaller inode against
slightly slower wakeup performance, and saves 12 (32-bit) or 20 (64-bit)
bytes in the XFS inode.
Reviewed-by: Alex Elder <aelder@sgi.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_inode.c | 27 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_inode_item.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 1 |
4 files changed, 24 insertions, 9 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index eeb60d31b086..62603369b523 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -2037,7 +2037,7 @@ xfs_idestroy_fork( | |||
2037 | * once someone is waiting for it to be unpinned. | 2037 | * once someone is waiting for it to be unpinned. |
2038 | */ | 2038 | */ |
2039 | static void | 2039 | static void |
2040 | xfs_iunpin_nowait( | 2040 | xfs_iunpin( |
2041 | struct xfs_inode *ip) | 2041 | struct xfs_inode *ip) |
2042 | { | 2042 | { |
2043 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); | 2043 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
@@ -2049,14 +2049,29 @@ xfs_iunpin_nowait( | |||
2049 | 2049 | ||
2050 | } | 2050 | } |
2051 | 2051 | ||
2052 | static void | ||
2053 | __xfs_iunpin_wait( | ||
2054 | struct xfs_inode *ip) | ||
2055 | { | ||
2056 | wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_IPINNED_BIT); | ||
2057 | DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_IPINNED_BIT); | ||
2058 | |||
2059 | xfs_iunpin(ip); | ||
2060 | |||
2061 | do { | ||
2062 | prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE); | ||
2063 | if (xfs_ipincount(ip)) | ||
2064 | io_schedule(); | ||
2065 | } while (xfs_ipincount(ip)); | ||
2066 | finish_wait(wq, &wait.wait); | ||
2067 | } | ||
2068 | |||
2052 | void | 2069 | void |
2053 | xfs_iunpin_wait( | 2070 | xfs_iunpin_wait( |
2054 | struct xfs_inode *ip) | 2071 | struct xfs_inode *ip) |
2055 | { | 2072 | { |
2056 | if (xfs_ipincount(ip)) { | 2073 | if (xfs_ipincount(ip)) |
2057 | xfs_iunpin_nowait(ip); | 2074 | __xfs_iunpin_wait(ip); |
2058 | wait_event(ip->i_ipin_wait, (xfs_ipincount(ip) == 0)); | ||
2059 | } | ||
2060 | } | 2075 | } |
2061 | 2076 | ||
2062 | /* | 2077 | /* |
@@ -2415,7 +2430,7 @@ xfs_iflush( | |||
2415 | * out for us if they occur after the log force completes. | 2430 | * out for us if they occur after the log force completes. |
2416 | */ | 2431 | */ |
2417 | if (!(flags & SYNC_WAIT) && xfs_ipincount(ip)) { | 2432 | if (!(flags & SYNC_WAIT) && xfs_ipincount(ip)) { |
2418 | xfs_iunpin_nowait(ip); | 2433 | xfs_iunpin(ip); |
2419 | xfs_ifunlock(ip); | 2434 | xfs_ifunlock(ip); |
2420 | return EAGAIN; | 2435 | return EAGAIN; |
2421 | } | 2436 | } |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 960d2a89b3ac..4acbe740be46 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -238,7 +238,6 @@ typedef struct xfs_inode { | |||
238 | mrlock_t i_lock; /* inode lock */ | 238 | mrlock_t i_lock; /* inode lock */ |
239 | mrlock_t i_iolock; /* inode IO lock */ | 239 | mrlock_t i_iolock; /* inode IO lock */ |
240 | atomic_t i_pincount; /* inode pin count */ | 240 | atomic_t i_pincount; /* inode pin count */ |
241 | wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */ | ||
242 | spinlock_t i_flags_lock; /* inode i_flags lock */ | 241 | spinlock_t i_flags_lock; /* inode i_flags lock */ |
243 | /* Miscellaneous state. */ | 242 | /* Miscellaneous state. */ |
244 | unsigned long i_flags; /* see defined flags below */ | 243 | unsigned long i_flags; /* see defined flags below */ |
@@ -367,6 +366,8 @@ xfs_set_projid(struct xfs_inode *ip, | |||
367 | #define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */ | 366 | #define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */ |
368 | #define __XFS_IFLOCK_BIT 7 /* inode is being flushed right now */ | 367 | #define __XFS_IFLOCK_BIT 7 /* inode is being flushed right now */ |
369 | #define XFS_IFLOCK (1 << __XFS_IFLOCK_BIT) | 368 | #define XFS_IFLOCK (1 << __XFS_IFLOCK_BIT) |
369 | #define __XFS_IPINNED_BIT 8 /* wakeup key for zero pin count */ | ||
370 | #define XFS_IPINNED (1 << __XFS_IPINNED_BIT) | ||
370 | 371 | ||
371 | /* | 372 | /* |
372 | * Per-lifetime flags need to be reset when re-using a reclaimable inode during | 373 | * Per-lifetime flags need to be reset when re-using a reclaimable inode during |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index c8d4ce0efd5a..91d71dcd4852 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -555,7 +555,7 @@ xfs_inode_item_unpin( | |||
555 | trace_xfs_inode_unpin(ip, _RET_IP_); | 555 | trace_xfs_inode_unpin(ip, _RET_IP_); |
556 | ASSERT(atomic_read(&ip->i_pincount) > 0); | 556 | ASSERT(atomic_read(&ip->i_pincount) > 0); |
557 | if (atomic_dec_and_test(&ip->i_pincount)) | 557 | if (atomic_dec_and_test(&ip->i_pincount)) |
558 | wake_up(&ip->i_ipin_wait); | 558 | wake_up_bit(&ip->i_flags, __XFS_IPINNED_BIT); |
559 | } | 559 | } |
560 | 560 | ||
561 | /* | 561 | /* |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 6851fa7b1afa..ee5b695c99a7 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -828,7 +828,6 @@ xfs_fs_inode_init_once( | |||
828 | /* xfs inode */ | 828 | /* xfs inode */ |
829 | atomic_set(&ip->i_pincount, 0); | 829 | atomic_set(&ip->i_pincount, 0); |
830 | spin_lock_init(&ip->i_flags_lock); | 830 | spin_lock_init(&ip->i_flags_lock); |
831 | init_waitqueue_head(&ip->i_ipin_wait); | ||
832 | 831 | ||
833 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | 832 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, |
834 | "xfsino", ip->i_ino); | 833 | "xfsino", ip->i_ino); |