diff options
-rw-r--r-- | include/linux/list_lru.h | 39 | ||||
-rw-r--r-- | mm/list_lru.c | 37 |
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); | |||
75 | bool list_lru_del(struct list_lru *lru, struct list_head *item); | 75 | bool 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 | */ |
85 | unsigned long list_lru_count(struct list_lru *lru); | 86 | unsigned long list_lru_count_node(struct list_lru *lru, int nid); |
87 | static 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 | ||
87 | typedef enum lru_status | 98 | typedef 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 | */ |
109 | unsigned long list_lru_walk(struct list_lru *lru, list_lru_walk_cb isolate, | 121 | unsigned 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 | |||
125 | static inline unsigned long | ||
126 | list_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 | ||
112 | typedef void (*list_lru_dispose_cb)(struct list_head *dispose_list); | 141 | typedef 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 | } |
48 | EXPORT_SYMBOL_GPL(list_lru_del); | 48 | EXPORT_SYMBOL_GPL(list_lru_del); |
49 | 49 | ||
50 | unsigned long list_lru_count(struct list_lru *lru) | 50 | unsigned long |
51 | list_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 | } |
66 | EXPORT_SYMBOL_GPL(list_lru_count); | 63 | EXPORT_SYMBOL_GPL(list_lru_count_node); |
67 | 64 | ||
68 | static unsigned long | 65 | unsigned long |
69 | list_lru_walk_node(struct list_lru *lru, int nid, list_lru_walk_cb isolate, | 66 | list_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 | } |
116 | EXPORT_SYMBOL_GPL(list_lru_walk_node); | 113 | EXPORT_SYMBOL_GPL(list_lru_walk_node); |
117 | 114 | ||
118 | unsigned 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 | } | ||
132 | EXPORT_SYMBOL_GPL(list_lru_walk); | ||
133 | |||
134 | static unsigned long list_lru_dispose_all_node(struct list_lru *lru, int nid, | 115 | static 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 | { |