public inbox for linux-ia64@vger.kernel.org
 help / color / mirror / Atom feed
From: Jes Sorensen <jes@sgi.com>
To: Andrew Morton <akpm@osdl.org>
Cc: torvalds@osdl.org, linux-kernel@vger.kernel.org,
	linux-ia64@vger.kernel.org, hch@lst.de, cotte@de.ibm.com,
	Hugh Dickins <hugh@veritas.com>
Subject: [patch 1/2] do_no_pfn handler (was: Re: [patch] mspec - special memory driver and do_no_pfn handler)
Date: Fri, 17 Mar 2006 12:28:09 +0000	[thread overview]
Message-ID: <yq0fylhuug6.fsf_-_@jaguar.mkp.net> (raw)
In-Reply-To: <20060316163728.06f49c00.akpm@osdl.org>

>>>>> "Andrew" = Andrew Morton <akpm@osdl.org> writes:

Andrew> Jes Sorensen <jes@sgi.com> wrote:
>>  Hi,
>> 
>> This is an updated version of the mspec driver (special memory
>> support), formerly known as fetchop.
>> 
>> With this version I have implemented a do_no_pfn() handler, similar
>> to the do_no_page() handler but for pages which are not backed by a
>> struct page.

Andrew> hm.  Is that a superset of ->nopage?  Should we be looking at
Andrew> migrating over to ->nopfn, retire ->nopage?

Andrew> <looks at the ghastly stuff in do_no_page>

It wasn't designed to handle all possible cases as a do_no_page
replacement :) My initial thought was that adding an extra op to the
vm_operations_struct was that it wouldn't be very expensive since we
don't allocate all that many of them.

>> Please let me know if there are any objections or comments etc. to
>> this approach. If preferred I can split out the do_no_pfn part into
>> a seperate patch.

Andrew> That would probably be best.

Here goes - if Linus comes back with a suggestion for how to do it in
a different fashion it may obsolete this patch, but at least until
then.

The cleaned up version of the actual mspec driver will be in a
seperate mail.

Cheers,
Jes

Implement do_no_pfn() for handling mapping of memory without a struct
page backing it.

Signed-off-by: Jes Sorensen <jes@sgi.com>

---
 include/linux/mm.h |    1 +
 mm/memory.c        |   51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 51 insertions(+), 1 deletion(-)

Index: linux-2.6/include/linux/mm.h
=================================--- linux-2.6.orig/include/linux/mm.h
+++ linux-2.6/include/linux/mm.h
@@ -199,6 +199,7 @@
 	void (*open)(struct vm_area_struct * area);
 	void (*close)(struct vm_area_struct * area);
 	struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int *type);
+	long (*nopfn)(struct vm_area_struct * area, unsigned long address, int *type);
 	int (*populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int nonblock);
 #ifdef CONFIG_NUMA
 	int (*set_policy)(struct vm_area_struct *vma, struct mempolicy *new);
Index: linux-2.6/mm/memory.c
=================================--- linux-2.6.orig/mm/memory.c
+++ linux-2.6/mm/memory.c
@@ -2148,6 +2148,51 @@
 }
 
 /*
+ * do_no_pfn() tries to create a new page mapping for a page without
+ * a struct_page backing it
+ *
+ * As this is called only for pages that do not currently exist, we
+ * do not need to flush old virtual caches or the TLB.
+ *
+ * We enter with non-exclusive mmap_sem (to exclude vma changes,
+ * but allow concurrent faults), and pte mapped but not yet locked.
+ * We return with mmap_sem still held, but pte unmapped and unlocked.
+ *
+ * It is expected that the ->nopfn handler always returns the same pfn
+ * for a given virtual mapping.
+ */
+static int do_no_pfn(struct mm_struct *mm, struct vm_area_struct *vma,
+		     unsigned long address, pte_t *page_table, pmd_t *pmd,
+		     int write_access)
+{
+	spinlock_t *ptl;
+	pte_t entry;
+	long pfn;
+	int ret = VM_FAULT_MINOR;
+
+	pte_unmap(page_table);
+	BUG_ON(!(vma->vm_flags & VM_PFNMAP));
+
+	pfn = vma->vm_ops->nopfn(vma, address & PAGE_MASK, &ret);
+	if (pfn = -ENOMEM)
+		return VM_FAULT_OOM;
+	if (pfn = -EFAULT)
+		return VM_FAULT_SIGBUS;
+	if (pfn < 0)
+		return VM_FAULT_SIGBUS;
+
+	page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+
+	entry = pfn_pte(pfn, vma->vm_page_prot);
+	if (write_access)
+		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+	set_pte_at(mm, address, page_table, entry);
+
+	pte_unmap_unlock(page_table, ptl);
+	return ret;
+}
+
+/*
  * Fault of a previously existing named mapping. Repopulate the pte
  * from the encoded file_pte if possible. This enables swappable
  * nonlinear vmas.
@@ -2209,9 +2254,13 @@
 	old_entry = entry = *pte;
 	if (!pte_present(entry)) {
 		if (pte_none(entry)) {
-			if (!vma->vm_ops || !vma->vm_ops->nopage)
+			if (!vma->vm_ops ||
+			    (!vma->vm_ops->nopage && !vma->vm_ops->nopfn))
 				return do_anonymous_page(mm, vma, address,
 					pte, pmd, write_access);
+			if (vma->vm_ops->nopfn)
+				return do_no_pfn(mm, vma, address,
+						 pte, pmd, write_access);
 			return do_no_page(mm, vma, address,
 					pte, pmd, write_access);
 		}


  parent reply	other threads:[~2006-03-17 12:28 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-03-16 16:55 [patch] mspec - special memory driver and do_no_pfn handler Jes Sorensen
2006-03-17  0:37 ` Andrew Morton
2006-03-17  1:04   ` Linus Torvalds
2006-03-17  2:13     ` Robin Holt
2006-03-17  4:58     ` Benjamin Herrenschmidt
2006-03-17  9:15       ` Jes Sorensen
2006-03-17 13:29         ` Carsten Otte
2006-03-17 18:03           ` Christoph Hellwig
2006-03-17  9:42     ` Jes Sorensen
2006-03-17 12:29     ` Carsten Otte
2006-03-17 12:28   ` Jes Sorensen [this message]
2006-03-17 12:38   ` [patch 2/2] mspec driver (was: Re: [patch] mspec - special memory driver and do_no_pfn handler) Jes Sorensen
2006-03-17 13:36     ` [patch 2/2] mspec driver Nick Piggin
2006-03-17 14:04       ` Jes Sorensen
2006-03-17 14:09         ` Nick Piggin
2006-03-17 14:11           ` Jes Sorensen
2006-03-17 14:16             ` Nick Piggin
2006-03-17 13:51 ` [patch] mspec - special memory driver and do_no_pfn handler Carsten Otte
2006-03-17 13:53   ` Carsten Otte
2006-03-17 13:56   ` Nick Piggin
2006-03-17 13:58   ` Jes Sorensen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=yq0fylhuug6.fsf_-_@jaguar.mkp.net \
    --to=jes@sgi.com \
    --cc=akpm@osdl.org \
    --cc=cotte@de.ibm.com \
    --cc=hch@lst.de \
    --cc=hugh@veritas.com \
    --cc=linux-ia64@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox