Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7300711e authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

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: default avatarThomas Gleixner <tglx@linutronix.de>
parent 7cfb0435
Loading
Loading
Loading
Loading
+36 −1
Original line number Diff line number Diff line
@@ -491,6 +491,18 @@ static void tick_broadcast_clear_oneshot(int cpu)
	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
 */
@@ -498,8 +510,31 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
{
	/* Set it up only once ! */
	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;
		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;
	}
}