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. Link: https://github.com/intel/compute-runtime/pull/261 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Steve Carbonari <steven.carbonari@intel.com> Reviewed-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200225192206.1107336-2-chris@chris-wilson.co.uk
This commit is contained in:
parent
d13a317700
commit
88be76cdaf
|
@ -82,6 +82,7 @@ gt-y += \
|
|||
gt/gen8_ppgtt.o \
|
||||
gt/intel_breadcrumbs.o \
|
||||
gt/intel_context.o \
|
||||
gt/intel_context_param.o \
|
||||
gt/intel_context_sseu.o \
|
||||
gt/intel_engine_cs.o \
|
||||
gt/intel_engine_heartbeat.o \
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
|
||||
#include "gt/gen6_ppgtt.h"
|
||||
#include "gt/intel_context.h"
|
||||
#include "gt/intel_context_param.h"
|
||||
#include "gt/intel_engine_heartbeat.h"
|
||||
#include "gt/intel_engine_user.h"
|
||||
#include "gt/intel_ring.h"
|
||||
|
@ -668,23 +669,30 @@ err_free:
|
|||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
context_apply_all(struct i915_gem_context *ctx,
|
||||
void (*fn)(struct intel_context *ce, void *data),
|
||||
int (*fn)(struct intel_context *ce, void *data),
|
||||
void *data)
|
||||
{
|
||||
struct i915_gem_engines_iter it;
|
||||
struct intel_context *ce;
|
||||
int err = 0;
|
||||
|
||||
for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it)
|
||||
fn(ce, data);
|
||||
for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
|
||||
err = fn(ce, data);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
i915_gem_context_unlock_engines(ctx);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __apply_ppgtt(struct intel_context *ce, void *vm)
|
||||
static int __apply_ppgtt(struct intel_context *ce, void *vm)
|
||||
{
|
||||
i915_vm_put(ce->vm);
|
||||
ce->vm = i915_vm_get(vm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i915_address_space *
|
||||
|
@ -722,9 +730,10 @@ static void __set_timeline(struct intel_timeline **dst,
|
|||
intel_timeline_put(old);
|
||||
}
|
||||
|
||||
static void __apply_timeline(struct intel_context *ce, void *timeline)
|
||||
static int __apply_timeline(struct intel_context *ce, void *timeline)
|
||||
{
|
||||
__set_timeline(&ce->timeline, timeline);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __assign_timeline(struct i915_gem_context *ctx,
|
||||
|
@ -1215,6 +1224,63 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int __apply_ringsize(struct intel_context *ce, void *sz)
|
||||
{
|
||||
return intel_context_set_ring_size(ce, (unsigned long)sz);
|
||||
}
|
||||
|
||||
static int set_ringsize(struct i915_gem_context *ctx,
|
||||
struct drm_i915_gem_context_param *args)
|
||||
{
|
||||
if (!HAS_LOGICAL_RING_CONTEXTS(ctx->i915))
|
||||
return -ENODEV;
|
||||
|
||||
if (args->size)
|
||||
return -EINVAL;
|
||||
|
||||
if (!IS_ALIGNED(args->value, I915_GTT_PAGE_SIZE))
|
||||
return -EINVAL;
|
||||
|
||||
if (args->value < I915_GTT_PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (args->value > 128 * I915_GTT_PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
return context_apply_all(ctx,
|
||||
__apply_ringsize,
|
||||
__intel_context_ring_size(args->value));
|
||||
}
|
||||
|
||||
static int __get_ringsize(struct intel_context *ce, void *arg)
|
||||
{
|
||||
long sz;
|
||||
|
||||
sz = intel_context_get_ring_size(ce);
|
||||
GEM_BUG_ON(sz > INT_MAX);
|
||||
|
||||
return sz; /* stop on first engine */
|
||||
}
|
||||
|
||||
static int get_ringsize(struct i915_gem_context *ctx,
|
||||
struct drm_i915_gem_context_param *args)
|
||||
{
|
||||
int sz;
|
||||
|
||||
if (!HAS_LOGICAL_RING_CONTEXTS(ctx->i915))
|
||||
return -ENODEV;
|
||||
|
||||
if (args->size)
|
||||
return -EINVAL;
|
||||
|
||||
sz = context_apply_all(ctx, __get_ringsize, NULL);
|
||||
if (sz < 0)
|
||||
return sz;
|
||||
|
||||
args->value = sz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
user_to_context_sseu(struct drm_i915_private *i915,
|
||||
const struct drm_i915_gem_context_param_sseu *user,
|
||||
|
@ -1852,17 +1918,19 @@ set_persistence(struct i915_gem_context *ctx,
|
|||
return __context_set_persistence(ctx, args->value);
|
||||
}
|
||||
|
||||
static void __apply_priority(struct intel_context *ce, void *arg)
|
||||
static int __apply_priority(struct intel_context *ce, void *arg)
|
||||
{
|
||||
struct i915_gem_context *ctx = arg;
|
||||
|
||||
if (!intel_engine_has_semaphores(ce->engine))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (ctx->sched.priority >= I915_PRIORITY_NORMAL)
|
||||
intel_context_set_use_semaphores(ce);
|
||||
else
|
||||
intel_context_clear_use_semaphores(ce);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_priority(struct i915_gem_context *ctx,
|
||||
|
@ -1955,6 +2023,10 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
|
|||
ret = set_persistence(ctx, args);
|
||||
break;
|
||||
|
||||
case I915_CONTEXT_PARAM_RINGSIZE:
|
||||
ret = set_ringsize(ctx, args);
|
||||
break;
|
||||
|
||||
case I915_CONTEXT_PARAM_BAN_PERIOD:
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
|
@ -1983,6 +2055,18 @@ static int create_setparam(struct i915_user_extension __user *ext, void *data)
|
|||
return ctx_setparam(arg->fpriv, arg->ctx, &local.param);
|
||||
}
|
||||
|
||||
static int copy_ring_size(struct intel_context *dst,
|
||||
struct intel_context *src)
|
||||
{
|
||||
long sz;
|
||||
|
||||
sz = intel_context_get_ring_size(src);
|
||||
if (sz < 0)
|
||||
return sz;
|
||||
|
||||
return intel_context_set_ring_size(dst, sz);
|
||||
}
|
||||
|
||||
static int clone_engines(struct i915_gem_context *dst,
|
||||
struct i915_gem_context *src)
|
||||
{
|
||||
|
@ -2026,6 +2110,12 @@ static int clone_engines(struct i915_gem_context *dst,
|
|||
}
|
||||
|
||||
intel_context_set_gem(clone->engines[n], dst);
|
||||
|
||||
/* Copy across the preferred ringsize */
|
||||
if (copy_ring_size(clone->engines[n], e->engines[n])) {
|
||||
__free_engines(clone, n + 1);
|
||||
goto err_unlock;
|
||||
}
|
||||
}
|
||||
clone->num_engines = n;
|
||||
|
||||
|
@ -2388,6 +2478,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
|
|||
args->value = i915_gem_context_is_persistent(ctx);
|
||||
break;
|
||||
|
||||
case I915_CONTEXT_PARAM_RINGSIZE:
|
||||
ret = get_ringsize(ctx, args);
|
||||
break;
|
||||
|
||||
case I915_CONTEXT_PARAM_BAN_PERIOD:
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
|
|
63
drivers/gpu/drm/i915/gt/intel_context_param.c
Normal file
63
drivers/gpu/drm/i915/gt/intel_context_param.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright © 2019 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "i915_active.h"
|
||||
#include "intel_context.h"
|
||||
#include "intel_context_param.h"
|
||||
#include "intel_ring.h"
|
||||
|
||||
int intel_context_set_ring_size(struct intel_context *ce, long sz)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (intel_context_lock_pinned(ce))
|
||||
return -EINTR;
|
||||
|
||||
err = i915_active_wait(&ce->active);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
if (intel_context_is_pinned(ce)) {
|
||||
err = -EBUSY; /* In active use, come back later! */
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
|
||||
struct intel_ring *ring;
|
||||
|
||||
/* Replace the existing ringbuffer */
|
||||
ring = intel_engine_create_ring(ce->engine, sz);
|
||||
if (IS_ERR(ring)) {
|
||||
err = PTR_ERR(ring);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
intel_ring_put(ce->ring);
|
||||
ce->ring = ring;
|
||||
|
||||
/* Context image will be updated on next pin */
|
||||
} else {
|
||||
ce->ring = __intel_context_ring_size(sz);
|
||||
}
|
||||
|
||||
unlock:
|
||||
intel_context_unlock_pinned(ce);
|
||||
return err;
|
||||
}
|
||||
|
||||
long intel_context_get_ring_size(struct intel_context *ce)
|
||||
{
|
||||
long sz = (unsigned long)READ_ONCE(ce->ring);
|
||||
|
||||
if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
|
||||
if (intel_context_lock_pinned(ce))
|
||||
return -EINTR;
|
||||
|
||||
sz = ce->ring->size;
|
||||
intel_context_unlock_pinned(ce);
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
14
drivers/gpu/drm/i915/gt/intel_context_param.h
Normal file
14
drivers/gpu/drm/i915/gt/intel_context_param.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2019 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef INTEL_CONTEXT_PARAM_H
|
||||
#define INTEL_CONTEXT_PARAM_H
|
||||
|
||||
struct intel_context;
|
||||
|
||||
int intel_context_set_ring_size(struct intel_context *ce, long sz);
|
||||
long intel_context_get_ring_size(struct intel_context *ce);
|
||||
|
||||
#endif /* INTEL_CONTEXT_PARAM_H */
|
|
@ -2966,6 +2966,7 @@ __execlists_update_reg_state(const struct intel_context *ce,
|
|||
regs[CTX_RING_START] = i915_ggtt_offset(ring->vma);
|
||||
regs[CTX_RING_HEAD] = head;
|
||||
regs[CTX_RING_TAIL] = ring->tail;
|
||||
regs[CTX_RING_CTL] = RING_CTL_SIZE(ring->size) | RING_VALID;
|
||||
|
||||
/* RPCS */
|
||||
if (engine->class == RENDER_CLASS) {
|
||||
|
|
|
@ -1619,6 +1619,27 @@ struct drm_i915_gem_context_param {
|
|||
* By default, new contexts allow persistence.
|
||||
*/
|
||||
#define I915_CONTEXT_PARAM_PERSISTENCE 0xb
|
||||
|
||||
/*
|
||||
* I915_CONTEXT_PARAM_RINGSIZE:
|
||||
*
|
||||
* Sets the size of the CS ringbuffer to use for logical ring contexts. This
|
||||
* applies a limit of how many batches can be queued to HW before the caller
|
||||
* is blocked due to lack of space for more commands.
|
||||
*
|
||||
* Only reliably possible to be set prior to first use, i.e. during
|
||||
* construction. At any later point, the current execution must be flushed as
|
||||
* the ring can only be changed while the context is idle. Note, the ringsize
|
||||
* can be specified as a constructor property, see
|
||||
* I915_CONTEXT_CREATE_EXT_SETPARAM, but can also be set later if required.
|
||||
*
|
||||
* Only applies to the current set of engine and lost when those engines
|
||||
* are replaced by a new mapping (see I915_CONTEXT_PARAM_ENGINES).
|
||||
*
|
||||
* Must be between 4 - 512 KiB, in intervals of page size [4 KiB].
|
||||
* Default is 16 KiB.
|
||||
*/
|
||||
#define I915_CONTEXT_PARAM_RINGSIZE 0xc
|
||||
/* Must be kept compact -- no holes and well documented */
|
||||
|
||||
__u64 value;
|
||||
|
|
Loading…
Reference in a new issue