03 Jun, 2006

1 commit

  • mm/slab.c's offlab_limit logic is totally broken.

    Firstly, "offslab_limit" is a global variable while it should either be
    calculated in situ or should be passed in as a parameter.

    Secondly, the more serious problem with it is that the condition for
    calculating it:

    if (!(OFF_SLAB(sizes->cs_cachep))) {
    offslab_limit = sizes->cs_size - sizeof(struct slab);
    offslab_limit /= sizeof(kmem_bufctl_t);

    is in total disconnect with the condition that makes use of it:

    /* More than offslab_limit objects will cause problems */
    if ((flags & CFLGS_OFF_SLAB) && num > offslab_limit)
    break;

    but due to offslab_limit being a global variable this breakage was
    hidden.

    Up until lockdep came along and perturbed the slab sizes sufficiently so
    that the first off-slab cache would still see a (non-calculated) zero
    value for offslab_limit and would panic with:

    kmem_cache_create: couldn't create cache size-512.

    Call Trace:
    [] show_trace+0x96/0x1c8
    [] dump_stack+0x13/0x15
    [] panic+0x39/0x21a
    [] kmem_cache_create+0x5a0/0x5d0
    [] kmem_cache_init+0x193/0x379
    [] start_kernel+0x17f/0x218
    [] _sinittext+0x263/0x26a

    Kernel panic - not syncing: kmem_cache_create(): failed to create slab `size-512'

    Paolo Ornati's config on x86_64 managed to trigger it.

    The fix is to move the calculation to the place that makes use of it.
    This also makes slab.o 54 bytes smaller.

    Btw., the check itself is quite silly. Its intention is to test whether
    the number of objects per slab would be higher than the number of slab
    control pointers possible. In theory it could be triggered: if someone
    tried to allocate 4-byte objects cache and explicitly requested with
    CFLGS_OFF_SLAB. So i kept the check.

    Out of historic interest i checked how old this bug was and it's
    ancient, 10 years old! It is the oldest hidden and then truly triggering
    bugs i ever saw being fixed in the kernel!

    Signed-off-by: Ingo Molnar
    Signed-off-by: Linus Torvalds

    Ingo Molnar
     

16 May, 2006

2 commits

  • With CONFIG_NUMA set, kmem_cache_destroy() may fail and say "Can't
    free all objects." The problem is caused by sequences such as the
    following (suppose we are on a NUMA machine with two nodes, 0 and 1):

    * Allocate an object from cache on node 0.
    * Free the object on node 1. The object is put into node 1's alien
    array_cache for node 0.
    * Call kmem_cache_destroy(), which ultimately ends up in __cache_shrink().
    * __cache_shrink() does drain_cpu_caches(), which loops through all nodes.
    For each node it drains the shared array_cache and then handles the
    alien array_cache for the other node.

    However this means that node 0's shared array_cache will be drained,
    and then node 1 will move the contents of its alien[0] array_cache
    into that same shared array_cache. node 0's shared array_cache is
    never looked at again, so the objects left there will appear to be in
    use when __cache_shrink() calls __node_shrink() for node 0. So
    __node_shrink() will return 1 and kmem_cache_destroy() will fail.

    This patch fixes this by having drain_cpu_caches() do
    drain_alien_cache() on every node before it does drain_array() on the
    nodes' shared array_caches.

    The problem was originally reported by Or Gerlitz .

    Signed-off-by: Roland Dreier
    Acked-by: Christoph Lameter
    Acked-by: Pekka Enberg
    Signed-off-by: Linus Torvalds

    Roland Dreier
     
  • slab_is_available() indicates slab based allocators are available for use.
    SPARSEMEM code needs to know this as it can be called at various times
    during the boot process.

    Signed-off-by: Mike Kravetz
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Mike Kravetz
     

29 Apr, 2006

1 commit


26 Apr, 2006

1 commit


11 Apr, 2006

3 commits

  • The earlier patch to consolidate mmu and nommu page allocation and
    refcounting by using compound pages for nommu allocations had a bug:
    kmalloc slabs who's pages were initially allocated by a non-__GFP_COMP
    allocator could be passed into mm/nommu.c kmalloc allocations which really
    wanted __GFP_COMP underlying pages. Fix that by having nommu pass
    __GFP_COMP to all higher order slab allocations.

    Signed-off-by: Luke Yang
    Acked-by: Nick Piggin
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Luke Yang
     
  • Add a statistics counter which is incremented everytime the alien cache
    overflows. alien_cache limit is hardcoded to 12 right now. We can use
    this statistics to tune alien cache if needed in the future.

    Signed-off-by: Alok N Kataria
    Signed-off-by: Ravikiran Thirumalai
    Signed-off-by: Shai Fultheim
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ravikiran G Thirumalai
     
  • Allocate off-slab slab descriptors from node local memory.

    Signed-off-by: Alok N Kataria
    Signed-off-by: Ravikiran Thirumalai
    Signed-off-by: Shai Fultheim
    Acked-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ravikiran G Thirumalai
     

02 Apr, 2006

1 commit


29 Mar, 2006

1 commit


26 Mar, 2006

7 commits

  • We have had this memory leak for a while now. The situation is complicated
    by the use of alloc_kmemlist() as a function to resize various caches by
    do_tune_cpucache().

    What we do here is first of all make sure that we deallocate properly in
    the loop over all the nodes.

    If we are just resizing caches then we can simply return with -ENOMEM if an
    allocation fails.

    If the cache is new then we need to rollback and remove all earlier
    allocations.

    We detect that a cache is new by checking if the link to the global cache
    chain has been setup. This is a bit hackish ....

    (also fix up too overlong lines that I added in the last patch...)

    Signed-off-by: Christoph Lameter
    Cc: Jesper Juhl
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • Inspired by Jesper Juhl's patch from today

    1. Get rid of err
    We do not set it to anything else but zero.

    2. Drop the CONFIG_NUMA stuff.
    There are definitions for alloc_alien_cache and free_alien_cache()
    that do the right thing for the non NUMA case.

    3. Better naming of variables.

    4. Remove redundant cachep->nodelists[node] expressions.

    Signed-off-by: Christoph Lameter
    Signed-off-by: Jesper Juhl
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • __drain_alien_cache() currently drains objects by freeing them to the
    (remote) freelists of the original node. However, each node also has a
    shared list containing objects to be used on any processor of that node.
    We can avoid a number of remote node accesses by copying the pointers to
    the free objects directly into the remote shared array.

    And while we are at it: Skip alien draining if the alien cache spinlock is
    already taken.

    Kiran reported that this is a performance benefit.

    Signed-off-by: Christoph Lameter
    Cc: Pekka Enberg
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • slabr_objects() can be used to transfer objects between various object
    caches of the slab allocator. It is currently only used during
    __cache_alloc() to retrieve elements from the shared array. We will be
    using it soon to transfer elements from the alien caches to the remote
    shared array.

    Signed-off-by: Christoph Lameter
    Cc: Pekka Enberg
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • Convert mm/ to use the new kmem_cache_zalloc allocator.

    Signed-off-by: Pekka Enberg
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Pekka Enberg
     
  • Introduce a memory-zeroing variant of kmem_cache_alloc. The allocator
    already exits in XFS and there are potential users for it so this patch
    makes the allocator available for the general public.

    Signed-off-by: Pekka Enberg
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Pekka Enberg
     
  • Implement /proc/slab_allocators. It produces output like:

    idr_layer_cache: 80 idr_pre_get+0x33/0x4e
    buffer_head: 2555 alloc_buffer_head+0x20/0x75
    mm_struct: 9 mm_alloc+0x1e/0x42
    mm_struct: 20 dup_mm+0x36/0x370
    vm_area_struct: 384 dup_mm+0x18f/0x370
    vm_area_struct: 151 do_mmap_pgoff+0x2e0/0x7c3
    vm_area_struct: 1 split_vma+0x5a/0x10e
    vm_area_struct: 11 do_brk+0x206/0x2e2
    vm_area_struct: 2 copy_vma+0xda/0x142
    vm_area_struct: 9 setup_arg_pages+0x99/0x214
    fs_cache: 8 copy_fs_struct+0x21/0x133
    fs_cache: 29 copy_process+0xf38/0x10e3
    files_cache: 30 alloc_files+0x1b/0xcf
    signal_cache: 81 copy_process+0xbaa/0x10e3
    sighand_cache: 77 copy_process+0xe65/0x10e3
    sighand_cache: 1 de_thread+0x4d/0x5f8
    anon_vma: 241 anon_vma_prepare+0xd9/0xf3
    size-2048: 1 add_sect_attrs+0x5f/0x145
    size-2048: 2 journal_init_revoke+0x99/0x302
    size-2048: 2 journal_init_revoke+0x137/0x302
    size-2048: 2 journal_init_inode+0xf9/0x1c4

    Cc: Manfred Spraul
    Cc: Alexander Nyberg
    Cc: Pekka Enberg
    Cc: Christoph Lameter
    Cc: Ravikiran Thirumalai
    Signed-off-by: Al Viro
    DESC
    slab-leaks3-locking-fix
    EDESC
    From: Andrew Morton

    Update for slab-remove-cachep-spinlock.patch

    Cc: Al Viro
    Cc: Manfred Spraul
    Cc: Alexander Nyberg
    Cc: Pekka Enberg
    Cc: Christoph Lameter
    Cc: Ravikiran Thirumalai
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Al Viro
     

24 Mar, 2006

3 commits

  • The hook in the slab cache allocation path to handle cpuset memory
    spreading for tasks in cpusets with 'memory_spread_slab' enabled has a
    modest performance bug. The hook calls into the memory spreading handler
    alternate_node_alloc() if either of 'memory_spread_slab' or
    'memory_spread_page' is enabled, even though the handler does nothing
    (albeit harmlessly) for the page case

    Fix - drop PF_SPREAD_PAGE from the set of flag bits that are used to
    trigger a call to alternate_node_alloc().

    The page case is handled by separate hooks -- see the calls conditioned on
    cpuset_do_page_mem_spread() in mm/filemap.c

    Signed-off-by: Paul Jackson
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Paul Jackson
     
  • The hooks in the slab cache allocator code path for support of NUMA
    mempolicies and cpuset memory spreading are in an important code path. Many
    systems will use neither feature.

    This patch optimizes those hooks down to a single check of some bits in the
    current tasks task_struct flags. For non NUMA systems, this hook and related
    code is already ifdef'd out.

    The optimization is done by using another task flag, set if the task is using
    a non-default NUMA mempolicy. Taking this flag bit along with the
    PF_SPREAD_PAGE and PF_SPREAD_SLAB flag bits added earlier in this 'cpuset
    memory spreading' patch set, one can check for the combination of any of these
    special case memory placement mechanisms with a single test of the current
    tasks task_struct flags.

    This patch also tightens up the code, to save a few bytes of kernel text
    space, and moves some of it out of line. Due to the nested inlines called
    from multiple places, we were ending up with three copies of this code, which
    once we get off the main code path (for local node allocation) seems a bit
    wasteful of instruction memory.

    Signed-off-by: Paul Jackson
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Paul Jackson
     
  • Provide the slab cache infrastructure to support cpuset memory spreading.

    See the previous patches, cpuset_mem_spread, for an explanation of cpuset
    memory spreading.

    This patch provides a slab cache SLAB_MEM_SPREAD flag. If set in the
    kmem_cache_create() call defining a slab cache, then any task marked with the
    process state flag PF_MEMSPREAD will spread memory page allocations for that
    cache over all the allowed nodes, instead of preferring the local (faulting)
    node.

    On systems not configured with CONFIG_NUMA, this results in no change to the
    page allocation code path for slab caches.

    On systems with cpusets configured in the kernel, but the "memory_spread"
    cpuset option not enabled for the current tasks cpuset, this adds a call to a
    cpuset routine and failed bit test of the processor state flag PF_SPREAD_SLAB.

    For tasks so marked, a second inline test is done for the slab cache flag
    SLAB_MEM_SPREAD, and if that is set and if the allocation is not
    in_interrupt(), this adds a call to to a cpuset routine that computes which of
    the tasks mems_allowed nodes should be preferred for this allocation.

    ==> This patch adds another hook into the performance critical
    code path to allocating objects from the slab cache, in the
    ____cache_alloc() chunk, below. The next patch optimizes this
    hook, reducing the impact of the combined mempolicy plus memory
    spreading hooks on this critical code path to a single check
    against the tasks task_struct flags word.

    This patch provides the generic slab flags and logic needed to apply memory
    spreading to a particular slab.

    A subsequent patch will mark a few specific slab caches for this placement
    policy.

    Signed-off-by: Paul Jackson
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Paul Jackson
     

22 Mar, 2006

14 commits

  • The alien cache rotor in mm/slab.c assumes that the first online node is
    node 0. Eventually for some archs, especially with hotplug, this will no
    longer be true.

    Fix the interleave rotor to handle the general case of node numbering.

    Signed-off-by: Paul Jackson
    Acked-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Paul Jackson
     
  • The list_lock also protects the shared array and we call drain_array() with
    the shared array. Therefore we cannot go as far as I wanted to but have to
    take the lock in a way so that it also protects the array_cache in
    drain_pages.

    (Note: maybe we should make the array_cache locking more consistent? I.e.
    always take the array cache lock for shared arrays and disable interrupts
    for the per cpu arrays?)

    Signed-off-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • Remove drain_array_locked and use that opportunity to limit the time the l3
    lock is taken further.

    Signed-off-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • And a parameter to drain_array to control the freeing of all objects and
    then use drain_array() to replace instances of drain_array_locked with
    drain_array. Doing so will avoid taking locks in those locations if the
    arrays are empty.

    Signed-off-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • cache_reap takes the l3->list_lock (disabling interrupts) unconditionally
    and then does a few checks and maybe does some cleanup. This patch makes
    cache_reap() only take the lock if there is work to do and then the lock is
    taken and released for each cleaning action.

    The checking of when to do the next reaping is done without any locking and
    becomes racy. Should not matter since reaping can also be skipped if the
    slab mutex cannot be acquired.

    The same is true for the touched processing. If we get this wrong once in
    awhile then we will mistakenly clean or not clean the shared cache. This
    will impact performance slightly.

    Note that the additional drain_array() function introduced here will fall
    out in a subsequent patch since array cleaning will now be very similar
    from all callers.

    Signed-off-by: Christoph Lameter
    Cc: Pekka Enberg
    Cc: Manfred Spraul
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • Now that compound page handling is properly fixed in the VM, move nommu
    over to using compound pages rather than rolling their own refcounting.

    nommu vm page refcounting is broken anyway, but there is no need to have
    divergent code in the core VM now, nor when it gets fixed.

    Signed-off-by: Nick Piggin
    Cc: David Howells

    (Needs testing, please).
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Nick Piggin
     
  • Slab duplicates on_each_cpu().

    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrew Morton
     
  • SLAB_NO_REAP is documented as an option that will cause this slab not to be
    reaped under memory pressure. However, that is not what happens. The only
    thing that SLAB_NO_REAP controls at the moment is the reclaim of the unused
    slab elements that were allocated in batch in cache_reap(). Cache_reap()
    is run every few seconds independently of memory pressure.

    Could we remove the whole thing? Its only used by three slabs anyways and
    I cannot find a reason for having this option.

    There is an additional problem with SLAB_NO_REAP. If set then the recovery
    of objects from alien caches is switched off. Objects not freed on the
    same node where they were initially allocated will only be reused if a
    certain amount of objects accumulates from one alien node (not very likely)
    or if the cache is explicitly shrunk. (Strangely __cache_shrink does not
    check for SLAB_NO_REAP)

    Getting rid of SLAB_NO_REAP fixes the problems with alien cache freeing.

    Signed-off-by: Christoph Lameter
    Cc: Pekka Enberg
    Cc: Manfred Spraul
    Cc: Mark Fasheh
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • Fix kernel-doc warnings in mm/slab.c.

    Signed-off-by: Randy Dunlap
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Randy Dunlap
     
  • Remove cachep->spinlock. Locking has moved to the kmem_list3 and most of
    the structures protected earlier by cachep->spinlock is now protected by
    the l3->list_lock. slab cache tunables like batchcount are accessed always
    with the cache_chain_mutex held.

    Patch tested on SMP and NUMA kernels with dbench processes running,
    constant onlining/offlining, and constant cache tuning, all at the same
    time.

    Signed-off-by: Ravikiran Thirumalai
    Cc: Christoph Lameter
    Cc: Pekka Enberg
    Cc: Manfred Spraul
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ravikiran G Thirumalai
     
  • slab.c has become a bit revolting again. Try to repair it.

    - Coding style fixes

    - Don't do assignments-in-if-statements.

    - Don't typecast assignments to/from void*

    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrew Morton
     
  • Extract setup_cpu_cache() function from kmem_cache_create() to make the
    latter a little less complex.

    Signed-off-by: Pekka Enberg
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Pekka Enberg
     
  • Clean up the object to index mapping that has been spread around mm/slab.c.

    Signed-off-by: Pekka Enberg
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Pekka Enberg
     
  • Atomic operation removal from slab

    Signed-off-by: Nick Piggin
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Nick Piggin
     

10 Mar, 2006

1 commit

  • The cache reaper currently tries to free all alien caches and all remote
    per cpu pages in each pass of cache_reap. For a machines with large number
    of nodes (such as Altix) this may lead to sporadic delays of around ~10ms.
    Interrupts are disabled while reclaiming creating unacceptable delays.

    This patch changes that behavior by adding a per cpu reap_node variable.
    Instead of attempting to free all caches, we free only one alien cache and
    the per cpu pages from one remote node. That reduces the time spend in
    cache_reap. However, doing so will lengthen the time it takes to
    completely drain all remote per cpu pagesets and all alien caches. The
    time needed will grow with the number of nodes in the system. All caches
    are drained when they overflow their respective capacity. So the drawback
    here is only that a bit of memory may be wasted for awhile longer.

    Details:

    1. Rename drain_remote_pages to drain_node_pages to allow the specification
    of the node to drain of pcp pages.

    2. Add additional functions init_reap_node, next_reap_node for NUMA
    that manage a per cpu reap_node counter.

    3. Add a reap_alien function that reaps only from the current reap_node.

    For us this seems to be a critical issue. Holdoffs of an average of ~7ms
    cause some HPC benchmarks to slow down significantly. F.e. NAS parallel
    slows down dramatically. NAS parallel has a 12-16 seconds runtime w/o rotor
    compared to 5.8 secs with the rotor patches. It gets down to 5.05 secs with
    the additional interrupt holdoff reductions.

    Signed-off-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     

09 Mar, 2006

2 commits


07 Mar, 2006

2 commits


11 Feb, 2006

1 commit