From: Oleg Nesterov <oleg@redhat.com>
To: Christian Brauner <brauner@kernel.org>
Cc: linux-fsdevel@vger.kernel.org, Jeff Layton <jlayton@kernel.org>,
Lennart Poettering <lennart@poettering.net>,
Daan De Meyer <daan.j.demeyer@gmail.com>,
Mike Yuan <me@yhndnzj.com>
Subject: Re: [PATCH v3 1/4] pidfs: improve multi-threaded exec and premature thread-group leader exit polling
Date: Thu, 20 Mar 2025 11:57:02 +0100 [thread overview]
Message-ID: <20250320105701.GA11256@redhat.com> (raw)
In-Reply-To: <20250320-work-pidfs-thread_group-v3-1-b7e5f7e2c3b1@kernel.org>
Christian,
All the comments look misleading (and overcomplicated) to me.
See below, but first lets recall the commit 64bef697d33b75fc06c5789
("pidfd: implement PIDFD_THREAD flag for pidfd_open()") which says
pidfd: implement PIDFD_THREAD flag for pidfd_open()
With this flag:
....
- pidfd_poll() succeeds when the task exits and becomes a
zombie (iow, passes exit_notify()), even if it is a leader
and thread-group is not empty.
This patch simply reverts this behaviour, the exiting leader will not
report the exit if it has sub-threads (alive or not). And afaics your
V1 tried to do the same. And this eliminates the
This means that the behaviour of pidfd_poll(PIDFD_THREAD,
pid-of-group-leader) is not well defined if it races with
exec() from its sub-thread; ...
problem mentioned in the changelog. That is all.
IOW, with this change PIDFD_THREAD has no effect.
Except the pid_has_task() checks in sys_pidfd_open() paths, without
PIDFD_THREAD the target task must be a group leader.
On 03/20, Christian Brauner wrote:
>
> @@ -218,12 +218,32 @@ static __poll_t pidfd_poll(struct file *file, struct poll_table_struct *pts)
Your forgot to remove the no longer used
bool thread = file->f_flags & PIDFD_THREAD;
above ;)
> /*
> * Depending on PIDFD_THREAD, inform pollers when the thread
> * or the whole thread-group exits.
See above (and below), this no longer depends on PIDFD_THREAD.
> + else if (task->exit_state && !delay_group_leader(task))
> poll_flags = EPOLLIN | EPOLLRDNORM;
So with this change:
If the exiting task is a sub-thread, report EPOLLIN as before.
delay_group_leader() can't be true. In this case PIDFD_THREAD
must be set.
If the exiting task is a leader, we do not care about PIDFD_THREAD.
We report EPOLLIN only if it is the last/only thread.
> diff --git a/kernel/exit.c b/kernel/exit.c
> index 9916305e34d3..ce5cdad5ba9c 100644
> --- a/kernel/exit.c
> +++ b/kernel/exit.c
> @@ -271,6 +271,9 @@ void release_task(struct task_struct *p)
> * If we were the last child thread and the leader has
> * exited already, and the leader's parent ignores SIGCHLD,
> * then we are the one who should release the leader.
> + *
> + * This will also wake PIDFD_THREAD pidfds for the
> + * thread-group leader that already exited.
> */
> zap_leader = do_notify_parent(leader, leader->exit_signal);
Again, this doesn't depend on PIDFD_THREAD.
> @@ -743,10 +746,13 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
>
> tsk->exit_state = EXIT_ZOMBIE;
> /*
> - * sub-thread or delay_group_leader(), wake up the
> - * PIDFD_THREAD waiters.
> + * Wake up PIDFD_THREAD waiters if this is a proper subthread
> + * exit. If this is a premature thread-group leader exit delay
> + * the notification until the last subthread exits. If a
> + * subthread should exec before then no notification will be
> + * generated.
> */
> - if (!thread_group_empty(tsk))
> + if (!delay_group_leader(tsk))
> do_notify_pidfd(tsk);
The same...
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -2180,8 +2180,10 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
> WARN_ON_ONCE(!tsk->ptrace &&
> (tsk->group_leader != tsk || !thread_group_empty(tsk)));
> /*
> - * tsk is a group leader and has no threads, wake up the
> - * non-PIDFD_THREAD waiters.
> + * This is a thread-group leader without subthreads so wake up
> + * the non-PIDFD_THREAD waiters. This also wakes the
> + * PIDFD_THREAD waiters for the thread-group leader in case it
> + * exited prematurely from release_task().
> */
This too.
Oleg.
next prev parent reply other threads:[~2025-03-20 10:57 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-20 9:29 [PATCH v3 0/4] pidfs: handle multi-threaded exec and premature thread-group leader exit Christian Brauner
2025-03-20 9:29 ` [PATCH v3 1/4] pidfs: improve multi-threaded exec and premature thread-group leader exit polling Christian Brauner
2025-03-20 10:57 ` Oleg Nesterov [this message]
2025-03-20 11:21 ` Oleg Nesterov
2025-03-20 13:16 ` Christian Brauner
2025-03-20 12:36 ` Christian Brauner
2025-03-20 14:02 ` Oleg Nesterov
2025-03-20 14:32 ` Christian Brauner
2025-03-20 9:29 ` [PATCH v3 2/4] selftests/pidfd: first test for multi-threaded exec polling Christian Brauner
2025-03-20 9:29 ` [PATCH v3 3/4] selftests/pidfd: second " Christian Brauner
2025-03-20 9:29 ` [PATCH v3 4/4] selftests/pidfd: third " Christian Brauner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250320105701.GA11256@redhat.com \
--to=oleg@redhat.com \
--cc=brauner@kernel.org \
--cc=daan.j.demeyer@gmail.com \
--cc=jlayton@kernel.org \
--cc=lennart@poettering.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=me@yhndnzj.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.