lkml.org 
[lkml]   [2008]   [Oct]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 34/35] cpumask: debug options for cpumasks
    It's useful to check that no one is accessing > nr_cpumask_bits for
    cpumasks. This also allows you to turn on CONFIG_CPUMASKS_OFFSTACK
    even for smaller CONFIG_NR_CPUS.

    From: Rusty Russell <rusty@rustcorp.com.au>
    Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
    Signed-off-by: Mike Travis <travis@sgi.com>
    ---
    include/linux/cpumask.h | 23 +++++++++++++++++------
    lib/Kconfig.debug | 6 ++++++
    lib/cpumask.c | 3 +++
    3 files changed, 26 insertions(+), 6 deletions(-)

    --- test-compile.orig/include/linux/cpumask.h
    +++ test-compile/include/linux/cpumask.h
    @@ -217,23 +217,34 @@ extern cpumask_t _unused_cpumask_arg_;
    }
    #endif /* CONFIG_NR_CPUS > BITS_PER_LONG */

    +/* verify cpu argument to cpumask_* operators */
    +static inline unsigned int cpumask_check(unsigned int cpu)
    +{
    +#ifdef CONFIG_DEBUG_PER_CPU_MAPS
    + /* This breaks at runtime. */
    + BUG_ON(cpu >= nr_cpumask_bits);
    +#endif /* CONFIG_DEBUG_PER_CPU_MAPS */
    + return cpu;
    +}
    +
    /* cpumask_* operators */
    static inline void cpumask_set_cpu(int cpu, volatile struct cpumask *dstp)
    {
    - set_bit(cpu, cpumask_bits(dstp));
    + set_bit(cpumask_check(cpu), cpumask_bits(dstp));
    }

    static inline void cpumask_clear_cpu(int cpu, volatile struct cpumask *dstp)
    {
    - clear_bit(cpu, cpumask_bits(dstp));
    + clear_bit(cpumask_check(cpu), cpumask_bits(dstp));
    }

    /* No static inline type checking - see Subtlety (1) above. */
    -#define cpumask_test_cpu(cpu, cpumask) test_bit((cpu), (cpumask)->bits)
    +#define cpumask_test_cpu(cpu, cpumask) \
    + test_bit(cpumask_check(cpu), (cpumask)->bits)

    static inline int cpumask_test_and_set_cpu(int cpu, struct cpumask *addr)
    {
    - return test_and_set_bit(cpu, cpumask_bits(addr));
    + return test_and_set_bit(cpumask_check(cpu), cpumask_bits(addr));
    }

    static inline void cpumask_setall(struct cpumask *dstp)
    @@ -367,8 +378,8 @@ static inline int cpumask_cpuremap(int o
    const struct cpumask *oldp,
    const struct cpumask *newp)
    {
    - return bitmap_bitremap(oldbit, cpumask_bits(oldp), cpumask_bits(newp),
    - nr_cpumask_bits);
    + return bitmap_bitremap(cpumask_check(oldbit), cpumask_bits(oldp),
    + cpumask_bits(newp), nr_cpumask_bits);
    }

    static inline void cpumask_remap(struct cpumask *dstp,
    --- test-compile.orig/lib/Kconfig.debug
    +++ test-compile/lib/Kconfig.debug
    @@ -766,6 +766,12 @@ config SYSCTL_SYSCALL_CHECK
    to properly maintain and use. This enables checks that help
    you to keep things correct.

    +config DEBUG_PER_CPU_MAPS
    + bool "Cpumask debug checks"
    + ---help---
    + Extra debugging for cpumasks.
    + eg. to make sure accesses to cpumasks are < nr_cpu_ids.
    +
    source kernel/trace/Kconfig

    config PROVIDE_OHCI1394_DMA_INIT
    --- test-compile.orig/lib/cpumask.c
    +++ test-compile/lib/cpumask.c
    @@ -11,6 +11,9 @@ EXPORT_SYMBOL(cpumask_first);

    int cpumask_next(int n, const cpumask_t *srcp)
    {
    + /* -1 is a legal arg here. */
    + if (n != -1)
    + cpumask_check(n);
    return find_next_bit(cpumask_bits(srcp), nr_cpumask_bits, n+1);
    }
    EXPORT_SYMBOL(cpumask_next);
    --


    \
     
     \ /
      Last update: 2008-10-20 19:15    [W:0.054 / U:29.036 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site