From d3ec16ca12e27d8a5772dcade0fb19da5ab5bc0b Mon Sep 17 00:00:00 2001 From: Terence Tritton Date: Wed, 14 Aug 2024 19:18:16 +0000 Subject: [PATCH] Revert "pidfd_poll: report POLLHUP when pid_task() == NULL" This reverts commit 43f0df54c96fa5abcab9df8649c1e52119bf0238. Change-Id: Id5c8932073dd90b073d8c8e1b7f06a9da5b5bc02 Signed-off-by: Terence Tritton Bug: 352286227 --- fs/pidfs.c | 26 +++++++++++++++++++------- kernel/pid.c | 5 ----- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/fs/pidfs.c b/fs/pidfs.c index 7ffdc88dfb52..af68bc8b4c0b 100644 --- a/fs/pidfs.c +++ b/fs/pidfs.c @@ -89,6 +89,23 @@ static void pidfd_show_fdinfo(struct seq_file *m, struct file *f) } #endif + +static bool pidfd_task_exited(struct pid *pid, bool thread) +{ + struct task_struct *task; + bool exited; + + rcu_read_lock(); + task = pid_task(pid, PIDTYPE_PID); + exited = !task || + (READ_ONCE(task->exit_state) && (thread || thread_group_empty(task))); + rcu_read_unlock(); + + return exited; +} + + + /* * Poll support for process exit notification. */ @@ -96,7 +113,6 @@ static __poll_t pidfd_poll(struct file *file, struct poll_table_struct *pts) { struct pid *pid = pidfd_pid(file); bool thread = file->f_flags & PIDFD_THREAD; - struct task_struct *task; __poll_t poll_flags = 0; poll_wait(file, &pid->wait_pidfd, pts); @@ -104,12 +120,8 @@ static __poll_t pidfd_poll(struct file *file, struct poll_table_struct *pts) * Depending on PIDFD_THREAD, inform pollers when the thread * or the whole thread-group exits. */ - guard(rcu)(); - task = pid_task(pid, PIDTYPE_PID); - if (!task) - poll_flags = EPOLLIN | EPOLLRDNORM | EPOLLHUP; - else if (task->exit_state && (thread || thread_group_empty(task))) - poll_flags = EPOLLIN | EPOLLRDNORM; + if(pidfd_task_exited(pid, thread)) + poll_flags = EPOLLIN | EPOLLRDNORM; return poll_flags; } diff --git a/kernel/pid.c b/kernel/pid.c index f3c8b40ba253..ed82446d7077 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -355,11 +355,6 @@ static void __change_pid(struct task_struct *task, enum pid_type type, hlist_del_rcu(&task->pid_links[type]); *pid_ptr = new; - if (type == PIDTYPE_PID) { - WARN_ON_ONCE(pid_has_task(pid, PIDTYPE_PID)); - wake_up_all(&pid->wait_pidfd); - } - for (tmp = PIDTYPE_MAX; --tmp >= 0; ) if (pid_has_task(pid, tmp)) return;