2008-01-08 09:38:26

by Nick Piggin

[permalink] [raw]
Subject: [patch 1/3] drm: nopage

Dave, this patch is against 2.6.24-rc6-mm1. You said git-drm had rewritten this area,
but the patch didn't have any rejects and seems to run fine here (although I'm not
exactly sure how to exercise drm too well).

Anyway, please apply.

--

drm: nopage

Convert drm from nopage to fault.
Remove redundant vma range checks.

Signed-off-by: Nick Piggin <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
drivers/char/drm/drm_vm.c | 131 +++++++++++++++++++++-------------------------
1 file changed, 61 insertions(+), 70 deletions(-)

Index: linux-2.6/drivers/char/drm/drm_vm.c
===================================================================
--- linux-2.6.orig/drivers/char/drm/drm_vm.c
+++ linux-2.6/drivers/char/drm/drm_vm.c
@@ -70,7 +70,7 @@ static pgprot_t drm_io_prot(uint32_t map
}

/**
- * \c nopage method for AGP virtual memory.
+ * \c fault method for AGP virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
@@ -80,8 +80,8 @@ static pgprot_t drm_io_prot(uint32_t map
* map, get the page, increment the use count and return it.
*/
#if __OS_HAS_AGP
-static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static __inline__ int drm_do_vm_fault(struct vm_area_struct *vma,
+ struct vm_fault *vmf)
{
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->head->dev;
@@ -93,19 +93,24 @@ static __inline__ struct page *drm_do_vm
* Find the right map
*/
if (!drm_core_has_AGP(dev))
- goto vm_nopage_error;
+ goto vm_fault_error;

if (!dev->agp || !dev->agp->cant_use_aperture)
- goto vm_nopage_error;
+ goto vm_fault_error;

if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash))
- goto vm_nopage_error;
+ goto vm_fault_error;

r_list = drm_hash_entry(hash, struct drm_map_list, hash);
map = r_list->map;

if (map && map->type == _DRM_AGP) {
- unsigned long offset = address - vma->vm_start;
+ /*
+ * Using vm_pgoff as a selector forces us to use this unusual
+ * addressing scheme.
+ */
+ unsigned long offset = (unsigned long)vmf->virtual_address -
+ vma->vm_start;
unsigned long baddr = map->offset + offset;
struct drm_agp_mem *agpmem;
struct page *page;
@@ -127,7 +132,7 @@ static __inline__ struct page *drm_do_vm
}

if (!agpmem)
- goto vm_nopage_error;
+ goto vm_fault_error;

/*
* Get the page, inc the use count, and return it
@@ -135,27 +140,28 @@ static __inline__ struct page *drm_do_vm
offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
page = virt_to_page(__va(agpmem->memory->memory[offset]));
get_page(page);
+ vmf->page = page;

DRM_DEBUG
("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
baddr, __va(agpmem->memory->memory[offset]), offset,
page_count(page));

- return page;
+ return 0;
}
- vm_nopage_error:
- return NOPAGE_SIGBUS; /* Disallow mremap */
+ vm_fault_error:
+ return VM_FAULT_SIGBUS; /* Disallow mremap */
}
#else /* __OS_HAS_AGP */
-static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static __inline__ int drm_do_vm_fault(struct vm_area_struct *vma,
+ struct vm_fault *vmf)
{
- return NOPAGE_SIGBUS;
+ return VM_FAULT_SIGBUS;
}
#endif /* __OS_HAS_AGP */

/**
- * \c nopage method for shared virtual memory.
+ * \c fault method for shared virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
@@ -164,28 +170,27 @@ static __inline__ struct page *drm_do_vm
* Get the mapping, find the real physical page to map, get the page, and
* return it.
*/
-static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static __inline__ int drm_do_vm_shm_fault(struct vm_area_struct *vma,
+ struct vm_fault *vmf)
{
struct drm_map *map = (struct drm_map *) vma->vm_private_data;
unsigned long offset;
unsigned long i;
struct page *page;

- if (address > vma->vm_end)
- return NOPAGE_SIGBUS; /* Disallow mremap */
if (!map)
- return NOPAGE_SIGBUS; /* Nothing allocated */
+ return VM_FAULT_SIGBUS; /* Nothing allocated */

- offset = address - vma->vm_start;
+ offset = (unsigned long)vmf->virtual_address - vma->vm_start;
i = (unsigned long)map->handle + offset;
page = vmalloc_to_page((void *)i);
if (!page)
- return NOPAGE_SIGBUS;
+ return VM_FAULT_SIGBUS;
get_page(page);
+ vmf->page = page;

- DRM_DEBUG("shm_nopage 0x%lx\n", address);
- return page;
+ DRM_DEBUG("shm_fault 0x%lx\n", offset);
+ return 0;
}

/**
@@ -270,7 +275,7 @@ static void drm_vm_shm_close(struct vm_a
}

/**
- * \c nopage method for DMA virtual memory.
+ * \c fault method for DMA virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
@@ -278,8 +283,8 @@ static void drm_vm_shm_close(struct vm_a
*
* Determine the page number from the page offset and get it from drm_device_dma::pagelist.
*/
-static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static __inline__ int drm_do_vm_dma_fault(struct vm_area_struct *vma,
+ struct vm_fault *vmf)
{
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->head->dev;
@@ -289,24 +294,23 @@ static __inline__ struct page *drm_do_vm
struct page *page;

if (!dma)
- return NOPAGE_SIGBUS; /* Error */
- if (address > vma->vm_end)
- return NOPAGE_SIGBUS; /* Disallow mremap */
+ return VM_FAULT_SIGBUS; /* Error */
if (!dma->pagelist)
- return NOPAGE_SIGBUS; /* Nothing allocated */
+ return VM_FAULT_SIGBUS; /* Nothing allocated */

- offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
- page_nr = offset >> PAGE_SHIFT;
+ offset = (unsigned long)vmf->virtual_address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
+ page_nr = offset >> PAGE_SHIFT; /* page_nr could just be vmf->pgoff */
page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK))));

get_page(page);
+ vmf->page = page;

- DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr);
- return page;
+ DRM_DEBUG("dma_fault 0x%lx (page %lu)\n", offset, page_nr);
+ return 0;
}

/**
- * \c nopage method for scatter-gather virtual memory.
+ * \c fault method for scatter-gather virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
@@ -314,8 +318,8 @@ static __inline__ struct page *drm_do_vm
*
* Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
*/
-static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
- unsigned long address)
+static __inline__ int drm_do_vm_sg_fault(struct vm_area_struct *vma,
+ struct vm_fault *vmf)
{
struct drm_map *map = (struct drm_map *) vma->vm_private_data;
struct drm_file *priv = vma->vm_file->private_data;
@@ -327,77 +331,64 @@ static __inline__ struct page *drm_do_vm
struct page *page;

if (!entry)
- return NOPAGE_SIGBUS; /* Error */
- if (address > vma->vm_end)
- return NOPAGE_SIGBUS; /* Disallow mremap */
+ return VM_FAULT_SIGBUS; /* Error */
if (!entry->pagelist)
- return NOPAGE_SIGBUS; /* Nothing allocated */
+ return VM_FAULT_SIGBUS; /* Nothing allocated */

- offset = address - vma->vm_start;
+ offset = (unsigned long)vmf->virtual_address - vma->vm_start;
map_offset = map->offset - (unsigned long)dev->sg->virtual;
page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
page = entry->pagelist[page_offset];
get_page(page);
+ vmf->page = page;

- return page;
+ return 0;
}

-static struct page *drm_vm_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int drm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- if (type)
- *type = VM_FAULT_MINOR;
- return drm_do_vm_nopage(vma, address);
+ return drm_do_vm_fault(vma, vmf);
}

-static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int drm_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- if (type)
- *type = VM_FAULT_MINOR;
- return drm_do_vm_shm_nopage(vma, address);
+ return drm_do_vm_shm_fault(vma, vmf);
}

-static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int drm_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- if (type)
- *type = VM_FAULT_MINOR;
- return drm_do_vm_dma_nopage(vma, address);
+ return drm_do_vm_dma_fault(vma, vmf);
}

-static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
- unsigned long address, int *type)
+static int drm_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- if (type)
- *type = VM_FAULT_MINOR;
- return drm_do_vm_sg_nopage(vma, address);
+ return drm_do_vm_sg_fault(vma, vmf);
}

/** AGP virtual memory operations */
static struct vm_operations_struct drm_vm_ops = {
- .nopage = drm_vm_nopage,
+ .fault = drm_vm_fault,
.open = drm_vm_open,
.close = drm_vm_close,
};

/** Shared virtual memory operations */
static struct vm_operations_struct drm_vm_shm_ops = {
- .nopage = drm_vm_shm_nopage,
+ .fault = drm_vm_shm_fault,
.open = drm_vm_open,
.close = drm_vm_shm_close,
};

/** DMA virtual memory operations */
static struct vm_operations_struct drm_vm_dma_ops = {
- .nopage = drm_vm_dma_nopage,
+ .fault = drm_vm_dma_fault,
.open = drm_vm_open,
.close = drm_vm_close,
};

/** Scatter-gather virtual memory operations */
static struct vm_operations_struct drm_vm_sg_ops = {
- .nopage = drm_vm_sg_nopage,
+ .fault = drm_vm_sg_fault,
.open = drm_vm_open,
.close = drm_vm_close,
};
@@ -610,7 +601,7 @@ static int drm_mmap_locked(struct file *
/*
* On some platforms we can't talk to bus dma address from the CPU, so for
* memory of type DRM_AGP, we'll deal with sorting out the real physical
- * pages and mappings in nopage()
+ * pages and mappings in fault()
*/
#if defined(__powerpc__)
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
@@ -640,7 +631,7 @@ static int drm_mmap_locked(struct file *
break;
case _DRM_CONSISTENT:
/* Consistent memory is really like shared memory. But
- * it's allocated in a different way, so avoid nopage */
+ * it's allocated in a different way, so avoid fault */
if (remap_pfn_range(vma, vma->vm_start,
page_to_pfn(virt_to_page(map->handle)),
vma->vm_end - vma->vm_start, vma->vm_page_prot))


2008-01-08 09:41:18

by Nick Piggin

[permalink] [raw]
Subject: [patch 3/3] mm: remove nopage

Patch against 2.6.24-rc6-mm1... nothing in your tree appears to use nopage.
This patch should transfer without rejects upstream, so it shouldn't be too
difficult.

Would be nice to get in 2.6.25 if we can.

---

mm: remove nopage

Nothing in the tree uses nopage any more. Remove support for it in the
core mm code and documentation (and a few stray references to it in comments).

Signed-off-by: Nick Piggin <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
Documentation/feature-removal-schedule.txt | 9 --------
Documentation/filesystems/Locking | 3 --
drivers/media/video/vino.c | 2 -
drivers/video/vermilion/vermilion.c | 5 ++--
include/linux/mm.h | 8 -------
mm/memory.c | 32 ++++++++++-------------------
mm/mincore.c | 2 -
mm/mmap.c | 20 +++++++++---------
mm/rmap.c | 1
9 files changed, 27 insertions(+), 55 deletions(-)

Index: linux-2.6/include/linux/mm.h
===================================================================
--- linux-2.6.orig/include/linux/mm.h
+++ linux-2.6/include/linux/mm.h
@@ -166,8 +166,6 @@ struct vm_operations_struct {
void (*open)(struct vm_area_struct * area);
void (*close)(struct vm_area_struct * area);
int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);
- struct page *(*nopage)(struct vm_area_struct *area,
- unsigned long address, int *type);
unsigned long (*nopfn)(struct vm_area_struct *area,
unsigned long address);

@@ -642,12 +640,6 @@ static inline int page_mapped(struct pag
}

/*
- * Error return values for the *_nopage functions
- */
-#define NOPAGE_SIGBUS (NULL)
-#define NOPAGE_OOM ((struct page *) (-1))
-
-/*
* Error return values for the *_nopfn functions
*/
#define NOPFN_SIGBUS ((unsigned long) -1)
Index: linux-2.6/mm/memory.c
===================================================================
--- linux-2.6.orig/mm/memory.c
+++ linux-2.6/mm/memory.c
@@ -1042,8 +1042,7 @@ int get_user_pages(struct task_struct *t
if (pages)
foll_flags |= FOLL_GET;
if (!write && !(vma->vm_flags & VM_LOCKED) &&
- (!vma->vm_ops || (!vma->vm_ops->nopage &&
- !vma->vm_ops->fault)))
+ (!vma->vm_ops || !vma->vm_ops->fault))
foll_flags |= FOLL_ANON;

do {
@@ -2184,20 +2183,9 @@ static int __do_fault(struct mm_struct *

BUG_ON(vma->vm_flags & VM_PFNMAP);

- if (likely(vma->vm_ops->fault)) {
- ret = vma->vm_ops->fault(vma, &vmf);
- if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))
- return ret;
- } else {
- /* Legacy ->nopage path */
- ret = 0;
- vmf.page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret);
- /* no page was available -- either SIGBUS or OOM */
- if (unlikely(vmf.page == NOPAGE_SIGBUS))
- return VM_FAULT_SIGBUS;
- else if (unlikely(vmf.page == NOPAGE_OOM))
- return VM_FAULT_OOM;
- }
+ ret = vma->vm_ops->fault(vma, &vmf);
+ if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))
+ return ret;

/*
* For consistency in subsequent calls, make the faulted page always
@@ -2443,7 +2431,7 @@ static inline int handle_pte_fault(struc
if (!pte_present(entry)) {
if (pte_none(entry)) {
if (vma->vm_ops) {
- if (vma->vm_ops->fault || vma->vm_ops->nopage)
+ if (likely(vma->vm_ops->fault))
return do_linear_fault(mm, vma, address,
pte, pmd, write_access, entry);
if (unlikely(vma->vm_ops->nopfn))
Index: linux-2.6/mm/mincore.c
===================================================================
--- linux-2.6.orig/mm/mincore.c
+++ linux-2.6/mm/mincore.c
@@ -33,7 +33,7 @@ static unsigned char mincore_page(struct
* When tmpfs swaps out a page from a file, any process mapping that
* file will not get a swp_entry_t in its pte, but rather it is like
* any other file mapping (ie. marked !present and faulted in with
- * tmpfs's .nopage). So swapped out tmpfs mappings are tested here.
+ * tmpfs's .fault). So swapped out tmpfs mappings are tested here.
*
* However when tmpfs moves the page from pagecache and into swapcache,
* it is still in core, but the find_get_page below won't find it.
Index: linux-2.6/Documentation/feature-removal-schedule.txt
===================================================================
--- linux-2.6.orig/Documentation/feature-removal-schedule.txt
+++ linux-2.6/Documentation/feature-removal-schedule.txt
@@ -155,15 +155,6 @@ Who: Greg Kroah-Hartman <[email protected]>

---------------------------

-What: vm_ops.nopage
-When: Soon, provided in-kernel callers have been converted
-Why: This interface is replaced by vm_ops.fault, but it has been around
- forever, is used by a lot of drivers, and doesn't cost much to
- maintain.
-Who: Nick Piggin <[email protected]>
-
----------------------------
-
What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment
When: October 2008
Why: The stacking of class devices makes these values misleading and
Index: linux-2.6/Documentation/filesystems/Locking
===================================================================
--- linux-2.6.orig/Documentation/filesystems/Locking
+++ linux-2.6/Documentation/filesystems/Locking
@@ -511,7 +511,6 @@ prototypes:
void (*open)(struct vm_area_struct*);
void (*close)(struct vm_area_struct*);
int (*fault)(struct vm_area_struct*, struct vm_fault *);
- struct page *(*nopage)(struct vm_area_struct*, unsigned long, int *);
int (*page_mkwrite)(struct vm_area_struct *, struct page *);

locking rules:
@@ -519,7 +518,6 @@ locking rules:
open: no yes
close: no yes
fault: no yes
-nopage: no yes
page_mkwrite: no yes no

->page_mkwrite() is called when a previously read-only page is
@@ -537,4 +535,3 @@ NULL.

ipc/shm.c::shm_delete() - may need BKL.
->read() and ->write() in many drivers are (probably) missing BKL.
-drivers/sgi/char/graphics.c::sgi_graphics_nopage() - may need BKL.
Index: linux-2.6/mm/rmap.c
===================================================================
--- linux-2.6.orig/mm/rmap.c
+++ linux-2.6/mm/rmap.c
@@ -655,7 +655,6 @@ void page_remove_rmap(struct page *page,
printk (KERN_EMERG " page->mapping = %p\n", page->mapping);
print_symbol (KERN_EMERG " vma->vm_ops = %s\n", (unsigned long)vma->vm_ops);
if (vma->vm_ops) {
- print_symbol (KERN_EMERG " vma->vm_ops->nopage = %s\n", (unsigned long)vma->vm_ops->nopage);
print_symbol (KERN_EMERG " vma->vm_ops->fault = %s\n", (unsigned long)vma->vm_ops->fault);
}
if (vma->vm_file && vma->vm_file->f_op)
Index: linux-2.6/drivers/media/video/vino.c
===================================================================
--- linux-2.6.orig/drivers/media/video/vino.c
+++ linux-2.6/drivers/media/video/vino.c
@@ -13,7 +13,7 @@
/*
* TODO:
* - remove "mark pages reserved-hacks" from memory allocation code
- * and implement nopage()
+ * and implement fault()
* - check decimation, calculating and reporting image size when
* using decimation
* - implement read(), user mode buffers and overlay (?)
Index: linux-2.6/drivers/video/vermilion/vermilion.c
===================================================================
--- linux-2.6.orig/drivers/video/vermilion/vermilion.c
+++ linux-2.6/drivers/video/vermilion/vermilion.c
@@ -114,8 +114,9 @@ static int vmlfb_alloc_vram_area(struct

/*
* It seems like __get_free_pages only ups the usage count
- * of the first page. This doesn't work with nopage mapping, so
- * up the usage count once more.
+ * of the first page. This doesn't work with fault mapping, so
+ * up the usage count once more (XXX: should use split_page or
+ * compound page).
*/

