• Andrew Morton's avatar
    [PATCH] batched slab shrink and registration API · 71419dc7
    Andrew Morton authored
    From Ed Tomlinson, then mauled by yours truly.
    
    The current shrinking of the dentry, inode and dquot caches seems to
    work OK, but it is slightly CPU-inefficient: we call the shrinking
    functions many times, for tiny numbers of objects.
    
    So here, we just batch that up - shrinking happens at the same rate but
    we perform it in larger units of work.
    
    To do this, we need a way of knowing how many objects are currently in
    use by individual caches.  slab does not actually track this
    information, but the existing shrinkable caches do have this on hand.
    So rather than adding the counters to slab, we require that the
    shrinker callback functions keep their own count - we query that via
    the callback.
    
    We add a simple registration API which is exported to modules.  A
    subsystem may register its own callback function via set_shrinker().
    
    set_shrinker() simply takes a function pointer.  The function is called
    with
    
    	int (*shrinker)(int nr_to_shrink, unsigned int gfp_mask);
    
    The shrinker callback must scan `nr_to_scan' objects and free all
    freeable scanned objects.  Note: it doesn't have to *free* `nr_to_scan'
    objects.  It need only scan that many.  Which is a fairly pedantic
    detail, really.
    
    The shrinker callback must return the number of objects which are in
    its cache at the end of the scanning attempt.  It will be called with
    nr_to_scan == 0 when we're just querying the cache size.
    
    The set_shrinker() registration API is passed a hint as to how many
    disk seeks a single cache object is worth.  Everything uses "2" at
    present.
    
    I saw no need to add the traditional `here is my void *data' to the
    registration/callback.  Because there is a one-to-one relationship
    between caches and their shrinkers.
    
    
    Various cleanups became possible:
    
    - shrink_icache_memory() is no longer exported to modules.
    
    - shrink_icache_memory() is now static to fs/inode.c
    
    - prune_icache() is now static to fs/inode.c, and made inline (single caller)
    
    - shrink_dcache_memory() is made static to fs/dcache.c
    
    - prune_dcache() is no longer exported to modules
    
    - prune_dcache() is made static to fs/dcache.c
    
    - shrink_dqcache_memory() is made static to fs/dquot.c
    
    - All the quota init code has been moved from fs/dcache.c into fs/dquot.c
    
    - All modifications to inodes_stat.nr_inodes are now inside
      inode_lock - the dispose_list one was racy.
    71419dc7
dquot.c 40.3 KB