Message ID | 20241002-mgtime-v9-7-77e2baad57ac@kernel.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | fs: multigrain timestamp redux | expand |
On Wed, Oct 02 2024 at 14:49, Jeff Layton wrote: > --- > fs/inode.c | 5 +++-- Grmbl. I explicitely asked to split this into timekeeping and fs patches, no? That allows me to pick the timekeeping patches up myself and give Christian a stable tag to pull them from. That lets me deal with the conflicts with other timekeeping stuff which is coming up instead of having cross tree conflicts. > +unsigned long timekeeping_get_mg_floor_swaps(void) > +{ > + int i; > + unsigned long sum = 0; https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#variable-declarations And please use 'cpu' > + > + for_each_possible_cpu(i) > + sum += per_cpu(timekeeping_mg_floor_swaps, i); This needs data_race(per_cpu.....) to tell KCSAN that this is intentionally racy. Your previous fs specific patch has the same issue. > + return sum < 0 ? 0 : sum; Right, a sum of unsigned longs really needs to be checked for being negative. > #ifdef CONFIG_DEBUG_FS > +DECLARE_PER_CPU(unsigned long, timekeeping_mg_floor_swaps); > +static inline void timekeeping_inc_mg_floor_swaps(void) Did you lose your newline key?. Can we please not glue this together for readability sake? Thanks, tglx
diff --git a/fs/inode.c b/fs/inode.c index 0223f8ec3cfb..1edac9ab1ecc 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -145,9 +145,10 @@ static int mgts_show(struct seq_file *s, void *p) unsigned long ctime_updates = get_mg_ctime_updates(); unsigned long ctime_swaps = get_mg_ctime_swaps(); unsigned long fine_stamps = get_mg_fine_stamps(); + unsigned long floor_swaps = timekeeping_get_mg_floor_swaps(); - seq_printf(s, "%lu %lu %lu\n", - ctime_updates, ctime_swaps, fine_stamps); + seq_printf(s, "%lu %lu %lu %lu\n", + ctime_updates, ctime_swaps, fine_stamps, floor_swaps); return 0; } diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index 7aa85246c183..84a035e86ac8 100644 --- a/include/linux/timekeeping.h +++ b/include/linux/timekeeping.h @@ -48,6 +48,7 @@ extern void ktime_get_coarse_real_ts64(struct timespec64 *ts); /* Multigrain timestamp interfaces */ extern void ktime_get_coarse_real_ts64_mg(struct timespec64 *ts); extern void ktime_get_real_ts64_mg(struct timespec64 *ts); +extern unsigned long timekeeping_get_mg_floor_swaps(void); void getboottime64(struct timespec64 *ts); diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index ebfe846ebde3..e8b713e8ce55 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -2488,6 +2488,7 @@ void ktime_get_real_ts64_mg(struct timespec64 *ts) if (atomic64_try_cmpxchg(&mg_floor, &old, mono)) { ts->tv_nsec = 0; timespec64_add_ns(ts, nsecs); + timekeeping_inc_mg_floor_swaps(); } else { /* * Another task changed mg_floor since "old" was fetched. diff --git a/kernel/time/timekeeping_debug.c b/kernel/time/timekeeping_debug.c index b73e8850e58d..b731621ad811 100644 --- a/kernel/time/timekeeping_debug.c +++ b/kernel/time/timekeeping_debug.c @@ -17,6 +17,9 @@ #define NUM_BINS 32 +/* incremented every time mg_floor is updated */ +DEFINE_PER_CPU(unsigned long, timekeeping_mg_floor_swaps); + static unsigned int sleep_time_bin[NUM_BINS] = {0}; static int tk_debug_sleep_time_show(struct seq_file *s, void *data) @@ -53,3 +56,13 @@ void tk_debug_account_sleep_time(const struct timespec64 *t) (s64)t->tv_sec, t->tv_nsec / NSEC_PER_MSEC); } +unsigned long timekeeping_get_mg_floor_swaps(void) +{ + int i; + unsigned long sum = 0; + + for_each_possible_cpu(i) + sum += per_cpu(timekeeping_mg_floor_swaps, i); + return sum < 0 ? 0 : sum; +} + diff --git a/kernel/time/timekeeping_internal.h b/kernel/time/timekeeping_internal.h index 4ca2787d1642..f53e76d5ee7c 100644 --- a/kernel/time/timekeeping_internal.h +++ b/kernel/time/timekeeping_internal.h @@ -10,9 +10,18 @@ * timekeeping debug functions */ #ifdef CONFIG_DEBUG_FS +DECLARE_PER_CPU(unsigned long, timekeeping_mg_floor_swaps); +static inline void timekeeping_inc_mg_floor_swaps(void) +{ + this_cpu_inc(timekeeping_mg_floor_swaps); +} + extern void tk_debug_account_sleep_time(const struct timespec64 *t); #else #define tk_debug_account_sleep_time(x) +static inline void timekeeping_inc_mg_floor_swaps(void) +{ +} #endif #ifdef CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE