lkml.org 
[lkml]   [2019]   [Mar]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 019/149] xtensa: SMP: fix secondary CPU initialization
    Date
    4.19-stable review patch.  If anyone has any objections, please let me know.

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

    [ Upstream commit 32a7726c4f4aadfabdb82440d84f88a5a2c8fe13 ]

    - add missing memory barriers to the secondary CPU synchronization spin
    loops; add comment to the matching memory barrier in the boot_secondary
    and __cpu_die functions;
    - use READ_ONCE/WRITE_ONCE to access cpu_start_id/cpu_start_ccount
    instead of reading/writing them directly;
    - re-initialize cpu_running every time before starting secondary CPU to
    flush possible previous CPU startup results.

    Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/xtensa/kernel/head.S | 5 ++++-
    arch/xtensa/kernel/smp.c | 34 +++++++++++++++++++++-------------
    2 files changed, 25 insertions(+), 14 deletions(-)

    diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
    index 9053a5622d2c..5bd38ea2da38 100644
    --- a/arch/xtensa/kernel/head.S
    +++ b/arch/xtensa/kernel/head.S
    @@ -280,12 +280,13 @@ should_never_return:

    movi a2, cpu_start_ccount
    1:
    + memw
    l32i a3, a2, 0
    beqi a3, 0, 1b
    movi a3, 0
    s32i a3, a2, 0
    - memw
    1:
    + memw
    l32i a3, a2, 0
    beqi a3, 0, 1b
    wsr a3, ccount
    @@ -321,11 +322,13 @@ ENTRY(cpu_restart)
    rsr a0, prid
    neg a2, a0
    movi a3, cpu_start_id
    + memw
    s32i a2, a3, 0
    #if XCHAL_DCACHE_IS_WRITEBACK
    dhwbi a3, 0
    #endif
    1:
    + memw
    l32i a2, a3, 0
    dhi a3, 0
    bne a2, a0, 1b
    diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c
    index 932d64689bac..c9fc2c4f71b3 100644
    --- a/arch/xtensa/kernel/smp.c
    +++ b/arch/xtensa/kernel/smp.c
    @@ -195,9 +195,11 @@ static int boot_secondary(unsigned int cpu, struct task_struct *ts)
    int i;

    #ifdef CONFIG_HOTPLUG_CPU
    - cpu_start_id = cpu;
    - system_flush_invalidate_dcache_range(
    - (unsigned long)&cpu_start_id, sizeof(cpu_start_id));
    + WRITE_ONCE(cpu_start_id, cpu);
    + /* Pairs with the third memw in the cpu_restart */
    + mb();
    + system_flush_invalidate_dcache_range((unsigned long)&cpu_start_id,
    + sizeof(cpu_start_id));
    #endif
    smp_call_function_single(0, mx_cpu_start, (void *)cpu, 1);

    @@ -206,18 +208,21 @@ static int boot_secondary(unsigned int cpu, struct task_struct *ts)
    ccount = get_ccount();
    while (!ccount);

    - cpu_start_ccount = ccount;
    + WRITE_ONCE(cpu_start_ccount, ccount);

    - while (time_before(jiffies, timeout)) {
    + do {
    + /*
    + * Pairs with the first two memws in the
    + * .Lboot_secondary.
    + */
    mb();
    - if (!cpu_start_ccount)
    - break;
    - }
    + ccount = READ_ONCE(cpu_start_ccount);
    + } while (ccount && time_before(jiffies, timeout));

    - if (cpu_start_ccount) {
    + if (ccount) {
    smp_call_function_single(0, mx_cpu_stop,
    - (void *)cpu, 1);
    - cpu_start_ccount = 0;
    + (void *)cpu, 1);
    + WRITE_ONCE(cpu_start_ccount, 0);
    return -EIO;
    }
    }
    @@ -237,6 +242,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
    pr_debug("%s: Calling wakeup_secondary(cpu:%d, idle:%p, sp: %08lx)\n",
    __func__, cpu, idle, start_info.stack);

    + init_completion(&cpu_running);
    ret = boot_secondary(cpu, idle);
    if (ret == 0) {
    wait_for_completion_timeout(&cpu_running,
    @@ -298,8 +304,10 @@ void __cpu_die(unsigned int cpu)
    unsigned long timeout = jiffies + msecs_to_jiffies(1000);
    while (time_before(jiffies, timeout)) {
    system_invalidate_dcache_range((unsigned long)&cpu_start_id,
    - sizeof(cpu_start_id));
    - if (cpu_start_id == -cpu) {
    + sizeof(cpu_start_id));
    + /* Pairs with the second memw in the cpu_restart */
    + mb();
    + if (READ_ONCE(cpu_start_id) == -cpu) {
    platform_cpu_kill(cpu);
    return;
    }
    --
    2.19.1


    \
     
     \ /
      Last update: 2019-03-12 18:55    [W:4.965 / U:0.144 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site