mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-14 07:42:38 -04:00
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: b770bcfae9 ("drm/i915/gt: create per-tile sysfs interface")
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Acked-by: Andrzej Hajda <andrzej.hajda@intel.com>
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/a6f6686517c85fba61a0c45097f5bb4fe7e257fb.1653484574.git.ashutosh.dixit@intel.com
This commit is contained in:
committed by
Tvrtko Ursulin
parent
9d15dd1bb3
commit
69d6bf5c37
@@ -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(>->rps);
|
intel_rps_driver_unregister(>->rps);
|
||||||
intel_gsc_fini(>->gsc);
|
intel_gsc_fini(>->gsc);
|
||||||
|
|
||||||
|
|||||||
@@ -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[] = {
|
|||||||
};
|
};
|
||||||
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 = {
|
|||||||
|
|
||||||
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)
|
|||||||
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(>->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, >->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(>->sysfs_gt);
|
||||||
drm_warn(>->i915->drm,
|
drm_warn(>->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(>->sysfs_gt);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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,
|
|||||||
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 {
|
|||||||
} 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)
|
|||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user