Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sched/hrtick: Avoid tiny hrtick rearms

Tiny adjustments to the hrtick expiry time below 5 microseconds are just
causing extra work for no real value. Filter them out when restarting the
hrtick.

Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260224163429.340593047@kernel.org

authored by

Thomas Gleixner and committed by
Peter Zijlstra
c8cdb9b5 96d1610e

+19 -5
+19 -5
kernel/sched/core.c
··· 903 903 return HRTIMER_NORESTART; 904 904 } 905 905 906 - static void __hrtick_restart(struct rq *rq) 906 + static inline bool hrtick_needs_rearm(struct hrtimer *timer, ktime_t expires) 907 + { 908 + /* 909 + * Queued is false when the timer is not started or currently 910 + * running the callback. In both cases, restart. If queued check 911 + * whether the expiry time actually changes substantially. 912 + */ 913 + return !hrtimer_is_queued(timer) || 914 + abs(expires - hrtimer_get_expires(timer)) > 5000; 915 + } 916 + 917 + static void hrtick_cond_restart(struct rq *rq) 907 918 { 908 919 struct hrtimer *timer = &rq->hrtick_timer; 909 920 ktime_t time = rq->hrtick_time; 910 921 911 - hrtimer_start(timer, time, HRTIMER_MODE_ABS_PINNED_HARD); 922 + if (hrtick_needs_rearm(timer, time)) 923 + hrtimer_start(timer, time, HRTIMER_MODE_ABS_PINNED_HARD); 912 924 } 913 925 914 926 /* ··· 932 920 struct rq_flags rf; 933 921 934 922 rq_lock(rq, &rf); 935 - __hrtick_restart(rq); 923 + hrtick_cond_restart(rq); 936 924 rq_unlock(rq, &rf); 937 925 } 938 926 ··· 962 950 } 963 951 964 952 rq->hrtick_time = ktime_add_ns(ktime_get(), delta); 953 + if (!hrtick_needs_rearm(&rq->hrtick_timer, rq->hrtick_time)) 954 + return; 965 955 966 956 if (rq == this_rq()) 967 - __hrtick_restart(rq); 957 + hrtimer_start(&rq->hrtick_timer, rq->hrtick_time, HRTIMER_MODE_ABS_PINNED_HARD); 968 958 else 969 959 smp_call_function_single_async(cpu_of(rq), &rq->hrtick_csd); 970 960 } ··· 980 966 { 981 967 if (rq->hrtick_sched & HRTICK_SCHED_START) { 982 968 rq->hrtick_time = ktime_add_ns(ktime_get(), rq->hrtick_delay); 983 - __hrtick_restart(rq); 969 + hrtick_cond_restart(rq); 984 970 } else if (idle_rq(rq)) { 985 971 /* 986 972 * No need for using hrtimer_is_active(). The timer is CPU local