aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_buf.c
diff options
context:
space:
mode:
authorVladimir Davydov <vdavydov@parallels.com>2015-02-12 17:59:35 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-12 21:54:10 -0500
commit3f97b163207c67a3b35931494ad3db1de66356f0 (patch)
tree012012aafb687ebfb7e794e2bcd0c1728212fafc /fs/xfs/xfs_buf.c
parent2a4db7eb9391a544ff58f4fa11d35246e87c87af (diff)
list_lru: add helpers to isolate items
Currently, the isolate callback passed to the list_lru_walk family of functions is supposed to just delete an item from the list upon returning LRU_REMOVED or LRU_REMOVED_RETRY, while nr_items counter is fixed by __list_lru_walk_one after the callback returns. Since the callback is allowed to drop the lock after removing an item (it has to return LRU_REMOVED_RETRY then), the nr_items can be less than the actual number of elements on the list even if we check them under the lock. This makes it difficult to move items from one list_lru_one to another, which is required for per-memcg list_lru reparenting - we can't just splice the lists, we have to move entries one by one. This patch therefore introduces helpers that must be used by callback functions to isolate items instead of raw list_del/list_move. These are list_lru_isolate and list_lru_isolate_move. They not only remove the entry from the list, but also fix the nr_items counter, making sure nr_items always reflects the actual number of elements on the list if checked under the appropriate lock. Signed-off-by: Vladimir Davydov <vdavydov@parallels.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@suse.cz> Cc: Tejun Heo <tj@kernel.org> Cc: Christoph Lameter <cl@linux.com> Cc: Pekka Enberg <penberg@kernel.org> Cc: David Rientjes <rientjes@google.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Dave Chinner <david@fromorbit.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/xfs/xfs_buf.c')
-rw-r--r--fs/xfs/xfs_buf.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 15c9d224c721..1790b00bea7a 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1488,6 +1488,7 @@ xfs_buf_iomove(
1488static enum lru_status 1488static enum lru_status
1489xfs_buftarg_wait_rele( 1489xfs_buftarg_wait_rele(
1490 struct list_head *item, 1490 struct list_head *item,
1491 struct list_lru_one *lru,
1491 spinlock_t *lru_lock, 1492 spinlock_t *lru_lock,
1492 void *arg) 1493 void *arg)
1493 1494
@@ -1509,7 +1510,7 @@ xfs_buftarg_wait_rele(
1509 */ 1510 */
1510 atomic_set(&bp->b_lru_ref, 0); 1511 atomic_set(&bp->b_lru_ref, 0);
1511 bp->b_state |= XFS_BSTATE_DISPOSE; 1512 bp->b_state |= XFS_BSTATE_DISPOSE;
1512 list_move(item, dispose); 1513 list_lru_isolate_move(lru, item, dispose);
1513 spin_unlock(&bp->b_lock); 1514 spin_unlock(&bp->b_lock);
1514 return LRU_REMOVED; 1515 return LRU_REMOVED;
1515} 1516}
@@ -1546,6 +1547,7 @@ xfs_wait_buftarg(
1546static enum lru_status 1547static enum lru_status
1547xfs_buftarg_isolate( 1548xfs_buftarg_isolate(
1548 struct list_head *item, 1549 struct list_head *item,
1550 struct list_lru_one *lru,
1549 spinlock_t *lru_lock, 1551 spinlock_t *lru_lock,
1550 void *arg) 1552 void *arg)
1551{ 1553{
@@ -1569,7 +1571,7 @@ xfs_buftarg_isolate(
1569 } 1571 }
1570 1572
1571 bp->b_state |= XFS_BSTATE_DISPOSE; 1573 bp->b_state |= XFS_BSTATE_DISPOSE;
1572 list_move(item, dispose); 1574 list_lru_isolate_move(lru, item, dispose);
1573 spin_unlock(&bp->b_lock); 1575 spin_unlock(&bp->b_lock);
1574 return LRU_REMOVED; 1576 return LRU_REMOVED;
1575} 1577}