OSDN Git Service

drm/i915: Add I915_PARAM_MMAP_GTT_VERSION to advertise unlimited mmaps
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 25 Aug 2016 18:05:19 +0000 (19:05 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 26 Aug 2016 07:42:26 +0000 (08:42 +0100)
Now that we have working partial VMA and faulting support for all
objects, including fence support, advertise to userspace that it can
take advantage of unlimited GGTT mmaps.

v2: Make room in the kerneldoc for a more detailed explanation of the
limitations of the GTT mmap interface.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20160825180519.11341-1-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
include/uapi/drm/i915_drm.h

index 1d2230f..47fe072 100644 (file)
@@ -355,6 +355,13 @@ static int i915_getparam(struct drm_device *dev, void *data,
        case I915_PARAM_MIN_EU_IN_POOL:
                value = INTEL_INFO(dev)->min_eu_in_pool;
                break;
+       case I915_PARAM_MMAP_GTT_VERSION:
+               /* Though we've started our numbering from 1, and so class all
+                * earlier versions as 0, in effect their value is undefined as
+                * the ioctl will report EINVAL for the unknown param!
+                */
+               value = i915_gem_mmap_gtt_version();
+               break;
        default:
                DRM_DEBUG("Unknown parameter %d\n", param->param);
                return -EINVAL;
index 04b4fd6..9fdaf23 100644 (file)
@@ -3218,6 +3218,7 @@ int i915_gem_dumb_create(struct drm_file *file_priv,
                         struct drm_mode_create_dumb *args);
 int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev,
                      uint32_t handle, uint64_t *offset);
+int i915_gem_mmap_gtt_version(void);
 
 void i915_gem_track_fb(struct drm_i915_gem_object *old,
                       struct drm_i915_gem_object *new,
index 04607d4..d37b441 100644 (file)
@@ -1680,6 +1680,56 @@ static unsigned int tile_row_pages(struct drm_i915_gem_object *obj)
 }
 
 /**
+ * i915_gem_mmap_gtt_version - report the current feature set for GTT mmaps
+ *
+ * A history of the GTT mmap interface:
+ *
+ * 0 - Everything had to fit into the GTT. Both parties of a memcpy had to
+ *     aligned and suitable for fencing, and still fit into the available
+ *     mappable space left by the pinned display objects. A classic problem
+ *     we called the page-fault-of-doom where we would ping-pong between
+ *     two objects that could not fit inside the GTT and so the memcpy
+ *     would page one object in at the expense of the other between every
+ *     single byte.
+ *
+ * 1 - Objects can be any size, and have any compatible fencing (X Y, or none
+ *     as set via i915_gem_set_tiling() [DRM_I915_GEM_SET_TILING]). If the
+ *     object is too large for the available space (or simply too large
+ *     for the mappable aperture!), a view is created instead and faulted
+ *     into userspace. (This view is aligned and sized appropriately for
+ *     fenced access.)
+ *
+ * Restrictions:
+ *
+ *  * snoopable objects cannot be accessed via the GTT. It can cause machine
+ *    hangs on some architectures, corruption on others. An attempt to service
+ *    a GTT page fault from a snoopable object will generate a SIGBUS.
+ *
+ *  * the object must be able to fit into RAM (physical memory, though no
+ *    limited to the mappable aperture).
+ *
+ *
+ * Caveats:
+ *
+ *  * a new GTT page fault will synchronize rendering from the GPU and flush
+ *    all data to system memory. Subsequent access will not be synchronized.
+ *
+ *  * all mappings are revoked on runtime device suspend.
+ *
+ *  * there are only 8, 16 or 32 fence registers to share between all users
+ *    (older machines require fence register for display and blitter access
+ *    as well). Contention of the fence registers will cause the previous users
+ *    to be unmapped and any new access will generate new page faults.
+ *
+ *  * running out of memory while servicing a fault may generate a SIGBUS,
+ *    rather than the expected SIGSEGV.
+ */
+int i915_gem_mmap_gtt_version(void)
+{
+       return 1;
+}
+
+/**
  * i915_gem_fault - fault a page into the GTT
  * @area: CPU VMA in question
  * @vmf: fault info
@@ -1694,6 +1744,9 @@ static unsigned int tile_row_pages(struct drm_i915_gem_object *obj)
  * from the GTT and/or fence registers to make room.  So performance may
  * suffer if the GTT working set is large or there are few fence registers
  * left.
+ *
+ * The current feature set supported by i915_gem_fault() and thus GTT mmaps
+ * is exposed via I915_PARAM_MMAP_GTT_VERSION (see i915_gem_mmap_gtt_version).
  */
 int i915_gem_fault(struct vm_area_struct *area, struct vm_fault *vmf)
 {
index 5501fe8..03725fe 100644 (file)
@@ -387,6 +387,7 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_HAS_EXEC_SOFTPIN     37
 #define I915_PARAM_HAS_POOLED_EU        38
 #define I915_PARAM_MIN_EU_IN_POOL       39
+#define I915_PARAM_MMAP_GTT_VERSION     40
 
 typedef struct drm_i915_getparam {
        __s32 param;