Re: [patch 03/18] drm: nopage

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

Hi Nick,

can you rebase against the -mm tree? or are you pushing this for before 
then? if so can you supply me a patch against -mm?

The drm git tree has a new VM user for the memory manager..

Dave.

> 
> 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
> @@ -66,7 +66,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.
> @@ -76,8 +76,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;
> @@ -89,19 +89,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;
> @@ -123,7 +128,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
> @@ -131,27 +136,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.
> @@ -160,28 +166,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;
>  }
>  
>  /**
> @@ -263,7 +268,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.
> @@ -271,8 +276,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;
> @@ -282,24 +287,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.
> @@ -307,8 +311,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;
> @@ -320,77 +324,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,
>  };
> @@ -603,7 +594,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;
> @@ -633,7 +624,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))
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux