diff options
author | Johannes Weiner <hannes@cmpxchg.org> | 2016-02-02 19:57:29 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-02-03 11:28:43 -0500 |
commit | 65376df582174ffcec9e6471bf5b0dd79ba05e4a (patch) | |
tree | 60c4841a00605605bf8c315783ed48648333e865 /fs/proc | |
parent | 5c2ff95e41c9290d16556cd02e35b25d81be8fe0 (diff) |
proc: revert /proc/<pid>/maps [stack:TID] annotation
Commit b76437579d13 ("procfs: mark thread stack correctly in
proc/<pid>/maps") added [stack:TID] annotation to /proc/<pid>/maps.
Finding the task of a stack VMA requires walking the entire thread list,
turning this into quadratic behavior: a thousand threads means a
thousand stacks, so the rendering of /proc/<pid>/maps needs to look at a
million combinations.
The cost is not in proportion to the usefulness as described in the
patch.
Drop the [stack:TID] annotation to make /proc/<pid>/maps (and
/proc/<pid>/numa_maps) usable again for higher thread counts.
The [stack] annotation inside /proc/<pid>/task/<tid>/maps is retained, as
identifying the stack VMA there is an O(1) operation.
Siddesh said:
"The end users needed a way to identify thread stacks programmatically and
there wasn't a way to do that. I'm afraid I no longer remember (or have
access to the resources that would aid my memory since I changed
employers) the details of their requirement. However, I did do this on my
own time because I thought it was an interesting project for me and nobody
really gave any feedback then as to its utility, so as far as I am
concerned you could roll back the main thread maps information since the
information is available in the thread-specific files"
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
Cc: Siddhesh Poyarekar <siddhesh.poyarekar@gmail.com>
Cc: Shaohua Li <shli@fb.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/task_mmu.c | 66 | ||||
-rw-r--r-- | fs/proc/task_nommu.c | 49 |
2 files changed, 43 insertions, 72 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 4a0c31f904a6..fa95ab2d3674 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -259,23 +259,29 @@ static int do_maps_open(struct inode *inode, struct file *file, | |||
259 | sizeof(struct proc_maps_private)); | 259 | sizeof(struct proc_maps_private)); |
260 | } | 260 | } |
261 | 261 | ||
262 | static pid_t pid_of_stack(struct proc_maps_private *priv, | 262 | /* |
263 | struct vm_area_struct *vma, bool is_pid) | 263 | * Indicate if the VMA is a stack for the given task; for |
264 | * /proc/PID/maps that is the stack of the main task. | ||
265 | */ | ||
266 | static int is_stack(struct proc_maps_private *priv, | ||
267 | struct vm_area_struct *vma, int is_pid) | ||
264 | { | 268 | { |
265 | struct inode *inode = priv->inode; | 269 | int stack = 0; |
266 | struct task_struct *task; | 270 | |
267 | pid_t ret = 0; | 271 | if (is_pid) { |
272 | stack = vma->vm_start <= vma->vm_mm->start_stack && | ||
273 | vma->vm_end >= vma->vm_mm->start_stack; | ||
274 | } else { | ||
275 | struct inode *inode = priv->inode; | ||
276 | struct task_struct *task; | ||
268 | 277 | ||
269 | rcu_read_lock(); | 278 | rcu_read_lock(); |
270 | task = pid_task(proc_pid(inode), PIDTYPE_PID); | 279 | task = pid_task(proc_pid(inode), PIDTYPE_PID); |
271 | if (task) { | ||
272 | task = task_of_stack(task, vma, is_pid); | ||
273 | if (task) | 280 | if (task) |
274 | ret = task_pid_nr_ns(task, inode->i_sb->s_fs_info); | 281 | stack = vma_is_stack_for_task(vma, task); |
282 | rcu_read_unlock(); | ||
275 | } | 283 | } |
276 | rcu_read_unlock(); | 284 | return stack; |
277 | |||
278 | return ret; | ||
279 | } | 285 | } |
280 | 286 | ||
281 | static void | 287 | static void |
@@ -335,8 +341,6 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) | |||
335 | 341 | ||
336 | name = arch_vma_name(vma); | 342 | name = arch_vma_name(vma); |
337 | if (!name) { | 343 | if (!name) { |
338 | pid_t tid; | ||
339 | |||
340 | if (!mm) { | 344 | if (!mm) { |
341 | name = "[vdso]"; | 345 | name = "[vdso]"; |
342 | goto done; | 346 | goto done; |
@@ -348,21 +352,8 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) | |||
348 | goto done; | 352 | goto done; |
349 | } | 353 | } |
350 | 354 | ||
351 | tid = pid_of_stack(priv, vma, is_pid); | 355 | if (is_stack(priv, vma, is_pid)) |
352 | if (tid != 0) { | 356 | name = "[stack]"; |
353 | /* | ||
354 | * Thread stack in /proc/PID/task/TID/maps or | ||
355 | * the main process stack. | ||
356 | */ | ||
357 | if (!is_pid || (vma->vm_start <= mm->start_stack && | ||
358 | vma->vm_end >= mm->start_stack)) { | ||
359 | name = "[stack]"; | ||
360 | } else { | ||
361 | /* Thread stack in /proc/PID/maps */ | ||
362 | seq_pad(m, ' '); | ||
363 | seq_printf(m, "[stack:%d]", tid); | ||
364 | } | ||
365 | } | ||
366 | } | 357 | } |
367 | 358 | ||
368 | done: | 359 | done: |
@@ -1618,19 +1609,8 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) | |||
1618 | seq_file_path(m, file, "\n\t= "); | 1609 | seq_file_path(m, file, "\n\t= "); |
1619 | } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { | 1610 | } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { |
1620 | seq_puts(m, " heap"); | 1611 | seq_puts(m, " heap"); |
1621 | } else { | 1612 | } else if (is_stack(proc_priv, vma, is_pid)) { |
1622 | pid_t tid = pid_of_stack(proc_priv, vma, is_pid); | 1613 | seq_puts(m, " stack"); |
1623 | if (tid != 0) { | ||
1624 | /* | ||
1625 | * Thread stack in /proc/PID/task/TID/maps or | ||
1626 | * the main process stack. | ||
1627 | */ | ||
1628 | if (!is_pid || (vma->vm_start <= mm->start_stack && | ||
1629 | vma->vm_end >= mm->start_stack)) | ||
1630 | seq_puts(m, " stack"); | ||
1631 | else | ||
1632 | seq_printf(m, " stack:%d", tid); | ||
1633 | } | ||
1634 | } | 1614 | } |
1635 | 1615 | ||
1636 | if (is_vm_hugetlb_page(vma)) | 1616 | if (is_vm_hugetlb_page(vma)) |
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index e0d64c92e4f6..faacb0c0d857 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c | |||
@@ -123,23 +123,26 @@ unsigned long task_statm(struct mm_struct *mm, | |||
123 | return size; | 123 | return size; |
124 | } | 124 | } |
125 | 125 | ||
126 | static pid_t pid_of_stack(struct proc_maps_private *priv, | 126 | static int is_stack(struct proc_maps_private *priv, |
127 | struct vm_area_struct *vma, bool is_pid) | 127 | struct vm_area_struct *vma, int is_pid) |
128 | { | 128 | { |
129 | struct inode *inode = priv->inode; | 129 | struct mm_struct *mm = vma->vm_mm; |
130 | struct task_struct *task; | 130 | int stack = 0; |
131 | pid_t ret = 0; | 131 | |
132 | 132 | if (is_pid) { | |
133 | rcu_read_lock(); | 133 | stack = vma->vm_start <= mm->start_stack && |
134 | task = pid_task(proc_pid(inode), PIDTYPE_PID); | 134 | vma->vm_end >= mm->start_stack; |
135 | if (task) { | 135 | } else { |
136 | task = task_of_stack(task, vma, is_pid); | 136 | struct inode *inode = priv->inode; |
137 | struct task_struct *task; | ||
138 | |||
139 | rcu_read_lock(); | ||
140 | task = pid_task(proc_pid(inode), PIDTYPE_PID); | ||
137 | if (task) | 141 | if (task) |
138 | ret = task_pid_nr_ns(task, inode->i_sb->s_fs_info); | 142 | stack = vma_is_stack_for_task(vma, task); |
143 | rcu_read_unlock(); | ||
139 | } | 144 | } |
140 | rcu_read_unlock(); | 145 | return stack; |
141 | |||
142 | return ret; | ||
143 | } | 146 | } |
144 | 147 | ||
145 | /* | 148 | /* |
@@ -181,21 +184,9 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma, | |||
181 | if (file) { | 184 | if (file) { |
182 | seq_pad(m, ' '); | 185 | seq_pad(m, ' '); |
183 | seq_file_path(m, file, ""); | 186 | seq_file_path(m, file, ""); |
184 | } else if (mm) { | 187 | } else if (mm && is_stack(priv, vma, is_pid)) { |
185 | pid_t tid = pid_of_stack(priv, vma, is_pid); | 188 | seq_pad(m, ' '); |
186 | 189 | seq_printf(m, "[stack]"); | |
187 | if (tid != 0) { | ||
188 | seq_pad(m, ' '); | ||
189 | /* | ||
190 | * Thread stack in /proc/PID/task/TID/maps or | ||
191 | * the main process stack. | ||
192 | */ | ||
193 | if (!is_pid || (vma->vm_start <= mm->start_stack && | ||
194 | vma->vm_end >= mm->start_stack)) | ||
195 | seq_printf(m, "[stack]"); | ||
196 | else | ||
197 | seq_printf(m, "[stack:%d]", tid); | ||
198 | } | ||
199 | } | 190 | } |
200 | 191 | ||
201 | seq_putc(m, '\n'); | 192 | seq_putc(m, '\n'); |