lkml.org 
[lkml]   [2013]   [Feb]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 60/89] smp: Fix SMP function call empty cpu mask race
    Date
    3.7-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Wang YanQing <udknight@gmail.com>

    commit f44310b98ddb7f0d06550d73ed67df5865e3eda5 upstream.

    I get the following warning every day with v3.7, once or
    twice a day:

    [ 2235.186027] WARNING: at /mnt/sda7/kernel/linux/arch/x86/kernel/apic/ipi.c:109 default_send_IPI_mask_logical+0x2f/0xb8()

    As explained by Linus as well:

    |
    | Once we've done the "list_add_rcu()" to add it to the
    | queue, we can have (another) IPI to the target CPU that can
    | now see it and clear the mask.
    |
    | So by the time we get to actually send the IPI, the mask might
    | have been cleared by another IPI.
    |

    This patch also fixes a system hang problem, if the data->cpumask
    gets cleared after passing this point:

    if (WARN_ONCE(!mask, "empty IPI mask"))
    return;

    then the problem in commit 83d349f35e1a ("x86: don't send an IPI to
    the empty set of CPU's") will happen again.

    Signed-off-by: Wang YanQing <udknight@gmail.com>
    Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
    Acked-by: Jan Beulich <jbeulich@suse.com>
    Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Cc: peterz@infradead.org
    Cc: mina86@mina86.org
    Cc: srivatsa.bhat@linux.vnet.ibm.com
    Link: http://lkml.kernel.org/r/20130126075357.GA3205@udknight
    [ Tidied up the changelog and the comment in the code. ]
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    kernel/smp.c | 13 ++++++++++++-
    1 file changed, 12 insertions(+), 1 deletion(-)

    --- a/kernel/smp.c
    +++ b/kernel/smp.c
    @@ -33,6 +33,7 @@ struct call_function_data {
    struct call_single_data csd;
    atomic_t refs;
    cpumask_var_t cpumask;
    + cpumask_var_t cpumask_ipi;
    };

    static DEFINE_PER_CPU_SHARED_ALIGNED(struct call_function_data, cfd_data);
    @@ -56,6 +57,9 @@ hotplug_cfd(struct notifier_block *nfb,
    if (!zalloc_cpumask_var_node(&cfd->cpumask, GFP_KERNEL,
    cpu_to_node(cpu)))
    return notifier_from_errno(-ENOMEM);
    + if (!zalloc_cpumask_var_node(&cfd->cpumask_ipi, GFP_KERNEL,
    + cpu_to_node(cpu)))
    + return notifier_from_errno(-ENOMEM);
    break;

    #ifdef CONFIG_HOTPLUG_CPU
    @@ -65,6 +69,7 @@ hotplug_cfd(struct notifier_block *nfb,
    case CPU_DEAD:
    case CPU_DEAD_FROZEN:
    free_cpumask_var(cfd->cpumask);
    + free_cpumask_var(cfd->cpumask_ipi);
    break;
    #endif
    };
    @@ -526,6 +531,12 @@ void smp_call_function_many(const struct
    return;
    }

    + /*
    + * After we put an entry into the list, data->cpumask
    + * may be cleared again when another CPU sends another IPI for
    + * a SMP function call, so data->cpumask will be zero.
    + */
    + cpumask_copy(data->cpumask_ipi, data->cpumask);
    raw_spin_lock_irqsave(&call_function.lock, flags);
    /*
    * Place entry at the _HEAD_ of the list, so that any cpu still
    @@ -549,7 +560,7 @@ void smp_call_function_many(const struct
    smp_mb();

    /* Send a message to all CPUs in the map */
    - arch_send_call_function_ipi_mask(data->cpumask);
    + arch_send_call_function_ipi_mask(data->cpumask_ipi);

    /* Optionally wait for the CPUs to complete */
    if (wait)



    \
     
     \ /
      Last update: 2013-02-01 15:21    [W:3.211 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site