mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 13:58:34 +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:
committed by
Andrei Vagin
parent
fc08fa9077
commit
c6ac396aa3
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user