lkml.org 
[lkml]   [2012]   [Feb]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v8 5/8] slub: only IPI CPUs that have per cpu obj to flush
    Date
    flush_all() is called for each kmem_cahce_destroy(). So every cache
    being destroyed dynamically ends up sending an IPI to each CPU in the
    system, regardless if the cache has ever been used there.

    For example, if you close the Infinband ipath driver char device file,
    the close file ops calls kmem_cache_destroy(). So running some
    infiniband config tool on one a single CPU dedicated to system tasks
    might interrupt the rest of the 127 CPUs dedicated to some CPU
    intensive or latency sensitive task.

    I suspect there is a good chance that every line in the output of "git
    grep kmem_cache_destroy linux/ | grep '\->'" has a similar scenario.

    This patch attempts to rectify this issue by sending an IPI to flush
    the per cpu objects back to the free lists only to CPUs that seem to
    have such objects.

    The check which CPU to IPI is racy but we don't care since asking a
    CPU without per cpu objects to flush does no damage and as far as I
    can tell the flush_all by itself is racy against allocs on remote
    CPUs anyway, so if you required the flush_all to be determinstic, you
    had to arrange for locking regardless.

    Without this patch the following artificial test case:

    $ cd /sys/kernel/slab
    $ for DIR in *; do cat $DIR/alloc_calls > /dev/null; done

    produces 166 IPIs on an cpuset isolated CPU. With it it produces none.

    The code path of memory allocation failure for CPUMASK_OFFSTACK=y
    config was tested using fault injection framework.

    Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
    Acked-by: Christoph Lameter <cl@linux.com>
    Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
    CC: Chris Metcalf <cmetcalf@tilera.com>
    CC: Frederic Weisbecker <fweisbec@gmail.com>
    CC: Russell King <linux@arm.linux.org.uk>
    CC: linux-mm@kvack.org
    CC: Pekka Enberg <penberg@kernel.org>
    CC: Matt Mackall <mpm@selenic.com>
    CC: Sasha Levin <levinsasha928@gmail.com>
    CC: Rik van Riel <riel@redhat.com>
    CC: Andi Kleen <andi@firstfloor.org>
    CC: Mel Gorman <mel@csn.ul.ie>
    CC: Andrew Morton <akpm@linux-foundation.org>
    CC: Alexander Viro <viro@zeniv.linux.org.uk>
    CC: linux-fsdevel@vger.kernel.org
    CC: Avi Kivity <avi@redhat.com>
    CC: Michal Nazarewicz <mina86@mina86.com>
    CC: Kosaki Motohiro <kosaki.motohiro@gmail.com>
    CC: Milton Miller <miltonm@bga.com>
    ---
    mm/slub.c | 10 +++++++++-
    1 files changed, 9 insertions(+), 1 deletions(-)

    diff --git a/mm/slub.c b/mm/slub.c
    index 4907563..3d75f89 100644
    --- a/mm/slub.c
    +++ b/mm/slub.c
    @@ -2018,9 +2018,17 @@ static void flush_cpu_slab(void *d)
    __flush_cpu_slab(s, smp_processor_id());
    }

    +static bool has_cpu_slab(int cpu, void *info)
    +{
    + struct kmem_cache *s = info;
    + struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
    +
    + return !!(c->page);
    +}
    +
    static void flush_all(struct kmem_cache *s)
    {
    - on_each_cpu(flush_cpu_slab, s, 1);
    + on_each_cpu_cond(has_cpu_slab, flush_cpu_slab, s, 1, GFP_ATOMIC);
    }

    /*
    --
    1.7.0.4


    \
     
     \ /
      Last update: 2012-02-05 14:53    [W:4.175 / U:0.376 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site