Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Parse command buffer earlier in eb_relocate(slow)

We want to introduce backoff logic, but we need to lock the
pool object as well for command parsing. Because of this, we
will need backoff logic for the engine pool obj, move the batch
validation up slightly to eb_lookup_vmas, and the actual command
parsing in a separate function which can get called from execbuf
relocation fast and slowpath.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Thomas Hellström <thomas.hellstrom@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200819140904.1708856-8-maarten.lankhorst@linux.intel.com
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

authored by

Maarten Lankhorst and committed by
Joonas Lahtinen
8e4ba491 1af343cd

+37 -31
+37 -31
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
··· 296 296 unsigned long num_fences; 297 297 }; 298 298 299 + static int eb_parse(struct i915_execbuffer *eb); 300 + 299 301 static inline bool eb_use_cmdparser(const struct i915_execbuffer *eb) 300 302 { 301 303 return intel_engine_requires_cmd_parser(eb->engine) || ··· 845 843 846 844 static int eb_lookup_vmas(struct i915_execbuffer *eb) 847 845 { 846 + struct drm_i915_private *i915 = eb->i915; 848 847 unsigned int batch = eb_batch_index(eb); 849 848 unsigned int i; 850 849 int err = 0; ··· 859 856 vma = eb_lookup_vma(eb, eb->exec[i].handle); 860 857 if (IS_ERR(vma)) { 861 858 err = PTR_ERR(vma); 862 - break; 859 + goto err; 863 860 } 864 861 865 862 err = eb_validate_vma(eb, &eb->exec[i], vma); 866 863 if (unlikely(err)) { 867 864 i915_vma_put(vma); 868 - break; 865 + goto err; 869 866 } 870 867 871 868 eb_add_vma(eb, i, batch, vma); 872 869 } 873 870 871 + if (unlikely(eb->batch->flags & EXEC_OBJECT_WRITE)) { 872 + drm_dbg(&i915->drm, 873 + "Attempting to use self-modifying batch buffer\n"); 874 + return -EINVAL; 875 + } 876 + 877 + if (range_overflows_t(u64, 878 + eb->batch_start_offset, eb->batch_len, 879 + eb->batch->vma->size)) { 880 + drm_dbg(&i915->drm, "Attempting to use out-of-bounds batch\n"); 881 + return -EINVAL; 882 + } 883 + 884 + if (eb->batch_len == 0) 885 + eb->batch_len = eb->batch->vma->size - eb->batch_start_offset; 886 + 887 + return 0; 888 + 889 + err: 874 890 eb->vma[i].vma = NULL; 875 891 return err; 876 892 } ··· 1824 1802 return 0; 1825 1803 } 1826 1804 1827 - static noinline int eb_relocate_slow(struct i915_execbuffer *eb) 1805 + static noinline int eb_relocate_parse_slow(struct i915_execbuffer *eb) 1828 1806 { 1829 1807 bool have_copy = false; 1830 1808 struct eb_vma *ev; ··· 1889 1867 if (err) 1890 1868 goto err; 1891 1869 1870 + /* as last step, parse the command buffer */ 1871 + err = eb_parse(eb); 1872 + if (err) 1873 + goto err; 1874 + 1892 1875 /* 1893 1876 * Leave the user relocations as are, this is the painfully slow path, 1894 1877 * and we want to avoid the complication of dropping the lock whilst ··· 1926 1899 return err; 1927 1900 } 1928 1901 1929 - static int eb_relocate(struct i915_execbuffer *eb) 1902 + static int eb_relocate_parse(struct i915_execbuffer *eb) 1930 1903 { 1931 1904 int err; 1932 1905 ··· 1951 1924 } 1952 1925 1953 1926 if (err) 1954 - return eb_relocate_slow(eb); 1927 + return eb_relocate_parse_slow(eb); 1955 1928 } 1956 1929 1957 - return 0; 1930 + return eb_parse(eb); 1958 1931 } 1959 1932 1960 1933 static int eb_move_to_gpu(struct i915_execbuffer *eb) ··· 3072 3045 if (unlikely(err)) 3073 3046 goto err_context; 3074 3047 3075 - err = eb_relocate(&eb); 3048 + err = eb_relocate_parse(&eb); 3076 3049 if (err) { 3077 3050 /* 3078 3051 * If the user expects the execobject.offset and ··· 3085 3058 goto err_vma; 3086 3059 } 3087 3060 3088 - if (unlikely(eb.batch->flags & EXEC_OBJECT_WRITE)) { 3089 - drm_dbg(&i915->drm, 3090 - "Attempting to use self-modifying batch buffer\n"); 3091 - err = -EINVAL; 3092 - goto err_vma; 3093 - } 3094 - 3095 - if (range_overflows_t(u64, 3096 - eb.batch_start_offset, eb.batch_len, 3097 - eb.batch->vma->size)) { 3098 - drm_dbg(&i915->drm, "Attempting to use out-of-bounds batch\n"); 3099 - err = -EINVAL; 3100 - goto err_vma; 3101 - } 3102 - 3103 - if (eb.batch_len == 0) 3104 - eb.batch_len = eb.batch->vma->size - eb.batch_start_offset; 3105 - 3106 - err = eb_parse(&eb); 3107 - if (err) 3108 - goto err_vma; 3109 - 3110 3061 /* 3111 3062 * snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure 3112 3063 * batch" bit. Hence we need to pin secure batches into the global gtt. 3113 3064 * hsw should have this fixed, but bdw mucks it up again. */ 3114 - batch = eb.batch->vma; 3115 3065 if (eb.batch_flags & I915_DISPATCH_SECURE) { 3116 3066 struct i915_vma *vma; 3117 3067 ··· 3102 3098 * fitting due to fragmentation. 3103 3099 * So this is actually safe. 3104 3100 */ 3105 - vma = i915_gem_object_ggtt_pin(batch->obj, NULL, 0, 0, 0); 3101 + vma = i915_gem_object_ggtt_pin(eb.batch->vma->obj, NULL, 0, 0, 0); 3106 3102 if (IS_ERR(vma)) { 3107 3103 err = PTR_ERR(vma); 3108 3104 goto err_parse; 3109 3105 } 3110 3106 3111 3107 batch = vma; 3108 + } else { 3109 + batch = eb.batch->vma; 3112 3110 } 3113 3111 3114 3112 /* All GPU relocation batches must be submitted prior to the user rq */