History

drm/i915: Drop the CONTEXT_CLONE API (v2)

This API allows one context to grab bits out of another context upon creation. It can be used as a short-cut for setparam(getparam()) for things like I915_CONTEXT_PARAM_VM. However, it's never been used by any real userspace. It's used by a few IGT tests and that's it. Since it doesn't add any real value (most of the stuff you can CLONE you can copy in other ways), drop it. There is one thing that this API allows you to clone which you cannot clone via getparam/setparam: timelines. However, timelines are an implementation detail of i915 and not really something that needs to be exposed to userspace. Also, sharing timelines between contexts isn't obviously useful and supporting it has the potential to complicate i915 internally. It also doesn't add any functionality that the client can't get in other ways. If a client really wants a shared timeline, they can use a syncobj and set it as an in and out fence on every submit. v2 (Jason Ekstrand): - More detailed commit message

Jason Ekstrand committed 5 years ago

Commit 4a766ae1 parent 8cc256a4 files · +6 −240Browse files

Unified · Split

4 files
  1. drivers/gpu/drm/i915/gem/i915_gem_context.c +3 −196
  2. drivers/gpu/drm/i915/gt/intel_execlists_submission.c +0 −28
  3. drivers/gpu/drm/i915/gt/intel_execlists_submission.h +0 −3
  4. include/uapi/drm/i915_drm.h +3 −13
