@@ -327,6 +327,42 @@ __copy_from_user_swizzled(char *gpu_vaddr, int gpu_offset,
327327 return 0 ;
328328}
329329
330+ /*
331+ * Pins the specified object's pages and synchronizes the object with
332+ * GPU accesses. Sets needs_clflush to non-zero if the caller should
333+ * flush the object from the CPU cache.
334+ */
335+ int i915_gem_obj_prepare_shmem_read (struct drm_i915_gem_object * obj ,
336+ int * needs_clflush )
337+ {
338+ int ret ;
339+
340+ * needs_clflush = 0 ;
341+
342+ if (!obj -> base .filp )
343+ return - EINVAL ;
344+
345+ if (!(obj -> base .read_domains & I915_GEM_DOMAIN_CPU )) {
346+ /* If we're not in the cpu read domain, set ourself into the gtt
347+ * read domain and manually flush cachelines (if required). This
348+ * optimizes for the case when the gpu will dirty the data
349+ * anyway again before the next pread happens. */
350+ * needs_clflush = !cpu_cache_is_coherent (obj -> base .dev ,
351+ obj -> cache_level );
352+ ret = i915_gem_object_wait_rendering (obj , true);
353+ if (ret )
354+ return ret ;
355+ }
356+
357+ ret = i915_gem_object_get_pages (obj );
358+ if (ret )
359+ return ret ;
360+
361+ i915_gem_object_pin_pages (obj );
362+
363+ return ret ;
364+ }
365+
330366/* Per-page copy function for the shmem pread fastpath.
331367 * Flushes invalid cachelines before reading the target if
332368 * needs_clflush is set. */
@@ -424,23 +460,10 @@ i915_gem_shmem_pread(struct drm_device *dev,
424460
425461 obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle (obj );
426462
427- if (!(obj -> base .read_domains & I915_GEM_DOMAIN_CPU )) {
428- /* If we're not in the cpu read domain, set ourself into the gtt
429- * read domain and manually flush cachelines (if required). This
430- * optimizes for the case when the gpu will dirty the data
431- * anyway again before the next pread happens. */
432- needs_clflush = !cpu_cache_is_coherent (dev , obj -> cache_level );
433- ret = i915_gem_object_wait_rendering (obj , true);
434- if (ret )
435- return ret ;
436- }
437-
438- ret = i915_gem_object_get_pages (obj );
463+ ret = i915_gem_obj_prepare_shmem_read (obj , & needs_clflush );
439464 if (ret )
440465 return ret ;
441466
442- i915_gem_object_pin_pages (obj );
443-
444467 offset = args -> offset ;
445468
446469 for_each_sg_page (obj -> pages -> sgl , & sg_iter , obj -> pages -> nents ,
0 commit comments