|
@@ -15,25 +15,25 @@
|
|
*/
|
|
*/
|
|
void task_mem(struct seq_file *m, struct mm_struct *mm)
|
|
void task_mem(struct seq_file *m, struct mm_struct *mm)
|
|
{
|
|
{
|
|
- struct vm_list_struct *vml;
|
|
|
|
|
|
+ struct vm_area_struct *vma;
|
|
|
|
+ struct rb_node *p;
|
|
unsigned long bytes = 0, sbytes = 0, slack = 0;
|
|
unsigned long bytes = 0, sbytes = 0, slack = 0;
|
|
|
|
|
|
down_read(&mm->mmap_sem);
|
|
down_read(&mm->mmap_sem);
|
|
- for (vml = mm->context.vmlist; vml; vml = vml->next) {
|
|
|
|
- if (!vml->vma)
|
|
|
|
- continue;
|
|
|
|
|
|
+ for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) {
|
|
|
|
+ vma = rb_entry(p, struct vm_area_struct, vm_rb);
|
|
|
|
|
|
- bytes += kobjsize(vml);
|
|
|
|
|
|
+ bytes += kobjsize(vma);
|
|
if (atomic_read(&mm->mm_count) > 1 ||
|
|
if (atomic_read(&mm->mm_count) > 1 ||
|
|
- atomic_read(&vml->vma->vm_usage) > 1
|
|
|
|
- ) {
|
|
|
|
- sbytes += kobjsize((void *) vml->vma->vm_start);
|
|
|
|
- sbytes += kobjsize(vml->vma);
|
|
|
|
|
|
+ vma->vm_region ||
|
|
|
|
+ vma->vm_flags & VM_MAYSHARE) {
|
|
|
|
+ sbytes += kobjsize((void *) vma->vm_start);
|
|
|
|
+ if (vma->vm_region)
|
|
|
|
+ sbytes += kobjsize(vma->vm_region);
|
|
} else {
|
|
} else {
|
|
- bytes += kobjsize((void *) vml->vma->vm_start);
|
|
|
|
- bytes += kobjsize(vml->vma);
|
|
|
|
- slack += kobjsize((void *) vml->vma->vm_start) -
|
|
|
|
- (vml->vma->vm_end - vml->vma->vm_start);
|
|
|
|
|
|
+ bytes += kobjsize((void *) vma->vm_start);
|
|
|
|
+ slack += kobjsize((void *) vma->vm_start) -
|
|
|
|
+ (vma->vm_end - vma->vm_start);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -70,13 +70,14 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
|
|
|
|
|
|
unsigned long task_vsize(struct mm_struct *mm)
|
|
unsigned long task_vsize(struct mm_struct *mm)
|
|
{
|
|
{
|
|
- struct vm_list_struct *tbp;
|
|
|
|
|
|
+ struct vm_area_struct *vma;
|
|
|
|
+ struct rb_node *p;
|
|
unsigned long vsize = 0;
|
|
unsigned long vsize = 0;
|
|
|
|
|
|
down_read(&mm->mmap_sem);
|
|
down_read(&mm->mmap_sem);
|
|
- for (tbp = mm->context.vmlist; tbp; tbp = tbp->next) {
|
|
|
|
- if (tbp->vma)
|
|
|
|
- vsize += kobjsize((void *) tbp->vma->vm_start);
|
|
|
|
|
|
+ for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) {
|
|
|
|
+ vma = rb_entry(p, struct vm_area_struct, vm_rb);
|
|
|
|
+ vsize += vma->vm_region->vm_end - vma->vm_region->vm_start;
|
|
}
|
|
}
|
|
up_read(&mm->mmap_sem);
|
|
up_read(&mm->mmap_sem);
|
|
return vsize;
|
|
return vsize;
|
|
@@ -85,16 +86,15 @@ unsigned long task_vsize(struct mm_struct *mm)
|
|
int task_statm(struct mm_struct *mm, int *shared, int *text,
|
|
int task_statm(struct mm_struct *mm, int *shared, int *text,
|
|
int *data, int *resident)
|
|
int *data, int *resident)
|
|
{
|
|
{
|
|
- struct vm_list_struct *tbp;
|
|
|
|
|
|
+ struct vm_area_struct *vma;
|
|
|
|
+ struct rb_node *p;
|
|
int size = kobjsize(mm);
|
|
int size = kobjsize(mm);
|
|
|
|
|
|
down_read(&mm->mmap_sem);
|
|
down_read(&mm->mmap_sem);
|
|
- for (tbp = mm->context.vmlist; tbp; tbp = tbp->next) {
|
|
|
|
- size += kobjsize(tbp);
|
|
|
|
- if (tbp->vma) {
|
|
|
|
- size += kobjsize(tbp->vma);
|
|
|
|
- size += kobjsize((void *) tbp->vma->vm_start);
|
|
|
|
- }
|
|
|
|
|
|
+ for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) {
|
|
|
|
+ vma = rb_entry(p, struct vm_area_struct, vm_rb);
|
|
|
|
+ size += kobjsize(vma);
|
|
|
|
+ size += kobjsize((void *) vma->vm_start);
|
|
}
|
|
}
|
|
|
|
|
|
size += (*text = mm->end_code - mm->start_code);
|
|
size += (*text = mm->end_code - mm->start_code);
|
|
@@ -104,21 +104,63 @@ int task_statm(struct mm_struct *mm, int *shared, int *text,
|
|
return size;
|
|
return size;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * display a single VMA to a sequenced file
|
|
|
|
+ */
|
|
|
|
+static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
|
|
|
|
+{
|
|
|
|
+ unsigned long ino = 0;
|
|
|
|
+ struct file *file;
|
|
|
|
+ dev_t dev = 0;
|
|
|
|
+ int flags, len;
|
|
|
|
+
|
|
|
|
+ flags = vma->vm_flags;
|
|
|
|
+ file = vma->vm_file;
|
|
|
|
+
|
|
|
|
+ if (file) {
|
|
|
|
+ struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
|
|
|
|
+ dev = inode->i_sb->s_dev;
|
|
|
|
+ ino = inode->i_ino;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ seq_printf(m,
|
|
|
|
+ "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
|
|
|
|
+ vma->vm_start,
|
|
|
|
+ vma->vm_end,
|
|
|
|
+ flags & VM_READ ? 'r' : '-',
|
|
|
|
+ flags & VM_WRITE ? 'w' : '-',
|
|
|
|
+ flags & VM_EXEC ? 'x' : '-',
|
|
|
|
+ flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p',
|
|
|
|
+ vma->vm_pgoff << PAGE_SHIFT,
|
|
|
|
+ MAJOR(dev), MINOR(dev), ino, &len);
|
|
|
|
+
|
|
|
|
+ if (file) {
|
|
|
|
+ len = 25 + sizeof(void *) * 6 - len;
|
|
|
|
+ if (len < 1)
|
|
|
|
+ len = 1;
|
|
|
|
+ seq_printf(m, "%*c", len, ' ');
|
|
|
|
+ seq_path(m, &file->f_path, "");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ seq_putc(m, '\n');
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* display mapping lines for a particular process's /proc/pid/maps
|
|
* display mapping lines for a particular process's /proc/pid/maps
|
|
*/
|
|
*/
|
|
-static int show_map(struct seq_file *m, void *_vml)
|
|
|
|
|
|
+static int show_map(struct seq_file *m, void *_p)
|
|
{
|
|
{
|
|
- struct vm_list_struct *vml = _vml;
|
|
|
|
|
|
+ struct rb_node *p = _p;
|
|
|
|
|
|
- return nommu_vma_show(m, vml->vma);
|
|
|
|
|
|
+ return nommu_vma_show(m, rb_entry(p, struct vm_area_struct, vm_rb));
|
|
}
|
|
}
|
|
|
|
|
|
static void *m_start(struct seq_file *m, loff_t *pos)
|
|
static void *m_start(struct seq_file *m, loff_t *pos)
|
|
{
|
|
{
|
|
struct proc_maps_private *priv = m->private;
|
|
struct proc_maps_private *priv = m->private;
|
|
- struct vm_list_struct *vml;
|
|
|
|
struct mm_struct *mm;
|
|
struct mm_struct *mm;
|
|
|
|
+ struct rb_node *p;
|
|
loff_t n = *pos;
|
|
loff_t n = *pos;
|
|
|
|
|
|
/* pin the task and mm whilst we play with them */
|
|
/* pin the task and mm whilst we play with them */
|
|
@@ -134,9 +176,9 @@ static void *m_start(struct seq_file *m, loff_t *pos)
|
|
}
|
|
}
|
|
|
|
|
|
/* start from the Nth VMA */
|
|
/* start from the Nth VMA */
|
|
- for (vml = mm->context.vmlist; vml; vml = vml->next)
|
|
|
|
|
|
+ for (p = rb_first(&mm->mm_rb); p; p = rb_next(p))
|
|
if (n-- == 0)
|
|
if (n-- == 0)
|
|
- return vml;
|
|
|
|
|
|
+ return p;
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -152,12 +194,12 @@ static void m_stop(struct seq_file *m, void *_vml)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static void *m_next(struct seq_file *m, void *_vml, loff_t *pos)
|
|
|
|
|
|
+static void *m_next(struct seq_file *m, void *_p, loff_t *pos)
|
|
{
|
|
{
|
|
- struct vm_list_struct *vml = _vml;
|
|
|
|
|
|
+ struct rb_node *p = _p;
|
|
|
|
|
|
(*pos)++;
|
|
(*pos)++;
|
|
- return vml ? vml->next : NULL;
|
|
|
|
|
|
+ return p ? rb_next(p) : NULL;
|
|
}
|
|
}
|
|
|
|
|
|
static const struct seq_operations proc_pid_maps_ops = {
|
|
static const struct seq_operations proc_pid_maps_ops = {
|