Skip to content

Commit 3f0acf2

Browse files
committed
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 Signed-off-by: Dave Airlie <airlied@redhat.com> From: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/8735g5xd25.fsf@intel.com
2 parents 2f90ec1 + 2636e00 commit 3f0acf2

8 files changed

Lines changed: 62 additions & 47 deletions

File tree

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,8 @@ static int eb_validate_vmas(struct i915_execbuffer *eb)
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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
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

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ bool is_object_gt(struct kobject *kobj)
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[] = {
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 = {
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)
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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@
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,
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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,9 @@ struct intel_gt {
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,14 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
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,
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)
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

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
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,
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,
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)

0 commit comments

Comments
 (0)