On 02/23, Pavel Tikhomirov wrote:
>
> To avoid possible problems related to cpu/compiler optimizations around
> ->child_reaper, let's use WRITE_ONCE (additional to task_list lock)
> everywhere we write it and use READ_ONCE everywhere we read it without
> explicit lock.

Yes, this is what I meant... but I can never recall if READ_ONCE() alone
is enough to make KCSAN happy...

I won't insist, but I think it would be better to do this in a separate
change for documenation purposes and for discussion.

> @@ -247,8 +247,9 @@ struct pid *alloc_pid(struct pid_namespace *ns, pid_t 
> *arg_set_tid,
>                        * alreay in use. Return EEXIST in that case.
>                        */
>                       if (nr == -ENOSPC)
> -
>                               nr = -EEXIST;
> +             } else if (!READ_ONCE(tmp->child_reaper) && 
> idr_get_cursor(&tmp->idr) != 0) {
> +                     nr = -EINVAL;
>               } else {

Oh, this doesn't look clear/clean... This even looks racy even if it is not.
Can you move this check into the "else" branch which does another get_cursor
and unify this check with the RESERVED_PIDS check?

Either way, I don't like the fact we check ->child_reaper != NULL twice.
Perhaps something like the preparational patch below makes sense ? Not
sure this is actually better...

Oleg.

--- x/kernel/pid.c
+++ x/kernel/pid.c
@@ -215,12 +215,6 @@ struct pid *alloc_pid(struct pid_namespa
                        retval = -EINVAL;
                        if (tid < 1 || tid >= pid_max[ns->level - i])
                                goto out_abort;
-                       /*
-                        * Also fail if a PID != 1 is requested and
-                        * no PID 1 exists.
-                        */
-                       if (tid != 1 && !tmp->child_reaper)
-                               goto out_abort;
                        retval = -EPERM;
                        if (!checkpoint_restore_ns_capable(tmp->user_ns))
                                goto out_abort;
@@ -299,6 +293,11 @@ struct pid *alloc_pid(struct pid_namespa
                tmp = tmp->parent;
                i--;
                retried_preload = false;
+
+               if (!READ_ONCE(tmp->child_reaper) && nr != 1) {
+                       retval = -EINVAL;
+                       goto out_free;
+               }
        }
 
        /*


Reply via email to