Skip to content

Commit

Permalink
powerpc/watchdog: add locking around init/exit functions
Browse files Browse the repository at this point in the history
When CPUs start and stop the watchdog, they manipulate shared data
that is normally protected by the lock. Other CPUs can be running
concurrently at this time, so it's a good idea to use locking here
to be on the safe side.

Remove the barrier which is undocumented and didn't do anything.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
Nicholas Piggin authored and Michael Ellerman committed Aug 9, 2017
1 parent 87607a3 commit 96ea91e
Showing 1 changed file with 10 additions and 1 deletion.
11 changes: 10 additions & 1 deletion arch/powerpc/kernel/watchdog.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ static void stop_watchdog_timer_on(unsigned int cpu)

static int start_wd_on_cpu(unsigned int cpu)
{
unsigned long flags;

if (cpumask_test_cpu(cpu, &wd_cpus_enabled)) {
WARN_ON(1);
return 0;
Expand All @@ -311,25 +313,32 @@ static int start_wd_on_cpu(unsigned int cpu)
if (!cpumask_test_cpu(cpu, &watchdog_cpumask))
return 0;

wd_smp_lock(&flags);
cpumask_set_cpu(cpu, &wd_cpus_enabled);
if (cpumask_weight(&wd_cpus_enabled) == 1) {
cpumask_set_cpu(cpu, &wd_smp_cpus_pending);
wd_smp_last_reset_tb = get_tb();
}
smp_wmb();
wd_smp_unlock(&flags);

start_watchdog_timer_on(cpu);

return 0;
}

static int stop_wd_on_cpu(unsigned int cpu)
{
unsigned long flags;

if (!cpumask_test_cpu(cpu, &wd_cpus_enabled))
return 0; /* Can happen in CPU unplug case */

stop_watchdog_timer_on(cpu);

wd_smp_lock(&flags);
cpumask_clear_cpu(cpu, &wd_cpus_enabled);
wd_smp_unlock(&flags);

wd_smp_clear_cpu_pending(cpu, get_tb());

return 0;
Expand Down

0 comments on commit 96ea91e

Please sign in to comment.