Skip to content

Commit

Permalink
list_lru: per-node API
Browse files Browse the repository at this point in the history
This patch adapts the list_lru API to accept an optional node argument, to
be used by NUMA aware shrinking functions.  Code that does not care about
the NUMA placement of objects can still call into the very same functions
as before.  They will simply iterate over all nodes.

Signed-off-by: Glauber Costa <[email protected]>
Cc: Dave Chinner <[email protected]>
Cc: Mel Gorman <[email protected]>
Cc: "Theodore Ts'o" <[email protected]>
Cc: Adrian Hunter <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Artem Bityutskiy <[email protected]>
Cc: Arve Hjønnevåg <[email protected]>
Cc: Carlos Maiolino <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Chuck Lever <[email protected]>
Cc: Daniel Vetter <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Gleb Natapov <[email protected]>
Cc: Greg Thelen <[email protected]>
Cc: J. Bruce Fields <[email protected]>
Cc: Jan Kara <[email protected]>
Cc: Jerome Glisse <[email protected]>
Cc: John Stultz <[email protected]>
Cc: KAMEZAWA Hiroyuki <[email protected]>
Cc: Kent Overstreet <[email protected]>
Cc: Kirill A. Shutemov <[email protected]>
Cc: Marcelo Tosatti <[email protected]>
Cc: Mel Gorman <[email protected]>
Cc: Steven Whitehouse <[email protected]>
Cc: Thomas Hellstrom <[email protected]>
Cc: Trond Myklebust <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Glauber Costa authored and Al Viro committed Sep 10, 2013
1 parent 5cedf72 commit 6a4f496
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 33 deletions.
39 changes: 34 additions & 5 deletions include/linux/list_lru.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,32 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item);
bool list_lru_del(struct list_lru *lru, struct list_head *item);

/**
* list_lru_count: return the number of objects currently held by @lru
* list_lru_count_node: return the number of objects currently held by @lru
* @lru: the lru pointer.
* @nid: the node id to count from.
*
* Always return a non-negative number, 0 for empty lists. There is no
* guarantee that the list is not updated while the count is being computed.
* Callers that want such a guarantee need to provide an outer lock.
*/
unsigned long list_lru_count(struct list_lru *lru);
unsigned long list_lru_count_node(struct list_lru *lru, int nid);
static inline unsigned long list_lru_count(struct list_lru *lru)
{
long count = 0;
int nid;

for_each_node_mask(nid, lru->active_nodes)
count += list_lru_count_node(lru, nid);

return count;
}

typedef enum lru_status
(*list_lru_walk_cb)(struct list_head *item, spinlock_t *lock, void *cb_arg);
/**
* list_lru_walk: walk a list_lru, isolating and disposing freeable items.
* list_lru_walk_node: walk a list_lru, isolating and disposing freeable items.
* @lru: the lru pointer.
* @nid: the node id to scan from.
* @isolate: callback function that is resposible for deciding what to do with
* the item currently being scanned
* @cb_arg: opaque type that will be passed to @isolate
Expand All @@ -106,8 +118,25 @@ typedef enum lru_status
*
* Return value: the number of objects effectively removed from the LRU.
*/
unsigned long list_lru_walk(struct list_lru *lru, list_lru_walk_cb isolate,
void *cb_arg, unsigned long nr_to_walk);
unsigned long list_lru_walk_node(struct list_lru *lru, int nid,
list_lru_walk_cb isolate, void *cb_arg,
unsigned long *nr_to_walk);

static inline unsigned long
list_lru_walk(struct list_lru *lru, list_lru_walk_cb isolate,
void *cb_arg, unsigned long nr_to_walk)
{
long isolated = 0;
int nid;

for_each_node_mask(nid, lru->active_nodes) {
isolated += list_lru_walk_node(lru, nid, isolate,
cb_arg, &nr_to_walk);
if (nr_to_walk <= 0)
break;
}
return isolated;
}

typedef void (*list_lru_dispose_cb)(struct list_head *dispose_list);
/**
Expand Down
37 changes: 9 additions & 28 deletions mm/list_lru.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,22 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item)
}
EXPORT_SYMBOL_GPL(list_lru_del);

unsigned long list_lru_count(struct list_lru *lru)
unsigned long
list_lru_count_node(struct list_lru *lru, int nid)
{
unsigned long count = 0;
int nid;

for_each_node_mask(nid, lru->active_nodes) {
struct list_lru_node *nlru = &lru->node[nid];
struct list_lru_node *nlru = &lru->node[nid];

spin_lock(&nlru->lock);
WARN_ON_ONCE(nlru->nr_items < 0);
count += nlru->nr_items;
spin_unlock(&nlru->lock);
}
spin_lock(&nlru->lock);
WARN_ON_ONCE(nlru->nr_items < 0);
count += nlru->nr_items;
spin_unlock(&nlru->lock);

return count;
}
EXPORT_SYMBOL_GPL(list_lru_count);
EXPORT_SYMBOL_GPL(list_lru_count_node);

static unsigned long
unsigned long
list_lru_walk_node(struct list_lru *lru, int nid, list_lru_walk_cb isolate,
void *cb_arg, unsigned long *nr_to_walk)
{
Expand Down Expand Up @@ -115,22 +112,6 @@ list_lru_walk_node(struct list_lru *lru, int nid, list_lru_walk_cb isolate,
}
EXPORT_SYMBOL_GPL(list_lru_walk_node);

unsigned long list_lru_walk(struct list_lru *lru, list_lru_walk_cb isolate,
void *cb_arg, unsigned long nr_to_walk)
{
unsigned long isolated = 0;
int nid;

for_each_node_mask(nid, lru->active_nodes) {
isolated += list_lru_walk_node(lru, nid, isolate,
cb_arg, &nr_to_walk);
if (nr_to_walk <= 0)
break;
}
return isolated;
}
EXPORT_SYMBOL_GPL(list_lru_walk);

static unsigned long list_lru_dispose_all_node(struct list_lru *lru, int nid,
list_lru_dispose_cb dispose)
{
Expand Down

0 comments on commit 6a4f496

Please sign in to comment.