drivers/gpu/drm/i915/gem/i915_gem_context.c+3−196
@@ -1957,207 +1957,14 @@ static int create_setparam(struct i915_user_extension __user *ext, void *data) · 1956 unmodified lines
19571957 return ctx_setparam(arg->fpriv, arg->ctx, &local.param);
19581958 }
19591959
1960−static int clone_engines(struct i915_gem_context *dst,
1961− struct i915_gem_context *src)
1960+static int invalid_ext(struct i915_user_extension __user *ext, void *data)
19621961 {
1963− struct i915_gem_engines *clone, *e;
1964− bool user_engines;
1965− unsigned long n;
1966−
1967− e = __context_engines_await(src, &user_engines);
1968− if (!e)
1969− return -ENOENT;
1970−
1971− clone = alloc_engines(e->num_engines);
1972− if (!clone)
1973− goto err_unlock;
1974−
1975− for (n = 0; n < e->num_engines; n++) {
1976− struct intel_engine_cs *engine;
1977−
1978− if (!e->engines[n]) {
1979− clone->engines[n] = NULL;
1980− continue;
1981− }
1982− engine = e->engines[n]->engine;
1983−
1984− /*
1985− * Virtual engines are singletons; they can only exist
1986− * inside a single context, because they embed their
1987− * HW context... As each virtual context implies a single
1988− * timeline (each engine can only dequeue a single request
1989− * at any time), it would be surprising for two contexts
1990− * to use the same engine. So let's create a copy of
1991− * the virtual engine instead.
1992− */
1993− if (intel_engine_is_virtual(engine))
1994− clone->engines[n] =
1995− intel_execlists_clone_virtual(engine);
1996− else
1997− clone->engines[n] = intel_context_create(engine);
1998− if (IS_ERR_OR_NULL(clone->engines[n])) {
1999− __free_engines(clone, n);
2000− goto err_unlock;
2001− }
2002−
2003− intel_context_set_gem(clone->engines[n], dst);
2004− }
2005− clone->num_engines = n;
2006− i915_sw_fence_complete(&e->fence);
2007−
2008− /* Serialised by constructor */
2009− engines_idle_release(dst, rcu_replace_pointer(dst->engines, clone, 1));
2010− if (user_engines)
2011− i915_gem_context_set_user_engines(dst);
2012− else
2013− i915_gem_context_clear_user_engines(dst);
2014− return 0;
2015−
2016−err_unlock:
2017− i915_sw_fence_complete(&e->fence);
2018− return -ENOMEM;
2019−}
2020−
2021−static int clone_flags(struct i915_gem_context *dst,
2022− struct i915_gem_context *src)
2023−{
2024− dst->user_flags = src->user_flags;
2025− return 0;
2026−}
2027−
2028−static int clone_schedattr(struct i915_gem_context *dst,
2029− struct i915_gem_context *src)
2030−{
2031− dst->sched = src->sched;
2032− return 0;
2033−}
2034−
2035−static int clone_sseu(struct i915_gem_context *dst,
2036− struct i915_gem_context *src)
2037−{
2038− struct i915_gem_engines *e = i915_gem_context_lock_engines(src);
2039− struct i915_gem_engines *clone;
2040− unsigned long n;
2041− int err;
2042−
2043− /* no locking required; sole access under constructor*/
2044− clone = __context_engines_static(dst);
2045− if (e->num_engines != clone->num_engines) {
2046− err = -EINVAL;
2047− goto unlock;
2048− }
2049−
2050− for (n = 0; n < e->num_engines; n++) {
2051− struct intel_context *ce = e->engines[n];
2052−
2053− if (clone->engines[n]->engine->class != ce->engine->class) {
2054− /* Must have compatible engine maps! */
2055− err = -EINVAL;
2056− goto unlock;
2057− }
2058−
2059− /* serialises with set_sseu */
2060− err = intel_context_lock_pinned(ce);
2061− if (err)
2062− goto unlock;
2063−
2064− clone->engines[n]->sseu = ce->sseu;
2065− intel_context_unlock_pinned(ce);
2066− }
2067−
2068− err = 0;
2069−unlock:
2070− i915_gem_context_unlock_engines(src);
2071− return err;
2072−}
2073−
2074−static int clone_timeline(struct i915_gem_context *dst,
2075− struct i915_gem_context *src)
2076−{
2077− if (src->timeline)
2078− __assign_timeline(dst, src->timeline);
2079−
2080− return 0;
2081−}
2082−
2083−static int clone_vm(struct i915_gem_context *dst,
2084− struct i915_gem_context *src)
2085−{
2086− struct i915_address_space *vm;
2087− int err = 0;
2088−
2089− if (!rcu_access_pointer(src->vm))
2090− return 0;
2091−
2092− rcu_read_lock();
2093− vm = context_get_vm_rcu(src);
2094− rcu_read_unlock();
2095−
2096− if (!mutex_lock_interruptible(&dst->mutex)) {
2097− __assign_ppgtt(dst, vm);
2098− mutex_unlock(&dst->mutex);
2099− } else {
2100− err = -EINTR;
2101− }
2102−
2103− i915_vm_put(vm);
2104− return err;
2105−}
2106−
2107−static int create_clone(struct i915_user_extension __user *ext, void *data)
2108−{
2109− static int (* const fn[])(struct i915_gem_context *dst,
2110− struct i915_gem_context *src) = {
2111−#define MAP(x, y) [ilog2(I915_CONTEXT_CLONE_##x)] = y
2112− MAP(ENGINES, clone_engines),
2113− MAP(FLAGS, clone_flags),
2114− MAP(SCHEDATTR, clone_schedattr),
2115− MAP(SSEU, clone_sseu),
2116− MAP(TIMELINE, clone_timeline),
2117− MAP(VM, clone_vm),
2118−#undef MAP
2119− };
2120− struct drm_i915_gem_context_create_ext_clone local;
2121− const struct create_ext *arg = data;
2122− struct i915_gem_context *dst = arg->ctx;
2123− struct i915_gem_context *src;
2124− int err, bit;
2125−
2126− if (copy_from_user(&local, ext, sizeof(local)))
2127− return -EFAULT;
2128−
2129− BUILD_BUG_ON(GENMASK(BITS_PER_TYPE(local.flags) - 1, ARRAY_SIZE(fn)) !=
2130− I915_CONTEXT_CLONE_UNKNOWN);
2131−
2132− if (local.flags & I915_CONTEXT_CLONE_UNKNOWN)
2133− return -EINVAL;
2134−
2135− if (local.rsvd)
2136− return -EINVAL;
2137−
2138− rcu_read_lock();
2139− src = __i915_gem_context_lookup_rcu(arg->fpriv, local.clone_id);
2140− rcu_read_unlock();
2141− if (!src)
2142− return -ENOENT;
2143−
2144− GEM_BUG_ON(src == dst);
2145−
2146− for (bit = 0; bit < ARRAY_SIZE(fn); bit++) {
2147− if (!(local.flags & BIT(bit)))
2148− continue;
2149−
2150− err = fn[bit](dst, src);
2151− if (err)
2152− return err;
2153− }
2154−
2155− return 0;
1962+ return -EINVAL;
21561963 }
21571964
21581965 static const i915_user_extension_fn create_extensions[] = {
21591966 [I915_CONTEXT_CREATE_EXT_SETPARAM] = create_setparam,
2160− [I915_CONTEXT_CREATE_EXT_CLONE] = create_clone,
1967+ [I915_CONTEXT_CREATE_EXT_CLONE] = invalid_ext,
21611968 };
21621969
21631970 static bool client_is_banned(struct drm_i915_file_private *file_priv)
drivers/gpu/drm/i915/gt/intel_execlists_submission.c+0−28
@@ -3850,34 +3850,6 @@ err_put: · 3849 unmodified lines
38503850 return ERR_PTR(err);
38513851 }
38523852
3853−struct intel_context *
3854−intel_execlists_clone_virtual(struct intel_engine_cs *src)
3855−{
3856− struct virtual_engine *se = to_virtual_engine(src);
3857− struct intel_context *dst;
3858−
3859− dst = intel_execlists_create_virtual(se->siblings,
3860− se->num_siblings);
3861− if (IS_ERR(dst))
3862− return dst;
3863−
3864− if (se->num_bonds) {
3865− struct virtual_engine *de = to_virtual_engine(dst->engine);
3866−
3867− de->bonds = kmemdup(se->bonds,
3868− sizeof(*se->bonds) * se->num_bonds,
3869− GFP_KERNEL);
3870− if (!de->bonds) {
3871− intel_context_put(dst);
3872− return ERR_PTR(-ENOMEM);
3873− }
3874−
3875− de->num_bonds = se->num_bonds;
3876− }
3877−
3878− return dst;
3879−}
3880−
38813853 int intel_virtual_engine_attach_bond(struct intel_engine_cs *engine,
38823854 const struct intel_engine_cs *master,
38833855 const struct intel_engine_cs *sibling)
drivers/gpu/drm/i915/gt/intel_execlists_submission.h+0−3
@@ -36,9 +36,6 @@ struct intel_context * · 35 unmodified lines
3636 intel_execlists_create_virtual(struct intel_engine_cs **siblings,
3737 unsigned int count);
3838
39−struct intel_context *
40−intel_execlists_clone_virtual(struct intel_engine_cs *src);
41−
4239 int intel_virtual_engine_attach_bond(struct intel_engine_cs *engine,
4340 const struct intel_engine_cs *master,
4441 const struct intel_engine_cs *sibling);
include/uapi/drm/i915_drm.h+3−13
@@ -2006,20 +2006,10 @@ struct drm_i915_gem_context_create_ext_setparam { · 2005 unmodified lines
20062006 struct drm_i915_gem_context_param param;
20072007 };
20082008
2009−struct drm_i915_gem_context_create_ext_clone {
2009+/* This API has been removed. On the off chance someone somewhere has
2010+ * attempted to use it, never re-use this extension number.
2011+ */
20102012 #define I915_CONTEXT_CREATE_EXT_CLONE 1
2011− struct i915_user_extension base;
2012− __u32 clone_id;
2013− __u32 flags;
2014−#define I915_CONTEXT_CLONE_ENGINES (1u << 0)
2015−#define I915_CONTEXT_CLONE_FLAGS (1u << 1)
2016−#define I915_CONTEXT_CLONE_SCHEDATTR (1u << 2)
2017−#define I915_CONTEXT_CLONE_SSEU (1u << 3)
2018−#define I915_CONTEXT_CLONE_TIMELINE (1u << 4)
2019−#define I915_CONTEXT_CLONE_VM (1u << 5)
2020−#define I915_CONTEXT_CLONE_UNKNOWN -(I915_CONTEXT_CLONE_VM << 1)
2021− __u64 rsvd;
2022−};
20232013
20242014 struct drm_i915_gem_context_destroy {
20252015 __u32 ctx_id;