Skip to content

Commit bc3b14c

Browse files
Dave ChinnerAl Viro
authored andcommitted
inode: convert inode lru list to generic lru list code.
[glommer@openvz.org: adapted for new LRU return codes] Signed-off-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Glauber Costa <glommer@openvz.org> Cc: "Theodore Ts'o" <tytso@mit.edu> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Cc: Arve Hjønnevåg <arve@android.com> Cc: Carlos Maiolino <cmaiolino@redhat.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Chuck Lever <chuck.lever@oracle.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: David Rientjes <rientjes@google.com> Cc: Gleb Natapov <gleb@redhat.com> Cc: Greg Thelen <gthelen@google.com> Cc: J. Bruce Fields <bfields@redhat.com> Cc: Jan Kara <jack@suse.cz> Cc: Jerome Glisse <jglisse@redhat.com> Cc: John Stultz <john.stultz@linaro.org> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Kent Overstreet <koverstreet@google.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Marcelo Tosatti <mtosatti@redhat.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Steven Whitehouse <swhiteho@redhat.com> Cc: Thomas Hellstrom <thellstrom@vmware.com> Cc: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent a38e408 commit bc3b14c

File tree

3 files changed

+77
-116
lines changed

3 files changed

+77
-116
lines changed

fs/inode.c

Lines changed: 70 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@
1717
#include <linux/prefetch.h>
1818
#include <linux/buffer_head.h> /* for inode_has_buffers */
1919
#include <linux/ratelimit.h>
20+
#include <linux/list_lru.h>
2021
#include "internal.h"
2122

