Re: [tip:timers/core 2/58] kernel/time/posix-cpu-timers.c:1307:9: sparse: sparse: incorrect type in argument 1 (different address spaces)
From: Bradley Morgan
Date: Thu Aug 13 2026 - 00:56:13 EST
On 12 August 2026 20:42:03 BST, Bradley Morgan <include@xxxxxxxxx> wrote:
>On 12 August 2026 20:40:00 BST, kernel test robot <lkp@xxxxxxxxx> wrote:
>>tree: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git
>timers/core
>>head: 4fa377c19e111c539a530a8200996b911ceff9ff
>>commit: a73d7f98e41a96d6e1bcb0e731ab185d9d67878e [2/58] posix-cpu-timers:
>Don't abuse lock_task_sighand() in handle_posix_cpu_timers()
>>config: microblaze-randconfig-r122-20260812
>(https://download.01.org/0day-ci/archive/20260813/202608130320.o3cNs7Lr-lkp@xxxxxxxxx/config)
>>compiler: microblaze-linux-gcc (GCC) 11.5.0
>>sparse: v0.6.5-rc1
>>reproduce (this is a W=1 build):
>>(https://download.01.org/0day-ci/archive/20260813/202608130320.o3cNs7Lr-lkp@xxxxxxxxx/reproduce)
>>
>>If you fix the issue in a separate patch/commit (i.e. not just a new
>>version of
>>the same patch/commit), kindly add following tags
>>| Reported-by: kernel test robot <lkp@xxxxxxxxx>
>>| Closes:
>>https://lore.kernel.org/oe-kbuild-all/202608130320.o3cNs7Lr-lkp@xxxxxxxxx/
>>
>>sparse warnings: (new ones prefixed by >>)
>>>> kernel/time/posix-cpu-timers.c:1307:9: sparse: sparse: incorrect type
>>in argument 1 (different address spaces) @@ expected struct spinlock
>>[usertype] *lock @@ got struct spinlock [noderef] __rcu * @@
>> kernel/time/posix-cpu-timers.c:1307:9: sparse: expected struct
>spinlock [usertype] *lock
>> kernel/time/posix-cpu-timers.c:1307:9: sparse: got struct spinlock
>[noderef] __rcu *
>> kernel/time/posix-cpu-timers.c:1367:36: sparse: sparse: incorrect type
>in argument 1 (different address spaces) @@ expected struct spinlock
>[usertype] *lock @@ got struct spinlock [noderef] __rcu * @@
>> kernel/time/posix-cpu-timers.c:1367:36: sparse: expected struct
>spinlock [usertype] *lock
>> kernel/time/posix-cpu-timers.c:1367:36: sparse: got struct
>spinlock [noderef] __rcu *
>> kernel/time/posix-cpu-timers.c: note: in included file:
>> include/linux/sched/signal.h:749:37: sparse: sparse: incorrect type in
>argument 1 (different address spaces) @@ expected struct spinlock
>[usertype] *lock @@ got struct spinlock [noderef] __rcu * @@
>> include/linux/sched/signal.h:749:37: sparse: expected struct
>spinlock [usertype] *lock
>> include/linux/sched/signal.h:749:37: sparse: got struct spinlock
>[noderef] __rcu *
>> include/linux/sched/signal.h:749:37: sparse: sparse: incorrect type in
>argument 1 (different address spaces) @@ expected struct spinlock
>[usertype] *lock @@ got struct spinlock [noderef] __rcu * @@
>> include/linux/sched/signal.h:749:37: sparse: expected struct
>spinlock [usertype] *lock
>> include/linux/sched/signal.h:749:37: sparse: got struct spinlock
>[noderef] __rcu *
>> include/linux/sched/signal.h:749:37: sparse: sparse: incorrect type in
>argument 1 (different address spaces) @@ expected struct spinlock
>[usertype] *lock @@ got struct spinlock [noderef] __rcu * @@
>> include/linux/sched/signal.h:749:37: sparse: expected struct
>spinlock [usertype] *lock
>> include/linux/sched/signal.h:749:37: sparse: got struct spinlock
>[noderef] __rcu *
>> include/linux/sched/signal.h:749:37: sparse: sparse: incorrect type in
>argument 1 (different address spaces) @@ expected struct spinlock
>[usertype] *lock @@ got struct spinlock [noderef] __rcu * @@
>> include/linux/sched/signal.h:749:37: sparse: expected struct
>spinlock [usertype] *lock
>> include/linux/sched/signal.h:749:37: sparse: got struct spinlock
>[noderef] __rcu *
>> include/linux/sched/signal.h:749:37: sparse: sparse: incorrect type in
>argument 1 (different address spaces) @@ expected struct spinlock
>[usertype] *lock @@ got struct spinlock [noderef] __rcu * @@
>> include/linux/sched/signal.h:749:37: sparse: expected struct
>spinlock [usertype] *lock
>> include/linux/sched/signal.h:749:37: sparse: got struct spinlock
>[noderef] __rcu *
>>
>>vim +1307 kernel/time/posix-cpu-timers.c
>>
>> 1296
>> 1297 static void handle_posix_cpu_timers(struct task_struct *tsk)
>> 1298 {
>> 1299 struct k_itimer *timer, *next;
>> 1300 unsigned long flags, start;
>> 1301 LIST_HEAD(firing);
>> 1302
>> 1303 /*
>> 1304 * tsk is current and ->sighand is stable, see the
>> 1305 * tsk->exit_state check in run_posix_cpu_timers()
>> 1306 */
>>> 1307 spin_lock_irqsave(&tsk->sighand->siglock, flags);
>> 1308
>> 1309 do {
>> 1310 /*
>> 1311 * On RT locking sighand lock does not disable interrupts,
>> 1312 * so this needs to be careful vs. ticks. Store the current
>> 1313 * jiffies value.
>> 1314 */
>> 1315 start = READ_ONCE(jiffies);
>> 1316 barrier();
>> 1317
>> 1318 /*
>> 1319 * Here we take off tsk->signal->cpu_timers[N] and
>> 1320 * tsk->cpu_timers[N] all the timers that are firing, and
>> 1321 * put them on the firing list.
>> 1322 */
>> 1323 check_thread_timers(tsk, &firing);
>> 1324
>> 1325 check_process_timers(tsk, &firing);
>> 1326
>> 1327 /*
>> 1328 * The above timer checks have updated the expiry cache and
>> 1329 * because nothing can have queued or modified timers after
>> 1330 * sighand lock was taken above it is guaranteed to be
>> 1331 * consistent. So the next timer interrupt fastpath check
>> 1332 * will find valid data.
>> 1333 *
>> 1334 * If timer expiry runs in the timer interrupt context then
>> 1335 * the loop is not relevant as timers will be directly
>> 1336 * expired in interrupt context. The stub function below
>> 1337 * returns always true which allows the compiler to
>> 1338 * optimize the loop out.
>> 1339 *
>> 1340 * If timer expiry is deferred to task work context then
>> 1341 * the following rules apply:
>> 1342 *
>> 1343 * - On !RT kernels no tick can have happened on this CPU
>> 1344 * after sighand lock was acquired because interrupts are
>> 1345 * disabled. So reenabling task work before dropping
>> 1346 * sighand lock and reenabling interrupts is race free.
>> 1347 *
>> 1348 * - On RT kernels ticks might have happened but the tick
>> 1349 * work ignored posix CPU timer handling because the
>> 1350 * CPUTIMERS_WORK_SCHEDULED bit is set. Reenabling work
>> 1351 * must be done very carefully including a check whether
>> 1352 * ticks have happened since the start of the timer
>> 1353 * expiry checks. posix_cpu_timers_enable_work() takes
>> 1354 * care of that and eventually lets the expiry checks
>> 1355 * run again.
>> 1356 */
>> 1357 } while (!posix_cpu_timers_enable_work(tsk, start));
>> 1358
>> 1359 /*
>> 1360 * We must release sighand lock before taking any timer's lock.
>> 1361 * There is a potential race with timer deletion here, as the
>> 1362 * siglock now protects our private firing list. We have set
>> 1363 * the firing flag in each timer, so that a deletion attempt
>> 1364 * that gets the timer lock before we do will give it up and
>> 1365 * spin until we've taken care of that timer below.
>> 1366 */
>> 1367 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
>> 1368
>> 1369 /*
>> 1370 * Now that all the timers on our list have the firing flag,
>> 1371 * no one will touch their list entries but us. We'll take
>> 1372 * each timer's lock before clearing its firing flag, so no
>> 1373 * timer call will interfere.
>> 1374 */
>> 1375 list_for_each_entry_safe(timer, next, &firing, it.cpu.elist) {
>> 1376 bool cpu_firing;
>> 1377
>> 1378 /*
>> 1379 * spin_lock() is sufficient here even independent of the
>> 1380 * expiry context. If expiry happens in hard interrupt
>> 1381 * context it's obvious. For task work context it's safe
>> 1382 * because all other operations on timer::it_lock happen in
>> 1383 * task context (syscall or exit).
>> 1384 */
>> 1385 spin_lock(&timer->it_lock);
>> 1386 list_del_init(&timer->it.cpu.elist);
>> 1387 cpu_firing = timer->it.cpu.firing;
>> 1388 timer->it.cpu.firing = false;
>> 1389 /*
>> 1390 * If the firing flag is cleared then this raced with a
>> 1391 * timer rearm/delete operation. So don't generate an
>> 1392 * event.
>> 1393 */
>> 1394 if (likely(cpu_firing))
>> 1395 cpu_timer_fire(timer);
>> 1396 /* See posix_cpu_timer_wait_running() */
>> 1397 rcu_assign_pointer(timer->it.cpu.handling, NULL);
>> 1398 spin_unlock(&timer->it_lock);
>> 1399 }
>> 1400 }
>> 1401
>>
>>--
>>0-DAY CI Kernel Test Service
>>https://github.com/intel/lkp-tests/wiki
>>
>
>
>Oleg already addressed to something like this, I think he said to nuke
>__rcu, which idm looking at and submitting.
>
>Thanks!
Suggested patch, Oleg, what do you think?