Skip to content

Commit 3ec9557

Browse files
ZhongqiuHan-QcomKAGA-KOKO
authored andcommitted
timers: Optimize get_timer_[this_]cpu_base()
If a timer is deferrable and NO_HZ_COMMON is enabled, get_timer_cpu_base() and get_timer_this_cpu_base() invoke per_cpu_ptr() and this_cpu_ptr() twice. While this seems to be cheap, get_timer_cpu_base() can be called in a loop in lock_timer_base(). Optimize the functions by updating the base index for deferrable timers and retrieving the actual base pointer once. In both cases the resulting assembly code of those helpers becomes smaller, which results in a ~30% execution time reduction for a lock_timer_base() micro bench mark. Signed-off-by: Zhongqiu Han <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Frederic Weisbecker <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent 2d2a46c commit 3ec9557

File tree

1 file changed

+6
-10
lines changed

1 file changed

+6
-10
lines changed

kernel/time/timer.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -956,33 +956,29 @@ static int detach_if_pending(struct timer_list *timer, struct timer_base *base,
956956
static inline struct timer_base *get_timer_cpu_base(u32 tflags, u32 cpu)
957957
{
958958
int index = tflags & TIMER_PINNED ? BASE_LOCAL : BASE_GLOBAL;
959-
struct timer_base *base;
960-
961-
base = per_cpu_ptr(&timer_bases[index], cpu);
962959

963960
/*
964961
* If the timer is deferrable and NO_HZ_COMMON is set then we need
965962
* to use the deferrable base.
966963
*/
967964
if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && (tflags & TIMER_DEFERRABLE))
968-
base = per_cpu_ptr(&timer_bases[BASE_DEF], cpu);
969-
return base;
965+
index = BASE_DEF;
966+
967+
return per_cpu_ptr(&timer_bases[index], cpu);
970968
}
971969

972970
static inline struct timer_base *get_timer_this_cpu_base(u32 tflags)
973971
{
974972
int index = tflags & TIMER_PINNED ? BASE_LOCAL : BASE_GLOBAL;
975-
struct timer_base *base;
976-
977-
base = this_cpu_ptr(&timer_bases[index]);
978973

979974
/*
980975
* If the timer is deferrable and NO_HZ_COMMON is set then we need
981976
* to use the deferrable base.
982977
*/
983978
if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && (tflags & TIMER_DEFERRABLE))
984-
base = this_cpu_ptr(&timer_bases[BASE_DEF]);
985-
return base;
979+
index = BASE_DEF;
980+
981+
return this_cpu_ptr(&timer_bases[index]);
986982
}
987983

988984
static inline struct timer_base *get_timer_base(u32 tflags)

0 commit comments

Comments
 (0)