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
999 }999 }
1000 }1000 }
1001 1001
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);
1003 if (err)1004 if (err)
1004 return err;1005 return err;
1005 1006
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
785{785{
786 intel_wakeref_t wakeref;786 intel_wakeref_t wakeref;
787 787
788 intel_gt_sysfs_unregister(gt);
788 intel_rps_driver_unregister(&gt->rps);789 intel_rps_driver_unregister(&gt->rps);
789 intel_gsc_fini(&gt->gsc);790 intel_gsc_fini(&gt->gsc);
790 791
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
24 24
25static struct intel_gt *kobj_to_gt(struct kobject *kobj)25static struct intel_gt *kobj_to_gt(struct kobject *kobj)
26{26{
27 return container_of(kobj, struct kobj_gt, base)->gt;27 return container_of(kobj, struct intel_gt, sysfs_gt);
28}28}
29 29
30struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,30struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
@@ -72,9 +72,9 @@ static struct attribute *id_attrs[] = { · 41 unmodified lines
72};72};
73ATTRIBUTE_GROUPS(id);73ATTRIBUTE_GROUPS(id);
74 74
75/* A kobject needs a release() method even if it does nothing */
75static void kobj_gt_release(struct kobject *kobj)76static void kobj_gt_release(struct kobject *kobj)
76{77{
77 kfree(kobj);
78}78}
79 79
80static struct kobj_type kobj_gt_type = {80static struct kobj_type kobj_gt_type = {
@@ -85,8 +85,6 @@ static struct kobj_type kobj_gt_type = { · 4 unmodified lines
85 85
86void intel_gt_sysfs_register(struct intel_gt *gt)86void intel_gt_sysfs_register(struct intel_gt *gt)
87{87{
88 struct kobj_gt *kg;
89
90 /*88 /*
91 * We need to make things right with the89 * We need to make things right with the
92 * ABI compatibility. The files were originally90 * ABI compatibility. The files were originally
@@ -98,25 +96,22 @@ void intel_gt_sysfs_register(struct intel_gt *gt) · 5 unmodified lines
98 if (gt_is_root(gt))96 if (gt_is_root(gt))
99 intel_gt_sysfs_pm_init(gt, gt_get_parent_obj(gt));97 intel_gt_sysfs_pm_init(gt, gt_get_parent_obj(gt));
100 98
101 kg = kzalloc(sizeof(*kg), GFP_KERNEL);99 /* init and xfer ownership to sysfs tree */
102 if (!kg)100 if (kobject_init_and_add(&gt->sysfs_gt, &kobj_gt_type,
101 gt->i915->sysfs_gt, "gt%d", gt->info.id))
103 goto exit_fail;102 goto exit_fail;
104 103
105 kobject_init(&kg->base, &kobj_gt_type);104 intel_gt_sysfs_pm_init(gt, &gt->sysfs_gt);
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);
113 105
114 return;106 return;
115 107
116exit_kobj_put:
117 kobject_put(&kg->base);
118
119exit_fail:108exit_fail:
109 kobject_put(&gt->sysfs_gt);
120 drm_warn(&gt->i915->drm,110 drm_warn(&gt->i915->drm,
121 "failed to initialize gt%d sysfs root\n", gt->info.id);111 "failed to initialize gt%d sysfs root\n", gt->info.id);
122}112}
113
114void 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
13 13
14struct intel_gt;14struct intel_gt;
15 15
16struct kobj_gt {
17 struct kobject base;
18 struct intel_gt *gt;
19};
20
21bool is_object_gt(struct kobject *kobj);16bool is_object_gt(struct kobject *kobj);
22 17
23struct drm_i915_private *kobj_to_i915(struct kobject *kobj);18struct drm_i915_private *kobj_to_i915(struct kobject *kobj);
@@ -28,6 +23,7 @@ intel_gt_create_kobj(struct intel_gt *gt, · 4 unmodified lines
28 const char *name);23 const char *name);
29 24
30void intel_gt_sysfs_register(struct intel_gt *gt);25void intel_gt_sysfs_register(struct intel_gt *gt);
26void intel_gt_sysfs_unregister(struct intel_gt *gt);
31struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,27struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
32 const char *name);28 const char *name);
33 29
drivers/gpu/drm/i915/gt/intel_gt_types.h+3−0
@@ -224,6 +224,9 @@ struct intel_gt { · 223 unmodified lines
224 } mocs;224 } mocs;
225 225
226 struct intel_pxp pxp;226 struct intel_pxp pxp;
227
228 /* gt/gtN sysfs */
229 struct kobject sysfs_gt;
227};230};
228 231
229enum intel_gt_scratch_field {232enum 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
156 [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },156 [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
157 [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },157 [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
158 };158 };
159 static const struct uc_fw_platform_requirement *fw_blobs;159 const struct uc_fw_platform_requirement *fw_blobs;
160 enum intel_platform p = INTEL_INFO(i915)->platform;160 enum intel_platform p = INTEL_INFO(i915)->platform;
161 u32 fw_count;161 u32 fw_count;
162 u8 rev = INTEL_REVID(i915);162 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
166 struct device *kdev = kobj_to_dev(kobj);166 struct device *kdev = kobj_to_dev(kobj);
167 struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);167 struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
168 struct i915_gpu_coredump *gpu;168 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 */
170 177
171 gpu = i915_first_error_state(i915);178 gpu = i915_first_error_state(i915);
172 if (IS_ERR(gpu)) {179 if (IS_ERR(gpu)) {
@@ -178,8 +185,10 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj, · 5 unmodified lines
178 const char *str = "No error state collected\n";185 const char *str = "No error state collected\n";
179 size_t len = strlen(str);186 size_t len = strlen(str);
180 187
181 ret = min_t(size_t, count, len - off);188 if (off < len) {
182 memcpy(buf, str + off, ret);189 ret = min_t(size_t, count, len - off);
190 memcpy(buf, str + off, ret);
191 }
183 }192 }
184 193
185 return ret;194 return ret;
@@ -259,4 +268,6 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv) · 73 unmodified lines
259 268
260 device_remove_bin_file(kdev, &dpf_attrs_1);269 device_remove_bin_file(kdev, &dpf_attrs_1);
261 device_remove_bin_file(kdev, &dpf_attrs);270 device_remove_bin_file(kdev, &dpf_attrs);
271
272 kobject_put(dev_priv->sysfs_gt);
262}273}
drivers/gpu/drm/i915/i915_vma.c+28−20
@@ -23,6 +23,7 @@ · 22 unmodified lines
23 */23 */
24 24
25#include <linux/sched/mm.h>25#include <linux/sched/mm.h>
26#include <linux/dma-fence-array.h>
26#include <drm/drm_gem.h>27#include <drm/drm_gem.h>
27 28
28#include "display/intel_frontbuffer.h"29#include "display/intel_frontbuffer.h"
@@ -1823,6 +1824,21 @@ int _i915_vma_move_to_active(struct i915_vma *vma, · 1794 unmodified lines
1823 if (unlikely(err))1824 if (unlikely(err))
1824 return err;1825 return err;
1825 1826
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
1826 if (flags & EXEC_OBJECT_WRITE) {1842 if (flags & EXEC_OBJECT_WRITE) {
1827 struct intel_frontbuffer *front;1843 struct intel_frontbuffer *front;
1828 1844
@@ -1832,31 +1848,23 @@ int _i915_vma_move_to_active(struct i915_vma *vma, · 3 unmodified lines
1832 i915_active_add_request(&front->write, rq);1848 i915_active_add_request(&front->write, rq);
1833 intel_frontbuffer_put(front);1849 intel_frontbuffer_put(front);
1834 }1850 }
1851 }
1835 1852
1836 if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {1853 if (fence) {
1837 err = dma_resv_reserve_fences(vma->obj->base.resv, 1);1854 struct dma_fence *curr;
1838 if (unlikely(err))1855 enum dma_resv_usage usage;
1839 return err;1856 int idx;
1840 }
1841 1857
1842 if (fence) {1858 obj->read_domains = 0;
1843 dma_resv_add_fence(vma->obj->base.resv, fence,1859 if (flags & EXEC_OBJECT_WRITE) {
1844 DMA_RESV_USAGE_WRITE);1860 usage = DMA_RESV_USAGE_WRITE;
1845 obj->write_domain = I915_GEM_DOMAIN_RENDER;1861 obj->write_domain = I915_GEM_DOMAIN_RENDER;
1846 obj->read_domains = 0;1862 } else {
1847 }1863 usage = DMA_RESV_USAGE_READ;
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;
1853 }1864 }
1854 1865
1855 if (fence) {1866 dma_fence_array_for_each(curr, idx, fence)
1856 dma_resv_add_fence(vma->obj->base.resv, fence,1867 dma_resv_add_fence(vma->obj->base.resv, curr, usage);
1857 DMA_RESV_USAGE_READ);
1858 obj->write_domain = 0;
1859 }
1860 }1868 }
1861 1869
1862 if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence)1870 if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence)