hulk inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/9840 ------------------ iommu_group_get_from_kobj() returns holding a reference on group->devices_kobj, which iommu_group_put() releases. The kobject_get() call only compensates for the kobject_put(&group->kobj) done internally by iommu_group_get_from_kobj(). Since iommu_group_put() was never called, this leaks one iommu_group reference per group on every call (e.g. on rmdir and every tasks file read). Since device_kobj pins the group's kobject, the leaked groups can never be freed. kset_get_next_obj() only drops its reference on the current kobject when it is passed back as 'prev' on the next iteration. Breaking out of the loop leaks the group_kobj reference taken by the iterator. The same patterns exist in both rdt_move_group_iommus() and show_rdt_iommu(). Fixes: 7e3f95a1a861 ("fs/resctrl: Add support for assigning iommu_groups to resctrl groups") Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- fs/resctrl/rdtgroup.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c index 2fab48af47000..17100c37b635f 100644 --- a/fs/resctrl/rdtgroup.c +++ b/fs/resctrl/rdtgroup.c @@ -815,17 +815,21 @@ static int rdt_move_group_iommus(struct rdtgroup *from, struct rdtgroup *to) kobject_get(group_kobj); group = iommu_group_get_from_kobj(group_kobj); - if (!group) + if (!group) { + kobject_put(group_kobj); continue; + } if (!from || iommu_matches_rdtgroup(group, from)) { err = kstrtoint(group_kobj->name, 0, &iommu_group_id); - if (err) - break; + if (!err) + err = rdtgroup_move_iommu(iommu_group_id, to); + } - err = rdtgroup_move_iommu(iommu_group_id, to); - if (err) - break; + iommu_group_put(group); + if (err) { + kobject_put(group_kobj); + break; } } @@ -926,11 +930,15 @@ static void show_rdt_iommu(struct rdtgroup *r, struct seq_file *s) kobject_get(group_kobj); group = iommu_group_get_from_kobj(group_kobj); - if (!group) + if (!group) { + kobject_put(group_kobj); continue; + } if (iommu_matches_rdtgroup(group, r)) seq_printf(s, "iommu_group:%s\n", group_kobj->name); + + iommu_group_put(group); } kset_put(iommu_groups); -- 2.43.0