|
12 | 12 |
|
13 | 13 | #include <linux/sched.h>
|
14 | 14 |
|
15 |
| -/** |
16 |
| - * is_single_threaded - Determine if a thread group is single-threaded or not |
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. |
| 15 | +/* |
| 16 | + * Returns true if the task does not share ->mm with another thread/process. |
21 | 17 | */
|
22 |
| -bool is_single_threaded(struct task_struct *p) |
| 18 | +bool is_single_threaded(struct task_struct *task) |
23 | 19 | {
|
24 |
| - struct task_struct *g, *t; |
25 |
| - struct mm_struct *mm = p->mm; |
26 |
| - |
27 |
| - if (atomic_read(&p->signal->count) != 1) |
28 |
| - goto no; |
29 |
| - |
30 |
| - if (atomic_read(&p->mm->mm_users) != 1) { |
31 |
| - read_lock(&tasklist_lock); |
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 |
| - } |
| 20 | + struct mm_struct *mm = task->mm; |
| 21 | + struct task_struct *p, *t; |
| 22 | + bool ret; |
| 23 | + |
| 24 | + might_sleep(); |
| 25 | + |
| 26 | + if (atomic_read(&task->signal->live) != 1) |
| 27 | + return false; |
38 | 28 |
|
39 |
| - return true; |
| 29 | + if (atomic_read(&mm->mm_users) == 1) |
| 30 | + return true; |
| 31 | + |
| 32 | + ret = false; |
| 33 | + down_write(&mm->mmap_sem); |
| 34 | + rcu_read_lock(); |
| 35 | + for_each_process(p) { |
| 36 | + if (unlikely(p->flags & PF_KTHREAD)) |
| 37 | + continue; |
| 38 | + if (unlikely(p == task->group_leader)) |
| 39 | + continue; |
| 40 | + |
| 41 | + t = p; |
| 42 | + do { |
| 43 | + if (unlikely(t->mm == mm)) |
| 44 | + goto found; |
| 45 | + if (likely(t->mm)) |
| 46 | + break; |
| 47 | + } while_each_thread(p, t); |
| 48 | + } |
| 49 | + ret = true; |
| 50 | +found: |
| 51 | + rcu_read_unlock(); |
| 52 | + up_write(&mm->mmap_sem); |
40 | 53 |
|
41 |
| -no_unlock: |
42 |
| - read_unlock(&tasklist_lock); |
43 |
| -no: |
44 |
| - return false; |
| 54 | + return ret; |
45 | 55 | }
|
0 commit comments