Modular caches that shrink automatically This patch adds the register_cache() and unregister_cache() functions which register a callback that is invoked on memory pressure to free some memory. The parameters and semantics to the callback are similar to the other shrink functions. diff -Nur linux-2.5.30/include/linux/cache_def.h linux-2.5.30.patch/include/linux/cache_def.h --- linux-2.5.30/include/linux/cache_def.h Thu Jan 1 01:00:00 1970 +++ linux-2.5.30.patch/include/linux/cache_def.h Sat Aug 3 13:58:07 2002 @@ -0,0 +1,15 @@ +/* + * linux/cache_def.h + * Modular caches that shrink automatically + * + * Copyright (C) 2002 by Andreas Gruenbacher, + */ + +struct cache_definition { + const char *name; + void (*shrink)(int, unsigned int); + struct list_head link; +}; + +extern void register_cache(struct cache_definition *); +extern void unregister_cache(struct cache_definition *); diff -Nur linux-2.5.30/kernel/ksyms.c linux-2.5.30.patch/kernel/ksyms.c --- linux-2.5.30/kernel/ksyms.c Thu Aug 1 23:16:02 2002 +++ linux-2.5.30.patch/kernel/ksyms.c Fri Aug 2 15:57:42 2002 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,8 @@ EXPORT_SYMBOL(kmem_cache_alloc); EXPORT_SYMBOL(kmem_cache_free); EXPORT_SYMBOL(kmem_cache_size); +EXPORT_SYMBOL(register_cache); +EXPORT_SYMBOL(unregister_cache); EXPORT_SYMBOL(kmalloc); EXPORT_SYMBOL(kfree); EXPORT_SYMBOL(vfree); Binary files linux-2.5.30/mm/.vmscan.c.swp and linux-2.5.30.patch/mm/.vmscan.c.swp differ diff -Nur linux-2.5.30/mm/vmscan.c linux-2.5.30.patch/mm/vmscan.c --- linux-2.5.30/mm/vmscan.c Thu Aug 1 23:16:08 2002 +++ linux-2.5.30.patch/mm/vmscan.c Sat Aug 3 13:56:55 2002 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,39 @@ return 0; } +static DECLARE_MUTEX(other_caches_lock); +static LIST_HEAD(other_caches); + +void register_cache(struct cache_definition *cache) +{ + down(&other_caches_lock); + list_add(&cache->link, &other_caches); + up(&other_caches_lock); +} + +void unregister_cache(struct cache_definition *cache) +{ + down(&other_caches_lock); + list_del(&cache->link); + up(&other_caches_lock); +} + +static void shrink_other_caches(unsigned int priority, int gfp_mask) +{ + struct list_head *p = other_caches.prev; + + down(&other_caches_lock); + while (p != &other_caches) { + struct cache_definition *cache = + list_entry(p, struct cache_definition, link); + + cache->shrink(priority, gfp_mask); + p = p->prev; + } + up(&other_caches_lock); +} + + static int shrink_cache(int nr_pages, zone_t *classzone, unsigned int gfp_mask, int priority, int max_scan) @@ -395,6 +429,7 @@ #ifdef CONFIG_QUOTA shrink_dqcache_memory(DEF_PRIORITY, gfp_mask); #endif + shrink_other_caches(priority, gfp_mask); return nr_pages; }