diff options
author | Vikas Shivappa <vikas.shivappa@linux.intel.com> | 2017-07-25 17:14:40 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-08-01 16:41:27 -0400 |
commit | f3cbeacaa06e2b8c2f3ce8531e9aa3fe1f2762cd (patch) | |
tree | a09d72887e6534a643c11a2eb913538f6775b77e | |
parent | f9049547f7e72377049d717354b2f56f36a5854a (diff) |
x86/intel_rdt/cqm: Add rmdir support
Resource groups (ctrl_mon and monitor groups) are represented by
directories in resctrl fs. Add support to remove the directories.
When a ctrl_mon directory is removed all the cpus and tasks are assigned
back to the root rdtgroup. When a monitor group is removed the cpus and
tasks are returned to the parent control group.
Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: ravi.v.shankar@intel.com
Cc: tony.luck@intel.com
Cc: fenghua.yu@intel.com
Cc: peterz@infradead.org
Cc: eranian@google.com
Cc: vikas.shivappa@intel.com
Cc: ak@linux.intel.com
Cc: davidcc@google.com
Cc: reinette.chatre@intel.com
Link: http://lkml.kernel.org/r/1501017287-28083-22-git-send-email-vikas.shivappa@linux.intel.com
-rw-r--r-- | arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 90 |
1 files changed, 86 insertions, 4 deletions
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c index 3b62287a2f01..e61908169dca 100644 --- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | |||
@@ -1130,6 +1130,18 @@ static int reset_all_ctrls(struct rdt_resource *r) | |||
1130 | return 0; | 1130 | return 0; |
1131 | } | 1131 | } |
1132 | 1132 | ||
1133 | static bool is_closid_match(struct task_struct *t, struct rdtgroup *r) | ||
1134 | { | ||
1135 | return (rdt_alloc_capable && | ||
1136 | (r->type == RDTCTRL_GROUP) && (t->closid == r->closid)); | ||
1137 | } | ||
1138 | |||
1139 | static bool is_rmid_match(struct task_struct *t, struct rdtgroup *r) | ||
1140 | { | ||
1141 | return (rdt_mon_capable && | ||
1142 | (r->type == RDTMON_GROUP) && (t->rmid == r->mon.rmid)); | ||
1143 | } | ||
1144 | |||
1133 | /* | 1145 | /* |
1134 | * Move tasks from one to the other group. If @from is NULL, then all tasks | 1146 | * Move tasks from one to the other group. If @from is NULL, then all tasks |
1135 | * in the systems are moved unconditionally (used for teardown). | 1147 | * in the systems are moved unconditionally (used for teardown). |
@@ -1145,8 +1157,11 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to, | |||
1145 | 1157 | ||
1146 | read_lock(&tasklist_lock); | 1158 | read_lock(&tasklist_lock); |
1147 | for_each_process_thread(p, t) { | 1159 | for_each_process_thread(p, t) { |
1148 | if (!from || t->closid == from->closid) { | 1160 | if (!from || is_closid_match(t, from) || |
1161 | is_rmid_match(t, from)) { | ||
1149 | t->closid = to->closid; | 1162 | t->closid = to->closid; |
1163 | t->rmid = to->mon.rmid; | ||
1164 | |||
1150 | #ifdef CONFIG_SMP | 1165 | #ifdef CONFIG_SMP |
1151 | /* | 1166 | /* |
1152 | * This is safe on x86 w/o barriers as the ordering | 1167 | * This is safe on x86 w/o barriers as the ordering |
@@ -1165,6 +1180,19 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to, | |||
1165 | read_unlock(&tasklist_lock); | 1180 | read_unlock(&tasklist_lock); |
1166 | } | 1181 | } |
1167 | 1182 | ||
1183 | static void free_all_child_rdtgrp(struct rdtgroup *rdtgrp) | ||
1184 | { | ||
1185 | struct rdtgroup *sentry, *stmp; | ||
1186 | struct list_head *head; | ||
1187 | |||
1188 | head = &rdtgrp->mon.crdtgrp_list; | ||
1189 | list_for_each_entry_safe(sentry, stmp, head, mon.crdtgrp_list) { | ||
1190 | free_rmid(sentry->mon.rmid); | ||
1191 | list_del(&sentry->mon.crdtgrp_list); | ||
1192 | kfree(sentry); | ||
1193 | } | ||
1194 | } | ||
1195 | |||
1168 | /* | 1196 | /* |
1169 | * Forcibly remove all of subdirectories under root. | 1197 | * Forcibly remove all of subdirectories under root. |
1170 | */ | 1198 | */ |
@@ -1565,6 +1593,44 @@ static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name, | |||
1565 | return -EPERM; | 1593 | return -EPERM; |
1566 | } | 1594 | } |
1567 | 1595 | ||
1596 | static int rdtgroup_rmdir_mon(struct kernfs_node *kn, struct rdtgroup *rdtgrp, | ||
1597 | cpumask_var_t tmpmask) | ||
1598 | { | ||
1599 | struct rdtgroup *prdtgrp = rdtgrp->mon.parent; | ||
1600 | int cpu; | ||
1601 | |||
1602 | /* Give any tasks back to the parent group */ | ||
1603 | rdt_move_group_tasks(rdtgrp, prdtgrp, tmpmask); | ||
1604 | |||
1605 | /* Update per cpu rmid of the moved CPUs first */ | ||
1606 | for_each_cpu(cpu, &rdtgrp->cpu_mask) | ||
1607 | per_cpu(rdt_cpu_default.rmid, cpu) = prdtgrp->mon.rmid; | ||
1608 | /* | ||
1609 | * Update the MSR on moved CPUs and CPUs which have moved | ||
1610 | * task running on them. | ||
1611 | */ | ||
1612 | cpumask_or(tmpmask, tmpmask, &rdtgrp->cpu_mask); | ||
1613 | update_closid_rmid(tmpmask, NULL); | ||
1614 | |||
1615 | rdtgrp->flags = RDT_DELETED; | ||
1616 | free_rmid(rdtgrp->mon.rmid); | ||
1617 | |||
1618 | /* | ||
1619 | * Remove the rdtgrp from the parent ctrl_mon group's list | ||
1620 | */ | ||
1621 | WARN_ON(list_empty(&prdtgrp->mon.crdtgrp_list)); | ||
1622 | list_del(&rdtgrp->mon.crdtgrp_list); | ||
1623 | |||
1624 | /* | ||
1625 | * one extra hold on this, will drop when we kfree(rdtgrp) | ||
1626 | * in rdtgroup_kn_unlock() | ||
1627 | */ | ||
1628 | kernfs_get(kn); | ||
1629 | kernfs_remove(rdtgrp->kn); | ||
1630 | |||
1631 | return 0; | ||
1632 | } | ||
1633 | |||
1568 | static int rdtgroup_rmdir_ctrl(struct kernfs_node *kn, struct rdtgroup *rdtgrp, | 1634 | static int rdtgroup_rmdir_ctrl(struct kernfs_node *kn, struct rdtgroup *rdtgrp, |
1569 | cpumask_var_t tmpmask) | 1635 | cpumask_var_t tmpmask) |
1570 | { | 1636 | { |
@@ -1577,9 +1643,12 @@ static int rdtgroup_rmdir_ctrl(struct kernfs_node *kn, struct rdtgroup *rdtgrp, | |||
1577 | cpumask_or(&rdtgroup_default.cpu_mask, | 1643 | cpumask_or(&rdtgroup_default.cpu_mask, |
1578 | &rdtgroup_default.cpu_mask, &rdtgrp->cpu_mask); | 1644 | &rdtgroup_default.cpu_mask, &rdtgrp->cpu_mask); |
1579 | 1645 | ||
1580 | /* Update per cpu closid of the moved CPUs first */ | 1646 | /* Update per cpu closid and rmid of the moved CPUs first */ |
1581 | for_each_cpu(cpu, &rdtgrp->cpu_mask) | 1647 | for_each_cpu(cpu, &rdtgrp->cpu_mask) { |
1582 | per_cpu(rdt_cpu_default.closid, cpu) = rdtgroup_default.closid; | 1648 | per_cpu(rdt_cpu_default.closid, cpu) = rdtgroup_default.closid; |
1649 | per_cpu(rdt_cpu_default.rmid, cpu) = rdtgroup_default.mon.rmid; | ||
1650 | } | ||
1651 | |||
1583 | /* | 1652 | /* |
1584 | * Update the MSR on moved CPUs and CPUs which have moved | 1653 | * Update the MSR on moved CPUs and CPUs which have moved |
1585 | * task running on them. | 1654 | * task running on them. |
@@ -1589,6 +1658,13 @@ static int rdtgroup_rmdir_ctrl(struct kernfs_node *kn, struct rdtgroup *rdtgrp, | |||
1589 | 1658 | ||
1590 | rdtgrp->flags = RDT_DELETED; | 1659 | rdtgrp->flags = RDT_DELETED; |
1591 | closid_free(rdtgrp->closid); | 1660 | closid_free(rdtgrp->closid); |
1661 | free_rmid(rdtgrp->mon.rmid); | ||
1662 | |||
1663 | /* | ||
1664 | * Free all the child monitor group rmids. | ||
1665 | */ | ||
1666 | free_all_child_rdtgrp(rdtgrp); | ||
1667 | |||
1592 | list_del(&rdtgrp->rdtgroup_list); | 1668 | list_del(&rdtgrp->rdtgroup_list); |
1593 | 1669 | ||
1594 | /* | 1670 | /* |
@@ -1619,10 +1695,16 @@ static int rdtgroup_rmdir(struct kernfs_node *kn) | |||
1619 | 1695 | ||
1620 | /* | 1696 | /* |
1621 | * If the rdtgroup is a ctrl_mon group and parent directory | 1697 | * If the rdtgroup is a ctrl_mon group and parent directory |
1622 | * is the root directory, remove the ctrl group. | 1698 | * is the root directory, remove the ctrl_mon group. |
1699 | * | ||
1700 | * If the rdtgroup is a mon group and parent directory | ||
1701 | * is a valid "mon_groups" directory, remove the mon group. | ||
1623 | */ | 1702 | */ |
1624 | if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn) | 1703 | if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn) |
1625 | ret = rdtgroup_rmdir_ctrl(kn, rdtgrp, tmpmask); | 1704 | ret = rdtgroup_rmdir_ctrl(kn, rdtgrp, tmpmask); |
1705 | else if (rdtgrp->type == RDTMON_GROUP && | ||
1706 | is_mon_groups(parent_kn, kn->name)) | ||
1707 | ret = rdtgroup_rmdir_mon(kn, rdtgrp, tmpmask); | ||
1626 | else | 1708 | else |
1627 | ret = -EPERM; | 1709 | ret = -EPERM; |
1628 | 1710 | ||