lkml.org 
[lkml]   [2008]   [Sep]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RFC 06/13] genapic: use get_cpumask_var operations for allbutself cpumask_ts
      * Adds a global allbutself PER_CPUMASK variable and modifies functions
    that create a temp cpumask variable for the following procedure:

    cpumask_t mask = cpu_online_map;

    cpu_clear(smp_processor_id(), mask);

    if (!cpus_empty(mask))
    XXX_send_IPI_mask(&mask, vector);

    This then becomes:

    cpumask_ptr mask;

    get_cpumask_var(mask, allbutself);
    *mask = cpu_online_map;
    cpu_clear(smp_processor_id(), *mask);

    if (!cpus_empty(*mask))
    XXX_send_IPI_mask(mask, vector);

    put_cpumask_var(mask, allbutself);

    * Note: this "allbutself" per_cpumask variable could be pre-built during
    system startup saving execution time, but would require that all the
    per_cpumask variables are updated whenever a cpu goes off- or on-line.


    Applies to linux-2.6.tip/master.

    Signed-off-by: Mike Travis <travis@sgi.com>
    ---
    arch/x86/kernel/apic.c | 3 +++
    arch/x86/kernel/genapic_flat_64.c | 26 +++++++++++++++++++-------
    arch/x86/kernel/genx2apic_cluster.c | 13 +++++++++----
    arch/x86/kernel/genx2apic_uv_x.c | 13 +++++++++----
    arch/x86/kernel/smp.c | 28 ++++++++++++++++++++++++----
    include/asm-x86/genapic_32.h | 2 ++
    include/asm-x86/genapic_64.h | 4 ++++
    include/asm-x86/mach-default/mach_ipi.h | 14 ++++++++++----
    8 files changed, 80 insertions(+), 23 deletions(-)

    --- linux-2.6.tip.orig/arch/x86/kernel/apic.c
    +++ linux-2.6.tip/arch/x86/kernel/apic.c
    @@ -30,6 +30,7 @@
    #include <linux/module.h>
    #include <linux/dmi.h>
    #include <linux/dmar.h>
    +#include <linux/cpumask_ptr.h>

    #include <asm/atomic.h>
    #include <asm/smp.h>
    @@ -162,6 +163,8 @@ static DEFINE_PER_CPU(struct clock_event

    static unsigned long apic_phys;

    +DEFINE_PER_CPUMASK(allbutself);
    +
    /*
    * Get the LAPIC version
    */
    --- linux-2.6.tip.orig/arch/x86/kernel/genapic_flat_64.c
    +++ linux-2.6.tip/arch/x86/kernel/genapic_flat_64.c
    @@ -11,6 +11,7 @@
    #include <linux/errno.h>
    #include <linux/threads.h>
    #include <linux/cpumask.h>
    +#include <linux/cpumask_ptr.h>
    #include <linux/string.h>
    #include <linux/kernel.h>
    #include <linux/ctype.h>
    @@ -87,12 +88,17 @@ static void flat_send_IPI_allbutself(int
    int hotplug = 0;
    #endif
    if (hotplug || vector == NMI_VECTOR) {
    - cpumask_t allbutme = cpu_online_map;
    + cpumask_ptr mask;

    - cpu_clear(smp_processor_id(), allbutme);
    + get_cpumask_var(mask, allbutself);
    + *mask = cpu_online_map;
    + cpu_clear(smp_processor_id(), *mask);
    +
    + if (!cpus_empty(*mask))
    + flat_send_IPI_mask(mask, vector);
    +
    + put_cpumask_var(mask, allbutself);

    - if (!cpus_empty(allbutme))
    - flat_send_IPI_mask(&allbutme, vector);
    } else if (num_online_cpus() > 1) {
    __send_IPI_shortcut(APIC_DEST_ALLBUT, vector,APIC_DEST_LOGICAL);
    }
    @@ -205,10 +211,16 @@ static void physflat_send_IPI_mask(const

    static void physflat_send_IPI_allbutself(int vector)
    {
    - cpumask_t allbutme = cpu_online_map;
    + cpumask_ptr mask;
    +
    + get_cpumask_var(mask, allbutself);
    + *mask = cpu_online_map;
    + cpu_clear(smp_processor_id(), *mask);
    +
    + if (!cpus_empty(*mask))
    + physflat_send_IPI_mask(mask, vector);

    - cpu_clear(smp_processor_id(), allbutme);
    - physflat_send_IPI_mask(&allbutme, vector);
    + put_cpumask_var(mask, allbutself);
    }

    static void physflat_send_IPI_all(int vector)
    --- linux-2.6.tip.orig/arch/x86/kernel/genx2apic_cluster.c
    +++ linux-2.6.tip/arch/x86/kernel/genx2apic_cluster.c
    @@ -1,5 +1,6 @@
    #include <linux/threads.h>
    #include <linux/cpumask.h>
    +#include <linux/cpumask_ptr.h>
    #include <linux/string.h>
    #include <linux/kernel.h>
    #include <linux/ctype.h>
    @@ -71,12 +72,16 @@ static void x2apic_send_IPI_mask(const c

    static void x2apic_send_IPI_allbutself(int vector)
    {
    - cpumask_t mask = cpu_online_map;
    + cpumask_ptr mask;

    - cpu_clear(smp_processor_id(), mask);
    + get_cpumask_var(mask, allbutself);
    + *mask = cpu_online_map;
    + cpu_clear(smp_processor_id(), *mask);

    - if (!cpus_empty(mask))
    - x2apic_send_IPI_mask(&mask, vector);
    + if (!cpus_empty(*mask))
    + x2apic_send_IPI_mask(mask, vector);
    +
    + put_cpumask_var(mask, allbutself);
    }

    static void x2apic_send_IPI_all(int vector)
    --- linux-2.6.tip.orig/arch/x86/kernel/genx2apic_uv_x.c
    +++ linux-2.6.tip/arch/x86/kernel/genx2apic_uv_x.c
    @@ -11,6 +11,7 @@
    #include <linux/kernel.h>
    #include <linux/threads.h>
    #include <linux/cpumask.h>
    +#include <linux/cpumask_ptr.h>
    #include <linux/string.h>
    #include <linux/ctype.h>
    #include <linux/init.h>
    @@ -135,12 +136,16 @@ static void uv_send_IPI_mask(const cpuma

    static void uv_send_IPI_allbutself(int vector)
    {
    - cpumask_t mask = cpu_online_map;
    + cpumask_ptr mask;

    - cpu_clear(smp_processor_id(), mask);
    + get_cpumask_var(mask, allbutself);
    + *mask = cpu_online_map;
    + cpu_clear(smp_processor_id(), *mask);

    - if (!cpus_empty(mask))
    - uv_send_IPI_mask(&mask, vector);
    + if (!cpus_empty(*mask))
    + uv_send_IPI_mask(mask, vector);
    +
    + put_cpumask_var(mask, allbutself);
    }

    static void uv_send_IPI_all(int vector)
    --- linux-2.6.tip.orig/arch/x86/kernel/smp.c
    +++ linux-2.6.tip/arch/x86/kernel/smp.c
    @@ -21,6 +21,7 @@
    #include <linux/cache.h>
    #include <linux/interrupt.h>
    #include <linux/cpu.h>
    +#include <linux/cpumask_ptr.h>

    #include <asm/mtrr.h>
    #include <asm/tlbflush.h>
    @@ -128,16 +129,35 @@ void native_send_call_func_single_ipi(in

    void native_send_call_func_ipi(const cpumask_t *mask)
    {
    - cpumask_t allbutself;

    - allbutself = cpu_online_map;
    - cpu_clear(smp_processor_id(), allbutself);
    +#ifndef ARCH_DOES_NOT_HAVE_ALLBUTSELF_IPI_CALL
    + /*
    + * Can't use global "allbutself" because many of the
    + * genapic->send_IPI_allbutself functions use it to
    + * expand to a mask to send to each cpu as they do not
    + * have a single IPI call to send to "allbutself".
    + *
    + * This is here only for the small count NR_CPUS that actually
    + * have one of those handy functions.
    + *
    + * There might be an ifdef I could use to short-circuit this out...?
    + */
    + static DEFINE_PER_CPUMASK(smp_temp_cpumask);
    + cpumask_ptr allbutself;
    +
    + get_cpumask_var(allbutself, smp_temp_cpumask);
    + *allbutself = cpu_online_map;
    + cpu_clear(smp_processor_id(), *allbutself);

    - if (cpus_equal(*mask, allbutself) &&
    + if (cpus_equal(*mask, *allbutself) &&
    cpus_equal(cpu_online_map, cpu_callout_map))
    send_IPI_allbutself(CALL_FUNCTION_VECTOR);
    else
    send_IPI_mask(*mask, CALL_FUNCTION_VECTOR);
    + put_cpumask_var(allbutself, smp_temp_cpumask);
    +#else
    + send_IPI_mask(*mask, CALL_FUNCTION_VECTOR);
    +#endif
    }

    static void stop_this_cpu(void *dummy)
    --- linux-2.6.tip.orig/include/asm-x86/genapic_32.h
    +++ linux-2.6.tip/include/asm-x86/genapic_32.h
    @@ -2,6 +2,7 @@
    #define ASM_X86__GENAPIC_32_H

    #include <asm/mpspec.h>
    +#include <linux/cpumask_ptr.h>

    /*
    * Generic APIC driver interface.
    @@ -122,5 +123,6 @@ enum uv_system_type {UV_NONE, UV_LEGACY_
    #define uv_wakeup_secondary(a, b) 1
    #define uv_system_init() do {} while (0)

    +DECLARE_PER_CPUMASK(allbutself);

    #endif /* ASM_X86__GENAPIC_32_H */
    --- linux-2.6.tip.orig/include/asm-x86/genapic_64.h
    +++ linux-2.6.tip/include/asm-x86/genapic_64.h
    @@ -1,6 +1,8 @@
    #ifndef ASM_X86__GENAPIC_64_H
    #define ASM_X86__GENAPIC_64_H

    +#include <linux/cpumask_ptr.h>
    +
    /*
    * Copyright 2004 James Cleverdon, IBM.
    * Subject to the GNU Public License, v.2
    @@ -55,4 +57,6 @@ extern int uv_wakeup_secondary(int phys_

    extern void setup_apic_routing(void);

    +DECLARE_PER_CPUMASK(allbutself);
    +
    #endif /* ASM_X86__GENAPIC_64_H */
    --- linux-2.6.tip.orig/include/asm-x86/mach-default/mach_ipi.h
    +++ linux-2.6.tip/include/asm-x86/mach-default/mach_ipi.h
    @@ -1,6 +1,8 @@
    #ifndef ASM_X86__MACH_DEFAULT__MACH_IPI_H
    #define ASM_X86__MACH_DEFAULT__MACH_IPI_H

    +#include <linux/cpumask_ptr.h>
    +
    /* Avoid include hell */
    #define NMI_VECTOR 0x02

    @@ -9,8 +11,9 @@ void __send_IPI_shortcut(unsigned int sh

    extern int no_broadcast;

    -#ifdef CONFIG_X86_64
    #include <asm/genapic.h>
    +
    +#ifdef CONFIG_X86_64
    #define send_IPI_mask(mask, vector) (genapic->send_IPI_mask)(&(mask), vector)
    #else
    static inline void send_IPI_mask(cpumask_t mask, int vector)
    @@ -22,10 +25,13 @@ static inline void send_IPI_mask(cpumask
    static inline void __local_send_IPI_allbutself(int vector)
    {
    if (no_broadcast || vector == NMI_VECTOR) {
    - cpumask_t mask = cpu_online_map;
    + cpumask_ptr mask;

    - cpu_clear(smp_processor_id(), mask);
    - send_IPI_mask(mask, vector);
    + get_cpumask_var(mask, allbutself);
    + *mask = cpu_online_map;
    + cpu_clear(smp_processor_id(), *mask);
    + send_IPI_mask(*mask, vector);
    + put_cpumask_var(mask, allbutself);
    } else
    __send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
    }
    --


    \
     
     \ /
      Last update: 2008-09-07 01:57    [W:0.039 / U:0.232 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site