On Thu, Apr 11, 2024, at 11:27, Adrian Hunter wrote: > On 11/04/24 11:22, Christophe Leroy wrote: >> Le 11/04/2024 à 10:12, Christophe Leroy a écrit : >>> >>> Looking at the report, I think the correct fix should be to use >>> BUILD_BUG() instead of BUG() >> >> I confirm the error goes away with the following change to next-20240411 >> on powerpc tinyconfig with gcc 13.2 >> >> diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c >> index 4e18db1819f8..3d5ac0cdd721 100644 >> --- a/kernel/time/timekeeping.c >> +++ b/kernel/time/timekeeping.c >> @@ -282,7 +282,7 @@ static inline void timekeeping_check_update(struct >> timekeeper *tk, u64 offset) >> } >> static inline u64 timekeeping_debug_get_ns(const struct tk_read_base *tkr) >> { >> - BUG(); >> + BUILD_BUG(); >> } >> #endif >> > > That is fragile because it depends on defined(__OPTIMIZE__), > so it should still be:
If there is a function that is defined but that must never be called, I think we are doing something wrong. Before e8e9d21a5df6 ("timekeeping: Refactor timekeeping helpers"), the #ifdef made some sense, but now the #else is not really that useful. Ideally we would make timekeeping_debug_get_delta() and timekeeping_check_update() just return in case of !IS_ENABLED(CONFIG_DEBUG_TIMEKEEPING), but unfortunately the code uses some struct members that are undefined then. The patch below moves the #ifdef check into these functions, which is not great, but it avoids defining useless functions. Maybe there is a better way here. How about just removing the BUG()? Arnd diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 4e18db1819f8..16c6dba64dd6 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -195,12 +195,11 @@ static inline u64 tk_clock_read(const struct tk_read_base *tkr) return clock->read(clock); } -#ifdef CONFIG_DEBUG_TIMEKEEPING #define WARNING_FREQ (HZ*300) /* 5 minute rate-limiting */ static void timekeeping_check_update(struct timekeeper *tk, u64 offset) { - +#ifdef CONFIG_DEBUG_TIMEKEEPING u64 max_cycles = tk->tkr_mono.clock->max_cycles; const char *name = tk->tkr_mono.clock->name; @@ -235,12 +234,19 @@ static void timekeeping_check_update(struct timekeeper *tk, u64 offset) } tk->overflow_seen = 0; } +#endif } static inline u64 timekeeping_cycles_to_ns(const struct tk_read_base *tkr, u64 cycles); -static inline u64 timekeeping_debug_get_ns(const struct tk_read_base *tkr) +static u64 __timekeeping_get_ns(const struct tk_read_base *tkr) +{ + return timekeeping_cycles_to_ns(tkr, tk_clock_read(tkr)); +} + +static inline u64 timekeeping_get_ns(const struct tk_read_base *tkr) { +#ifdef CONFIG_DEBUG_TIMEKEEPING struct timekeeper *tk = &tk_core.timekeeper; u64 now, last, mask, max, delta; unsigned int seq; @@ -275,16 +281,10 @@ static inline u64 timekeeping_debug_get_ns(const struct tk_read_base *tkr) /* timekeeping_cycles_to_ns() handles both under and overflow */ return timekeeping_cycles_to_ns(tkr, now); -} #else -static inline void timekeeping_check_update(struct timekeeper *tk, u64 offset) -{ -} -static inline u64 timekeeping_debug_get_ns(const struct tk_read_base *tkr) -{ - BUG(); -} + return __timekeeping_get_ns(tkr); #endif +} /** * tk_setup_internals - Set up internals to use clocksource clock. @@ -390,19 +390,6 @@ static inline u64 timekeeping_cycles_to_ns(const struct tk_read_base *tkr, u64 c return ((delta * tkr->mult) + tkr->xtime_nsec) >> tkr->shift; } -static __always_inline u64 __timekeeping_get_ns(const struct tk_read_base *tkr) -{ - return timekeeping_cycles_to_ns(tkr, tk_clock_read(tkr)); -} - -static inline u64 timekeeping_get_ns(const struct tk_read_base *tkr) -{ - if (IS_ENABLED(CONFIG_DEBUG_TIMEKEEPING)) - return timekeeping_debug_get_ns(tkr); - - return __timekeeping_get_ns(tkr); -} - /** * update_fast_timekeeper - Update the fast and NMI safe monotonic timekeeper. * @tkr: Timekeeping readout base from which we take the update