[PATCH 03/24] drm/i915: Pin backing pages for pwrite

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

 



On Tue,  4 Sep 2012 21:02:55 +0100
Chris Wilson <chris at chris-wilson.co.uk> wrote:

> By using the recently introduced pinning of pages, we can safely drop
> the mutex in the knowledge that the pages are not going to disappear
> beneath us, and so we can simplify the code for iterating over the pages.
> 
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/i915_gem.c |   37 +++++++++++++------------------------
>  1 file changed, 13 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index aa088ef..8a4eac0 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -690,7 +690,7 @@ shmem_pwrite_fast(struct page *page, int shmem_page_offset, int page_length,
>  				       page_length);
>  	kunmap_atomic(vaddr);
>  
> -	return ret;
> +	return ret ? -EFAULT : 0;
>  }
>  
>  /* Only difference to the fast-path function is that this can handle bit17
> @@ -724,7 +724,7 @@ shmem_pwrite_slow(struct page *page, int shmem_page_offset, int page_length,
>  					     page_do_bit17_swizzling);
>  	kunmap(page);
>  
> -	return ret;
> +	return ret ? -EFAULT : 0;
>  }
>  
>  static int
> @@ -733,7 +733,6 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
>  		      struct drm_i915_gem_pwrite *args,
>  		      struct drm_file *file)
>  {
> -	struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
>  	ssize_t remain;
>  	loff_t offset;
>  	char __user *user_data;
> @@ -742,7 +741,6 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
>  	int hit_slowpath = 0;
>  	int needs_clflush_after = 0;
>  	int needs_clflush_before = 0;
> -	int release_page;
>  
>  	user_data = (char __user *) (uintptr_t) args->data_ptr;
>  	remain = args->size;
> @@ -768,6 +766,12 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
>  	    && obj->cache_level == I915_CACHE_NONE)
>  		needs_clflush_before = 1;
>  
> +	ret = i915_gem_object_get_pages(obj);
> +	if (ret)
> +		return ret;
> +
> +	i915_gem_object_pin_pages(obj);
> +
>  	offset = args->offset;
>  	obj->dirty = 1;
>  
> @@ -793,18 +797,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
>  			((shmem_page_offset | page_length)
>  				& (boot_cpu_data.x86_clflush_size - 1));
>  
> -		if (obj->pages) {
> -			page = obj->pages[offset >> PAGE_SHIFT];
> -			release_page = 0;
> -		} else {
> -			page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
> -			if (IS_ERR(page)) {
> -				ret = PTR_ERR(page);
> -				goto out;
> -			}
> -			release_page = 1;
> -		}
> -
> +		page = obj->pages[offset >> PAGE_SHIFT];
>  		page_do_bit17_swizzling = obj_do_bit17_swizzling &&
>  			(page_to_phys(page) & (1 << 17)) != 0;
>  
> @@ -816,26 +809,20 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
>  			goto next_page;
>  
>  		hit_slowpath = 1;
> -		page_cache_get(page);
>  		mutex_unlock(&dev->struct_mutex);
> -
>  		ret = shmem_pwrite_slow(page, shmem_page_offset, page_length,
>  					user_data, page_do_bit17_swizzling,
>  					partial_cacheline_write,
>  					needs_clflush_after);
>  
>  		mutex_lock(&dev->struct_mutex);
> -		page_cache_release(page);
> +
>  next_page:
>  		set_page_dirty(page);
>  		mark_page_accessed(page);
> -		if (release_page)
> -			page_cache_release(page);
>  
> -		if (ret) {
> -			ret = -EFAULT;
> +		if (ret)
>  			goto out;
> -		}
>  
>  		remain -= page_length;
>  		user_data += page_length;
> @@ -843,6 +830,8 @@ next_page:
>  	}
>  
>  out:
> +	i915_gem_object_unpin_pages(obj);
> +
>  	if (hit_slowpath) {
>  		/* Fixup: Kill any reinstated backing storage pages */
>  		if (obj->madv == __I915_MADV_PURGED)

I'll leave the pread/pwrite reviewing to Daniel...

-- 
Jesse Barnes, Intel Open Source Technology Center


[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux