From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753792AbdBARTQ (ORCPT ); Wed, 1 Feb 2017 12:19:16 -0500 Received: from mx1.redhat.com ([209.132.183.28]:56952 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753771AbdBARTN (ORCPT ); Wed, 1 Feb 2017 12:19:13 -0500 Date: Wed, 1 Feb 2017 18:19:11 +0100 From: Oleg Nesterov To: Tetsuo Handa Cc: dserrg@gmail.com, snanda@chromium.org, rientjes@google.com, linux-kernel@vger.kernel.org Subject: Re: Question about replacing while_each_thread(). Message-ID: <20170201171911.GA18136@redhat.com> References: <201702011947.DBD56740.OMVHOLOtSJFFFQ@I-love.SAKURA.ne.jp> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <201702011947.DBD56740.OMVHOLOtSJFFFQ@I-love.SAKURA.ne.jp> User-Agent: Mutt/1.5.24 (2015-08-30) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Wed, 01 Feb 2017 17:19:14 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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.