History

Merge tag 'drm-intel-fixes-2022-06-16' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes

drm/i915 fixes for v5.19-rc3: - Fix page fault on error state read - Fix memory leaks in per-gt sysfs - Fix multiple fence handling - Remove accidental static from a local variable

Dave Airlie committed 4 years ago

Commit 3f0acf22 parents 2f90ec1 2636e008 files · +62 −47Browse files

Unified · Split

8 files
  1. drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +2 −1
  2. drivers/gpu/drm/i915/gt/intel_gt.c +1 −0
  3. drivers/gpu/drm/i915/gt/intel_gt_sysfs.c +12 −17
  4. drivers/gpu/drm/i915/gt/intel_gt_sysfs.h +1 −5
  5. drivers/gpu/drm/i915/gt/intel_gt_types.h +3 −0
  6. drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c +1 −1
  7. drivers/gpu/drm/i915/i915_sysfs.c +14 −3
  8. drivers/gpu/drm/i915/i915_vma.c +28 −20
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c+2−1
@@ -999,7 +999,8 @@ static int eb_validate_vmas(struct i915_execbuffer *eb) · 998 unmodified lines
999999 }
10001000 }
10011001
1002− err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
1002+ /* Reserve enough slots to accommodate composite fences */
1003+ err = dma_resv_reserve_fences(vma->obj->base.resv, eb->num_batches);
10031004 if (err)
10041005 return err;
10051006
drivers/gpu/drm/i915/gt/intel_gt.c+1−0
@@ -785,6 +785,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt) · 784 unmodified lines
785785 {
786786 intel_wakeref_t wakeref;
787787
788+ intel_gt_sysfs_unregister(gt);
788789 intel_rps_driver_unregister(&gt->rps);
789790 intel_gsc_fini(&gt->gsc);
790791
drivers/gpu/drm/i915/gt/intel_gt_sysfs.c+12−17
@@ -24,7 +24,7 @@ bool is_object_gt(struct kobject *kobj) · 23 unmodified lines
2424
2525 static struct intel_gt *kobj_to_gt(struct kobject *kobj)
2626 {
27− return container_of(kobj, struct kobj_gt, base)->gt;
27+ return container_of(kobj, struct intel_gt, sysfs_gt);
2828 }
2929
3030 struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
@@ -72,9 +72,9 @@ static struct attribute *id_attrs[] = { · 41 unmodified lines
7272 };
7373 ATTRIBUTE_GROUPS(id);
7474
75+/* A kobject needs a release() method even if it does nothing */
7576 static void kobj_gt_release(struct kobject *kobj)
7677 {
77− kfree(kobj);
7878 }
7979
8080 static struct kobj_type kobj_gt_type = {
@@ -85,8 +85,6 @@ static struct kobj_type kobj_gt_type = { · 4 unmodified lines
8585
8686 void intel_gt_sysfs_register(struct intel_gt *gt)
8787 {
88− struct kobj_gt *kg;
89−
9088 /*
9189 * We need to make things right with the
9290 * ABI compatibility. The files were originally
@@ -98,25 +96,22 @@ void intel_gt_sysfs_register(struct intel_gt *gt) · 5 unmodified lines
9896 if (gt_is_root(gt))
9997 intel_gt_sysfs_pm_init(gt, gt_get_parent_obj(gt));
10098
101− kg = kzalloc(sizeof(*kg), GFP_KERNEL);
102− if (!kg)
99+ /* init and xfer ownership to sysfs tree */
100+ if (kobject_init_and_add(&gt->sysfs_gt, &kobj_gt_type,
101+ gt->i915->sysfs_gt, "gt%d", gt->info.id))
103102 goto exit_fail;
104103
105− kobject_init(&kg->base, &kobj_gt_type);
106− kg->gt = gt;
107−
108− /* xfer ownership to sysfs tree */
109− if (kobject_add(&kg->base, gt->i915->sysfs_gt, "gt%d", gt->info.id))
110− goto exit_kobj_put;
111−
112− intel_gt_sysfs_pm_init(gt, &kg->base);
104+ intel_gt_sysfs_pm_init(gt, &gt->sysfs_gt);
113105
114106 return;
115107
116−exit_kobj_put:
117− kobject_put(&kg->base);
118−
119108 exit_fail:
109+ kobject_put(&gt->sysfs_gt);
120110 drm_warn(&gt->i915->drm,
121111 "failed to initialize gt%d sysfs root\n", gt->info.id);
122112 }
113+
114+void intel_gt_sysfs_unregister(struct intel_gt *gt)
115+{
116+ kobject_put(&gt->sysfs_gt);
117+}
drivers/gpu/drm/i915/gt/intel_gt_sysfs.h+1−5
@@ -13,11 +13,6 @@ · 12 unmodified lines
1313
1414 struct intel_gt;
1515
16−struct kobj_gt {
17− struct kobject base;
18− struct intel_gt *gt;
19−};
20−
2116 bool is_object_gt(struct kobject *kobj);
2217
2318 struct drm_i915_private *kobj_to_i915(struct kobject *kobj);
@@ -28,6 +23,7 @@ intel_gt_create_kobj(struct intel_gt *gt, · 4 unmodified lines
2823 const char *name);
2924
3025 void intel_gt_sysfs_register(struct intel_gt *gt);
26+void intel_gt_sysfs_unregister(struct intel_gt *gt);
3127 struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
3228 const char *name);
3329
drivers/gpu/drm/i915/gt/intel_gt_types.h+3−0
@@ -224,6 +224,9 @@ struct intel_gt { · 223 unmodified lines
224224 } mocs;
225225
226226 struct intel_pxp pxp;
227+
228+ /* gt/gtN sysfs */
229+ struct kobject sysfs_gt;
227230 };
228231
229232 enum intel_gt_scratch_field {
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c+1−1
@@ -156,7 +156,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw) · 155 unmodified lines
156156 [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
157157 [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
158158 };
159− static const struct uc_fw_platform_requirement *fw_blobs;
159+ const struct uc_fw_platform_requirement *fw_blobs;
160160 enum intel_platform p = INTEL_INFO(i915)->platform;
161161 u32 fw_count;
162162 u8 rev = INTEL_REVID(i915);
drivers/gpu/drm/i915/i915_sysfs.c+14−3
@@ -166,7 +166,14 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj, · 165 unmodified lines
166166 struct device *kdev = kobj_to_dev(kobj);
167167 struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
168168 struct i915_gpu_coredump *gpu;
169− ssize_t ret;
169+ ssize_t ret = 0;
170+
171+ /*
172+ * FIXME: Concurrent clients triggering resets and reading + clearing
173+ * dumps can cause inconsistent sysfs reads when a user calls in with a
174+ * non-zero offset to complete a prior partial read but the
175+ * gpu_coredump has been cleared or replaced.
176+ */
170177
171178 gpu = i915_first_error_state(i915);
172179 if (IS_ERR(gpu)) {
@@ -178,8 +185,10 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj, · 5 unmodified lines
178185 const char *str = "No error state collected\n";
179186 size_t len = strlen(str);
180187
181− ret = min_t(size_t, count, len - off);
182− memcpy(buf, str + off, ret);
188+ if (off < len) {
189+ ret = min_t(size_t, count, len - off);
190+ memcpy(buf, str + off, ret);
191+ }
183192 }
184193
185194 return ret;
@@ -259,4 +268,6 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv) · 73 unmodified lines
259268
260269 device_remove_bin_file(kdev, &dpf_attrs_1);
261270 device_remove_bin_file(kdev, &dpf_attrs);
271+
272+ kobject_put(dev_priv->sysfs_gt);
262273 }
drivers/gpu/drm/i915/i915_vma.c+28−20
@@ -23,6 +23,7 @@ · 22 unmodified lines
2323 */
2424
2525 #include <linux/sched/mm.h>
26+#include <linux/dma-fence-array.h>
2627 #include <drm/drm_gem.h>
2728
2829 #include "display/intel_frontbuffer.h"
@@ -1823,6 +1824,21 @@ int _i915_vma_move_to_active(struct i915_vma *vma, · 1794 unmodified lines
18231824 if (unlikely(err))
18241825 return err;
18251826
1827+ /*
1828+ * Reserve fences slot early to prevent an allocation after preparing
1829+ * the workload and associating fences with dma_resv.
1830+ */
1831+ if (fence && !(flags & __EXEC_OBJECT_NO_RESERVE)) {
1832+ struct dma_fence *curr;
1833+ int idx;
1834+
1835+ dma_fence_array_for_each(curr, idx, fence)
1836+ ;
1837+ err = dma_resv_reserve_fences(vma->obj->base.resv, idx);
1838+ if (unlikely(err))
1839+ return err;
1840+ }
1841+
18261842 if (flags & EXEC_OBJECT_WRITE) {
18271843 struct intel_frontbuffer *front;
18281844
@@ -1832,31 +1848,23 @@ int _i915_vma_move_to_active(struct i915_vma *vma, · 3 unmodified lines
18321848 i915_active_add_request(&front->write, rq);
18331849 intel_frontbuffer_put(front);
18341850 }
1851+ }
18351852
1836− if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
1837− err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
1838− if (unlikely(err))
1839− return err;
1840− }
1853+ if (fence) {
1854+ struct dma_fence *curr;
1855+ enum dma_resv_usage usage;
1856+ int idx;
18411857
1842− if (fence) {
1843− dma_resv_add_fence(vma->obj->base.resv, fence,
1844− DMA_RESV_USAGE_WRITE);
1858+ obj->read_domains = 0;
1859+ if (flags & EXEC_OBJECT_WRITE) {
1860+ usage = DMA_RESV_USAGE_WRITE;
18451861 obj->write_domain = I915_GEM_DOMAIN_RENDER;
1846− obj->read_domains = 0;
1847− }
1848− } else {
1849− if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
1850− err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
1851− if (unlikely(err))
1852− return err;
1862+ } else {
1863+ usage = DMA_RESV_USAGE_READ;
18531864 }
18541865
1855− if (fence) {
1856− dma_resv_add_fence(vma->obj->base.resv, fence,
1857− DMA_RESV_USAGE_READ);
1858− obj->write_domain = 0;
1859− }
1866+ dma_fence_array_for_each(curr, idx, fence)
1867+ dma_resv_add_fence(vma->obj->base.resv, curr, usage);
18601868 }
18611869
18621870 if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence)