summaryrefslogtreecommitdiff
path: root/fs/proc/array.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2002-02-19 18:27:40 +0100
committerIngo Molnar <mingo@elte.hu>2002-02-19 18:27:40 +0100
commit3a0b82c08a0e86683783c30d7fec9d1b06c2fe20 (patch)
tree0439ad16655bdfbec6dfdd0058e3ce6cdd25c766 /fs/proc/array.c
parent094686d30d5f58780a1efda2ade5cb0d18e25f82 (diff)
adds simple support for atomically-mapped PTEs. On highmem systems this enables the allocation of the pagetables in highmem.
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,