All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.