aboutsummaryrefslogtreecommitdiffstats
path: root/lib/is_single_threaded.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-11 11:55:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-11 11:55:49 -0400
commitf6f79190866d5b2d06a2114d673f91f54e7c7ce4 (patch)
tree025bc2ff00351c71a719cb5bc2aa3f59133400f6 /lib/is_single_threaded.c
parent0d03d59d9b31cd1e33b7e46a80b6fef66244b1f2 (diff)
parenta3c8b97396ef42edfb845788ba6f53b2a93ce980 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6: (57 commits) binfmt_elf: fix PT_INTERP bss handling TPM: Fixup boot probe timeout for tpm_tis driver sysfs: Add labeling support for sysfs LSM/SELinux: inode_{get,set,notify}secctx hooks to access LSM security context information. VFS: Factor out part of vfs_setxattr so it can be called from the SELinux hook for inode_setsecctx. KEYS: Add missing linux/tracehook.h #inclusions KEYS: Fix default security_session_to_parent() Security/SELinux: includecheck fix kernel/sysctl.c KEYS: security_cred_alloc_blank() should return int under all circumstances IMA: open new file for read KEYS: Add a keyctl to install a process's session keyring on its parent [try #6] KEYS: Extend TIF_NOTIFY_RESUME to (almost) all architectures [try #6] KEYS: Do some whitespace cleanups [try #6] KEYS: Make /proc/keys use keyid not numread as file position [try #6] KEYS: Add garbage collection for dead, revoked and expired keys. [try #6] KEYS: Flag dead keys to induce EKEYREVOKED [try #6] KEYS: Allow keyctl_revoke() on keys that have SETATTR but not WRITE perm [try #6] KEYS: Deal with dead-type keys appropriately [try #6] CRED: Add some configurable debugging [try #6] selinux: Support for the new TUN LSM hooks ...
Diffstat (limited to 'lib/is_single_threaded.c')
-rw-r--r--lib/is_single_threaded.c61
1 files changed, 37 insertions, 24 deletions
diff --git a/lib/is_single_threaded.c b/lib/is_single_threaded.c
index f1ed2fe76c65..bd2bea963364 100644
--- a/lib/is_single_threaded.c
+++ b/lib/is_single_threaded.c
@@ -12,34 +12,47 @@
12 12
13#include <linux/sched.h> 13#include <linux/sched.h>
14 14
15/** 15/*
16 * is_single_threaded - Determine if a thread group is single-threaded or not 16 * Returns true if the task does not share ->mm with another thread/process.
17 * @p: A task in the thread group in question
18 *
19 * This returns true if the thread group to which a task belongs is single
20 * threaded, false if it is not.
21 */ 17 */
22bool is_single_threaded(struct task_struct *p) 18bool current_is_single_threaded(void)
23{ 19{
24 struct task_struct *g, *t; 20 struct task_struct *task = current;
25 struct mm_struct *mm = p->mm; 21 struct mm_struct *mm = task->mm;
22 struct task_struct *p, *t;
23 bool ret;
26 24
27 if (atomic_read(&p->signal->count) != 1) 25 if (atomic_read(&task->signal->live) != 1)
28 goto no; 26 return false;
29 27
30 if (atomic_read(&p->mm->mm_users) != 1) { 28 if (atomic_read(&mm->mm_users) == 1)
31 read_lock(&tasklist_lock); 29 return true;
32 do_each_thread(g, t) {
33 if (t->mm == mm && t != p)
34 goto no_unlock;
35 } while_each_thread(g, t);
36 read_unlock(&tasklist_lock);
37 }
38 30
39 return true; 31 ret = false;
32 rcu_read_lock();
33 for_each_process(p) {
34 if (unlikely(p->flags & PF_KTHREAD))
35 continue;
36 if (unlikely(p == task->group_leader))
37 continue;
38
39 t = p;
40 do {
41 if (unlikely(t->mm == mm))
42 goto found;
43 if (likely(t->mm))
44 break;
45 /*
46 * t->mm == NULL. Make sure next_thread/next_task
47 * will see other CLONE_VM tasks which might be
48 * forked before exiting.
49 */
50 smp_rmb();
51 } while_each_thread(p, t);
52 }
53 ret = true;
54found:
55 rcu_read_unlock();
40 56
41no_unlock: 57 return ret;
42 read_unlock(&tasklist_lock);
43no:
44 return false;
45} 58}