Commit 7961c5b6 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Matthew Auld

drm/i915: Add TTM offset argument to mmap.

The FIXED mapping is only used for ttm, and tells userspace that the
mapping type is pre-defined. This disables the other type of mmap
offsets when discrete memory is used, so fix the selftests as well.

Document the struct as well, so it shows up in docbook.

Cc: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: default avatarJason Ekstrand <jason@jlekstrand.net>
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
[mauld: Included minor fixes from the review comments]
Signed-off-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210714122833.766586-1-maarten.lankhorst@linux.intel.com
parent 15eb083b
...@@ -679,10 +679,16 @@ __assign_mmap_offset(struct drm_i915_gem_object *obj, ...@@ -679,10 +679,16 @@ __assign_mmap_offset(struct drm_i915_gem_object *obj,
return -ENODEV; return -ENODEV;
if (obj->ops->mmap_offset) { if (obj->ops->mmap_offset) {
if (mmap_type != I915_MMAP_TYPE_FIXED)
return -ENODEV;
*offset = obj->ops->mmap_offset(obj); *offset = obj->ops->mmap_offset(obj);
return 0; return 0;
} }
if (mmap_type == I915_MMAP_TYPE_FIXED)
return -ENODEV;
if (mmap_type != I915_MMAP_TYPE_GTT && if (mmap_type != I915_MMAP_TYPE_GTT &&
!i915_gem_object_has_struct_page(obj) && !i915_gem_object_has_struct_page(obj) &&
!i915_gem_object_has_iomem(obj)) !i915_gem_object_has_iomem(obj))
...@@ -727,7 +733,9 @@ i915_gem_dumb_mmap_offset(struct drm_file *file, ...@@ -727,7 +733,9 @@ i915_gem_dumb_mmap_offset(struct drm_file *file,
{ {
enum i915_mmap_type mmap_type; enum i915_mmap_type mmap_type;
if (boot_cpu_has(X86_FEATURE_PAT)) if (HAS_LMEM(to_i915(dev)))
mmap_type = I915_MMAP_TYPE_FIXED;
else if (boot_cpu_has(X86_FEATURE_PAT))
mmap_type = I915_MMAP_TYPE_WC; mmap_type = I915_MMAP_TYPE_WC;
else if (!i915_ggtt_has_aperture(&to_i915(dev)->ggtt)) else if (!i915_ggtt_has_aperture(&to_i915(dev)->ggtt))
return -ENODEV; return -ENODEV;
...@@ -798,6 +806,10 @@ i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data, ...@@ -798,6 +806,10 @@ i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
type = I915_MMAP_TYPE_UC; type = I915_MMAP_TYPE_UC;
break; break;
case I915_MMAP_OFFSET_FIXED:
type = I915_MMAP_TYPE_FIXED;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -968,6 +980,9 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -968,6 +980,9 @@ int i915_gem_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_ops = &vm_ops_cpu; vma->vm_ops = &vm_ops_cpu;
break; break;
case I915_MMAP_TYPE_FIXED:
GEM_WARN_ON(1);
fallthrough;
case I915_MMAP_TYPE_WB: case I915_MMAP_TYPE_WB:
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
vma->vm_ops = &vm_ops_cpu; vma->vm_ops = &vm_ops_cpu;
......
...@@ -105,6 +105,7 @@ enum i915_mmap_type { ...@@ -105,6 +105,7 @@ enum i915_mmap_type {
I915_MMAP_TYPE_WC, I915_MMAP_TYPE_WC,
I915_MMAP_TYPE_WB, I915_MMAP_TYPE_WB,
I915_MMAP_TYPE_UC, I915_MMAP_TYPE_UC,
I915_MMAP_TYPE_FIXED,
}; };
struct i915_mmap_offset { struct i915_mmap_offset {
......
...@@ -573,6 +573,14 @@ static int make_obj_busy(struct drm_i915_gem_object *obj) ...@@ -573,6 +573,14 @@ static int make_obj_busy(struct drm_i915_gem_object *obj)
return 0; return 0;
} }
static enum i915_mmap_type default_mapping(struct drm_i915_private *i915)
{
if (HAS_LMEM(i915))
return I915_MMAP_TYPE_FIXED;
return I915_MMAP_TYPE_GTT;
}
static bool assert_mmap_offset(struct drm_i915_private *i915, static bool assert_mmap_offset(struct drm_i915_private *i915,
unsigned long size, unsigned long size,
int expected) int expected)
...@@ -585,7 +593,7 @@ static bool assert_mmap_offset(struct drm_i915_private *i915, ...@@ -585,7 +593,7 @@ static bool assert_mmap_offset(struct drm_i915_private *i915,
if (IS_ERR(obj)) if (IS_ERR(obj))
return expected && expected == PTR_ERR(obj); return expected && expected == PTR_ERR(obj);
ret = __assign_mmap_offset(obj, I915_MMAP_TYPE_GTT, &offset, NULL); ret = __assign_mmap_offset(obj, default_mapping(i915), &offset, NULL);
i915_gem_object_put(obj); i915_gem_object_put(obj);
return ret == expected; return ret == expected;
...@@ -689,7 +697,7 @@ static int igt_mmap_offset_exhaustion(void *arg) ...@@ -689,7 +697,7 @@ static int igt_mmap_offset_exhaustion(void *arg)
goto out; goto out;
} }
err = __assign_mmap_offset(obj, I915_MMAP_TYPE_GTT, &offset, NULL); err = __assign_mmap_offset(obj, default_mapping(i915), &offset, NULL);
if (err) { if (err) {
pr_err("Unable to insert object into reclaimed hole\n"); pr_err("Unable to insert object into reclaimed hole\n");
goto err_obj; goto err_obj;
...@@ -831,8 +839,14 @@ static int wc_check(struct drm_i915_gem_object *obj) ...@@ -831,8 +839,14 @@ static int wc_check(struct drm_i915_gem_object *obj)
static bool can_mmap(struct drm_i915_gem_object *obj, enum i915_mmap_type type) static bool can_mmap(struct drm_i915_gem_object *obj, enum i915_mmap_type type)
{ {
struct drm_i915_private *i915 = to_i915(obj->base.dev);
bool no_map; bool no_map;
if (HAS_LMEM(i915))
return type == I915_MMAP_TYPE_FIXED;
else if (type == I915_MMAP_TYPE_FIXED)
return false;
if (type == I915_MMAP_TYPE_GTT && if (type == I915_MMAP_TYPE_GTT &&
!i915_ggtt_has_aperture(&to_i915(obj->base.dev)->ggtt)) !i915_ggtt_has_aperture(&to_i915(obj->base.dev)->ggtt))
return false; return false;
...@@ -970,6 +984,8 @@ static int igt_mmap(void *arg) ...@@ -970,6 +984,8 @@ static int igt_mmap(void *arg)
err = __igt_mmap(i915, obj, I915_MMAP_TYPE_GTT); err = __igt_mmap(i915, obj, I915_MMAP_TYPE_GTT);
if (err == 0) if (err == 0)
err = __igt_mmap(i915, obj, I915_MMAP_TYPE_WC); err = __igt_mmap(i915, obj, I915_MMAP_TYPE_WC);
if (err == 0)
err = __igt_mmap(i915, obj, I915_MMAP_TYPE_FIXED);
i915_gem_object_put(obj); i915_gem_object_put(obj);
if (err) if (err)
...@@ -987,6 +1003,7 @@ static const char *repr_mmap_type(enum i915_mmap_type type) ...@@ -987,6 +1003,7 @@ static const char *repr_mmap_type(enum i915_mmap_type type)
case I915_MMAP_TYPE_WB: return "wb"; case I915_MMAP_TYPE_WB: return "wb";
case I915_MMAP_TYPE_WC: return "wc"; case I915_MMAP_TYPE_WC: return "wc";
case I915_MMAP_TYPE_UC: return "uc"; case I915_MMAP_TYPE_UC: return "uc";
case I915_MMAP_TYPE_FIXED: return "fixed";
default: return "unknown"; default: return "unknown";
} }
} }
...@@ -1100,6 +1117,8 @@ static int igt_mmap_access(void *arg) ...@@ -1100,6 +1117,8 @@ static int igt_mmap_access(void *arg)
err = __igt_mmap_access(i915, obj, I915_MMAP_TYPE_WC); err = __igt_mmap_access(i915, obj, I915_MMAP_TYPE_WC);
if (err == 0) if (err == 0)
err = __igt_mmap_access(i915, obj, I915_MMAP_TYPE_UC); err = __igt_mmap_access(i915, obj, I915_MMAP_TYPE_UC);
if (err == 0)
err = __igt_mmap_access(i915, obj, I915_MMAP_TYPE_FIXED);
i915_gem_object_put(obj); i915_gem_object_put(obj);
if (err) if (err)
...@@ -1241,6 +1260,8 @@ static int igt_mmap_gpu(void *arg) ...@@ -1241,6 +1260,8 @@ static int igt_mmap_gpu(void *arg)
err = __igt_mmap_gpu(i915, obj, I915_MMAP_TYPE_GTT); err = __igt_mmap_gpu(i915, obj, I915_MMAP_TYPE_GTT);
if (err == 0) if (err == 0)
err = __igt_mmap_gpu(i915, obj, I915_MMAP_TYPE_WC); err = __igt_mmap_gpu(i915, obj, I915_MMAP_TYPE_WC);
if (err == 0)
err = __igt_mmap_gpu(i915, obj, I915_MMAP_TYPE_FIXED);
i915_gem_object_put(obj); i915_gem_object_put(obj);
if (err) if (err)
...@@ -1396,6 +1417,8 @@ static int igt_mmap_revoke(void *arg) ...@@ -1396,6 +1417,8 @@ static int igt_mmap_revoke(void *arg)
err = __igt_mmap_revoke(i915, obj, I915_MMAP_TYPE_GTT); err = __igt_mmap_revoke(i915, obj, I915_MMAP_TYPE_GTT);
if (err == 0) if (err == 0)
err = __igt_mmap_revoke(i915, obj, I915_MMAP_TYPE_WC); err = __igt_mmap_revoke(i915, obj, I915_MMAP_TYPE_WC);
if (err == 0)
err = __igt_mmap_revoke(i915, obj, I915_MMAP_TYPE_FIXED);
i915_gem_object_put(obj); i915_gem_object_put(obj);
if (err) if (err)
......
...@@ -849,31 +849,56 @@ struct drm_i915_gem_mmap_gtt { ...@@ -849,31 +849,56 @@ struct drm_i915_gem_mmap_gtt {
__u64 offset; __u64 offset;
}; };
/**
* struct drm_i915_gem_mmap_offset - Retrieve an offset so we can mmap this buffer object.
*
* This struct is passed as argument to the `DRM_IOCTL_I915_GEM_MMAP_OFFSET` ioctl,
* and is used to retrieve the fake offset to mmap an object specified by &handle.
*
* The legacy way of using `DRM_IOCTL_I915_GEM_MMAP` is removed on gen12+.
* `DRM_IOCTL_I915_GEM_MMAP_GTT` is an older supported alias to this struct, but will behave
* as setting the &extensions to 0, and &flags to `I915_MMAP_OFFSET_GTT`.
*/
struct drm_i915_gem_mmap_offset { struct drm_i915_gem_mmap_offset {
/** Handle for the object being mapped. */ /** @handle: Handle for the object being mapped. */
__u32 handle; __u32 handle;
/** @pad: Must be zero */
__u32 pad; __u32 pad;
/** /**
* Fake offset to use for subsequent mmap call * @offset: The fake offset to use for subsequent mmap call
* *
* This is a fixed-size type for 32/64 compatibility. * This is a fixed-size type for 32/64 compatibility.
*/ */
__u64 offset; __u64 offset;
/** /**
* Flags for extended behaviour. * @flags: Flags for extended behaviour.
* *
* It is mandatory that one of the MMAP_OFFSET types * It is mandatory that one of the `MMAP_OFFSET` types
* (GTT, WC, WB, UC, etc) should be included. * should be included:
*
* - `I915_MMAP_OFFSET_GTT`: Use mmap with the object bound to GTT. (Write-Combined)
* - `I915_MMAP_OFFSET_WC`: Use Write-Combined caching.
* - `I915_MMAP_OFFSET_WB`: Use Write-Back caching.
* - `I915_MMAP_OFFSET_FIXED`: Use object placement to determine caching.
*
* On devices with local memory `I915_MMAP_OFFSET_FIXED` is the only valid
* type. On devices without local memory, this caching mode is invalid.
*
* As caching mode when specifying `I915_MMAP_OFFSET_FIXED`, WC or WB will
* be used, depending on the object placement on creation. WB will be used
* when the object can only exist in system memory, WC otherwise.
*/ */
__u64 flags; __u64 flags;
#define I915_MMAP_OFFSET_GTT 0
#define I915_MMAP_OFFSET_WC 1
#define I915_MMAP_OFFSET_WB 2
#define I915_MMAP_OFFSET_UC 3
/* #define I915_MMAP_OFFSET_GTT 0
* Zero-terminated chain of extensions. #define I915_MMAP_OFFSET_WC 1
#define I915_MMAP_OFFSET_WB 2
#define I915_MMAP_OFFSET_UC 3
#define I915_MMAP_OFFSET_FIXED 4
/**
* @extensions: Zero-terminated chain of extensions.
* *
* No current extensions defined; mbz. * No current extensions defined; mbz.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment