diff options
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/array.c | 2 | ||||
-rw-r--r-- | fs/proc/generic.c | 2 | ||||
-rw-r--r-- | fs/proc/inode.c | 17 | ||||
-rw-r--r-- | fs/proc/task_mmu.c | 51 |
4 files changed, 43 insertions, 29 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c index d84eecacbeaf..3e1239e4b303 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -438,7 +438,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) | |||
438 | jiffies_to_clock_t(it_real_value), | 438 | jiffies_to_clock_t(it_real_value), |
439 | start_time, | 439 | start_time, |
440 | vsize, | 440 | vsize, |
441 | mm ? get_mm_counter(mm, rss) : 0, /* you might want to shift this left 3 */ | 441 | mm ? get_mm_rss(mm) : 0, |
442 | rsslim, | 442 | rsslim, |
443 | mm ? mm->start_code : 0, | 443 | mm ? mm->start_code : 0, |
444 | mm ? mm->end_code : 0, | 444 | mm ? mm->end_code : 0, |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 8a8c34461d48..b638fb500743 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -533,7 +533,7 @@ static void proc_kill_inodes(struct proc_dir_entry *de) | |||
533 | */ | 533 | */ |
534 | file_list_lock(); | 534 | file_list_lock(); |
535 | list_for_each(p, &sb->s_files) { | 535 | list_for_each(p, &sb->s_files) { |
536 | struct file * filp = list_entry(p, struct file, f_list); | 536 | struct file * filp = list_entry(p, struct file, f_u.fu_list); |
537 | struct dentry * dentry = filp->f_dentry; | 537 | struct dentry * dentry = filp->f_dentry; |
538 | struct inode * inode; | 538 | struct inode * inode; |
539 | struct file_operations *fops; | 539 | struct file_operations *fops; |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index effa6c0c467a..e6a818a93f3d 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -156,10 +156,13 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | |||
156 | 156 | ||
157 | WARN_ON(de && de->deleted); | 157 | WARN_ON(de && de->deleted); |
158 | 158 | ||
159 | if (de != NULL && !try_module_get(de->owner)) | ||
160 | goto out_mod; | ||
161 | |||
159 | inode = iget(sb, ino); | 162 | inode = iget(sb, ino); |
160 | if (!inode) | 163 | if (!inode) |
161 | goto out_fail; | 164 | goto out_ino; |
162 | 165 | ||
163 | PROC_I(inode)->pde = de; | 166 | PROC_I(inode)->pde = de; |
164 | if (de) { | 167 | if (de) { |
165 | if (de->mode) { | 168 | if (de->mode) { |
@@ -171,20 +174,20 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | |||
171 | inode->i_size = de->size; | 174 | inode->i_size = de->size; |
172 | if (de->nlink) | 175 | if (de->nlink) |
173 | inode->i_nlink = de->nlink; | 176 | inode->i_nlink = de->nlink; |
174 | if (!try_module_get(de->owner)) | ||
175 | goto out_fail; | ||
176 | if (de->proc_iops) | 177 | if (de->proc_iops) |
177 | inode->i_op = de->proc_iops; | 178 | inode->i_op = de->proc_iops; |
178 | if (de->proc_fops) | 179 | if (de->proc_fops) |
179 | inode->i_fop = de->proc_fops; | 180 | inode->i_fop = de->proc_fops; |
180 | } | 181 | } |
181 | 182 | ||
182 | out: | ||
183 | return inode; | 183 | return inode; |
184 | 184 | ||
185 | out_fail: | 185 | out_ino: |
186 | if (de != NULL) | ||
187 | module_put(de->owner); | ||
188 | out_mod: | ||
186 | de_put(de); | 189 | de_put(de); |
187 | goto out; | 190 | return NULL; |
188 | } | 191 | } |
189 | 192 | ||
190 | int proc_fill_super(struct super_block *s, void *data, int silent) | 193 | int proc_fill_super(struct super_block *s, void *data, int silent) |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index c7ef3e48e35b..d2fa42006d8f 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -14,22 +14,41 @@ | |||
14 | char *task_mem(struct mm_struct *mm, char *buffer) | 14 | char *task_mem(struct mm_struct *mm, char *buffer) |
15 | { | 15 | { |
16 | unsigned long data, text, lib; | 16 | unsigned long data, text, lib; |
17 | unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss; | ||
18 | |||
19 | /* | ||
20 | * Note: to minimize their overhead, mm maintains hiwater_vm and | ||
21 | * hiwater_rss only when about to *lower* total_vm or rss. Any | ||
22 | * collector of these hiwater stats must therefore get total_vm | ||
23 | * and rss too, which will usually be the higher. Barriers? not | ||
24 | * worth the effort, such snapshots can always be inconsistent. | ||
25 | */ | ||
26 | hiwater_vm = total_vm = mm->total_vm; | ||
27 | if (hiwater_vm < mm->hiwater_vm) | ||
28 | hiwater_vm = mm->hiwater_vm; | ||
29 | hiwater_rss = total_rss = get_mm_rss(mm); | ||
30 | if (hiwater_rss < mm->hiwater_rss) | ||
31 | hiwater_rss = mm->hiwater_rss; | ||
17 | 32 | ||
18 | data = mm->total_vm - mm->shared_vm - mm->stack_vm; | 33 | data = mm->total_vm - mm->shared_vm - mm->stack_vm; |
19 | text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10; | 34 | text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10; |
20 | lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text; | 35 | lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text; |
21 | buffer += sprintf(buffer, | 36 | buffer += sprintf(buffer, |
37 | "VmPeak:\t%8lu kB\n" | ||
22 | "VmSize:\t%8lu kB\n" | 38 | "VmSize:\t%8lu kB\n" |
23 | "VmLck:\t%8lu kB\n" | 39 | "VmLck:\t%8lu kB\n" |
40 | "VmHWM:\t%8lu kB\n" | ||
24 | "VmRSS:\t%8lu kB\n" | 41 | "VmRSS:\t%8lu kB\n" |
25 | "VmData:\t%8lu kB\n" | 42 | "VmData:\t%8lu kB\n" |
26 | "VmStk:\t%8lu kB\n" | 43 | "VmStk:\t%8lu kB\n" |
27 | "VmExe:\t%8lu kB\n" | 44 | "VmExe:\t%8lu kB\n" |
28 | "VmLib:\t%8lu kB\n" | 45 | "VmLib:\t%8lu kB\n" |
29 | "VmPTE:\t%8lu kB\n", | 46 | "VmPTE:\t%8lu kB\n", |
30 | (mm->total_vm - mm->reserved_vm) << (PAGE_SHIFT-10), | 47 | hiwater_vm << (PAGE_SHIFT-10), |
48 | (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10), | ||
31 | mm->locked_vm << (PAGE_SHIFT-10), | 49 | mm->locked_vm << (PAGE_SHIFT-10), |
32 | get_mm_counter(mm, rss) << (PAGE_SHIFT-10), | 50 | hiwater_rss << (PAGE_SHIFT-10), |
51 | total_rss << (PAGE_SHIFT-10), | ||
33 | data << (PAGE_SHIFT-10), | 52 | data << (PAGE_SHIFT-10), |
34 | mm->stack_vm << (PAGE_SHIFT-10), text, lib, | 53 | mm->stack_vm << (PAGE_SHIFT-10), text, lib, |
35 | (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); | 54 | (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); |
@@ -44,13 +63,11 @@ unsigned long task_vsize(struct mm_struct *mm) | |||
44 | int task_statm(struct mm_struct *mm, int *shared, int *text, | 63 | int task_statm(struct mm_struct *mm, int *shared, int *text, |
45 | int *data, int *resident) | 64 | int *data, int *resident) |
46 | { | 65 | { |
47 | int rss = get_mm_counter(mm, rss); | 66 | *shared = get_mm_counter(mm, file_rss); |
48 | |||
49 | *shared = rss - get_mm_counter(mm, anon_rss); | ||
50 | *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) | 67 | *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) |
51 | >> PAGE_SHIFT; | 68 | >> PAGE_SHIFT; |
52 | *data = mm->total_vm - mm->shared_vm; | 69 | *data = mm->total_vm - mm->shared_vm; |
53 | *resident = rss; | 70 | *resident = *shared + get_mm_counter(mm, anon_rss); |
54 | return mm->total_vm; | 71 | return mm->total_vm; |
55 | } | 72 | } |
56 | 73 | ||
@@ -186,13 +203,14 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, | |||
186 | struct mem_size_stats *mss) | 203 | struct mem_size_stats *mss) |
187 | { | 204 | { |
188 | pte_t *pte, ptent; | 205 | pte_t *pte, ptent; |
206 | spinlock_t *ptl; | ||
189 | unsigned long pfn; | 207 | unsigned long pfn; |
190 | struct page *page; | 208 | struct page *page; |
191 | 209 | ||
192 | pte = pte_offset_map(pmd, addr); | 210 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); |
193 | do { | 211 | do { |
194 | ptent = *pte; | 212 | ptent = *pte; |
195 | if (pte_none(ptent) || !pte_present(ptent)) | 213 | if (!pte_present(ptent)) |
196 | continue; | 214 | continue; |
197 | 215 | ||
198 | mss->resident += PAGE_SIZE; | 216 | mss->resident += PAGE_SIZE; |
@@ -213,8 +231,8 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, | |||
213 | mss->private_clean += PAGE_SIZE; | 231 | mss->private_clean += PAGE_SIZE; |
214 | } | 232 | } |
215 | } while (pte++, addr += PAGE_SIZE, addr != end); | 233 | } while (pte++, addr += PAGE_SIZE, addr != end); |
216 | pte_unmap(pte - 1); | 234 | pte_unmap_unlock(pte - 1, ptl); |
217 | cond_resched_lock(&vma->vm_mm->page_table_lock); | 235 | cond_resched(); |
218 | } | 236 | } |
219 | 237 | ||
220 | static inline void smaps_pmd_range(struct vm_area_struct *vma, pud_t *pud, | 238 | static inline void smaps_pmd_range(struct vm_area_struct *vma, pud_t *pud, |
@@ -268,17 +286,11 @@ static inline void smaps_pgd_range(struct vm_area_struct *vma, | |||
268 | static int show_smap(struct seq_file *m, void *v) | 286 | static int show_smap(struct seq_file *m, void *v) |
269 | { | 287 | { |
270 | struct vm_area_struct *vma = v; | 288 | struct vm_area_struct *vma = v; |
271 | struct mm_struct *mm = vma->vm_mm; | ||
272 | struct mem_size_stats mss; | 289 | struct mem_size_stats mss; |
273 | 290 | ||
274 | memset(&mss, 0, sizeof mss); | 291 | memset(&mss, 0, sizeof mss); |
275 | 292 | if (vma->vm_mm) | |
276 | if (mm) { | ||
277 | spin_lock(&mm->page_table_lock); | ||
278 | smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss); | 293 | smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss); |
279 | spin_unlock(&mm->page_table_lock); | ||
280 | } | ||
281 | |||
282 | return show_map_internal(m, v, &mss); | 294 | return show_map_internal(m, v, &mss); |
283 | } | 295 | } |
284 | 296 | ||
@@ -407,7 +419,6 @@ static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma) | |||
407 | for_each_node(i) | 419 | for_each_node(i) |
408 | md->node[i] =0; | 420 | md->node[i] =0; |
409 | 421 | ||
410 | spin_lock(&mm->page_table_lock); | ||
411 | for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) { | 422 | for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) { |
412 | page = follow_page(mm, vaddr, 0); | 423 | page = follow_page(mm, vaddr, 0); |
413 | if (page) { | 424 | if (page) { |
@@ -422,8 +433,8 @@ static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma) | |||
422 | md->anon++; | 433 | md->anon++; |
423 | md->node[page_to_nid(page)]++; | 434 | md->node[page_to_nid(page)]++; |
424 | } | 435 | } |
436 | cond_resched(); | ||
425 | } | 437 | } |
426 | spin_unlock(&mm->page_table_lock); | ||
427 | return md; | 438 | return md; |
428 | } | 439 | } |
429 | 440 | ||
@@ -469,7 +480,7 @@ static int show_numa_map(struct seq_file *m, void *v) | |||
469 | seq_printf(m, " interleave={"); | 480 | seq_printf(m, " interleave={"); |
470 | first = 1; | 481 | first = 1; |
471 | for_each_node(n) { | 482 | for_each_node(n) { |
472 | if (test_bit(n, pol->v.nodes)) { | 483 | if (node_isset(n, pol->v.nodes)) { |
473 | if (!first) | 484 | if (!first) |
474 | seq_putc(m,','); | 485 | seq_putc(m,','); |
475 | else | 486 | else |