History

drm/i915: Allow userspace to specify ringsize on construction

No good reason why we must always use a static ringsize, so let userspace select one during construction.

Chris Wilson committed 6 years ago

Commit 88be76c1 parent d13a3176 files · +202 −8Browse files

Unified · Split

6 files
  1. drivers/gpu/drm/i915/Makefile +1 −0
  2. drivers/gpu/drm/i915/gem/i915_gem_context.c +102 −8
  3. drivers/gpu/drm/i915/gt/intel_context_param.c +63 −0
  4. drivers/gpu/drm/i915/gt/intel_context_param.h +14 −0
  5. drivers/gpu/drm/i915/gt/intel_lrc.c +1 −0
  6. include/uapi/drm/i915_drm.h +21 −0
drivers/gpu/drm/i915/Makefile+1−0
@@ -82,6 +82,7 @@ gt-y += \ · 81 unmodified lines
8282 gt/gen8_ppgtt.o \
8383 gt/intel_breadcrumbs.o \
8484 gt/intel_context.o \
85+ gt/intel_context_param.o \
8586 gt/intel_context_sseu.o \
8687 gt/intel_engine_cs.o \
8788 gt/intel_engine_heartbeat.o \
drivers/gpu/drm/i915/gem/i915_gem_context.c+102−8
@@ -71,6 +71,7 @@ · 70 unmodified lines
7171
7272 #include "gt/gen6_ppgtt.h"
7373 #include "gt/intel_context.h"
74+#include "gt/intel_context_param.h"
7475 #include "gt/intel_engine_heartbeat.h"
7576 #include "gt/intel_engine_user.h"
7677 #include "gt/intel_ring.h"
@@ -668,23 +669,30 @@ err_free: · 591 unmodified lines
668669 return ERR_PTR(err);
669670 }
670671
671−static void
672+static int
672673 context_apply_all(struct i915_gem_context *ctx,
673− void (*fn)(struct intel_context *ce, void *data),
674+ int (*fn)(struct intel_context *ce, void *data),
674675 void *data)
675676 {
676677 struct i915_gem_engines_iter it;
677678 struct intel_context *ce;
679+ int err = 0;
678680
679− for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it)
680− fn(ce, data);
681+ for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
682+ err = fn(ce, data);
683+ if (err)
684+ break;
685+ }
681686 i915_gem_context_unlock_engines(ctx);
687+
688+ return err;
682689 }
683690
684−static void __apply_ppgtt(struct intel_context *ce, void *vm)
691+static int __apply_ppgtt(struct intel_context *ce, void *vm)
685692 {
686693 i915_vm_put(ce->vm);
687694 ce->vm = i915_vm_get(vm);
695+ return 0;
688696 }
689697
690698 static struct i915_address_space *
@@ -722,9 +730,10 @@ static void __set_timeline(struct intel_timeline **dst, · 31 unmodified lines
722730 intel_timeline_put(old);
723731 }
724732
725−static void __apply_timeline(struct intel_context *ce, void *timeline)
733+static int __apply_timeline(struct intel_context *ce, void *timeline)
726734 {
727735 __set_timeline(&ce->timeline, timeline);
736+ return 0;
728737 }
729738
730739 static void __assign_timeline(struct i915_gem_context *ctx,
@@ -1215,6 +1224,63 @@ out: · 484 unmodified lines
12151224 return err;
12161225 }
12171226
1227+static int __apply_ringsize(struct intel_context *ce, void *sz)
1228+{
1229+ return intel_context_set_ring_size(ce, (unsigned long)sz);
1230+}
1231+
1232+static int set_ringsize(struct i915_gem_context *ctx,
1233+ struct drm_i915_gem_context_param *args)
1234+{
1235+ if (!HAS_LOGICAL_RING_CONTEXTS(ctx->i915))
1236+ return -ENODEV;
1237+
1238+ if (args->size)
1239+ return -EINVAL;
1240+
1241+ if (!IS_ALIGNED(args->value, I915_GTT_PAGE_SIZE))
1242+ return -EINVAL;
1243+
1244+ if (args->value < I915_GTT_PAGE_SIZE)
1245+ return -EINVAL;
1246+
1247+ if (args->value > 128 * I915_GTT_PAGE_SIZE)
1248+ return -EINVAL;
1249+
1250+ return context_apply_all(ctx,
1251+ __apply_ringsize,
1252+ __intel_context_ring_size(args->value));
1253+}
1254+
1255+static int __get_ringsize(struct intel_context *ce, void *arg)
1256+{
1257+ long sz;
1258+
1259+ sz = intel_context_get_ring_size(ce);
1260+ GEM_BUG_ON(sz > INT_MAX);
1261+
1262+ return sz; /* stop on first engine */
1263+}
1264+
1265+static int get_ringsize(struct i915_gem_context *ctx,
1266+ struct drm_i915_gem_context_param *args)
1267+{
1268+ int sz;
1269+
1270+ if (!HAS_LOGICAL_RING_CONTEXTS(ctx->i915))
1271+ return -ENODEV;
1272+
1273+ if (args->size)
1274+ return -EINVAL;
1275+
1276+ sz = context_apply_all(ctx, __get_ringsize, NULL);
1277+ if (sz < 0)
1278+ return sz;
1279+
1280+ args->value = sz;
1281+ return 0;
1282+}
1283+
12181284 static int
12191285 user_to_context_sseu(struct drm_i915_private *i915,
12201286 const struct drm_i915_gem_context_param_sseu *user,
@@ -1852,17 +1918,19 @@ set_persistence(struct i915_gem_context *ctx, · 631 unmodified lines
18521918 return __context_set_persistence(ctx, args->value);
18531919 }
18541920
1855−static void __apply_priority(struct intel_context *ce, void *arg)
1921+static int __apply_priority(struct intel_context *ce, void *arg)
18561922 {
18571923 struct i915_gem_context *ctx = arg;
18581924
18591925 if (!intel_engine_has_semaphores(ce->engine))
1860− return;
1926+ return 0;
18611927
18621928 if (ctx->sched.priority >= I915_PRIORITY_NORMAL)
18631929 intel_context_set_use_semaphores(ce);
18641930 else
18651931 intel_context_clear_use_semaphores(ce);
1932+
1933+ return 0;
18661934 }
18671935
18681936 static int set_priority(struct i915_gem_context *ctx,
@@ -1955,6 +2023,10 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv, · 86 unmodified lines
19552023 ret = set_persistence(ctx, args);
19562024 break;
19572025
2026+ case I915_CONTEXT_PARAM_RINGSIZE:
2027+ ret = set_ringsize(ctx, args);
2028+ break;
2029+
19582030 case I915_CONTEXT_PARAM_BAN_PERIOD:
19592031 default:
19602032 ret = -EINVAL;
@@ -1983,6 +2055,18 @@ static int create_setparam(struct i915_user_extension __user *ext, void *data) · 22 unmodified lines
19832055 return ctx_setparam(arg->fpriv, arg->ctx, &local.param);
19842056 }
19852057
2058+static int copy_ring_size(struct intel_context *dst,
2059+ struct intel_context *src)
2060+{
2061+ long sz;
2062+
2063+ sz = intel_context_get_ring_size(src);
2064+ if (sz < 0)
2065+ return sz;
2066+
2067+ return intel_context_set_ring_size(dst, sz);
2068+}
2069+
19862070 static int clone_engines(struct i915_gem_context *dst,
19872071 struct i915_gem_context *src)
19882072 {
@@ -2026,6 +2110,12 @@ static int clone_engines(struct i915_gem_context *dst, · 37 unmodified lines
20262110 }
20272111
20282112 intel_context_set_gem(clone->engines[n], dst);
2113+
2114+ /* Copy across the preferred ringsize */
2115+ if (copy_ring_size(clone->engines[n], e->engines[n])) {
2116+ __free_engines(clone, n + 1);
2117+ goto err_unlock;
2118+ }
20292119 }
20302120 clone->num_engines = n;
20312121
@@ -2388,6 +2478,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, · 356 unmodified lines
23882478 args->value = i915_gem_context_is_persistent(ctx);
23892479 break;
23902480
2481+ case I915_CONTEXT_PARAM_RINGSIZE:
2482+ ret = get_ringsize(ctx, args);
2483+ break;
2484+
23912485 case I915_CONTEXT_PARAM_BAN_PERIOD:
23922486 default:
23932487 ret = -EINVAL;
drivers/gpu/drm/i915/gt/intel_context_param.c+63−0
@@ -0,0 +1,63 @@
1+// SPDX-License-Identifier: MIT
2+/*
3+ * Copyright © 2019 Intel Corporation
4+ */
5+
6+#include "i915_active.h"
7+#include "intel_context.h"
8+#include "intel_context_param.h"
9+#include "intel_ring.h"
10+
11+int intel_context_set_ring_size(struct intel_context *ce, long sz)
12+{
13+ int err;
14+
15+ if (intel_context_lock_pinned(ce))
16+ return -EINTR;
17+
18+ err = i915_active_wait(&ce->active);
19+ if (err < 0)
20+ goto unlock;
21+
22+ if (intel_context_is_pinned(ce)) {
23+ err = -EBUSY; /* In active use, come back later! */
24+ goto unlock;
25+ }
26+
27+ if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
28+ struct intel_ring *ring;
29+
30+ /* Replace the existing ringbuffer */
31+ ring = intel_engine_create_ring(ce->engine, sz);
32+ if (IS_ERR(ring)) {
33+ err = PTR_ERR(ring);
34+ goto unlock;
35+ }
36+
37+ intel_ring_put(ce->ring);
38+ ce->ring = ring;
39+
40+ /* Context image will be updated on next pin */
41+ } else {
42+ ce->ring = __intel_context_ring_size(sz);
43+ }
44+
45+unlock:
46+ intel_context_unlock_pinned(ce);
47+ return err;
48+}
49+
50+long intel_context_get_ring_size(struct intel_context *ce)
51+{
52+ long sz = (unsigned long)READ_ONCE(ce->ring);
53+
54+ if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
55+ if (intel_context_lock_pinned(ce))
56+ return -EINTR;
57+
58+ sz = ce->ring->size;
59+ intel_context_unlock_pinned(ce);
60+ }
61+
62+ return sz;
63+}
drivers/gpu/drm/i915/gt/intel_context_param.h+14−0
@@ -0,0 +1,14 @@
1+/* SPDX-License-Identifier: MIT */
2+/*
3+ * Copyright © 2019 Intel Corporation
4+ */
5+
6+#ifndef INTEL_CONTEXT_PARAM_H
7+#define INTEL_CONTEXT_PARAM_H
8+
9+struct intel_context;
10+
11+int intel_context_set_ring_size(struct intel_context *ce, long sz);
12+long intel_context_get_ring_size(struct intel_context *ce);
13+
14+#endif /* INTEL_CONTEXT_PARAM_H */
drivers/gpu/drm/i915/gt/intel_lrc.c+1−0
@@ -2966,6 +2966,7 @@ __execlists_update_reg_state(const struct intel_context *ce, · 2965 unmodified lines
29662966 regs[CTX_RING_START] = i915_ggtt_offset(ring->vma);
29672967 regs[CTX_RING_HEAD] = head;
29682968 regs[CTX_RING_TAIL] = ring->tail;
2969+ regs[CTX_RING_CTL] = RING_CTL_SIZE(ring->size) | RING_VALID;
29692970
29702971 /* RPCS */
29712972 if (engine->class == RENDER_CLASS) {
include/uapi/drm/i915_drm.h+21−0
@@ -1619,6 +1619,27 @@ struct drm_i915_gem_context_param { · 1618 unmodified lines
16191619 * By default, new contexts allow persistence.
16201620 */
16211621 #define I915_CONTEXT_PARAM_PERSISTENCE 0xb
1622+
1623+/*
1624+ * I915_CONTEXT_PARAM_RINGSIZE:
1625+ *
1626+ * Sets the size of the CS ringbuffer to use for logical ring contexts. This
1627+ * applies a limit of how many batches can be queued to HW before the caller
1628+ * is blocked due to lack of space for more commands.
1629+ *
1630+ * Only reliably possible to be set prior to first use, i.e. during
1631+ * construction. At any later point, the current execution must be flushed as
1632+ * the ring can only be changed while the context is idle. Note, the ringsize
1633+ * can be specified as a constructor property, see
1634+ * I915_CONTEXT_CREATE_EXT_SETPARAM, but can also be set later if required.
1635+ *
1636+ * Only applies to the current set of engine and lost when those engines
1637+ * are replaced by a new mapping (see I915_CONTEXT_PARAM_ENGINES).
1638+ *
1639+ * Must be between 4 - 512 KiB, in intervals of page size [4 KiB].
1640+ * Default is 16 KiB.
1641+ */
1642+#define I915_CONTEXT_PARAM_RINGSIZE 0xc
16221643 /* Must be kept compact -- no holes and well documented */
16231644
16241645 __u64 value;