|
@@ -70,17 +70,6 @@ struct scan_control {
|
|
int order;
|
|
int order;
|
|
};
|
|
};
|
|
|
|
|
|
-/*
|
|
|
|
- * The list of shrinker callbacks used by to apply pressure to
|
|
|
|
- * ageable caches.
|
|
|
|
- */
|
|
|
|
-struct shrinker {
|
|
|
|
- shrinker_t shrinker;
|
|
|
|
- struct list_head list;
|
|
|
|
- int seeks; /* seeks to recreate an obj */
|
|
|
|
- long nr; /* objs pending delete */
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
#define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru))
|
|
#define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru))
|
|
|
|
|
|
#ifdef ARCH_HAS_PREFETCH
|
|
#ifdef ARCH_HAS_PREFETCH
|
|
@@ -123,34 +112,25 @@ static DECLARE_RWSEM(shrinker_rwsem);
|
|
/*
|
|
/*
|
|
* Add a shrinker callback to be called from the vm
|
|
* Add a shrinker callback to be called from the vm
|
|
*/
|
|
*/
|
|
-struct shrinker *set_shrinker(int seeks, shrinker_t theshrinker)
|
|
|
|
|
|
+void register_shrinker(struct shrinker *shrinker)
|
|
{
|
|
{
|
|
- struct shrinker *shrinker;
|
|
|
|
-
|
|
|
|
- shrinker = kmalloc(sizeof(*shrinker), GFP_KERNEL);
|
|
|
|
- if (shrinker) {
|
|
|
|
- shrinker->shrinker = theshrinker;
|
|
|
|
- shrinker->seeks = seeks;
|
|
|
|
- shrinker->nr = 0;
|
|
|
|
- down_write(&shrinker_rwsem);
|
|
|
|
- list_add_tail(&shrinker->list, &shrinker_list);
|
|
|
|
- up_write(&shrinker_rwsem);
|
|
|
|
- }
|
|
|
|
- return shrinker;
|
|
|
|
|
|
+ shrinker->nr = 0;
|
|
|
|
+ down_write(&shrinker_rwsem);
|
|
|
|
+ list_add_tail(&shrinker->list, &shrinker_list);
|
|
|
|
+ up_write(&shrinker_rwsem);
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL(set_shrinker);
|
|
|
|
|
|
+EXPORT_SYMBOL(register_shrinker);
|
|
|
|
|
|
/*
|
|
/*
|
|
* Remove one
|
|
* Remove one
|
|
*/
|
|
*/
|
|
-void remove_shrinker(struct shrinker *shrinker)
|
|
|
|
|
|
+void unregister_shrinker(struct shrinker *shrinker)
|
|
{
|
|
{
|
|
down_write(&shrinker_rwsem);
|
|
down_write(&shrinker_rwsem);
|
|
list_del(&shrinker->list);
|
|
list_del(&shrinker->list);
|
|
up_write(&shrinker_rwsem);
|
|
up_write(&shrinker_rwsem);
|
|
- kfree(shrinker);
|
|
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL(remove_shrinker);
|
|
|
|
|
|
+EXPORT_SYMBOL(unregister_shrinker);
|
|
|
|
|
|
#define SHRINK_BATCH 128
|
|
#define SHRINK_BATCH 128
|
|
/*
|
|
/*
|
|
@@ -187,7 +167,7 @@ unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
|
|
list_for_each_entry(shrinker, &shrinker_list, list) {
|
|
list_for_each_entry(shrinker, &shrinker_list, list) {
|
|
unsigned long long delta;
|
|
unsigned long long delta;
|
|
unsigned long total_scan;
|
|
unsigned long total_scan;
|
|
- unsigned long max_pass = (*shrinker->shrinker)(0, gfp_mask);
|
|
|
|
|
|
+ unsigned long max_pass = (*shrinker->shrink)(0, gfp_mask);
|
|
|
|
|
|
delta = (4 * scanned) / shrinker->seeks;
|
|
delta = (4 * scanned) / shrinker->seeks;
|
|
delta *= max_pass;
|
|
delta *= max_pass;
|
|
@@ -215,8 +195,8 @@ unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
|
|
int shrink_ret;
|
|
int shrink_ret;
|
|
int nr_before;
|
|
int nr_before;
|
|
|
|
|
|
- nr_before = (*shrinker->shrinker)(0, gfp_mask);
|
|
|
|
- shrink_ret = (*shrinker->shrinker)(this_scan, gfp_mask);
|
|
|
|
|
|
+ nr_before = (*shrinker->shrink)(0, gfp_mask);
|
|
|
|
+ shrink_ret = (*shrinker->shrink)(this_scan, gfp_mask);
|
|
if (shrink_ret == -1)
|
|
if (shrink_ret == -1)
|
|
break;
|
|
break;
|
|
if (shrink_ret < nr_before)
|
|
if (shrink_ret < nr_before)
|