[PATCH mpam mpam/snapshot+extras/v6.18-rc1 v2 3/3] fs/resctrl: Migrate IOMMU groups when removing resource groups

Lee Trager lee at trager.us
Wed Jul 15 14:35:26 PDT 2026


Hi Zeng,

Thanks for the series, I found it while backporting MPAM support to 6.18.

On 4/13/26 8:26 PM, Zeng Heng wrote:
> When deleting a control group, monitor group, or unmounting the resctrl
> filesystem, migrate all associated IOMMU groups to the appropriate
> destination:
>    * Control group deletion: move IOMMU groups to the default group
>    * Monitor group deletion: move IOMMU groups to the parent control group
>    * Filesystem unmount: move all IOMMU groups to the default group
>
> Without this migration, IOMMU groups remain bound to stale PARTID/PMG
> values of the destroyed group, causing them to "disappear" from the
> resctrl interface.
>
> Add rdt_move_group_iommus() to handle this migration, mirroring the
> existing rdt_move_group_tasks() pattern for task migration.
>
> When deleting a control group or unmounting the resctrl file system, it
> is necessary to move its all iommu_groups back to the default group. When
> removing a monitor group, need to move its iommu_groups back to the parent
> control group.
>
> Otherwise, these iommu_groups remain bound to the old PARTID and PMG, and
> they will appear to "disappear" from the resctrl fs.
>
> Signed-off-by: Zeng Heng <zengheng4 at huawei.com>
> ---
>   fs/resctrl/rdtgroup.c | 47 +++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 47 insertions(+)
>
> diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
> index e92b5dcb6f2e..351e430bde1a 100644
> --- a/fs/resctrl/rdtgroup.c
> +++ b/fs/resctrl/rdtgroup.c
> @@ -3292,6 +3292,44 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to,
>   	read_unlock(&tasklist_lock);
>   }
>   
> +static int rdt_move_group_iommus(struct rdtgroup *from, struct rdtgroup *to)
> +{
> +	struct kset *iommu_groups;
> +	struct iommu_group *group;
> +	int err = 0, iommu_group_id;
> +	struct kobject *group_kobj = NULL;
> +
> +	if (!IS_ENABLED(CONFIG_RESCTRL_IOMMU))
> +		return 0;
> +
> +	if (from == to)
> +		return 0;
> +
> +	iommu_groups = iommu_get_group_kset();
> +
> +	while ((group_kobj = kset_get_next_obj(iommu_groups, group_kobj))) {
> +		/* iommu_group_get_from_kobj() wants to drop a reference */
> +		kobject_get(group_kobj);
> +
> +		group = iommu_group_get_from_kobj(group_kobj);
> +		if (!group)
> +			continue;
> +
> +		if (!from || iommu_matches_rdtgroup(group, from)) {
> +			err = kstrtoint(group_kobj->name, 0, &iommu_group_id);
> +			if (err)
> +				break;
> +
> +			err = rdtgroup_move_iommu(iommu_group_id, to);
> +			if (err)
> +				break;
> +		}
> +	}
> +
> +	kset_put(iommu_groups);
> +	return err;
> +}

iommu_group_get_from_kobj() returns holding a reference on 
group->devices_kobj, the one iommu_group_put() releases. The 
kobject_get() above only compensates for the kobject_put(&group->kobj) 
done internally by iommu_group_get_from_kobj(). Nothing in this loop 
ever calls iommu_group_put(), so this leaks one iommu_group reference  
per group in the kset on every call, e.g on rmdir and every unmount. 
Since device_kobj pins the group's koject, the leaked groups can never 
be freed.

The same pattern exists in show_rdt_iommu() from "fs/resctrl: Add 
support for assigning iommu_groups to resctrl groups", where it leaks 
one reference per group on every read of a tasks file.

There is a second, smaller leak on these break paths: 
kset_get_next_obj() only drops its reference on the current kobject when 
it is passed back as @prev on the next iteration, so breaking out of the 
loop also leaks the group_kobj reference taken by the iterator. I am 
carrying the fix below:

if (!from || iommu_matches_rdtgroup(group, from)) {
	err = kstrtoint(group_kobj->name, 0, &iommu_group_id);
	if (!err)
		err = rdtgroup_move_iommu(iommu_group_id, to);
}

iommu_group_put(group);
if (err) {
	kobject_put(group_kobj);
	break;
}

Thanks,

Lee




More information about the linux-arm-kernel mailing list