Skip to content

Commit

Permalink
clocksource: Make clocksource watchdog test safe for slow-HZ systems
Browse files Browse the repository at this point in the history
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: Paul E. McKenney <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/lkml/20210812000133.GA402890@paulmck-ThinkPad-P17-Gen-1/
  • Loading branch information
paulmckrcu authored and KAGA-KOKO committed Aug 28, 2021
1 parent 127c92f commit d25a025
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 23 deletions.
5 changes: 2 additions & 3 deletions kernel/time/clocksource-wdtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include <linux/prandom.h>
#include <linux/cpu.h>

#include "tick-internal.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Paul E. McKenney <[email protected]>");

Expand All @@ -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*/
Expand Down
21 changes: 1 addition & 20 deletions kernel/time/jiffies.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
20 changes: 20 additions & 0 deletions kernel/time/tick-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit d25a025

Please sign in to comment.