Skip to content

Commit 3e5822e

Browse files
committed
Merge tag 'x86_cache_for_v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 resource control updates from Borislav Petkov: - Implement a rename operation in resctrlfs to facilitate handling of application containers with dynamically changing task lists - When reading the tasks file, show the tasks' pid which are only in the current namespace as opposed to showing the pids from the init namespace too - Other fixes and improvements * tag 'x86_cache_for_v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: Documentation/x86: Documentation for MON group move feature x86/resctrl: Implement rename op for mon groups x86/resctrl: Factor rdtgroup lock for multi-file ops x86/resctrl: Only show tasks' pid in current pid namespace
2 parents 5903513 + e0a6ede commit 3e5822e

File tree

2 files changed

+163
-15
lines changed

2 files changed

+163
-15
lines changed

Documentation/arch/x86/resctrl.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,13 @@ Removing a directory will move all tasks and cpus owned by the group it
287287
represents to the parent. Removing one of the created CTRL_MON groups
288288
will automatically remove all MON groups below it.
289289

290+
Moving MON group directories to a new parent CTRL_MON group is supported
291+
for the purpose of changing the resource allocations of a MON group
292+
without impacting its monitoring data or assigned tasks. This operation
293+
is not allowed for MON groups which monitor CPUs. No other move
294+
operation is currently allowed other than simply renaming a CTRL_MON or
295+
MON group.
296+
290297
All groups contain the following files:
291298

292299
"tasks":

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

Lines changed: 156 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -726,11 +726,15 @@ static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of,
726726
static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s)
727727
{
728728
struct task_struct *p, *t;
729+
pid_t pid;
729730

730731
rcu_read_lock();
731732
for_each_process_thread(p, t) {
732-
if (is_closid_match(t, r) || is_rmid_match(t, r))
733-
seq_printf(s, "%d\n", t->pid);
733+
if (is_closid_match(t, r) || is_rmid_match(t, r)) {
734+
pid = task_pid_vnr(t);
735+
if (pid)
736+
seq_printf(s, "%d\n", pid);
737+
}
734738
}
735739
rcu_read_unlock();
736740
}
@@ -2301,15 +2305,34 @@ static struct rdtgroup *kernfs_to_rdtgroup(struct kernfs_node *kn)
23012305
}
23022306
}
23032307

2308+
static void rdtgroup_kn_get(struct rdtgroup *rdtgrp, struct kernfs_node *kn)
2309+
{
2310+
atomic_inc(&rdtgrp->waitcount);
2311+
kernfs_break_active_protection(kn);
2312+
}
2313+
2314+
static void rdtgroup_kn_put(struct rdtgroup *rdtgrp, struct kernfs_node *kn)
2315+
{
2316+
if (atomic_dec_and_test(&rdtgrp->waitcount) &&
2317+
(rdtgrp->flags & RDT_DELETED)) {
2318+
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP ||
2319+
rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED)
2320+
rdtgroup_pseudo_lock_remove(rdtgrp);
2321+
kernfs_unbreak_active_protection(kn);
2322+
rdtgroup_remove(rdtgrp);
2323+
} else {
2324+
kernfs_unbreak_active_protection(kn);
2325+
}
2326+
}
2327+
23042328
struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn)
23052329
{
23062330
struct rdtgroup *rdtgrp = kernfs_to_rdtgroup(kn);
23072331

23082332
if (!rdtgrp)
23092333
return NULL;
23102334

2311-
atomic_inc(&rdtgrp->waitcount);
2312-
kernfs_break_active_protection(kn);
2335+
rdtgroup_kn_get(rdtgrp, kn);
23132336

23142337
mutex_lock(&rdtgroup_mutex);
23152338

@@ -2328,17 +2351,7 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn)
23282351
return;
23292352

23302353
mutex_unlock(&rdtgroup_mutex);
2331-
2332-
if (atomic_dec_and_test(&rdtgrp->waitcount) &&
2333-
(rdtgrp->flags & RDT_DELETED)) {
2334-
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP ||
2335-
rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED)
2336-
rdtgroup_pseudo_lock_remove(rdtgrp);
2337-
kernfs_unbreak_active_protection(kn);
2338-
rdtgroup_remove(rdtgrp);
2339-
} else {
2340-
kernfs_unbreak_active_protection(kn);
2341-
}
2354+
rdtgroup_kn_put(rdtgrp, kn);
23422355
}
23432356

23442357
static int mkdir_mondata_all(struct kernfs_node *parent_kn,
@@ -3505,6 +3518,133 @@ static int rdtgroup_rmdir(struct kernfs_node *kn)
35053518
return ret;
35063519
}
35073520

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+
35083648
static int rdtgroup_show_options(struct seq_file *seq, struct kernfs_root *kf)
35093649
{
35103650
if (resctrl_arch_get_cdp_enabled(RDT_RESOURCE_L3))
@@ -3522,6 +3662,7 @@ static int rdtgroup_show_options(struct seq_file *seq, struct kernfs_root *kf)
35223662
static struct kernfs_syscall_ops rdtgroup_kf_syscall_ops = {
35233663
.mkdir = rdtgroup_mkdir,
35243664
.rmdir = rdtgroup_rmdir,
3665+
.rename = rdtgroup_rename,
35253666
.show_options = rdtgroup_show_options,
35263667
};
35273668

0 commit comments

Comments
 (0)