Skip to content

Commit 8da2b93

Browse files
Peter Newmanbp3tk0v
authored andcommitted
x86/resctrl: Implement rename op for mon groups
To change the resources allocated to a large group of tasks, such as an application container, a container manager must write all of the tasks' IDs into the tasks file interface of the new control group. This is challenging when the container's task list is always changing. In addition, if the container manager is using monitoring groups to separately track the bandwidth of containers assigned to the same control group, when moving a container, it must first move the container's tasks to the default monitoring group of the new control group before it can move these tasks into the container's replacement monitoring group under the destination control group. This is undesirable because it makes bandwidth usage during the move unattributable to the correct tasks and resets monitoring event counters and cache usage information for the group. Implement the rename operation only for resctrlfs monitor groups to enable users to move a monitoring group from one control group to another. This effects a change in resources allocated to all the tasks in the monitoring group while otherwise leaving the monitoring data intact. Signed-off-by: Peter Newman <peternewman@google.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Reviewed-by: Reinette Chatre <reinette.chatre@intel.com> Tested-by: Babu Moger <babu.moger@amd.com> Link: https://lore.kernel.org/r/20230419125015.693566-3-peternewman@google.com
1 parent c45c06d commit 8da2b93

1 file changed

Lines changed: 128 additions & 0 deletions

File tree

arch/x86/kernel/cpu/resctrl/rdtgroup.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3518,6 +3518,133 @@ static int rdtgroup_rmdir(struct kernfs_node *kn)
35183518
return ret;
35193519
}
35203520