2223
/*
2324
* Inode locking rules:
2425
*
2526
* inode->i_lock protects:
2627
* inode->i_state, inode->i_hash, __iget()
27-
* inode->i_sb->s_inode_lru_lock protects:
28+
* Inode LRU list locks protect:
2829
* inode->i_sb->s_inode_lru, inode->i_lru
2930
* inode_sb_list_lock protects:
3031
* sb->s_inodes, inode->i_sb_list
@@ -37,7 +38,7 @@
3738
*
3839
* inode_sb_list_lock
3940
* inode->i_lock
40-
* inode->i_sb->s_inode_lru_lock
41+
* Inode LRU list locks
4142
*
4243
* bdi->wb.list_lock
4344
* inode->i_lock
@@ -401,13 +402,8 @@ EXPORT_SYMBOL(ihold);
401402

402403
static void inode_lru_list_add(struct inode *inode)
403404
{
404-
spin_lock(&inode->i_sb->s_inode_lru_lock);
405-
if (list_empty(&inode->i_lru)) {
406-
list_add(&inode->i_lru, &inode->i_sb->s_inode_lru);
407-
inode->i_sb->s_nr_inodes_unused++;
405+
if (list_lru_add(&inode->i_sb->s_inode_lru, &inode->i_lru))
408406
this_cpu_inc(nr_unused);
409-
}
410-
spin_unlock(&inode->i_sb->s_inode_lru_lock);
411407
}
412408

413409
/*
@@ -425,13 +421,9 @@ void inode_add_lru(struct inode *inode)
425421

426422
static void inode_lru_list_del(struct inode *inode)
427423
{
428-
spin_lock(&inode->i_sb->s_inode_lru_lock);
429-
if (!list_empty(&inode->i_lru)) {
430-
list_del_init(&inode->i_lru);
431-
inode->i_sb->s_nr_inodes_unused--;
424+
425+
if (list_lru_del(&inode->i_sb->s_inode_lru, &inode->i_lru))
432426
this_cpu_dec(nr_unused);
433-
}
434-
spin_unlock(&inode->i_sb->s_inode_lru_lock);
435427
}
436428

437429
/**
@@ -675,24 +667,8 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty)
675667
return busy;
676668
}
677669

678-
static int can_unuse(struct inode *inode)
679-
{
680-
if (inode->i_state & ~I_REFERENCED)
681-
return 0;
682-
if (inode_has_buffers(inode))
683-
return 0;
684-
if (atomic_read(&inode->i_count))
685-
return 0;
686-
if (inode->i_data.nrpages)
687-
return 0;
688-
return 1;
689-
}
690-
691670
/*
692-
* Walk the superblock inode LRU for freeable inodes and attempt to free them.
693-
* This is called from the superblock shrinker function with a number of inodes
694-
* to trim from the LRU. Inodes to be freed are moved to a temporary list and
695-
* then are freed outside inode_lock by dispose_list().
671+
* Isolate the inode from the LRU in preparation for freeing it.
696672
*
697673
* Any inodes which are pinned purely because of attached pagecache have their
698674
* pagecache removed. If the inode has metadata buffers attached to
@@ -706,90 +682,79 @@ static int can_unuse(struct inode *inode)
706682
* LRU does not have strict ordering. Hence we don't want to reclaim inodes
707683
* with this flag set because they are the inodes that are out of order.
708684
*/
709-
long prune_icache_sb(struct super_block *sb, unsigned long nr_to_scan)
685+
static enum lru_status
686+
inode_lru_isolate(struct list_head *item, spinlock_t *lru_lock, void *arg)
710687
{
711-
LIST_HEAD(freeable);
712-
long nr_scanned;
713-
long freed = 0;
714-
unsigned long reap = 0;
688+
struct list_head *freeable = arg;
689+
struct inode *inode = container_of(item, struct inode, i_lru);
715690

716-
spin_lock(&sb->s_inode_lru_lock);
717-
for (nr_scanned = nr_to_scan; nr_scanned >= 0; nr_scanned--) {
718-
struct inode *inode;
691+
/*
692+
* we are inverting the lru lock/inode->i_lock here, so use a trylock.
693+
* If we fail to get the lock, just skip it.
694+
*/
695+
if (!spin_trylock(&inode->i_lock))
696+
return LRU_SKIP;
719697

720-
if (list_empty(&sb->s_inode_lru))
721-
break;
698+
/*
699+
* Referenced or dirty inodes are still in use. Give them another pass
700+
* through the LRU as we canot reclaim them now.
701+
*/
702+
if (atomic_read(&inode->i_count) ||
703+
(inode->i_state & ~I_REFERENCED)) {
704+
list_del_init(&inode->i_lru);
705+
spin_unlock(&inode->i_lock);
706+
this_cpu_dec(nr_unused);
707+
return LRU_REMOVED;
708+
}
722709

723-
inode = list_entry(sb->s_inode_lru.prev, struct inode, i_lru);
710+
/* recently referenced inodes get one more pass */
711+
if (inode->i_state & I_REFERENCED) {
712+
inode->i_state &= ~I_REFERENCED;
713+
spin_unlock(&inode->i_lock);
714+
return LRU_ROTATE;
715+
}
724716

725-
/*
726-
* we are inverting the sb->s_inode_lru_lock/inode->i_lock here,
727-
* so use a trylock. If we fail to get the lock, just move the
728-
* inode to the back of the list so we don't spin on it.
729-
*/
730-
if (!spin_trylock(&inode->i_lock)) {
731-
list_move(&inode->i_lru, &sb->s_inode_lru);
732-
continue;
717+
if (inode_has_buffers(inode) || inode->i_data.nrpages) {
718+
__iget(inode);
719+
spin_unlock(&inode->i_lock);
720+
spin_unlock(lru_lock);
721+
if (remove_inode_buffers(inode)) {
722+
unsigned long reap;
723+
reap = invalidate_mapping_pages(&inode->i_data, 0, -1);
724+
if (current_is_kswapd())
725+
__count_vm_events(KSWAPD_INODESTEAL, reap);
726+
else
727+
__count_vm_events(PGINODESTEAL, reap);
728+
if (current->reclaim_state)
729+
current->reclaim_state->reclaimed_slab += reap;
733730
}
731+
iput(inode);
732+
spin_lock(lru_lock);
733+
return LRU_RETRY;
734+
}
734735

735-
/*
736-
* Referenced or dirty inodes are still in use. Give them
737-
* another pass through the LRU as we canot reclaim them now.
738-
*/
739-
if (atomic_read(&inode->i_count) ||
740-
(inode->i_state & ~I_REFERENCED)) {
741-
list_del_init(&inode->i_lru);
742-
spin_unlock(&inode->i_lock);
743-
sb->s_nr_inodes_unused--;
744-
this_cpu_dec(nr_unused);
745-
continue;
746-
}
736+
WARN_ON(inode->i_state & I_NEW);
737+
inode->i_state |= I_FREEING;
738+
spin_unlock(&inode->i_lock);
747739

748-
/* recently referenced inodes get one more pass */
749-
if (inode->i_state & I_REFERENCED) {
750-
inode->i_state &= ~I_REFERENCED;
751-
list_move(&inode->i_lru, &sb->s_inode_lru);
752-
spin_unlock(&inode->i_lock);
753-
continue;
754-
}
755-
if (inode_has_buffers(inode) || inode->i_data.nrpages) {
756-
__iget(inode);
757-
spin_unlock(&inode->i_lock);
758-
spin_unlock(&sb->s_inode_lru_lock);
759-
if (remove_inode_buffers(inode))
760-
reap += invalidate_mapping_pages(&inode->i_data,
761-
0, -1);
762-
iput(inode);
763-
spin_lock(&sb->s_inode_lru_lock);
764-
765-
if (inode != list_entry(sb->s_inode_lru.next,
766-
struct inode, i_lru))
767-
continue; /* wrong inode or list_empty */
768-
/* avoid lock inversions with trylock */
769-
if (!spin_trylock(&inode->i_lock))
770-
continue;
771-
if (!can_unuse(inode)) {
772-
spin_unlock(&inode->i_lock);
773-
continue;
774-
}
775-
}
776-
WARN_ON(inode->i_state & I_NEW);
777-
inode->i_state |= I_FREEING;
778-
spin_unlock(&inode->i_lock);
740+
list_move(&inode->i_lru, freeable);
741+
this_cpu_dec(nr_unused);
742+
return LRU_REMOVED;
743+
}
779744

780-
list_move(&inode->i_lru, &freeable);
781-
sb->s_nr_inodes_unused--;
782-
this_cpu_dec(nr_unused);
783-
freed++;
784-
}
785-
if (current_is_kswapd())
786-
__count_vm_events(KSWAPD_INODESTEAL, reap);
787-
else
788-
__count_vm_events(PGINODESTEAL, reap);
789-
spin_unlock(&sb->s_inode_lru_lock);
790-
if (current->reclaim_state)
791-
current->reclaim_state->reclaimed_slab += reap;
745+
/*
746+
* Walk the superblock inode LRU for freeable inodes and attempt to free them.
747+
* This is called from the superblock shrinker function with a number of inodes
748+
* to trim from the LRU. Inodes to be freed are moved to a temporary list and
749+
* then are freed outside inode_lock by dispose_list().
750+
*/
751+
long prune_icache_sb(struct super_block *sb, unsigned long nr_to_scan)
752+
{
753+
LIST_HEAD(freeable);
754+
long freed;
792755

756+
freed = list_lru_walk(&sb->s_inode_lru, inode_lru_isolate,
757+
&freeable, nr_to_scan);
793758
dispose_list(&freeable);
794759
return freed;
795760
}

fs/super.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,13 @@ static unsigned long super_cache_scan(struct shrinker *shrink,
7878
if (sb->s_op->nr_cached_objects)
7979
fs_objects = sb->s_op->nr_cached_objects(sb);
8080

81-
total_objects = sb->s_nr_dentry_unused +
82-
sb->s_nr_inodes_unused + fs_objects + 1;
81+
inodes = list_lru_count(&sb->s_inode_lru);
82+
total_objects = sb->s_nr_dentry_unused + inodes + fs_objects + 1;
8383

8484
/* proportion the scan between the caches */
8585
dentries = mult_frac(sc->nr_to_scan, sb->s_nr_dentry_unused,
8686
total_objects);
87-
inodes = mult_frac(sc->nr_to_scan, sb->s_nr_inodes_unused,
88-
total_objects);
87+
inodes = mult_frac(sc->nr_to_scan, inodes, total_objects);
8988

9089
/*
9190
* prune the dcache first as the icache is pinned by it, then
@@ -119,7 +118,7 @@ static unsigned long super_cache_count(struct shrinker *shrink,
119118
total_objects = sb->s_op->nr_cached_objects(sb);
120119

121120
total_objects += sb->s_nr_dentry_unused;
122-
total_objects += sb->s_nr_inodes_unused;
121+
total_objects += list_lru_count(&sb->s_inode_lru);
123122

124123
total_objects = vfs_pressure_ratio(total_objects);
125124
drop_super(sb);
@@ -194,8 +193,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
194193
INIT_LIST_HEAD(&s->s_inodes);
195194
INIT_LIST_HEAD(&s->s_dentry_lru);
196195
spin_lock_init(&s->s_dentry_lru_lock);
197-
INIT_LIST_HEAD(&s->s_inode_lru);
198-
spin_lock_init(&s->s_inode_lru_lock);
196+
list_lru_init(&s->s_inode_lru);
199197
INIT_LIST_HEAD(&s->s_mounts);
200198
init_rwsem(&s->s_umount);
201199
lockdep_set_class(&s->s_umount, &type->s_umount_key);

include/linux/fs.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/stat.h>
1111
#include <linux/cache.h>
1212
#include <linux/list.h>
13+
#include <linux/list_lru.h>
1314
#include <linux/llist.h>
1415
#include <linux/radix-tree.h>
1516
#include <linux/rbtree.h>
@@ -1275,10 +1276,7 @@ struct super_block {
12751276
struct list_head s_dentry_lru; /* unused dentry lru */
12761277
long s_nr_dentry_unused; /* # of dentry on lru */
12771278

1278-
/* s_inode_lru_lock protects s_inode_lru and s_nr_inodes_unused */
1279-
spinlock_t s_inode_lru_lock ____cacheline_aligned_in_smp;
1280-
struct list_head s_inode_lru; /* unused inode lru */
1281-
long s_nr_inodes_unused; /* # of inodes on lru */
1279+
struct list_lru s_inode_lru ____cacheline_aligned_in_smp;
12821280

12831281
struct block_device *s_bdev;
12841282
struct backing_dev_info *s_bdi;

0 commit comments

Comments
 (0)