public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* mincore on anon mappings
@ 2004-06-19 16:25 Andrea Arcangeli
  2004-06-19 18:54 ` David S. Miller
  2004-06-19 21:55 ` William Lee Irwin III
  0 siblings, 2 replies; 5+ messages in thread
From: Andrea Arcangeli @ 2004-06-19 16:25 UTC (permalink / raw)
  To: David S. Miller; +Cc: linux-kernel

Hi David,

here a first (untested) attempt to allow mincore on anon vmas too.

I heard you need this from gcc, right?

(btw, returning -ENOMEM for anon vmas was pretty bogus, -EINVAL or
even -ENOSYS would been more correct)

--- sles/mm/mincore.c.~1~	2004-02-04 16:07:06.000000000 +0100
+++ sles/mm/mincore.c	2004-06-15 00:42:52.122127224 +0200
@@ -11,6 +11,8 @@
 #include <linux/pagemap.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
+#include <linux/swap.h>
+#include <linux/swapops.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -22,7 +24,7 @@
  * and is up to date; i.e. that no page-in operation would be required
  * at this time if an application were to map and access this page.
  */
-static unsigned char mincore_page(struct vm_area_struct * vma,
+static unsigned char mincore_page_inode(struct vm_area_struct * vma,
 	unsigned long pgoff)
 {
 	unsigned char present = 0;
@@ -38,16 +40,74 @@ static unsigned char mincore_page(struct
 	return present;
 }
 
+/*
+ * Careful this only works with anon-vma for the vma->vm_pgoff settings.
+ */
+static unsigned char mincore_page_anon(struct vm_area_struct * vma,
+				       unsigned long pgoff)
+{
+	unsigned char present = 0;
+	struct page * page;
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *ptep, pte;
+	unsigned long address;
+
+	address = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
+	BUG_ON(address < vma->vm_start || address >= vma->vm_end);
+
+	spin_lock(&mm->page_table_lock);
+
+	pgd = pgd_offset(mm, address);
+	if (!pgd_present(*pgd))
+		goto out_unlock;
+
+	pmd = pmd_offset(pgd, address);
+	if (!pmd_present(*pmd))
+		goto out_unlock;
+
+	ptep = pte_offset_map(pmd, address);
+	pte = *ptep;
+	pte_unmap(ptep);
+
+	spin_unlock(&mm->page_table_lock);
+
+	if (pte_none(pte))
+		goto out;
+	if (!pte_present(pte)) {
+		swp_entry_t entry = pte_to_swp_entry(pte);
+		page = lookup_swap_cache(entry);
+		if (page) {
+			present = PageUptodate(page);
+			page_cache_release(page);
+		}
+	} else
+		present = 1;
+
+ out:
+	return present;
+
+ out_unlock:
+	spin_unlock(&mm->page_table_lock);
+	goto out;
+}
+
+static unsigned char mincore_page(struct vm_area_struct * vma,
+				  unsigned long pgoff)
+{
+	if (vma->vm_file)
+		return mincore_page_inode(vma, pgoff);
+	else
+		return mincore_page_anon(vma, pgoff);
+}
+
 static long mincore_vma(struct vm_area_struct * vma,
 	unsigned long start, unsigned long end, unsigned char __user * vec)
 {
 	long error, i, remaining;
 	unsigned char * tmp;
 
-	error = -ENOMEM;
-	if (!vma->vm_file)
-		return error;
-
 	start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
 	if (end > vma->vm_end)
 		end = vma->vm_end;

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2004-06-19 22:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <28R2T-8ld-13@gated-at.bofh.it>
     [not found] ` <28Tev-1Bm-23@gated-at.bofh.it>
2004-06-20  0:05   ` mincore on anon mappings Andi Kleen
2004-06-19 22:50     ` David S. Miller
2004-06-19 16:25 Andrea Arcangeli
2004-06-19 18:54 ` David S. Miller
2004-06-19 21:55 ` William Lee Irwin III

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox