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
1957 return ctx_setparam(arg->fpriv, arg->ctx, &local.param);1957 return ctx_setparam(arg->fpriv, arg->ctx, &local.param);
1958}1958}
1959 1959
1960static int clone_engines(struct i915_gem_context *dst,1960static int invalid_ext(struct i915_user_extension __user *ext, void *data)
1961 struct i915_gem_context *src)
1962{1961{
1963 struct i915_gem_engines *clone, *e;1962 return -EINVAL;
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
2016err_unlock:
2017 i915_sw_fence_complete(&e->fence);
2018 return -ENOMEM;
2019}
2020
2021static 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
2028static 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
2035static 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;
2069unlock:
2070 i915_gem_context_unlock_engines(src);
2071 return err;
2072}
2073
2074static 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
2083static 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
2107static 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;
2156}1963}
2157 1964
2158static const i915_user_extension_fn create_extensions[] = {1965static const i915_user_extension_fn create_extensions[] = {
2159 [I915_CONTEXT_CREATE_EXT_SETPARAM] = create_setparam,1966 [I915_CONTEXT_CREATE_EXT_SETPARAM] = create_setparam,
2160 [I915_CONTEXT_CREATE_EXT_CLONE] = create_clone,1967 [I915_CONTEXT_CREATE_EXT_CLONE] = invalid_ext,
2161};1968};
2162 1969
2163static bool client_is_banned(struct drm_i915_file_private *file_priv)1970static 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
3850 return ERR_PTR(err);3850 return ERR_PTR(err);
3851}3851}
3852 3852
3853struct intel_context *
3854intel_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
3881int intel_virtual_engine_attach_bond(struct intel_engine_cs *engine,3853int intel_virtual_engine_attach_bond(struct intel_engine_cs *engine,
3882 const struct intel_engine_cs *master,3854 const struct intel_engine_cs *master,
3883 const struct intel_engine_cs *sibling)3855 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
36intel_execlists_create_virtual(struct intel_engine_cs **siblings,36intel_execlists_create_virtual(struct intel_engine_cs **siblings,
37 unsigned int count);37 unsigned int count);
38 38
39struct intel_context *
40intel_execlists_clone_virtual(struct intel_engine_cs *src);
41
42int intel_virtual_engine_attach_bond(struct intel_engine_cs *engine,39int intel_virtual_engine_attach_bond(struct intel_engine_cs *engine,
43 const struct intel_engine_cs *master,40 const struct intel_engine_cs *master,
44 const struct intel_engine_cs *sibling);41 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
2006 struct drm_i915_gem_context_param param;2006 struct drm_i915_gem_context_param param;
2007};2007};
2008 2008
2009struct 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 */
2010#define I915_CONTEXT_CREATE_EXT_CLONE 12012#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};
2023 2013
2024struct drm_i915_gem_context_destroy {2014struct drm_i915_gem_context_destroy {
2025 __u32 ctx_id;2015 __u32 ctx_id;