summaryrefslogtreecommitdiff
path: root/fs/proc/array.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/array.c')
-rw-r--r--fs/proc/array.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index a718316d7ffd..7186199d5e4b 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -393,11 +393,10 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
return res;
}
-static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size,
- int * pages, int * shared, int * dirty, int * total)
+static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size, int * pages, int * shared, int * dirty, int * total)
{
- pte_t * pte;
- unsigned long end;
+ unsigned long end, pmd_end;
+ pte_t *pte;
if (pmd_none(*pmd))
return;
@@ -406,11 +405,12 @@ static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned
pmd_clear(pmd);
return;
}
- pte = pte_offset(pmd, address);
- address &= ~PMD_MASK;
+ preempt_disable();
+ pte = pte_offset_map(pmd, address);
end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
+ pmd_end = (address + PMD_SIZE) & PMD_MASK;
+ if (end > pmd_end)
+ end = pmd_end;
do {
pte_t page = *pte;
struct page *ptpage;
@@ -431,6 +431,8 @@ static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned
if (page_count(pte_page(page)) > 1)
++*shared;
} while (address < end);
+ pte_unmap(pte - 1);
+ preempt_enable();
}
static inline void statm_pmd_range(pgd_t * pgd, unsigned long address, unsigned long size,