Skip to content

Commit

Permalink
fs/proc/task_mmu.c: simplify the vma_stop() logic
Browse files Browse the repository at this point in the history
m_start() drops ->mmap_sem and does mmput() if it retuns vsyscall
vma. This is because in this case m_stop()->vma_stop() obviously
can't use gate_vma->vm_mm.

Now that we have proc_maps_private->mm we can simplify this logic:

  - Change m_start() to return with ->mmap_sem held unless it returns
    IS_ERR_OR_NULL().

  - Change vma_stop() to use priv->mm and avoid the ugly vma checks,
    this makes "vm_area_struct *vma" unnecessary.

  - This also allows m_start() to use vm_stop().

  - Cleanup m_next() to follow the new locking rule.

    Note: m_stop() looks very ugly, and this temporary uglifies it
    even more. Fixed by the next change.

[[email protected]: coding-style fixes]
Signed-off-by: Oleg Nesterov <[email protected]>
Acked-by: Kirill A. Shutemov <[email protected]>
Acked-by: Cyrill Gorcunov <[email protected]>
Cc: "Eric W. Biederman" <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
oleg-nesterov authored and torvalds committed Oct 10, 2014
1 parent 29a40ac commit 59b4bf1
Showing 1 changed file with 19 additions and 16 deletions.
35 changes: 19 additions & 16 deletions fs/proc/task_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,13 @@ static void release_task_mempolicy(struct proc_maps_private *priv)
}
#endif

static void vma_stop(struct proc_maps_private *priv, struct vm_area_struct *vma)
static void vma_stop(struct proc_maps_private *priv)
{
if (vma && vma != priv->tail_vma) {
struct mm_struct *mm = vma->vm_mm;
release_task_mempolicy(priv);
up_read(&mm->mmap_sem);
mmput(mm);
}
struct mm_struct *mm = priv->mm;

release_task_mempolicy(priv);
up_read(&mm->mmap_sem);
mmput(mm);
}

static void *m_start(struct seq_file *m, loff_t *pos)
Expand Down Expand Up @@ -199,34 +198,38 @@ static void *m_start(struct seq_file *m, loff_t *pos)
if (vma)
return vma;

release_task_mempolicy(priv);
/* End of vmas has been reached */
m->version = (tail_vma != NULL)? 0: -1UL;
up_read(&mm->mmap_sem);
mmput(mm);
return tail_vma;
if (tail_vma)
return tail_vma;

vma_stop(priv);
return NULL;
}

static void *m_next(struct seq_file *m, void *v, loff_t *pos)
{
struct proc_maps_private *priv = m->private;
struct vm_area_struct *vma = v;
struct vm_area_struct *tail_vma = priv->tail_vma;
struct vm_area_struct *next;

(*pos)++;
if (vma && (vma != tail_vma) && vma->vm_next)
return vma->vm_next;
vma_stop(priv, vma);
return (vma != tail_vma)? tail_vma: NULL;

next = (vma != tail_vma) ? tail_vma : NULL;
if (!next)
vma_stop(priv);
return next;
}

static void m_stop(struct seq_file *m, void *v)
{
struct proc_maps_private *priv = m->private;
struct vm_area_struct *vma = v;

if (!IS_ERR(vma))
vma_stop(priv, vma);
if (!IS_ERR_OR_NULL(v))
vma_stop(priv);
if (priv->task)
put_task_struct(priv->task);
}
Expand Down

0 comments on commit 59b4bf1

Please sign in to comment.