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

Commit a49b116d authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Ingo Molnar
Browse files

clockevents: Cleanup dead cpu explicitely



clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism,
it's a multiplex call. We are way better off to have explicit
calls instead of this monstrosity.

Split out the cleanup function for a dead cpu and invoke it
directly from the cpu down code. Make it conditional on
CPU_HOTPLUG as well.

Temporary change, will be refined in the future.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
[ Rebased, added clockevents_notify() removal ]
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1735025.raBZdQHM3m@vostro.rjw.lan


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 52c063d1
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -8,12 +8,6 @@
#ifndef _LINUX_CLOCKCHIPS_H
#define _LINUX_CLOCKCHIPS_H

/* Clock event notification values */
enum clock_event_nofitiers {
	CLOCK_EVT_NOTIFY_ADD,
	CLOCK_EVT_NOTIFY_CPU_DEAD,
};

#ifdef CONFIG_GENERIC_CLOCKEVENTS

# include <linux/clocksource.h>
+2 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ extern void tick_suspend_local(void);
/* Should be core only, but XEN resume magic and ARM BL switcher require it */
extern void tick_resume_local(void);
extern void tick_handover_do_timer(void);
extern void tick_cleanup_dead_cpu(int cpu);
#else /* CONFIG_GENERIC_CLOCKEVENTS */
static inline void tick_init(void) { }
static inline void tick_freeze(void) { }
@@ -27,6 +28,7 @@ static inline void tick_unfreeze(void) { }
static inline void tick_suspend_local(void) { }
static inline void tick_resume_local(void) { }
static inline void tick_handover_do_timer(void) { }
static inline void tick_cleanup_dead_cpu(int cpu) { }
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */

#ifdef CONFIG_TICK_ONESHOT
+1 −0
Original line number Diff line number Diff line
@@ -419,6 +419,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
	__cpu_die(cpu);

	/* CPU is completely dead: tell everyone.  Too late to complain. */
	tick_cleanup_dead_cpu(cpu);
	cpu_notify_nofail(CPU_DEAD | mod, hcpu);

	check_for_tasks(cpu);
+21 −30
Original line number Diff line number Diff line
@@ -642,23 +642,20 @@ void clockevents_resume(void)
			dev->resume(dev);
}

#ifdef CONFIG_HOTPLUG_CPU
/**
 * clockevents_notify - notification about relevant events
 * Returns 0 on success, any other value on error
 * tick_cleanup_dead_cpu - Cleanup the tick and clockevents of a dead cpu
 */
int clockevents_notify(unsigned long reason, void *arg)
void tick_cleanup_dead_cpu(int cpu)
{
	struct clock_event_device *dev, *tmp;
	unsigned long flags;
	int cpu, ret = 0;

	raw_spin_lock_irqsave(&clockevents_lock, flags);

	switch (reason) {
	case CLOCK_EVT_NOTIFY_CPU_DEAD:
		tick_shutdown_broadcast_oneshot(arg);
		tick_shutdown_broadcast(arg);
		tick_shutdown(arg);
	tick_shutdown_broadcast_oneshot(cpu);
	tick_shutdown_broadcast(cpu);
	tick_shutdown(cpu);
	/*
	 * Unregister the clock event devices which were
	 * released from the users in the notify chain.
@@ -668,7 +665,6 @@ int clockevents_notify(unsigned long reason, void *arg)
	/*
	 * Now check whether the CPU has left unused per cpu devices
	 */
		cpu = *((int *)arg);
	list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) {
		if (cpumask_test_cpu(cpu, dev->cpumask) &&
		    cpumask_weight(dev->cpumask) == 1 &&
@@ -677,14 +673,9 @@ int clockevents_notify(unsigned long reason, void *arg)
			list_del(&dev->list);
		}
	}
		break;
	default:
		break;
	}
	raw_spin_unlock_irqrestore(&clockevents_lock, flags);
	return ret;
}
EXPORT_SYMBOL_GPL(clockevents_notify);
#endif

#ifdef CONFIG_SYSFS
struct bus_type clockevents_subsys = {
+0 −3
Original line number Diff line number Diff line
@@ -1709,11 +1709,8 @@ static int hrtimer_cpu_notify(struct notifier_block *self,
#ifdef CONFIG_HOTPLUG_CPU
	case CPU_DEAD:
	case CPU_DEAD_FROZEN:
	{
		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DEAD, &scpu);
		migrate_hrtimers(scpu);
		break;
	}
#endif

	default:
Loading