Commit 69d6bf5c authored by Ashutosh Dixit's avatar Ashutosh Dixit Committed by Tvrtko Ursulin

drm/i915/gt: Fix memory leaks in per-gt sysfs

All kmalloc'd kobjects need a kobject_put() to free memory. For example in
previous code, kobj_gt_release() never gets called. The requirement of
kobject_put() now results in a slightly different code organization.

v2: s/gtn/gt/ (Andi)

Fixes: b770bcfa ("drm/i915/gt: create per-tile sysfs interface")
Signed-off-by: default avatarAshutosh Dixit <ashutosh.dixit@intel.com>
Reviewed-by: default avatarAndi Shyti <andi.shyti@linux.intel.com>
Acked-by: default avatarAndrzej Hajda <andrzej.hajda@intel.com>
Signed-off-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/a6f6686517c85fba61a0c45097f5bb4fe7e257fb.1653484574.git.ashutosh.dixit@intel.com
parent 9d15dd1b
...@@ -790,6 +790,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt) ...@@ -790,6 +790,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
{ {
intel_wakeref_t wakeref; intel_wakeref_t wakeref;
intel_gt_sysfs_unregister(gt);
intel_rps_driver_unregister(&gt->rps); intel_rps_driver_unregister(&gt->rps);
intel_gsc_fini(&gt->gsc); intel_gsc_fini(&gt->gsc);
......
...@@ -24,7 +24,7 @@ bool is_object_gt(struct kobject *kobj) ...@@ -24,7 +24,7 @@ bool is_object_gt(struct kobject *kobj)
static struct intel_gt *kobj_to_gt(struct kobject *kobj) static struct intel_gt *kobj_to_gt(struct kobject *kobj)
{ {
return container_of(kobj, struct kobj_gt, base)->gt; return container_of(kobj, struct intel_gt, sysfs_gt);
} }
struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
...@@ -72,9 +72,9 @@ static struct attribute *id_attrs[] = { ...@@ -72,9 +72,9 @@ static struct attribute *id_attrs[] = {
}; };
ATTRIBUTE_GROUPS(id); ATTRIBUTE_GROUPS(id);
/* A kobject needs a release() method even if it does nothing */
static void kobj_gt_release(struct kobject *kobj) static void kobj_gt_release(struct kobject *kobj)
{ {
kfree(kobj);
} }
static struct kobj_type kobj_gt_type = { static struct kobj_type kobj_gt_type = {
...@@ -85,8 +85,6 @@ static struct kobj_type kobj_gt_type = { ...@@ -85,8 +85,6 @@ static struct kobj_type kobj_gt_type = {
void intel_gt_sysfs_register(struct intel_gt *gt) void intel_gt_sysfs_register(struct intel_gt *gt)
{ {
struct kobj_gt *kg;
/* /*
* We need to make things right with the * We need to make things right with the
* ABI compatibility. The files were originally * ABI compatibility. The files were originally
...@@ -98,25 +96,22 @@ void intel_gt_sysfs_register(struct intel_gt *gt) ...@@ -98,25 +96,22 @@ void intel_gt_sysfs_register(struct intel_gt *gt)
if (gt_is_root(gt)) if (gt_is_root(gt))
intel_gt_sysfs_pm_init(gt, gt_get_parent_obj(gt)); intel_gt_sysfs_pm_init(gt, gt_get_parent_obj(gt));
kg = kzalloc(sizeof(*kg), GFP_KERNEL); /* init and xfer ownership to sysfs tree */
if (!kg) if (kobject_init_and_add(&gt->sysfs_gt, &kobj_gt_type,
gt->i915->sysfs_gt, "gt%d", gt->info.id))
goto exit_fail; goto exit_fail;
kobject_init(&kg->base, &kobj_gt_type); intel_gt_sysfs_pm_init(gt, &gt->sysfs_gt);
kg->gt = gt;
/* xfer ownership to sysfs tree */
if (kobject_add(&kg->base, gt->i915->sysfs_gt, "gt%d", gt->info.id))
goto exit_kobj_put;
intel_gt_sysfs_pm_init(gt, &kg->base);
return; return;
exit_kobj_put:
kobject_put(&kg->base);
exit_fail: exit_fail:
kobject_put(&gt->sysfs_gt);
drm_warn(&gt->i915->drm, drm_warn(&gt->i915->drm,
"failed to initialize gt%d sysfs root\n", gt->info.id); "failed to initialize gt%d sysfs root\n", gt->info.id);
} }
void intel_gt_sysfs_unregister(struct intel_gt *gt)
{
kobject_put(&gt->sysfs_gt);
}
...@@ -13,11 +13,6 @@ ...@@ -13,11 +13,6 @@
struct intel_gt; struct intel_gt;
struct kobj_gt {
struct kobject base;
struct intel_gt *gt;
};
bool is_object_gt(struct kobject *kobj); bool is_object_gt(struct kobject *kobj);
struct drm_i915_private *kobj_to_i915(struct kobject *kobj); struct drm_i915_private *kobj_to_i915(struct kobject *kobj);
...@@ -28,6 +23,7 @@ intel_gt_create_kobj(struct intel_gt *gt, ...@@ -28,6 +23,7 @@ intel_gt_create_kobj(struct intel_gt *gt,
const char *name); const char *name);
void intel_gt_sysfs_register(struct intel_gt *gt); void intel_gt_sysfs_register(struct intel_gt *gt);
void intel_gt_sysfs_unregister(struct intel_gt *gt);
struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
const char *name); const char *name);
......
...@@ -225,6 +225,9 @@ struct intel_gt { ...@@ -225,6 +225,9 @@ struct intel_gt {
} mocs; } mocs;
struct intel_pxp pxp; struct intel_pxp pxp;
/* gt/gtN sysfs */
struct kobject sysfs_gt;
}; };
enum intel_gt_scratch_field { enum intel_gt_scratch_field {
......
...@@ -268,4 +268,6 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv) ...@@ -268,4 +268,6 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv)
device_remove_bin_file(kdev, &dpf_attrs_1); device_remove_bin_file(kdev, &dpf_attrs_1);
device_remove_bin_file(kdev, &dpf_attrs); device_remove_bin_file(kdev, &dpf_attrs);
kobject_put(dev_priv->sysfs_gt);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment