lkml.org 
[lkml]   [2002]   [Aug]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH] Caches that shrink automatically
    Date
    Hello,

    Currently there is no way for modules to define dynamically sized caches that
    shrink upon memory pressure. We need this for implementing Extended Attribute
    caches on ext2, ext3, and ReiserFS. Other caches could also make use of the
    same mechanism (e.g., nfsd's permission cache, dcache, icache, dqache).

    I propose this patch, which adds the register_cache() and unregister_cache()
    functions. They allow to register a callback which is invoked on memory
    pressure. This callback shall then try to free some memory; the parameters
    and semantics are similar to the other shrink functions in mm/vmscan.c.


    Regards,
    Andreas.

    ------------------------------------------------------------------
    Andreas Gruenbacher SuSE Linux AG
    mailto:agruen@suse.de Deutschherrnstr. 15-19
    http://www.suse.de/ D-90429 Nuernberg, GermanyModular 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, <a.gruenbacher@computer.org>
    + */
    +
    +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 <linux/genhd.h>
    #include <linux/blkpg.h>
    #include <linux/swap.h>
    +#include <linux/cache_def.h>
    #include <linux/ctype.h>
    #include <linux/file.h>
    #include <linux/iobuf.h>
    @@ -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 <linux/slab.h>
    #include <linux/kernel_stat.h>
    #include <linux/swap.h>
    +#include <linux/cache_def.h>
    #include <linux/smp_lock.h>
    #include <linux/pagemap.h>
    #include <linux/init.h>
    @@ -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;
    }
    \
     
     \ /
      Last update: 2005-03-22 13:27    [W:0.042 / U:29.768 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site