Re: [PATCH 1/2] hung_task: split for_each_process_thread() into for_each_process() + __for_each_thread()

Aaron Tomlin
2015-03-20T16:55:58Z

On Tue 2015-03-17 20:25 +0100, Oleg Nesterov wrote:
> Preparation. Change the main loop in check_hung_uninterruptible_tasks()
> to use the nested for_each_process() + __for_each_thread() loops explicitly.
> Note that we use __for_each_thread(), not for_each_thread(). This way it
> is clear that the inner loop doesn't depend on 'g' after we read ->signal.
>
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
> ---
> kernel/hung_task.c | 23 ++++++++++++++---------
> 1 files changed, 14 insertions(+), 9 deletions(-)
>
> diff --git a/kernel/hung_task.c b/kernel/hung_task.c
> index e0f90c2..4735b99 100644
> --- a/kernel/hung_task.c
> +++ b/kernel/hung_task.c
> @@ -169,17 +169,22 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
> return;
>
> rcu_read_lock();
> - for_each_process_thread(g, t) {
> - if (!max_count--)
> - goto unlock;
> - if (!--batch_count) {
> - batch_count = HUNG_TASK_BATCHING;
> - if (!rcu_lock_break(g, t))
> + for_each_process(g) {
> + struct signal_struct *sig = g->signal;
> +
> + __for_each_thread(sig, t) {
> + if (!max_count--)
> goto unlock;
> +
> + if (!--batch_count) {
> + batch_count = HUNG_TASK_BATCHING;
> + if (!rcu_lock_break(g, t))
> + goto unlock;
> + }
> + /* use "==" to skip the TASK_KILLABLE tasks */
> + if (t->state == TASK_UNINTERRUPTIBLE)
> + check_hung_task(t, timeout);
> }
> - /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */
> - if (t->state == TASK_UNINTERRUPTIBLE)
> - check_hung_task(t, timeout);
> }
> unlock:
> rcu_read_unlock();
>

Acked-by: Aaron Tomlin <atomlin@redhat.com>