Skip to content

Commit bf7172c

Browse files
mwajdeczrodrigovivi
authored andcommitted
drm/xe/pf: Fix sysfs initialization
In case of devm_add_action_or_reset() failure the provided cleanup action will be run immediately on the not yet initialized kobject. This may lead to errors like: [ ] kobject: '(null)' (ff110001393608e0): is not initialized, yet kobject_put() is being called. [ ] WARNING: lib/kobject.c:734 at kobject_put+0xd9/0x250, CPU#0: kworker/0:0/9 [ ] RIP: 0010:kobject_put+0xdf/0x250 [ ] Call Trace: [ ] xe_sriov_pf_sysfs_init+0x21/0x100 [xe] [ ] xe_sriov_pf_init_late+0x87/0x2b0 [xe] [ ] xe_sriov_init_late+0x5f/0x2c0 [xe] [ ] xe_device_probe+0x5f2/0xc20 [xe] [ ] xe_pci_probe+0x396/0x610 [xe] [ ] local_pci_probe+0x47/0xb0 [ ] refcount_t: underflow; use-after-free. [ ] WARNING: lib/refcount.c:28 at refcount_warn_saturate+0x68/0xb0, CPU#0: kworker/0:0/9 [ ] RIP: 0010:refcount_warn_saturate+0x68/0xb0 [ ] Call Trace: [ ] kobject_put+0x174/0x250 [ ] xe_sriov_pf_sysfs_init+0x21/0x100 [xe] [ ] xe_sriov_pf_init_late+0x87/0x2b0 [xe] [ ] xe_sriov_init_late+0x5f/0x2c0 [xe] [ ] xe_device_probe+0x5f2/0xc20 [xe] [ ] xe_pci_probe+0x396/0x610 [xe] [ ] local_pci_probe+0x47/0xb0 Fix that by calling kobject_init() and kobject_add() separately and register cleanup action after the kobject is initialized. Also make this cleanup registration a part of the create helper to fix another mistake, as in the loop we were wrongly passing parent kobject while registering cleanup action, and this resulted in some undetected leaks. Fixes: 5c170a4 ("drm/xe/pf: Prepare sysfs for SR-IOV admin attributes") Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Shuicheng Lin <shuicheng.lin@intel.com> Link: https://patch.msgid.link/20260203235332.1350-1-michal.wajdeczko@intel.com (cherry picked from commit 98b1672) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
1 parent 2f5db9b commit bf7172c

1 file changed

Lines changed: 26 additions & 28 deletions

File tree

drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -349,18 +349,33 @@ static const struct attribute_group *xe_sriov_vf_attr_groups[] = {
349349

350350
/* no user serviceable parts below */
351351

352-
static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid)
352+
static void action_put_kobject(void *arg)
353+
{
354+
struct kobject *kobj = arg;
355+
356+
kobject_put(kobj);
357+
}
358+
359+
static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid,
360+
const struct kobj_type *ktype)
353361
{
354362
struct xe_sriov_kobj *vkobj;
363+
int err;
355364

356365
xe_sriov_pf_assert_vfid(xe, vfid);
357366

358367
vkobj = kzalloc(sizeof(*vkobj), GFP_KERNEL);
359368
if (!vkobj)
360-
return NULL;
369+
return ERR_PTR(-ENOMEM);
361370

362371
vkobj->xe = xe;
363372
vkobj->vfid = vfid;
373+
kobject_init(&vkobj->base, ktype);
374+
375+
err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, &vkobj->base);
376+
if (err)
377+
return ERR_PTR(err);
378+
364379
return &vkobj->base;
365380
}
366381

@@ -463,28 +478,17 @@ static void pf_sysfs_note(struct xe_device *xe, int err, const char *what)
463478
xe_sriov_dbg(xe, "Failed to setup sysfs %s (%pe)\n", what, ERR_PTR(err));
464479
}
465480

466-
static void action_put_kobject(void *arg)
467-
{
468-
struct kobject *kobj = arg;
469-
470-
kobject_put(kobj);
471-
}
472-
473481
static int pf_setup_root(struct xe_device *xe)
474482
{
475483
struct kobject *parent = &xe->drm.dev->kobj;
476484
struct kobject *root;
477485
int err;
478486

479-
root = create_xe_sriov_kobj(xe, PFID);
480-
if (!root)
481-
return pf_sysfs_error(xe, -ENOMEM, "root obj");
482-
483-
err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root);
484-
if (err)
485-
return pf_sysfs_error(xe, err, "root action");
487+
root = create_xe_sriov_kobj(xe, PFID, &xe_sriov_dev_ktype);
488+
if (IS_ERR(root))
489+
return pf_sysfs_error(xe, PTR_ERR(root), "root obj");
486490

487-
err = kobject_init_and_add(root, &xe_sriov_dev_ktype, parent, "sriov_admin");
491+
err = kobject_add(root, parent, "sriov_admin");
488492
if (err)
489493
return pf_sysfs_error(xe, err, "root init");
490494

@@ -505,20 +509,14 @@ static int pf_setup_tree(struct xe_device *xe)
505509
root = xe->sriov.pf.sysfs.root;
506510

507511
for (n = 0; n <= totalvfs; n++) {
508-
kobj = create_xe_sriov_kobj(xe, VFID(n));
509-
if (!kobj)
510-
return pf_sysfs_error(xe, -ENOMEM, "tree obj");
511-
512-
err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root);
513-
if (err)
514-
return pf_sysfs_error(xe, err, "tree action");
512+
kobj = create_xe_sriov_kobj(xe, VFID(n), &xe_sriov_vf_ktype);
513+
if (IS_ERR(kobj))
514+
return pf_sysfs_error(xe, PTR_ERR(kobj), "tree obj");
515515

516516
if (n)
517-
err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype,
518-
root, "vf%u", n);
517+
err = kobject_add(kobj, root, "vf%u", n);
519518
else
520-
err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype,
521-
root, "pf");
519+
err = kobject_add(kobj, root, "pf");
522520
if (err)
523521
return pf_sysfs_error(xe, err, "tree init");
524522

0 commit comments

Comments
 (0)