lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue,  6 Jun 2017 14:03:33 -0500
From:   "Eric W. Biederman" <ebiederm@...ssion.com>
To:     linux-kernel@...r.kernel.org
Cc:     linux-api@...r.kernel.org,
        Linus Torvalds <torvalds@...ux-foundation.org>,
        Oleg Nesterov <oleg@...hat.com>,
        Ingo Molnar <mingo@...nel.org>,
        Thomas Gleixner <tglx@...utronix.de>,
        Kees Cook <keescook@...omium.org>,
        Roland McGrath <roland@...k.frob.com>,
        Al Viro <viro@...IV.linux.org.uk>,
        David Howells <dhowells@...hat.com>,
        "Michael Kerrisk (man-pages)" <mtk.manpages@...il.com>,
        "Eric W. Biederman" <ebiederm@...ssion.com>
Subject: [PATCH 21/26] wait: Optmize waitpid

Now that which list a task is found on does not matter there is no
reason to walk the child lists for waitpid when task_pid can directly
find the child.

Add a new helper do_wait_pid that finds the target task via pid_task
and verifies it is on one of the lists for the thread we are
reaping.

This is more efficient in two ways.  It skips the list traversal
so uninteresting tasks don't slow things down.  It guarantees
a task will only be visited once if p->parent == p->real_parent.

Except for the increase in efficiency this results in no user
visible behavioral differences.

Signed-off-by: "Eric W. Biederman" <ebiederm@...ssion.com>
---
 kernel/exit.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/kernel/exit.c b/kernel/exit.c
index c783d5fb5ab3..2f01b75e3b2e 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1438,6 +1438,18 @@ static int ptrace_do_wait(struct wait_opts *wo, struct task_struct *tsk)
 	return 0;
 }
 
+static int do_wait_pid(struct wait_opts *wo, struct task_struct *tsk)
+{
+	struct task_struct *p = pid_task(wo->wo_pid, wo->wo_type);
+
+	/* Not on one of this tasks child lists? */
+	if ((tsk != p->parent) &&
+	    ((tsk != p->real_parent) || !thread_group_leader(p)))
+		return 0;
+
+	return wait_consider_task(wo, p);
+}
+
 static int child_wait_callback(wait_queue_t *wait, unsigned mode,
 				int sync, void *key)
 {
@@ -1486,11 +1498,15 @@ static long do_wait(struct wait_opts *wo)
 	read_lock(&tasklist_lock);
 	tsk = current;
 	do {
-		retval = do_wait_thread(wo, tsk);
-		if (retval)
-			goto end;
+		if (wo->wo_type == PIDTYPE_PID) {
+			retval = do_wait_pid(wo, tsk);
+		} else {
+			retval = do_wait_thread(wo, tsk);
+			if (retval)
+				goto end;
 
-		retval = ptrace_do_wait(wo, tsk);
+			retval = ptrace_do_wait(wo, tsk);
+		}
 		if (retval)
 			goto end;
 
-- 
2.10.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