3521+
/**
3522+
* mongrp_reparent() - replace parent CTRL_MON group of a MON group
3523+
* @rdtgrp: the MON group whose parent should be replaced
3524+
* @new_prdtgrp: replacement parent CTRL_MON group for @rdtgrp
3525+
* @cpus: cpumask provided by the caller for use during this call
3526+
*
3527+
* Replaces the parent CTRL_MON group for a MON group, resulting in all member
3528+
* tasks' CLOSID immediately changing to that of the new parent group.
3529+
* Monitoring data for the group is unaffected by this operation.
3530+
*/
3531+
static void mongrp_reparent(struct rdtgroup *rdtgrp,
3532+
struct rdtgroup *new_prdtgrp,
3533+
cpumask_var_t cpus)
3534+
{
3535+
struct rdtgroup *prdtgrp = rdtgrp->mon.parent;
3536+
3537+
WARN_ON(rdtgrp->type != RDTMON_GROUP);
3538+
WARN_ON(new_prdtgrp->type != RDTCTRL_GROUP);
3539+
3540+
/* Nothing to do when simply renaming a MON group. */
3541+
if (prdtgrp == new_prdtgrp)
3542+
return;
3543+
3544+
WARN_ON(list_empty(&prdtgrp->mon.crdtgrp_list));
3545+
list_move_tail(&rdtgrp->mon.crdtgrp_list,
3546+
&new_prdtgrp->mon.crdtgrp_list);
3547+
3548+
rdtgrp->mon.parent = new_prdtgrp;
3549+
rdtgrp->closid = new_prdtgrp->closid;
3550+
3551+
/* Propagate updated closid to all tasks in this group. */
3552+
rdt_move_group_tasks(rdtgrp, rdtgrp, cpus);
3553+
3554+
update_closid_rmid(cpus, NULL);
3555+
}
3556+
3557+
static int rdtgroup_rename(struct kernfs_node *kn,
3558+
struct kernfs_node *new_parent, const char *new_name)
3559+
{
3560+
struct rdtgroup *new_prdtgrp;
3561+
struct rdtgroup *rdtgrp;
3562+
cpumask_var_t tmpmask;
3563+
int ret;
3564+
3565+
rdtgrp = kernfs_to_rdtgroup(kn);
3566+
new_prdtgrp = kernfs_to_rdtgroup(new_parent);
3567+
if (!rdtgrp || !new_prdtgrp)
3568+
return -ENOENT;
3569+
3570+
/* Release both kernfs active_refs before obtaining rdtgroup mutex. */
3571+
rdtgroup_kn_get(rdtgrp, kn);
3572+
rdtgroup_kn_get(new_prdtgrp, new_parent);
3573+
3574+
mutex_lock(&rdtgroup_mutex);
3575+
3576+
rdt_last_cmd_clear();
3577+
3578+
/*
3579+
* Don't allow kernfs_to_rdtgroup() to return a parent rdtgroup if
3580+
* either kernfs_node is a file.
3581+
*/
3582+
if (kernfs_type(kn) != KERNFS_DIR ||
3583+
kernfs_type(new_parent) != KERNFS_DIR) {
3584+
rdt_last_cmd_puts("Source and destination must be directories");
3585+
ret = -EPERM;
3586+
goto out;
3587+
}
3588+
3589+
if ((rdtgrp->flags & RDT_DELETED) || (new_prdtgrp->flags & RDT_DELETED)) {
3590+
ret = -ENOENT;
3591+
goto out;
3592+
}
3593+
3594+
if (rdtgrp->type != RDTMON_GROUP || !kn->parent ||
3595+
!is_mon_groups(kn->parent, kn->name)) {
3596+
rdt_last_cmd_puts("Source must be a MON group\n");
3597+
ret = -EPERM;
3598+
goto out;
3599+
}
3600+
3601+
if (!is_mon_groups(new_parent, new_name)) {
3602+
rdt_last_cmd_puts("Destination must be a mon_groups subdirectory\n");
3603+
ret = -EPERM;
3604+
goto out;
3605+
}
3606+
3607+
/*
3608+
* If the MON group is monitoring CPUs, the CPUs must be assigned to the
3609+
* current parent CTRL_MON group and therefore cannot be assigned to
3610+
* the new parent, making the move illegal.
3611+
*/
3612+
if (!cpumask_empty(&rdtgrp->cpu_mask) &&
3613+
rdtgrp->mon.parent != new_prdtgrp) {
3614+
rdt_last_cmd_puts("Cannot move a MON group that monitors CPUs\n");
3615+
ret = -EPERM;
3616+
goto out;
3617+
}
3618+
3619+
/*
3620+
* Allocate the cpumask for use in mongrp_reparent() to avoid the
3621+
* possibility of failing to allocate it after kernfs_rename() has
3622+
* succeeded.
3623+
*/
3624+
if (!zalloc_cpumask_var(&tmpmask, GFP_KERNEL)) {
3625+
ret = -ENOMEM;
3626+
goto out;
3627+
}
3628+
3629+
/*
3630+
* Perform all input validation and allocations needed to ensure
3631+
* mongrp_reparent() will succeed before calling kernfs_rename(),
3632+
* otherwise it would be necessary to revert this call if
3633+
* mongrp_reparent() failed.
3634+
*/
3635+
ret = kernfs_rename(kn, new_parent, new_name);
3636+
if (!ret)
3637+
mongrp_reparent(rdtgrp, new_prdtgrp, tmpmask);
3638+
3639+
free_cpumask_var(tmpmask);
3640+
3641+
out:
3642+
mutex_unlock(&rdtgroup_mutex);
3643+
rdtgroup_kn_put(rdtgrp, kn);
3644+
rdtgroup_kn_put(new_prdtgrp, new_parent);
3645+
return ret;
3646+
}
3647+
35213648
static int rdtgroup_show_options(struct seq_file *seq, struct kernfs_root *kf)
35223649
{
35233650
if (resctrl_arch_get_cdp_enabled(RDT_RESOURCE_L3))
@@ -3535,6 +3662,7 @@ static int rdtgroup_show_options(struct seq_file *seq, struct kernfs_root *kf)
35353662
static struct kernfs_syscall_ops rdtgroup_kf_syscall_ops = {
35363663
.mkdir = rdtgroup_mkdir,
35373664
.rmdir = rdtgroup_rmdir,
3665+
.rename = rdtgroup_rename,
35383666
.show_options = rdtgroup_show_options,
35393667
};
35403668

0 commit comments

Comments
 (0)