tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git hrtimer head: 16c372aeaca31d5d9d998466e75e845a2926685f commit: 6161421a8190f07b3c0a52c0b62c8b3f51de6ddf [8/12] hrtimer: Avoid reprogramming when callback is running config: hexagon-randconfig-r023-20210919 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project c8b3d7d6d6de37af68b2f379d0e37304f78e115f) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git/commit/?id=6161421a8190f07b3c0a52c0b62c8b3f51de6ddf git remote add tglx-devel https://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git git fetch --no-tags tglx-devel hrtimer git checkout 6161421a8190f07b3c0a52c0b62c8b3f51de6ddf # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=hexagon If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): kernel/time/hrtimer.c:120:21: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides] [CLOCK_REALTIME] = HRTIMER_BASE_REALTIME, ^~~~~~~~~~~~~~~~~~~~~ kernel/time/hrtimer.c:118:27: note: previous initialization is here [0 ... MAX_CLOCKS - 1] = HRTIMER_MAX_CLOCK_BASES, ^~~~~~~~~~~~~~~~~~~~~~~ kernel/time/hrtimer.c:121:22: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides] [CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC, ^~~~~~~~~~~~~~~~~~~~~~ kernel/time/hrtimer.c:118:27: note: previous initialization is here [0 ... MAX_CLOCKS - 1] = HRTIMER_MAX_CLOCK_BASES, ^~~~~~~~~~~~~~~~~~~~~~~ kernel/time/hrtimer.c:122:21: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides] [CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME, ^~~~~~~~~~~~~~~~~~~~~ kernel/time/hrtimer.c:118:27: note: previous initialization is here [0 ... MAX_CLOCKS - 1] = HRTIMER_MAX_CLOCK_BASES, ^~~~~~~~~~~~~~~~~~~~~~~ kernel/time/hrtimer.c:123:17: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides] [CLOCK_TAI] = HRTIMER_BASE_TAI, ^~~~~~~~~~~~~~~~ kernel/time/hrtimer.c:118:27: note: previous initialization is here [0 ... MAX_CLOCKS - 1] = HRTIMER_MAX_CLOCK_BASES, ^~~~~~~~~~~~~~~~~~~~~~~ >> kernel/time/hrtimer.c:1232:53: warning: | has lower precedence than ==; == will be evaluated first [-Wparentheses] force_local &= base->cpu_base->next_timer == timer | in_callback; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ kernel/time/hrtimer.c:1232:53: note: place parentheses around the '==' expression to silence this warning force_local &= base->cpu_base->next_timer == timer | in_callback; ^ ( ) kernel/time/hrtimer.c:1232:53: note: place parentheses around the | expression to evaluate it first force_local &= base->cpu_base->next_timer == timer | in_callback; ^ ( ) kernel/time/hrtimer.c:147:20: warning: unused function 'is_migration_base' [-Wunused-function] static inline bool is_migration_base(struct hrtimer_clock_base *base) ^ kernel/time/hrtimer.c:1902:20: warning: unused function '__hrtimer_peek_ahead_timers' [-Wunused-function] static inline void __hrtimer_peek_ahead_timers(void) ^ 7 warnings generated. vim +1232 kernel/time/hrtimer.c 1211 1212 static int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, 1213 u64 delta_ns, const enum hrtimer_mode mode, 1214 struct hrtimer_clock_base *base) 1215 { 1216 struct hrtimer_clock_base *new_base; 1217 bool in_callback, force_local, first; 1218 1219 /* 1220 * If the timer is on the local cpu base and is the first expiring 1221 * timer then this might end up reprogramming the hardware twice 1222 * (on removal and on enqueue). To avoid that by prevent the 1223 * reprogram on removal, keep the timer local to the current CPU 1224 * and enforce reprogramming after it is queued no matter whether 1225 * it is the new first expiring timer again or not. 1226 * 1227 * Also avoid reprogramming if the timer callback is currently 1228 * running. 1229 */ 1230 in_callback = base->running == timer; 1231 force_local = base->cpu_base == this_cpu_ptr(&hrtimer_bases); > 1232 force_local &= base->cpu_base->next_timer == timer | in_callback; 1233 1234 /* 1235 * Remove an active timer from the queue. In case it is not queued 1236 * on the current CPU, make sure that remove_hrtimer() updates the 1237 * remote data correctly. 1238 * 1239 * If it's on the current CPU and the first expiring timer, then 1240 * skip reprogramming, keep the timer local and enforce 1241 * reprogramming later if it was the first expiring timer. This 1242 * avoids programming the underlying clock event twice (once at 1243 * removal and once after enqueue). 1244 */ 1245 remove_hrtimer(timer, base, true, force_local); 1246 1247 if (mode & HRTIMER_MODE_REL) 1248 tim = ktime_add_safe(tim, base->get_time()); 1249 1250 tim = hrtimer_update_lowres(timer, tim, mode); 1251 1252 hrtimer_set_expires_range_ns(timer, tim, delta_ns); 1253 1254 /* Switch the timer base, if necessary: */ 1255 if (!force_local) { 1256 new_base = switch_hrtimer_base(timer, base, 1257 mode & HRTIMER_MODE_PINNED); 1258 } else { 1259 new_base = base; 1260 } 1261 1262 first = enqueue_hrtimer(timer, new_base, mode); 1263 if (!force_local || in_callback) 1264 return first; 1265 1266 /* 1267 * Timer was forced to stay on the current CPU to avoid 1268 * reprogramming on removal and enqueue. Force reprogram the 1269 * hardware by evaluating the new first expiring timer. 1270 */ 1271 hrtimer_force_reprogram(new_base->cpu_base, 1); 1272 return 0; 1273 } 1274 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org