On Tue, 2015-11-10 at 09:55 +0200, Mika Kuoppala wrote: > ankitprasad.r.sharma@xxxxxxxxx writes: > > > From: Ankitprasad Sharma <ankitprasad.r.sharma@xxxxxxxxx> > > > > In pwrite_fast, map an object page by page if obj_ggtt_pin fails. First, > > we try a nonblocking pin for the whole object (since that is fastest if > > reused), then failing that we try to grab one page in the mappable > > aperture. It also allows us to handle objects larger than the mappable > > aperture (e.g. if we need to pwrite with vGPU restricting the aperture > > to a measely 8MiB or something like that). > > > > v2: Pin pages before starting pwrite, Combined duplicate loops (Chris) > > > > v3: Combined loops based on local patch by Chris (Chris) > > > > Signed-off-by: Ankitprasad Sharma <ankitprasad.r.sharma@xxxxxxxxx> > > Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > > --- > > drivers/gpu/drm/i915/i915_gem.c | 75 +++++++++++++++++++++++++++++------------ > > 1 file changed, 53 insertions(+), 22 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c > > index f1e3fde..9d2e6e3 100644 > > --- a/drivers/gpu/drm/i915/i915_gem.c > > +++ b/drivers/gpu/drm/i915/i915_gem.c > > @@ -760,20 +760,33 @@ fast_user_write(struct io_mapping *mapping, > > * user into the GTT, uncached. > > */ > > static int > > -i915_gem_gtt_pwrite_fast(struct drm_device *dev, > > +i915_gem_gtt_pwrite_fast(struct drm_i915_private *i915, > > struct drm_i915_gem_object *obj, > > struct drm_i915_gem_pwrite *args, > > struct drm_file *file) > > { > > - struct drm_i915_private *dev_priv = dev->dev_private; > > - ssize_t remain; > > - loff_t offset, page_base; > > + struct drm_mm_node node; > > + uint64_t remain, offset; > > char __user *user_data; > > - int page_offset, page_length, ret; > > + int ret; > > > > ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_MAPPABLE | PIN_NONBLOCK); > > - if (ret) > > - goto out; > > + if (ret) { > > + memset(&node, 0, sizeof(node)); > > + ret = drm_mm_insert_node_in_range_generic(&i915->gtt.base.mm, > > + &node, 4096, 0, > > + I915_CACHE_NONE, 0, > > + i915->gtt.mappable_end, > > + DRM_MM_SEARCH_DEFAULT, > > + DRM_MM_CREATE_DEFAULT); > > + if (ret) > > + goto out; > > + > > + i915_gem_object_pin_pages(obj); > > + } else { > > + node.start = i915_gem_obj_ggtt_offset(obj); > > + node.allocated = false; > > + } > > > > ret = i915_gem_object_set_to_gtt_domain(obj, true); > > if (ret) > > @@ -783,31 +796,39 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, > > if (ret) > > goto out_unpin; > > > > - user_data = to_user_ptr(args->data_ptr); > > - remain = args->size; > > - > > - offset = i915_gem_obj_ggtt_offset(obj) + args->offset; > > - > > intel_fb_obj_invalidate(obj, ORIGIN_GTT); > > + obj->dirty = true; > > > > - while (remain > 0) { > > + user_data = to_user_ptr(args->data_ptr); > > + offset = args->offset; > > + remain = args->size; > > + while (remain) { > > /* Operation in this page > > * > > * page_base = page offset within aperture > > * page_offset = offset within page > > * page_length = bytes to copy for this page > > */ > > - page_base = offset & PAGE_MASK; > > - page_offset = offset_in_page(offset); > > - page_length = remain; > > - if ((page_offset + remain) > PAGE_SIZE) > > - page_length = PAGE_SIZE - page_offset; > > - > > + u32 page_base = node.start; > > You truncate here as node.start is 64bit offset into the vm area. > True, but it will work here always as node.start is going to be less than 256 MB for both the cases (whole object pin or page by page pwrite) Thanks, Ankit _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx