[PATCH 14/15] x86/resctrl: Add interface unassign a ABMC counter

From: Babu Moger
Date: Thu Nov 30 2023 - 19:58:47 EST


With the support of ABMC (Assignable Bandwidth Monitoring Counters)
feature, the user has the option to pin (or assign) or unpin (or unassign)
the RMID to hardware counter and monitor the bandwidth for the longer
duration.

Provide the interface to unpin (or unassign) the counter.

Signed-off-by: Babu Moger <babu.moger@xxxxxxx>
---
Documentation/arch/x86/resctrl.rst | 11 ++++++++
arch/x86/kernel/cpu/resctrl/rdtgroup.c | 36 ++++++++++++++++++++++++++
2 files changed, 47 insertions(+)

diff --git a/Documentation/arch/x86/resctrl.rst b/Documentation/arch/x86/resctrl.rst
index 65306e7d01b6..b42b59a7ba3c 100644
--- a/Documentation/arch/x86/resctrl.rst
+++ b/Documentation/arch/x86/resctrl.rst
@@ -417,6 +417,17 @@ When monitoring is enabled all MON groups will also contain:
# echo total=assign > /sys/fs/resctrl/monitor_state
# echo total=assign;local=assign > /sys/fs/resctrl/monitor_state

+ The user needs to unpin (or unassign) counter to release it.
+ Example::
+
+ # echo total=unassign > /sys/fs/resctrl/monitor_state
+ # cat /sys/fs/resctrl/monitor_state
+ total=unassign;local=assign
+
+ # echo total=unassign;local=unassign > /sys/fs/resctrl/monitor_state
+ # cat /sys/fs/resctrl/monitor_state
+ total=unassign;local=unassign
+
"mon_hw_id":
Available only with debug option. The identifier used by hardware
for the monitor group. On x86 this is the RMID.
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
index 671ff732992c..6eca47673344 100644
--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -192,6 +192,11 @@ static int abmc_counters_alloc(void)
return counterid;
}

+void abmc_counters_free(int counterid)
+{
+ abmc_free_map |= 1 << counterid;
+}
+
/**
* rdtgroup_mode_by_closid - Return mode of resource group with closid
* @closid: closid if the resource group
@@ -1671,6 +1676,31 @@ static ssize_t rdtgroup_assign_abmc(struct rdtgroup *rdtgrp,
return 0;
}

+static ssize_t rdtgroup_unassign_abmc(struct rdtgroup *rdtgrp,
+ struct rdt_resource *r,
+ u32 evtid, int mon_state)
+{
+ struct rdt_domain *d;
+ int index;
+
+ index = mon_event_config_index_get(evtid);
+ if (index == INVALID_CONFIG_INDEX) {
+ pr_warn_once("Invalid event id %d\n", evtid);
+ return -EINVAL;
+ }
+
+ if (rdtgrp->mon.monitor_state & mon_state) {
+ list_for_each_entry(d, &r->domains, list)
+ rdtgroup_abmc_domain(d, rdtgrp, evtid, index, 0);
+
+ abmc_counters_free(rdtgrp->mon.abmc_ctr_id[index]);
+ }
+
+ rdtgrp->mon.monitor_state &= ~mon_state;
+
+ return 0;
+}
+
/**
* rdtgroup_monitor_state_write - Modify the resource group's assign
*
@@ -1716,6 +1746,12 @@ static ssize_t rdtgroup_monitor_state_write(struct kernfs_open_file *of,
rdt_last_cmd_puts("ABMC assign failed\n");
break;
}
+ } else if (!strcmp(abmc_str, "unassign")) {
+ ret = rdtgroup_unassign_abmc(rdtgrp, r, evtid, mon_state);
+ if (ret) {
+ rdt_last_cmd_puts("ABMC unassign failed\n");
+ break;
+ }
} else {
rdt_last_cmd_puts("Invalid ABMC event\n");
ret = -EINVAL;
--
2.34.1