2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-30 05:48:05 +00:00

timers: improve and fix posix timer id sequence checks

This is a patch proposed by Thomas here:
https://lore.kernel.org/all/87ilczc7d9.ffs@tglx/

It removes (created id > desired id) "sanity" check and adds proper
checking that ids start at zero and increment by one each time when we
create/delete a posix timer.

First purpose of it is to fix infinite looping in create_posix_timers on
old pre 3.11 kernels.

Second purpose is to allow kernel interface of creating posix timers
with desired id change from iterating with predictable next id to just
setting next id directly. And at the same time removing predictable next
id so that criu with this patch would not get to infinite loop in
create_posix_timers if this happens.

Thanks a lot to Thomas!

Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
This commit is contained in:
Pavel Tikhomirov 2023-05-11 22:59:28 +08:00 committed by Andrei Vagin
parent fc08fa9077
commit c6ac396aa3

View File

@ -1169,7 +1169,7 @@ static int timerfd_arm(struct task_restore_args *args)
static int create_posix_timers(struct task_restore_args *args)
{
int ret, i;
kernel_timer_t next_id;
kernel_timer_t next_id = 0, timer_id;
struct sigevent sev;
for (i = 0; i < args->posix_timers_n; i++) {
@ -1183,25 +1183,26 @@ static int create_posix_timers(struct task_restore_args *args)
sev.sigev_value.sival_ptr = args->posix_timers[i].spt.sival_ptr;
while (1) {
ret = sys_timer_create(args->posix_timers[i].spt.clock_id, &sev, &next_id);
ret = sys_timer_create(args->posix_timers[i].spt.clock_id, &sev, &timer_id);
if (ret < 0) {
pr_err("Can't create posix timer - %d\n", i);
return ret;
}
if (next_id == args->posix_timers[i].spt.it_id)
break;
ret = sys_timer_delete(next_id);
if (ret < 0) {
pr_err("Can't remove temporaty posix timer 0x%x\n", next_id);
return ret;
}
if ((long)next_id > args->posix_timers[i].spt.it_id) {
if (timer_id != next_id) {
pr_err("Can't create timers, kernel don't give them consequently\n");
return -1;
}
next_id++;
if (timer_id == args->posix_timers[i].spt.it_id)
break;
ret = sys_timer_delete(timer_id);
if (ret < 0) {
pr_err("Can't remove temporaty posix timer 0x%x\n", timer_id);
return ret;
}
}
}