posix-timers: Add proper comments in do_timer_create()
authorThomas Gleixner <tglx@linutronix.de>
Tue, 25 Apr 2023 18:49:19 +0000 (20:49 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Sun, 18 Jun 2023 20:41:51 +0000 (22:41 +0200)
The comment about timer lifetime at the end of the function is misplaced
and uncomprehensible.

Make it understandable and put it at the right place. Add a new comment
about the visibility of the new timer ID to user space.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Link: https://lore.kernel.org/r/20230425183313.619897296@linutronix.de
kernel/time/posix-timers.c

index 54adb4c..20d3b99 100644 (file)
@@ -529,12 +529,17 @@ static int do_timer_create(clockid_t which_clock, struct sigevent *event,
        new_timer->sigq->info.si_tid   = new_timer->it_id;
        new_timer->sigq->info.si_code  = SI_TIMER;
 
-       if (copy_to_user(created_timer_id,
-                        &new_timer_id, sizeof (new_timer_id))) {
+       if (copy_to_user(created_timer_id, &new_timer_id, sizeof (new_timer_id))) {
                error = -EFAULT;
                goto out;
        }
-
+       /*
+        * After succesful copy out, the timer ID is visible to user space
+        * now but not yet valid because new_timer::signal is still NULL.
+        *
+        * Complete the initialization with the clock specific create
+        * callback.
+        */
        error = kc->timer_create(new_timer);
        if (error)
                goto out;
@@ -544,14 +549,11 @@ static int do_timer_create(clockid_t which_clock, struct sigevent *event,
        WRITE_ONCE(new_timer->it_signal, current->signal);
        list_add(&new_timer->list, &current->signal->posix_timers);
        spin_unlock_irq(&current->sighand->siglock);
-
-       return 0;
        /*
-        * In the case of the timer belonging to another task, after
-        * the task is unlocked, the timer is owned by the other task
-        * and may cease to exist at any time.  Don't use or modify
-        * new_timer after the unlock call.
+        * After unlocking sighand::siglock @new_timer is subject to
+        * concurrent removal and cannot be touched anymore
         */
+       return 0;
 out:
        posix_timer_unhash_and_free(new_timer);
        return error;