aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/array.c2
-rw-r--r--fs/proc/generic.c2
-rw-r--r--fs/proc/inode.c17
-rw-r--r--fs/proc/task_mmu.c51
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
182out:
183 return inode; 183 return inode;
184 184
185out_fail: 185out_ino:
186 if (de != NULL)
187 module_put(de->owner);
188out_mod:
186 de_put(de); 189 de_put(de);
187 goto out; 190 return NULL;
188} 191}
189 192
190int proc_fill_super(struct super_block *s, void *data, int silent) 193int 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 @@
14char *task_mem(struct mm_struct *mm, char *buffer) 14char *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)
44int task_statm(struct mm_struct *mm, int *shared, int *text, 63int 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
220static inline void smaps_pmd_range(struct vm_area_struct *vma, pud_t *pud, 238static 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,
268static int show_smap(struct seq_file *m, void *v) 286static 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