memset((void *)va->logical, 0x00, va->size);
Index: linux-2.6/fs/gfs2/ops_address.c
===================================================================
--- linux-2.6.orig/fs/gfs2/ops_address.c
+++ linux-2.6/fs/gfs2/ops_address.c
@@ -441,7 +441,7 @@ static int stuffed_readpage(struct gfs2_
int error;

/*
- * Due to the order of unstuffing files and ->nopage(), we can be
+ * Due to the order of unstuffing files and ->fault(), we can be
* asked for a zero page in the case of a stuffed file being extended,
* so we need to supply one here. It doesn't happen often.
*/

2008-01-08 22:25:33

by Dave Airlie

[permalink] [raw]
Subject: Re: [patch 1/3] drm: nopage



> Dave, this patch is against 2.6.24-rc6-mm1. You said git-drm had rewritten this area,
> but the patch didn't have any rejects and seems to run fine here (although I'm not
> exactly sure how to exercise drm too well).

Hi Nick,

there should be a new nopage method added though which you need to
convert..

Dave.

>
> Anyway, please apply.
>
> --
>
> drm: nopage
>
> Convert drm from nopage to fault.
> Remove redundant vma range checks.
>
> Signed-off-by: Nick Piggin <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/char/drm/drm_vm.c | 131 +++++++++++++++++++++-------------------------
> 1 file changed, 61 insertions(+), 70 deletions(-)
>
> Index: linux-2.6/drivers/char/drm/drm_vm.c
> ===================================================================
> --- linux-2.6.orig/drivers/char/drm/drm_vm.c
> +++ linux-2.6/drivers/char/drm/drm_vm.c
> @@ -70,7 +70,7 @@ static pgprot_t drm_io_prot(uint32_t map
> }
>
> /**
> - * \c nopage method for AGP virtual memory.
> + * \c fault method for AGP virtual memory.
> *
> * \param vma virtual memory area.
> * \param address access address.
> @@ -80,8 +80,8 @@ static pgprot_t drm_io_prot(uint32_t map
> * map, get the page, increment the use count and return it.
> */
> #if __OS_HAS_AGP
> -static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
> - unsigned long address)
> +static __inline__ int drm_do_vm_fault(struct vm_area_struct *vma,
> + struct vm_fault *vmf)
> {
> struct drm_file *priv = vma->vm_file->private_data;
> struct drm_device *dev = priv->head->dev;
> @@ -93,19 +93,24 @@ static __inline__ struct page *drm_do_vm
> * Find the right map
> */
> if (!drm_core_has_AGP(dev))
> - goto vm_nopage_error;
> + goto vm_fault_error;
>
> if (!dev->agp || !dev->agp->cant_use_aperture)
> - goto vm_nopage_error;
> + goto vm_fault_error;
>
> if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash))
> - goto vm_nopage_error;
> + goto vm_fault_error;
>
> r_list = drm_hash_entry(hash, struct drm_map_list, hash);
> map = r_list->map;
>
> if (map && map->type == _DRM_AGP) {
> - unsigned long offset = address - vma->vm_start;
> + /*
> + * Using vm_pgoff as a selector forces us to use this unusual
> + * addressing scheme.
> + */
> + unsigned long offset = (unsigned long)vmf->virtual_address -
> + vma->vm_start;
> unsigned long baddr = map->offset + offset;
> struct drm_agp_mem *agpmem;
> struct page *page;
> @@ -127,7 +132,7 @@ static __inline__ struct page *drm_do_vm
> }
>
> if (!agpmem)
> - goto vm_nopage_error;
> + goto vm_fault_error;
>
> /*
> * Get the page, inc the use count, and return it
> @@ -135,27 +140,28 @@ static __inline__ struct page *drm_do_vm
> offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
> page = virt_to_page(__va(agpmem->memory->memory[offset]));
> get_page(page);
> + vmf->page = page;
>
> DRM_DEBUG
> ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
> baddr, __va(agpmem->memory->memory[offset]), offset,
> page_count(page));
>
> - return page;
> + return 0;
> }
> - vm_nopage_error:
> - return NOPAGE_SIGBUS; /* Disallow mremap */
> + vm_fault_error:
> + return VM_FAULT_SIGBUS; /* Disallow mremap */
> }
> #else /* __OS_HAS_AGP */
> -static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
> - unsigned long address)
> +static __inline__ int drm_do_vm_fault(struct vm_area_struct *vma,
> + struct vm_fault *vmf)
> {
> - return NOPAGE_SIGBUS;
> + return VM_FAULT_SIGBUS;
> }
> #endif /* __OS_HAS_AGP */
>
> /**
> - * \c nopage method for shared virtual memory.
> + * \c fault method for shared virtual memory.
> *
> * \param vma virtual memory area.
> * \param address access address.
> @@ -164,28 +170,27 @@ static __inline__ struct page *drm_do_vm
> * Get the mapping, find the real physical page to map, get the page, and
> * return it.
> */
> -static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
> - unsigned long address)
> +static __inline__ int drm_do_vm_shm_fault(struct vm_area_struct *vma,
> + struct vm_fault *vmf)
> {
> struct drm_map *map = (struct drm_map *) vma->vm_private_data;
> unsigned long offset;
> unsigned long i;
> struct page *page;
>
> - if (address > vma->vm_end)
> - return NOPAGE_SIGBUS; /* Disallow mremap */
> if (!map)
> - return NOPAGE_SIGBUS; /* Nothing allocated */
> + return VM_FAULT_SIGBUS; /* Nothing allocated */
>
> - offset = address - vma->vm_start;
> + offset = (unsigned long)vmf->virtual_address - vma->vm_start;
> i = (unsigned long)map->handle + offset;
> page = vmalloc_to_page((void *)i);
> if (!page)
> - return NOPAGE_SIGBUS;
> + return VM_FAULT_SIGBUS;
> get_page(page);
> + vmf->page = page;
>
> - DRM_DEBUG("shm_nopage 0x%lx\n", address);
> - return page;
> + DRM_DEBUG("shm_fault 0x%lx\n", offset);
> + return 0;
> }
>
> /**
> @@ -270,7 +275,7 @@ static void drm_vm_shm_close(struct vm_a
> }
>
> /**
> - * \c nopage method for DMA virtual memory.
> + * \c fault method for DMA virtual memory.
> *
> * \param vma virtual memory area.
> * \param address access address.
> @@ -278,8 +283,8 @@ static void drm_vm_shm_close(struct vm_a
> *
> * Determine the page number from the page offset and get it from drm_device_dma::pagelist.
> */
> -static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
> - unsigned long address)
> +static __inline__ int drm_do_vm_dma_fault(struct vm_area_struct *vma,
> + struct vm_fault *vmf)
> {
> struct drm_file *priv = vma->vm_file->private_data;
> struct drm_device *dev = priv->head->dev;
> @@ -289,24 +294,23 @@ static __inline__ struct page *drm_do_vm
> struct page *page;
>
> if (!dma)
> - return NOPAGE_SIGBUS; /* Error */
> - if (address > vma->vm_end)
> - return NOPAGE_SIGBUS; /* Disallow mremap */
> + return VM_FAULT_SIGBUS; /* Error */
> if (!dma->pagelist)
> - return NOPAGE_SIGBUS; /* Nothing allocated */
> + return VM_FAULT_SIGBUS; /* Nothing allocated */
>
> - offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
> - page_nr = offset >> PAGE_SHIFT;
> + offset = (unsigned long)vmf->virtual_address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
> + page_nr = offset >> PAGE_SHIFT; /* page_nr could just be vmf->pgoff */
> page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK))));
>
> get_page(page);
> + vmf->page = page;
>
> - DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr);
> - return page;
> + DRM_DEBUG("dma_fault 0x%lx (page %lu)\n", offset, page_nr);
> + return 0;
> }
>
> /**
> - * \c nopage method for scatter-gather virtual memory.
> + * \c fault method for scatter-gather virtual memory.
> *
> * \param vma virtual memory area.
> * \param address access address.
> @@ -314,8 +318,8 @@ static __inline__ struct page *drm_do_vm
> *
> * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
> */
> -static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
> - unsigned long address)
> +static __inline__ int drm_do_vm_sg_fault(struct vm_area_struct *vma,
> + struct vm_fault *vmf)
> {
> struct drm_map *map = (struct drm_map *) vma->vm_private_data;
> struct drm_file *priv = vma->vm_file->private_data;
> @@ -327,77 +331,64 @@ static __inline__ struct page *drm_do_vm
> struct page *page;
>
> if (!entry)
> - return NOPAGE_SIGBUS; /* Error */
> - if (address > vma->vm_end)
> - return NOPAGE_SIGBUS; /* Disallow mremap */
> + return VM_FAULT_SIGBUS; /* Error */
> if (!entry->pagelist)
> - return NOPAGE_SIGBUS; /* Nothing allocated */
> + return VM_FAULT_SIGBUS; /* Nothing allocated */
>
> - offset = address - vma->vm_start;
> + offset = (unsigned long)vmf->virtual_address - vma->vm_start;
> map_offset = map->offset - (unsigned long)dev->sg->virtual;
> page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
> page = entry->pagelist[page_offset];
> get_page(page);
> + vmf->page = page;
>
> - return page;
> + return 0;
> }
>
> -static struct page *drm_vm_nopage(struct vm_area_struct *vma,
> - unsigned long address, int *type)
> +static int drm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
> {
> - if (type)
> - *type = VM_FAULT_MINOR;
> - return drm_do_vm_nopage(vma, address);
> + return drm_do_vm_fault(vma, vmf);
> }
>
> -static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
> - unsigned long address, int *type)
> +static int drm_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
> {
> - if (type)
> - *type = VM_FAULT_MINOR;
> - return drm_do_vm_shm_nopage(vma, address);
> + return drm_do_vm_shm_fault(vma, vmf);
> }
>
> -static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
> - unsigned long address, int *type)
> +static int drm_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
> {
> - if (type)
> - *type = VM_FAULT_MINOR;
> - return drm_do_vm_dma_nopage(vma, address);
> + return drm_do_vm_dma_fault(vma, vmf);
> }
>
> -static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
> - unsigned long address, int *type)
> +static int drm_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
> {
> - if (type)
> - *type = VM_FAULT_MINOR;
> - return drm_do_vm_sg_nopage(vma, address);
> + return drm_do_vm_sg_fault(vma, vmf);
> }
>
> /** AGP virtual memory operations */
> static struct vm_operations_struct drm_vm_ops = {
> - .nopage = drm_vm_nopage,
> + .fault = drm_vm_fault,
> .open = drm_vm_open,
> .close = drm_vm_close,
> };
>
> /** Shared virtual memory operations */
> static struct vm_operations_struct drm_vm_shm_ops = {
> - .nopage = drm_vm_shm_nopage,
> + .fault = drm_vm_shm_fault,
> .open = drm_vm_open,
> .close = drm_vm_shm_close,
> };
>
> /** DMA virtual memory operations */
> static struct vm_operations_struct drm_vm_dma_ops = {
> - .nopage = drm_vm_dma_nopage,
> + .fault = drm_vm_dma_fault,
> .open = drm_vm_open,
> .close = drm_vm_close,
> };
>
> /** Scatter-gather virtual memory operations */
> static struct vm_operations_struct drm_vm_sg_ops = {
> - .nopage = drm_vm_sg_nopage,
> + .fault = drm_vm_sg_fault,
> .open = drm_vm_open,
> .close = drm_vm_close,
> };
> @@ -610,7 +601,7 @@ static int drm_mmap_locked(struct file *
> /*
> * On some platforms we can't talk to bus dma address from the CPU, so for
> * memory of type DRM_AGP, we'll deal with sorting out the real physical
> - * pages and mappings in nopage()
> + * pages and mappings in fault()
> */
> #if defined(__powerpc__)
> pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
> @@ -640,7 +631,7 @@ static int drm_mmap_locked(struct file *
> break;
> case _DRM_CONSISTENT:
> /* Consistent memory is really like shared memory. But
> - * it's allocated in a different way, so avoid nopage */
> + * it's allocated in a different way, so avoid fault */
> if (remap_pfn_range(vma, vma->vm_start,
> page_to_pfn(virt_to_page(map->handle)),
> vma->vm_end - vma->vm_start, vma->vm_page_prot))
>
>

2008-01-08 22:31:04

by Nick Piggin

[permalink] [raw]
Subject: Re: [patch 1/3] drm: nopage

On Tue, Jan 08, 2008 at 10:25:15PM +0000, Dave Airlie wrote:
>
>
> > Dave, this patch is against 2.6.24-rc6-mm1. You said git-drm had rewritten this area,
> > but the patch didn't have any rejects and seems to run fine here (although I'm not
> > exactly sure how to exercise drm too well).
>
> Hi Nick,
>
> there should be a new nopage method added though which you need to
> convert..

Well they're all gone.. ;)

There is a nopfn method which I converted in a subsequent patch I sent you.
Maybe that's what you mean?

Thanks,
Nick
>
> Dave.
>
> >
> > Anyway, please apply.
> >
> > --
> >
> > drm: nopage
> >
> > Convert drm from nopage to fault.
> > Remove redundant vma range checks.
> >
> > Signed-off-by: Nick Piggin <[email protected]>
> > Cc: [email protected]
> > Cc: [email protected]
> > ---

2008-01-08 22:33:50

by Dave Airlie

[permalink] [raw]
Subject: Re: [patch 1/3] drm: nopage

> Well they're all gone.. ;)
>
> There is a nopfn method which I converted in a subsequent patch I sent you.
> Maybe that's what you mean?
>

Ah thats what it was, we added a nopfn not a nopage..

Thanks,

Dave.

> Thanks,
> Nick
> >
> > Dave.
> >
> > >
> > > Anyway, please apply.
> > >
> > > --
> > >
> > > drm: nopage
> > >
> > > Convert drm from nopage to fault.
> > > Remove redundant vma range checks.
> > >
> > > Signed-off-by: Nick Piggin <[email protected]>
> > > Cc: [email protected]
> > > Cc: [email protected]
> > > ---
>
>