| @@ -71,6 +71,7 @@ · 70 unmodified lines |
| 71 | 71 | |
| 72 | 72 | #include "gt/gen6_ppgtt.h" |
| 73 | 73 | #include "gt/intel_context.h" |
| 74 | +#include "gt/intel_context_param.h" |
| 74 | 75 | #include "gt/intel_engine_heartbeat.h" |
| 75 | 76 | #include "gt/intel_engine_user.h" |
| 76 | 77 | #include "gt/intel_ring.h" |
| @@ -668,23 +669,30 @@ err_free: · 591 unmodified lines |
| 668 | 669 | return ERR_PTR(err); |
| 669 | 670 | } |
| 670 | 671 | |
| 671 | | −static void |
| 672 | +static int |
| 672 | 673 | 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), |
| 674 | 675 | void *data) |
| 675 | 676 | { |
| 676 | 677 | struct i915_gem_engines_iter it; |
| 677 | 678 | struct intel_context *ce; |
| 679 | + int err = 0; |
| 678 | 680 | |
| 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 | + } |
| 681 | 686 | i915_gem_context_unlock_engines(ctx); |
| 687 | + |
| 688 | + return err; |
| 682 | 689 | } |
| 683 | 690 | |
| 684 | | −static void __apply_ppgtt(struct intel_context *ce, void *vm) |
| 691 | +static int __apply_ppgtt(struct intel_context *ce, void *vm) |
| 685 | 692 | { |
| 686 | 693 | i915_vm_put(ce->vm); |
| 687 | 694 | ce->vm = i915_vm_get(vm); |
| 695 | + return 0; |
| 688 | 696 | } |
| 689 | 697 | |
| 690 | 698 | static struct i915_address_space * |
| @@ -722,9 +730,10 @@ static void __set_timeline(struct intel_timeline **dst, · 31 unmodified lines |
| 722 | 730 | intel_timeline_put(old); |
| 723 | 731 | } |
| 724 | 732 | |
| 725 | | −static void __apply_timeline(struct intel_context *ce, void *timeline) |
| 733 | +static int __apply_timeline(struct intel_context *ce, void *timeline) |
| 726 | 734 | { |
| 727 | 735 | __set_timeline(&ce->timeline, timeline); |
| 736 | + return 0; |
| 728 | 737 | } |
| 729 | 738 | |
| 730 | 739 | static void __assign_timeline(struct i915_gem_context *ctx, |
| @@ -1215,6 +1224,63 @@ out: · 484 unmodified lines |
| 1215 | 1224 | return err; |
| 1216 | 1225 | } |
| 1217 | 1226 | |
| 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 | + |
| 1218 | 1284 | static int |
| 1219 | 1285 | user_to_context_sseu(struct drm_i915_private *i915, |
| 1220 | 1286 | const struct drm_i915_gem_context_param_sseu *user, |
| @@ -1852,17 +1918,19 @@ set_persistence(struct i915_gem_context *ctx, · 631 unmodified lines |
| 1852 | 1918 | return __context_set_persistence(ctx, args->value); |
| 1853 | 1919 | } |
| 1854 | 1920 | |
| 1855 | | −static void __apply_priority(struct intel_context *ce, void *arg) |
| 1921 | +static int __apply_priority(struct intel_context *ce, void *arg) |
| 1856 | 1922 | { |
| 1857 | 1923 | struct i915_gem_context *ctx = arg; |
| 1858 | 1924 | |
| 1859 | 1925 | if (!intel_engine_has_semaphores(ce->engine)) |
| 1860 | | − return; |
| 1926 | + return 0; |
| 1861 | 1927 | |
| 1862 | 1928 | if (ctx->sched.priority >= I915_PRIORITY_NORMAL) |
| 1863 | 1929 | intel_context_set_use_semaphores(ce); |
| 1864 | 1930 | else |
| 1865 | 1931 | intel_context_clear_use_semaphores(ce); |
| 1932 | + |
| 1933 | + return 0; |
| 1866 | 1934 | } |
| 1867 | 1935 | |
| 1868 | 1936 | 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 |
| 1955 | 2023 | ret = set_persistence(ctx, args); |
| 1956 | 2024 | break; |
| 1957 | 2025 | |
| 2026 | + case I915_CONTEXT_PARAM_RINGSIZE: |
| 2027 | + ret = set_ringsize(ctx, args); |
| 2028 | + break; |
| 2029 | + |
| 1958 | 2030 | case I915_CONTEXT_PARAM_BAN_PERIOD: |
| 1959 | 2031 | default: |
| 1960 | 2032 | ret = -EINVAL; |
| @@ -1983,6 +2055,18 @@ static int create_setparam(struct i915_user_extension __user *ext, void *data) · 22 unmodified lines |
| 1983 | 2055 | return ctx_setparam(arg->fpriv, arg->ctx, &local.param); |
| 1984 | 2056 | } |
| 1985 | 2057 | |
| 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 | + |
| 1986 | 2070 | static int clone_engines(struct i915_gem_context *dst, |
| 1987 | 2071 | struct i915_gem_context *src) |
| 1988 | 2072 | { |
| @@ -2026,6 +2110,12 @@ static int clone_engines(struct i915_gem_context *dst, · 37 unmodified lines |
| 2026 | 2110 | } |
| 2027 | 2111 | |
| 2028 | 2112 | 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 | + } |
| 2029 | 2119 | } |
| 2030 | 2120 | clone->num_engines = n; |
| 2031 | 2121 | |
| @@ -2388,6 +2478,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, · 356 unmodified lines |
| 2388 | 2478 | args->value = i915_gem_context_is_persistent(ctx); |
| 2389 | 2479 | break; |
| 2390 | 2480 | |
| 2481 | + case I915_CONTEXT_PARAM_RINGSIZE: |
| 2482 | + ret = get_ringsize(ctx, args); |
| 2483 | + break; |
| 2484 | + |
| 2391 | 2485 | case I915_CONTEXT_PARAM_BAN_PERIOD: |
| 2392 | 2486 | default: |
| 2393 | 2487 | ret = -EINVAL; |