aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-03-22 01:15:10 -0400
committerBen Myers <bpm@sgi.com>2012-03-26 18:19:08 -0400
commit5132ba8f2b7705fb6b06fa6ad3d009233c816b67 (patch)
treee552a365b600af005abec13f3a1deb1f57bae3b9
parentf616137519feb17b849894fcbe634a021d3fa7db (diff)
xfs: don't cache inodes read through bulkstat
When we read inodes via bulkstat, we generally only read them once and then throw them away - they never get used again. If we retain them in cache, then it simply causes the working set of inodes and other cached items to be reclaimed just so the inode cache can grow. Avoid this problem by marking inodes read by bulkstat not to be cached and check this flag in .drop_inode to determine whether the inode should be added to the VFS LRU or not. If the inode lookup hits an already cached inode, then don't set the flag. If the inode lookup hits an inode marked with no cache flag, remove the flag and allow it to be cached once the current reference goes away. Inodes marked as not cached will get cleaned up by the background inode reclaim or via memory pressure, so they will still generate some short term cache pressure. They will, however, be reclaimed much sooner and in preference to cache hot inodes. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
-rw-r--r--fs/xfs/xfs_iget.c8
-rw-r--r--fs/xfs/xfs_inode.h4
-rw-r--r--fs/xfs/xfs_itable.c3
-rw-r--r--fs/xfs/xfs_super.c17
4 files changed, 28 insertions, 4 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index a98cb4524e6c..bcc6c249b2c7 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -289,7 +289,7 @@ xfs_iget_cache_hit(
289 if (lock_flags != 0) 289 if (lock_flags != 0)
290 xfs_ilock(ip, lock_flags); 290 xfs_ilock(ip, lock_flags);
291 291
292 xfs_iflags_clear(ip, XFS_ISTALE); 292 xfs_iflags_clear(ip, XFS_ISTALE | XFS_IDONTCACHE);
293 XFS_STATS_INC(xs_ig_found); 293 XFS_STATS_INC(xs_ig_found);
294 294
295 return 0; 295 return 0;
@@ -314,6 +314,7 @@ xfs_iget_cache_miss(
314 struct xfs_inode *ip; 314 struct xfs_inode *ip;
315 int error; 315 int error;
316 xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino); 316 xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino);
317 int iflags;
317 318
318 ip = xfs_inode_alloc(mp, ino); 319 ip = xfs_inode_alloc(mp, ino);
319 if (!ip) 320 if (!ip)
@@ -358,8 +359,11 @@ xfs_iget_cache_miss(
358 * memory barrier that ensures this detection works correctly at lookup 359 * memory barrier that ensures this detection works correctly at lookup
359 * time. 360 * time.
360 */ 361 */
362 iflags = XFS_INEW;
363 if (flags & XFS_IGET_DONTCACHE)
364 iflags |= XFS_IDONTCACHE;
361 ip->i_udquot = ip->i_gdquot = NULL; 365 ip->i_udquot = ip->i_gdquot = NULL;
362 xfs_iflags_set(ip, XFS_INEW); 366 xfs_iflags_set(ip, iflags);
363 367
364 /* insert the new inode */ 368 /* insert the new inode */
365 spin_lock(&pag->pag_ici_lock); 369 spin_lock(&pag->pag_ici_lock);
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index f123dbe6d42a..7fee3387e1c8 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -387,10 +387,11 @@ xfs_set_projid(struct xfs_inode *ip,
387#define XFS_IFLOCK (1 << __XFS_IFLOCK_BIT) 387#define XFS_IFLOCK (1 << __XFS_IFLOCK_BIT)
388#define __XFS_IPINNED_BIT 8 /* wakeup key for zero pin count */ 388#define __XFS_IPINNED_BIT 8 /* wakeup key for zero pin count */
389#define XFS_IPINNED (1 << __XFS_IPINNED_BIT) 389#define XFS_IPINNED (1 << __XFS_IPINNED_BIT)
390#define XFS_IDONTCACHE (1 << 9) /* don't cache the inode long term */
390 391
391/* 392/*
392 * Per-lifetime flags need to be reset when re-using a reclaimable inode during 393 * Per-lifetime flags need to be reset when re-using a reclaimable inode during
393 * inode lookup. Thi prevents unintended behaviour on the new inode from 394 * inode lookup. This prevents unintended behaviour on the new inode from
394 * ocurring. 395 * ocurring.
395 */ 396 */
396#define XFS_IRECLAIM_RESET_FLAGS \ 397#define XFS_IRECLAIM_RESET_FLAGS \
@@ -553,6 +554,7 @@ do { \
553 */ 554 */
554#define XFS_IGET_CREATE 0x1 555#define XFS_IGET_CREATE 0x1
555#define XFS_IGET_UNTRUSTED 0x2 556#define XFS_IGET_UNTRUSTED 0x2
557#define XFS_IGET_DONTCACHE 0x4
556 558
557int xfs_inotobp(struct xfs_mount *, struct xfs_trans *, 559int xfs_inotobp(struct xfs_mount *, struct xfs_trans *,
558 xfs_ino_t, struct xfs_dinode **, 560 xfs_ino_t, struct xfs_dinode **,
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 9720c54bbed0..acc2bf264dab 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -75,7 +75,8 @@ xfs_bulkstat_one_int(
75 return XFS_ERROR(ENOMEM); 75 return XFS_ERROR(ENOMEM);
76 76
77 error = xfs_iget(mp, NULL, ino, 77 error = xfs_iget(mp, NULL, ino,
78 XFS_IGET_UNTRUSTED, XFS_ILOCK_SHARED, &ip); 78 (XFS_IGET_DONTCACHE | XFS_IGET_UNTRUSTED),
79 XFS_ILOCK_SHARED, &ip);
79 if (error) { 80 if (error) {
80 *stat = BULKSTAT_RV_NOTHING; 81 *stat = BULKSTAT_RV_NOTHING;
81 goto out_free; 82 goto out_free;
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 5484888d39c4..e1c623b43ab2 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -950,6 +950,22 @@ xfs_fs_evict_inode(
950 xfs_inactive(ip); 950 xfs_inactive(ip);
951} 951}
952 952
953/*
954 * We do an unlocked check for XFS_IDONTCACHE here because we are already
955 * serialised against cache hits here via the inode->i_lock and igrab() in
956 * xfs_iget_cache_hit(). Hence a lookup that might clear this flag will not be
957 * racing with us, and it avoids needing to grab a spinlock here for every inode
958 * we drop the final reference on.
959 */
960STATIC int
961xfs_fs_drop_inode(
962 struct inode *inode)
963{
964 struct xfs_inode *ip = XFS_I(inode);
965
966 return generic_drop_inode(inode) || (ip->i_flags & XFS_IDONTCACHE);
967}
968
953STATIC void 969STATIC void
954xfs_free_fsname( 970xfs_free_fsname(
955 struct xfs_mount *mp) 971 struct xfs_mount *mp)
@@ -1434,6 +1450,7 @@ static const struct super_operations xfs_super_operations = {
1434 .destroy_inode = xfs_fs_destroy_inode, 1450 .destroy_inode = xfs_fs_destroy_inode,
1435 .dirty_inode = xfs_fs_dirty_inode, 1451 .dirty_inode = xfs_fs_dirty_inode,
1436 .evict_inode = xfs_fs_evict_inode, 1452 .evict_inode = xfs_fs_evict_inode,
1453 .drop_inode = xfs_fs_drop_inode,
1437 .put_super = xfs_fs_put_super, 1454 .put_super = xfs_fs_put_super,
1438 .sync_fs = xfs_fs_sync_fs, 1455 .sync_fs = xfs_fs_sync_fs,
1439 .freeze_fs = xfs_fs_freeze, 1456 .freeze_fs = xfs_fs_freeze,