aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/list_lru.h39
-rw-r--r--mm/list_lru.c37
2 files changed, 43 insertions, 33 deletions
diff --git a/include/linux/list_lru.h b/include/linux/list_lru.h
index f4d4cb608c02..2fe13e1a809a 100644
--- a/include/linux/list_lru.h
+++ b/include/linux/list_lru.h
@@ -75,20 +75,32 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item);
75bool list_lru_del(struct list_lru *lru, struct list_head *item); 75bool list_lru_del(struct list_lru *lru, struct list_head *item);
76 76
77/** 77/**
78 * list_lru_count: return the number of objects currently held by @lru 78 * list_lru_count_node: return the number of objects currently held by @lru
79 * @lru: the lru pointer. 79 * @lru: the lru pointer.
80 * @nid: the node id to count from.
80 * 81 *
81 * Always return a non-negative number, 0 for empty lists. There is no 82 * Always return a non-negative number, 0 for empty lists. There is no
82 * guarantee that the list is not updated while the count is being computed. 83 * guarantee that the list is not updated while the count is being computed.
83 * Callers that want such a guarantee need to provide an outer lock. 84 * Callers that want such a guarantee need to provide an outer lock.
84 */ 85 */
85unsigned long list_lru_count(struct list_lru *lru); 86unsigned long list_lru_count_node(struct list_lru *lru, int nid);
87static inline unsigned long list_lru_count(struct list_lru *lru)
88{
89 long count = 0;
90 int nid;
91
92 for_each_node_mask(nid, lru->active_nodes)
93 count += list_lru_count_node(lru, nid);
94
95 return count;
96}
86 97
87typedef enum lru_status 98typedef enum lru_status
88(*list_lru_walk_cb)(struct list_head *item, spinlock_t *lock, void *cb_arg); 99(*list_lru_walk_cb)(struct list_head *item, spinlock_t *lock, void *cb_arg);
89/** 100/**
90 * list_lru_walk: walk a list_lru, isolating and disposing freeable items. 101 * list_lru_walk_node: walk a list_lru, isolating and disposing freeable items.
91 * @lru: the lru pointer. 102 * @lru: the lru pointer.
103 * @nid: the node id to scan from.
92 * @isolate: callback function that is resposible for deciding what to do with 104 * @isolate: callback function that is resposible for deciding what to do with
93 * the item currently being scanned 105 * the item currently being scanned
94 * @cb_arg: opaque type that will be passed to @isolate 106 * @cb_arg: opaque type that will be passed to @isolate
@@ -106,8 +118,25 @@ typedef enum lru_status
106 * 118 *
107 * Return value: the number of objects effectively removed from the LRU. 119 * Return value: the number of objects effectively removed from the LRU.
108 */ 120 */
109unsigned long list_lru_walk(struct list_lru *lru, list_lru_walk_cb isolate, 121unsigned long list_lru_walk_node(struct list_lru *lru, int nid,
110 void *cb_arg, unsigned long nr_to_walk); 122 list_lru_walk_cb isolate, void *cb_arg,
123 unsigned long *nr_to_walk);
124
125static inline unsigned long
126list_lru_walk(struct list_lru *lru, list_lru_walk_cb isolate,
127 void *cb_arg, unsigned long nr_to_walk)
128{
129 long isolated = 0;
130 int nid;
131
132 for_each_node_mask(nid, lru->active_nodes) {
133 isolated += list_lru_walk_node(lru, nid, isolate,
134 cb_arg, &nr_to_walk);
135 if (nr_to_walk <= 0)
136 break;
137 }
138 return isolated;
139}
111 140
112typedef void (*list_lru_dispose_cb)(struct list_head *dispose_list); 141typedef void (*list_lru_dispose_cb)(struct list_head *dispose_list);
113/** 142/**
diff --git a/mm/list_lru.c b/mm/list_lru.c
index e77c29f4c243..86cb55464f71 100644
--- a/mm/list_lru.c
+++ b/mm/list_lru.c
@@ -47,25 +47,22 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item)
47} 47}
48EXPORT_SYMBOL_GPL(list_lru_del); 48EXPORT_SYMBOL_GPL(list_lru_del);
49 49
50unsigned long list_lru_count(struct list_lru *lru) 50unsigned long
51list_lru_count_node(struct list_lru *lru, int nid)
51{ 52{
52 unsigned long count = 0; 53 unsigned long count = 0;
53 int nid; 54 struct list_lru_node *nlru = &lru->node[nid];
54
55 for_each_node_mask(nid, lru->active_nodes) {
56 struct list_lru_node *nlru = &lru->node[nid];
57 55
58 spin_lock(&nlru->lock); 56 spin_lock(&nlru->lock);
59 WARN_ON_ONCE(nlru->nr_items < 0); 57 WARN_ON_ONCE(nlru->nr_items < 0);
60 count += nlru->nr_items; 58 count += nlru->nr_items;
61 spin_unlock(&nlru->lock); 59 spin_unlock(&nlru->lock);
62 }
63 60
64 return count; 61 return count;
65} 62}
66EXPORT_SYMBOL_GPL(list_lru_count); 63EXPORT_SYMBOL_GPL(list_lru_count_node);
67 64
68static unsigned long 65unsigned long
69list_lru_walk_node(struct list_lru *lru, int nid, list_lru_walk_cb isolate, 66list_lru_walk_node(struct list_lru *lru, int nid, list_lru_walk_cb isolate,
70 void *cb_arg, unsigned long *nr_to_walk) 67 void *cb_arg, unsigned long *nr_to_walk)
71{ 68{
@@ -115,22 +112,6 @@ restart:
115} 112}
116EXPORT_SYMBOL_GPL(list_lru_walk_node); 113EXPORT_SYMBOL_GPL(list_lru_walk_node);
117 114
118unsigned long list_lru_walk(struct list_lru *lru, list_lru_walk_cb isolate,
119 void *cb_arg, unsigned long nr_to_walk)
120{
121 unsigned long isolated = 0;
122 int nid;
123
124 for_each_node_mask(nid, lru->active_nodes) {
125 isolated += list_lru_walk_node(lru, nid, isolate,
126 cb_arg, &nr_to_walk);
127 if (nr_to_walk <= 0)
128 break;
129 }
130 return isolated;
131}
132EXPORT_SYMBOL_GPL(list_lru_walk);
133
134static unsigned long list_lru_dispose_all_node(struct list_lru *lru, int nid, 115static unsigned long list_lru_dispose_all_node(struct list_lru *lru, int nid,
135 list_lru_dispose_cb dispose) 116 list_lru_dispose_cb dispose)
136{ 117{