aboutsummaryrefslogtreecommitdiffstats
path: root/mm/vmscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r--mm/vmscan.c42
1 files changed, 11 insertions, 31 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 1d9971d8924b..2225b7c9df85 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -70,17 +70,6 @@ struct scan_control {
70 int order; 70 int order;
71}; 71};
72 72
73/*
74 * The list of shrinker callbacks used by to apply pressure to
75 * ageable caches.
76 */
77struct shrinker {
78 shrinker_t shrinker;
79 struct list_head list;
80 int seeks; /* seeks to recreate an obj */
81 long nr; /* objs pending delete */
82};
83
84#define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru)) 73#define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru))
85 74
86#ifdef ARCH_HAS_PREFETCH 75#ifdef ARCH_HAS_PREFETCH
@@ -123,34 +112,25 @@ static DECLARE_RWSEM(shrinker_rwsem);
123/* 112/*
124 * Add a shrinker callback to be called from the vm 113 * Add a shrinker callback to be called from the vm
125 */ 114 */
126struct shrinker *set_shrinker(int seeks, shrinker_t theshrinker) 115void register_shrinker(struct shrinker *shrinker)
127{ 116{
128 struct shrinker *shrinker; 117 shrinker->nr = 0;
129 118 down_write(&shrinker_rwsem);
130 shrinker = kmalloc(sizeof(*shrinker), GFP_KERNEL); 119 list_add_tail(&shrinker->list, &shrinker_list);
131 if (shrinker) { 120 up_write(&shrinker_rwsem);
132 shrinker->shrinker = theshrinker;
133 shrinker->seeks = seeks;
134 shrinker->nr = 0;
135 down_write(&shrinker_rwsem);
136 list_add_tail(&shrinker->list, &shrinker_list);
137 up_write(&shrinker_rwsem);
138 }
139 return shrinker;
140} 121}
141EXPORT_SYMBOL(set_shrinker); 122EXPORT_SYMBOL(register_shrinker);
142 123
143/* 124/*
144 * Remove one 125 * Remove one
145 */ 126 */
146void remove_shrinker(struct shrinker *shrinker) 127void unregister_shrinker(struct shrinker *shrinker)
147{ 128{
148 down_write(&shrinker_rwsem); 129 down_write(&shrinker_rwsem);
149 list_del(&shrinker->list); 130 list_del(&shrinker->list);
150 up_write(&shrinker_rwsem); 131 up_write(&shrinker_rwsem);
151 kfree(shrinker);
152} 132}
153EXPORT_SYMBOL(remove_shrinker); 133EXPORT_SYMBOL(unregister_shrinker);
154 134
155#define SHRINK_BATCH 128 135#define SHRINK_BATCH 128
156/* 136/*
@@ -187,7 +167,7 @@ unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
187 list_for_each_entry(shrinker, &shrinker_list, list) { 167 list_for_each_entry(shrinker, &shrinker_list, list) {
188 unsigned long long delta; 168 unsigned long long delta;
189 unsigned long total_scan; 169 unsigned long total_scan;
190 unsigned long max_pass = (*shrinker->shrinker)(0, gfp_mask); 170 unsigned long max_pass = (*shrinker->shrink)(0, gfp_mask);
191 171
192 delta = (4 * scanned) / shrinker->seeks; 172 delta = (4 * scanned) / shrinker->seeks;
193 delta *= max_pass; 173 delta *= max_pass;
@@ -215,8 +195,8 @@ unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
215 int shrink_ret; 195 int shrink_ret;
216 int nr_before; 196 int nr_before;
217 197
218 nr_before = (*shrinker->shrinker)(0, gfp_mask); 198 nr_before = (*shrinker->shrink)(0, gfp_mask);
219 shrink_ret = (*shrinker->shrinker)(this_scan, gfp_mask); 199 shrink_ret = (*shrinker->shrink)(this_scan, gfp_mask);
220 if (shrink_ret == -1) 200 if (shrink_ret == -1)
221 break; 201 break;
222 if (shrink_ret < nr_before) 202 if (shrink_ret < nr_before)