Hi Tetsuo,

On 02/01, Tetsuo Handa wrote:
>
> Is rcu_read_lock() sufficient (i.e.
>
>   rcu_read_lock();
>   for_each_process_thread(g, p) {
>     (...snipped...)
>   }
>   rcu_read_unlock();
>
> is OK) for "can't go away" ?

Yes, this should work just fine,

> Likewise, IOPRIO_WHO_PGRP case are using
>
>   rcu_read_lock();
>   do {
>     if ((pgrp) != NULL)
>       hlist_for_each_entry_rcu((p), &(pgrp)->tasks[PIDTYPE_PGID], 
> pids[PIDTYPE_PGID].node) {
>         {
>           struct task_struct *tg___ = p;
>           do {
>             (...snipped...)
>           } while_each_thread(tg___, p);
>           p = tg___;
>         }
>         if (PIDTYPE_PGID == PIDTYPE_PID)
>           break;
>       }
>   } while (0);
>   rcu_read_unlock();
>
> sequence which I guess it is unsafe as well.

Hmm, indeed, I forgot there is another while_each_thread() hidden in
do_each_pid_thread()

> In this case updating do_each_pid_thread() to use for_each_thread() and
> updating while_each_pid_thread() not to use while_each_thread() is
> the correct fix?

Yes, I think so, just

        --- a/include/linux/pid.h
        +++ b/include/linux/pid.h
        @@ -191,10 +191,10 @@ pid_t pid_vnr(struct pid *pid);
         #define do_each_pid_thread(pid, type, task)                            
\
                do_each_pid_task(pid, type, task) {                             
\
                        struct task_struct *tg___ = task;                       
\
        -               do {
        +               for_each_thread(tg__, task) {
         
         #define while_each_pid_thread(pid, type, task)                         
\
        -               } while_each_thread(tg___, task);                       
\
        +               }                                                       
\
                        task = tg___;                                           
\
                } while_each_pid_task(pid, type, task)
         #endif /* _LINUX_PID_H */


but perhaps we can also cleanup it... the usage of 'tg___' doesn't look nice
either way, so perhaps

        #define do_each_pid_thread(pid, type, task) do {                        
\
                struct task_struct *tg___;                                      
\
                do_each_pid_task(pid, type, tg___) {                            
\
                        for_each_thread(tg__, task) {

        #define while_each_pid_thread(pid, type, task)                          
\
                        }                                                       
\
                } while_each_pid_task(pid, type, task);                         
\
                } while (0)

will look a bit better? up to you.

Oleg.

Reply via email to