Commit d25a0252 authored by Paul E. McKenney's avatar Paul E. McKenney Committed by Thomas Gleixner
Browse files

clocksource: Make clocksource watchdog test safe for slow-HZ systems



The clocksource watchdog test sets a local JIFFIES_SHIFT macro and assumes
that HZ is >= 100. For smaller HZ values this shift value is too large and
causes undefined behaviour.

Move the HZ-based definitions of JIFFIES_SHIFT from kernel/time/jiffies.c
to kernel/time/tick-internal.h so the clocksource watchdog test can utilize
them, which makes it work correctly with all HZ values.

[ tglx: Resolved conflicts and massaged changelog ]

Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/lkml/20210812000133.GA402890@paulmck-ThinkPad-P17-Gen-1/
parent 127c92fe
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#include <linux/prandom.h>
#include <linux/cpu.h>

#include "tick-internal.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Paul E. McKenney <paulmck@kernel.org>");

@@ -34,9 +36,6 @@ static u64 wdtest_jiffies_read(struct clocksource *cs)
	return (u64)jiffies;
}

/* Assume HZ > 100. */
#define JIFFIES_SHIFT	8

static struct clocksource clocksource_wdtest_jiffies = {
	.name			= "wdtest-jiffies",
	.rating			= 1, /* lowest valid rating*/
+1 −20
Original line number Diff line number Diff line
@@ -10,28 +10,9 @@
#include <linux/init.h>

#include "timekeeping.h"
#include "tick-internal.h"


/* Since jiffies uses a simple TICK_NSEC multiplier
 * conversion, the .shift value could be zero. However
 * this would make NTP adjustments impossible as they are
 * in units of 1/2^.shift. Thus we use JIFFIES_SHIFT to
 * shift both the nominator and denominator the same
 * amount, and give ntp adjustments in units of 1/2^8
 *
 * The value 8 is somewhat carefully chosen, as anything
 * larger can result in overflows. TICK_NSEC grows as HZ
 * shrinks, so values greater than 8 overflow 32bits when
 * HZ=100.
 */
#if HZ < 34
#define JIFFIES_SHIFT	6
#elif HZ < 67
#define JIFFIES_SHIFT	7
#else
#define JIFFIES_SHIFT	8
#endif

static u64 jiffies_read(struct clocksource *cs)
{
	return (u64) jiffies;
+20 −0
Original line number Diff line number Diff line
@@ -177,3 +177,23 @@ void clock_was_set(unsigned int bases);
void clock_was_set_delayed(void);

void hrtimers_resume_local(void);

/* Since jiffies uses a simple TICK_NSEC multiplier
 * conversion, the .shift value could be zero. However
 * this would make NTP adjustments impossible as they are
 * in units of 1/2^.shift. Thus we use JIFFIES_SHIFT to
 * shift both the nominator and denominator the same
 * amount, and give ntp adjustments in units of 1/2^8
 *
 * The value 8 is somewhat carefully chosen, as anything
 * larger can result in overflows. TICK_NSEC grows as HZ
 * shrinks, so values greater than 8 overflow 32bits when
 * HZ=100.
 */
#if HZ < 34
#define JIFFIES_SHIFT	6
#elif HZ < 67
#define JIFFIES_SHIFT	7
#else
#define JIFFIES_SHIFT	8
#endif