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

Commit 6ea41d25 authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

clocksource: Call clocksource_change_rating() outside of watchdog_lock



The changes to the watchdog logic introduced a lock inversion between
watchdog_lock and clocksource_mutex. Change the rating outside of
watchdog_lock to avoid it.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 23970e38
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -307,16 +307,23 @@ static void clocksource_watchdog_work(struct work_struct *work)
{
	struct clocksource *cs, *tmp;
	unsigned long flags;
	LIST_HEAD(unstable);

	spin_lock_irqsave(&watchdog_lock, flags);
	list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list)
		if (cs->flags & CLOCK_SOURCE_UNSTABLE) {
			list_del_init(&cs->wd_list);
			clocksource_change_rating(cs, 0);
			list_add(&cs->wd_list, &unstable);
		}
	/* Check if the watchdog timer needs to be stopped. */
	clocksource_stop_watchdog();
	spin_unlock(&watchdog_lock);
	spin_unlock_irqrestore(&watchdog_lock, flags);

	/* Needs to be done outside of watchdog lock */
	list_for_each_entry_safe(cs, tmp, &unstable, wd_list) {
		list_del_init(&cs->wd_list);
		clocksource_change_rating(cs, 0);
	}
}

#else /* CONFIG_CLOCKSOURCE_WATCHDOG */