mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-22 14:23:58 +00:00
clockevents: broadcast fixup possible waiters
Until the C1E patches arrived there where no users of periodic broadcast before switching to oneshot mode. Now we need to trigger a possible waiter for a periodic broadcast when switching to oneshot mode. Otherwise we can starve them for ever. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
7cfb043533
commit
7300711e8c
1 changed files with 36 additions and 1 deletions
|
@ -491,6 +491,18 @@ static void tick_broadcast_clear_oneshot(int cpu)
|
||||||
cpu_clear(cpu, tick_broadcast_oneshot_mask);
|
cpu_clear(cpu, tick_broadcast_oneshot_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tick_broadcast_init_next_event(cpumask_t *mask, ktime_t expires)
|
||||||
|
{
|
||||||
|
struct tick_device *td;
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
for_each_cpu_mask_nr(cpu, *mask) {
|
||||||
|
td = &per_cpu(tick_cpu_device, cpu);
|
||||||
|
if (td->evtdev)
|
||||||
|
td->evtdev->next_event = expires;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tick_broadcast_setup_oneshot - setup the broadcast device
|
* tick_broadcast_setup_oneshot - setup the broadcast device
|
||||||
*/
|
*/
|
||||||
|
@ -498,8 +510,31 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
|
||||||
{
|
{
|
||||||
/* Set it up only once ! */
|
/* Set it up only once ! */
|
||||||
if (bc->event_handler != tick_handle_oneshot_broadcast) {
|
if (bc->event_handler != tick_handle_oneshot_broadcast) {
|
||||||
|
int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC;
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
cpumask_t mask;
|
||||||
|
|
||||||
bc->event_handler = tick_handle_oneshot_broadcast;
|
bc->event_handler = tick_handle_oneshot_broadcast;
|
||||||
clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
|
clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
|
||||||
|
|
||||||
|
/* Take the do_timer update */
|
||||||
|
tick_do_timer_cpu = cpu;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We must be careful here. There might be other CPUs
|
||||||
|
* waiting for periodic broadcast. We need to set the
|
||||||
|
* oneshot_mask bits for those and program the
|
||||||
|
* broadcast device to fire.
|
||||||
|
*/
|
||||||
|
mask = tick_broadcast_mask;
|
||||||
|
cpu_clear(cpu, mask);
|
||||||
|
cpus_or(tick_broadcast_oneshot_mask,
|
||||||
|
tick_broadcast_oneshot_mask, mask);
|
||||||
|
|
||||||
|
if (was_periodic && !cpus_empty(mask)) {
|
||||||
|
tick_broadcast_init_next_event(&mask, tick_next_period);
|
||||||
|
tick_broadcast_set_event(tick_next_period, 1);
|
||||||
|
} else
|
||||||
bc->next_event.tv64 = KTIME_MAX;
|
bc->next_event.tv64 = KTIME_MAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue