aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle/coupled.c
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2013-08-28 21:41:47 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-29 16:15:04 -0400
commitf983827bcb9d2c34c4d8935861a1e9128aec2baf (patch)
tree39b917dc5651fe3dfeeb96d6a215ccaa6e73a292 /drivers/cpuidle/coupled.c
parent59e998561103a93f294c8d3138dd659af772a5da (diff)
cpuidle: coupled: abort idle if pokes are pending
Joseph Lo <josephl@nvidia.com> reported a lockup on Tegra20 caused by a race condition in coupled cpuidle. When two or more cpus enter idle at the same time, the first cpus to arrive may go to the ready loop without processing pending pokes from the last cpu to arrive. This patch adds a check for pending pokes once all cpus have been synchronized in the ready loop and resets the coupled state and retries if any cpus failed to handle their pending poke. Retrying on all cpus may trigger the same issue again, so this patch also adds a check to ensure that each cpu has received at least one poke between when it enters the waiting loop and when it moves on to the ready loop. Reported-and-tested-by: Joseph Lo <josephl@nvidia.com> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Colin Cross <ccross@android.com> Cc: 3.6+ <stable@vger.kernel.org> # 3.6+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpuidle/coupled.c')
-rw-r--r--drivers/cpuidle/coupled.c107
1 files changed, 82 insertions, 25 deletions
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c
index db92bcbe6946..5d3962730063 100644
--- a/drivers/cpuidle/coupled.c
+++ b/drivers/cpuidle/coupled.c
@@ -106,6 +106,7 @@ struct cpuidle_coupled {
106 cpumask_t coupled_cpus; 106 cpumask_t coupled_cpus;
107 int requested_state[NR_CPUS]; 107 int requested_state[NR_CPUS];
108 atomic_t ready_waiting_counts; 108 atomic_t ready_waiting_counts;
109 atomic_t abort_barrier;
109 int online_count; 110 int online_count;
110 int refcnt; 111 int refcnt;
111 int prevent; 112 int prevent;
@@ -122,12 +123,19 @@ static DEFINE_MUTEX(cpuidle_coupled_lock);
122static DEFINE_PER_CPU(struct call_single_data, cpuidle_coupled_poke_cb); 123static DEFINE_PER_CPU(struct call_single_data, cpuidle_coupled_poke_cb);
123 124
124/* 125/*
125 * The cpuidle_coupled_poked_mask mask is used to avoid calling 126 * The cpuidle_coupled_poke_pending mask is used to avoid calling
126 * __smp_call_function_single with the per cpu call_single_data struct already 127 * __smp_call_function_single with the per cpu call_single_data struct already
127 * in use. This prevents a deadlock where two cpus are waiting for each others 128 * in use. This prevents a deadlock where two cpus are waiting for each others
128 * call_single_data struct to be available 129 * call_single_data struct to be available
129 */ 130 */
130static cpumask_t cpuidle_coupled_poked_mask; 131static cpumask_t cpuidle_coupled_poke_pending;
132
133/*
134 * The cpuidle_coupled_poked mask is used to ensure that each cpu has been poked
135 * once to minimize entering the ready loop with a poke pending, which would
136 * require aborting and retrying.
137 */
138static cpumask_t cpuidle_coupled_poked;
131 139
132/** 140/**
133 * cpuidle_coupled_parallel_barrier - synchronize all online coupled cpus 141 * cpuidle_coupled_parallel_barrier - synchronize all online coupled cpus
@@ -291,10 +299,11 @@ static inline int cpuidle_coupled_get_state(struct cpuidle_device *dev,
291 return state; 299 return state;
292} 300}
293 301
294static void cpuidle_coupled_poked(void *info) 302static void cpuidle_coupled_handle_poke(void *info)
295{ 303{
296 int cpu = (unsigned long)info; 304 int cpu = (unsigned long)info;
297 cpumask_clear_cpu(cpu, &cpuidle_coupled_poked_mask); 305 cpumask_set_cpu(cpu, &cpuidle_coupled_poked);
306 cpumask_clear_cpu(cpu, &cpuidle_coupled_poke_pending);
298} 307}
299 308
300/** 309/**
@@ -313,7 +322,7 @@ static void cpuidle_coupled_poke(int cpu)
313{ 322{
314 struct call_single_data *csd = &per_cpu(cpuidle_coupled_poke_cb, cpu); 323 struct call_single_data *csd = &per_cpu(cpuidle_coupled_poke_cb, cpu);
315 324
316 if (!cpumask_test_and_set_cpu(cpu, &cpuidle_coupled_poked_mask)) 325 if (!cpumask_test_and_set_cpu(cpu, &cpuidle_coupled_poke_pending))
317 __smp_call_function_single(cpu, csd, 0); 326 __smp_call_function_single(cpu, csd, 0);
318} 327}
319 328
@@ -340,30 +349,19 @@ static void cpuidle_coupled_poke_others(int this_cpu,
340 * @coupled: the struct coupled that contains the current cpu 349 * @coupled: the struct coupled that contains the current cpu
341 * @next_state: the index in drv->states of the requested state for this cpu 350 * @next_state: the index in drv->states of the requested state for this cpu
342 * 351 *
343 * Updates the requested idle state for the specified cpuidle device, 352 * Updates the requested idle state for the specified cpuidle device.
344 * poking all coupled cpus out of idle if necessary to let them see the new 353 * Returns the number of waiting cpus.
345 * state.
346 */ 354 */
347static void cpuidle_coupled_set_waiting(int cpu, 355static int cpuidle_coupled_set_waiting(int cpu,
348 struct cpuidle_coupled *coupled, int next_state) 356 struct cpuidle_coupled *coupled, int next_state)
349{ 357{
350 int w;
351
352 coupled->requested_state[cpu] = next_state; 358 coupled->requested_state[cpu] = next_state;
353 359
354 /* 360 /*
355 * If this is the last cpu to enter the waiting state, poke
356 * all the other cpus out of their waiting state so they can
357 * enter a deeper state. This can race with one of the cpus
358 * exiting the waiting state due to an interrupt and
359 * decrementing waiting_count, see comment below.
360 *
361 * The atomic_inc_return provides a write barrier to order the write 361 * The atomic_inc_return provides a write barrier to order the write
362 * to requested_state with the later write that increments ready_count. 362 * to requested_state with the later write that increments ready_count.
363 */ 363 */
364 w = atomic_inc_return(&coupled->ready_waiting_counts) & WAITING_MASK; 364 return atomic_inc_return(&coupled->ready_waiting_counts) & WAITING_MASK;
365 if (w == coupled->online_count)
366 cpuidle_coupled_poke_others(cpu, coupled);
367} 365}
368 366
369/** 367/**
@@ -418,13 +416,24 @@ static void cpuidle_coupled_set_done(int cpu, struct cpuidle_coupled *coupled)
418static int cpuidle_coupled_clear_pokes(int cpu) 416static int cpuidle_coupled_clear_pokes(int cpu)
419{ 417{
420 local_irq_enable(); 418 local_irq_enable();
421 while (cpumask_test_cpu(cpu, &cpuidle_coupled_poked_mask)) 419 while (cpumask_test_cpu(cpu, &cpuidle_coupled_poke_pending))
422 cpu_relax(); 420 cpu_relax();
423 local_irq_disable(); 421 local_irq_disable();
424 422
425 return need_resched() ? -EINTR : 0; 423 return need_resched() ? -EINTR : 0;
426} 424}
427 425
426static bool cpuidle_coupled_any_pokes_pending(struct cpuidle_coupled *coupled)
427{
428 cpumask_t cpus;
429 int ret;
430
431 cpumask_and(&cpus, cpu_online_mask, &coupled->coupled_cpus);
432 ret = cpumask_and(&cpus, &cpuidle_coupled_poke_pending, &cpus);
433
434 return ret;
435}
436
428/** 437/**
429 * cpuidle_enter_state_coupled - attempt to enter a state with coupled cpus 438 * cpuidle_enter_state_coupled - attempt to enter a state with coupled cpus
430 * @dev: struct cpuidle_device for the current cpu 439 * @dev: struct cpuidle_device for the current cpu
@@ -449,6 +458,7 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
449{ 458{
450 int entered_state = -1; 459 int entered_state = -1;
451 struct cpuidle_coupled *coupled = dev->coupled; 460 struct cpuidle_coupled *coupled = dev->coupled;
461 int w;
452 462
453 if (!coupled) 463 if (!coupled)
454 return -EINVAL; 464 return -EINVAL;
@@ -466,14 +476,33 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
466 /* Read barrier ensures online_count is read after prevent is cleared */ 476 /* Read barrier ensures online_count is read after prevent is cleared */
467 smp_rmb(); 477 smp_rmb();
468 478
469 cpuidle_coupled_set_waiting(dev->cpu, coupled, next_state); 479reset:
480 cpumask_clear_cpu(dev->cpu, &cpuidle_coupled_poked);
481
482 w = cpuidle_coupled_set_waiting(dev->cpu, coupled, next_state);
483 /*
484 * If this is the last cpu to enter the waiting state, poke
485 * all the other cpus out of their waiting state so they can
486 * enter a deeper state. This can race with one of the cpus
487 * exiting the waiting state due to an interrupt and
488 * decrementing waiting_count, see comment below.
489 */
490 if (w == coupled->online_count) {
491 cpumask_set_cpu(dev->cpu, &cpuidle_coupled_poked);
492 cpuidle_coupled_poke_others(dev->cpu, coupled);
493 }
470 494
471retry: 495retry:
472 /* 496 /*
473 * Wait for all coupled cpus to be idle, using the deepest state 497 * Wait for all coupled cpus to be idle, using the deepest state
474 * allowed for a single cpu. 498 * allowed for a single cpu. If this was not the poking cpu, wait
499 * for at least one poke before leaving to avoid a race where
500 * two cpus could arrive at the waiting loop at the same time,
501 * but the first of the two to arrive could skip the loop without
502 * processing the pokes from the last to arrive.
475 */ 503 */
476 while (!cpuidle_coupled_cpus_waiting(coupled)) { 504 while (!cpuidle_coupled_cpus_waiting(coupled) ||
505 !cpumask_test_cpu(dev->cpu, &cpuidle_coupled_poked)) {
477 if (cpuidle_coupled_clear_pokes(dev->cpu)) { 506 if (cpuidle_coupled_clear_pokes(dev->cpu)) {
478 cpuidle_coupled_set_not_waiting(dev->cpu, coupled); 507 cpuidle_coupled_set_not_waiting(dev->cpu, coupled);
479 goto out; 508 goto out;
@@ -495,6 +524,12 @@ retry:
495 } 524 }
496 525
497 /* 526 /*
527 * Make sure final poke status for this cpu is visible before setting
528 * cpu as ready.
529 */
530 smp_wmb();
531
532 /*
498 * All coupled cpus are probably idle. There is a small chance that 533 * All coupled cpus are probably idle. There is a small chance that
499 * one of the other cpus just became active. Increment the ready count, 534 * one of the other cpus just became active. Increment the ready count,
500 * and spin until all coupled cpus have incremented the counter. Once a 535 * and spin until all coupled cpus have incremented the counter. Once a
@@ -513,6 +548,28 @@ retry:
513 cpu_relax(); 548 cpu_relax();
514 } 549 }
515 550
551 /*
552 * Make sure read of all cpus ready is done before reading pending pokes
553 */
554 smp_rmb();
555
556 /*
557 * There is a small chance that a cpu left and reentered idle after this
558 * cpu saw that all cpus were waiting. The cpu that reentered idle will
559 * have sent this cpu a poke, which will still be pending after the
560 * ready loop. The pending interrupt may be lost by the interrupt
561 * controller when entering the deep idle state. It's not possible to
562 * clear a pending interrupt without turning interrupts on and handling
563 * it, and it's too late to turn on interrupts here, so reset the
564 * coupled idle state of all cpus and retry.
565 */
566 if (cpuidle_coupled_any_pokes_pending(coupled)) {
567 cpuidle_coupled_set_done(dev->cpu, coupled);
568 /* Wait for all cpus to see the pending pokes */
569 cpuidle_coupled_parallel_barrier(dev, &coupled->abort_barrier);
570 goto reset;
571 }
572
516 /* all cpus have acked the coupled state */ 573 /* all cpus have acked the coupled state */
517 next_state = cpuidle_coupled_get_state(dev, coupled); 574 next_state = cpuidle_coupled_get_state(dev, coupled);
518 575
@@ -598,7 +655,7 @@ have_coupled:
598 coupled->refcnt++; 655 coupled->refcnt++;
599 656
600 csd = &per_cpu(cpuidle_coupled_poke_cb, dev->cpu); 657 csd = &per_cpu(cpuidle_coupled_poke_cb, dev->cpu);
601 csd->func = cpuidle_coupled_poked; 658 csd->func = cpuidle_coupled_handle_poke;
602 csd->info = (void *)(unsigned long)dev->cpu; 659 csd->info = (void *)(unsigned long)dev->cpu;
603 660
604 return 0; 661 return 0;