[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <467077e6fcf2ffeb9f20204671b6902b85974820.1734556832.git.babu.moger@amd.com>
Date: Wed, 18 Dec 2024 15:38:01 -0600
From: Babu Moger <babu.moger@....com>
To: <reinette.chatre@...el.com>, <tglx@...utronix.de>, <mingo@...hat.com>,
<bp@...en8.de>, <dave.hansen@...ux.intel.com>
CC: <babu.moger@....com>, <fenghua.yu@...el.com>, <x86@...nel.org>,
<hpa@...or.com>, <akpm@...ux-foundation.org>, <paulmck@...nel.org>,
<thuth@...hat.com>, <rostedt@...dmis.org>, <xiongwei.song@...driver.com>,
<pawan.kumar.gupta@...ux.intel.com>, <jpoimboe@...nel.org>,
<daniel.sneddon@...ux.intel.com>, <thomas.lendacky@....com>,
<perry.yuan@....com>, <sandipan.das@....com>, <kai.huang@...el.com>,
<seanjc@...gle.com>, <xin3.li@...el.com>, <ebiggers@...gle.com>,
<andrew.cooper3@...rix.com>, <mario.limonciello@....com>,
<tan.shaopeng@...itsu.com>, <james.morse@....com>, <tony.luck@...el.com>,
<peternewman@...gle.com>, <linux-doc@...r.kernel.org>,
<linux-kernel@...r.kernel.org>, <eranian@...gle.com>, <corbet@....net>
Subject: [PATCH v2 5/7] x86/resctrl: Add interface to enable/disable io_alloc feature
The io_alloc feature in resctrl enables system software to configure
the portion of the L3 cache allocated for I/O traffic.
Smart Data Cache Injection (SDCI) is a mechanism that allows direct
insertion of data from I/O devices into the L3 cache. By caching I/O
data directly in the L3 cache, instead of writing it to DRAM first,
SDCI reduces DRAM bandwidth usage and lowers latency for the processor
consuming the I/O data.
When enabled, SDCIAE forces all SDCI lines to be placed into the L3 cache
partitions identified by the highest-supported L3_MASK_n register as
reported by CPUID Fn0000_0010_EDX_x1.MAX_COS. For example, if MAX_COS=15,
SDCI lines will be allocated into the L3 cache partitions determined by
the bitmask in the L3_MASK_15 register.
Introduce interface to enable/disable "io_alloc" feature on user input.
Signed-off-by: Babu Moger <babu.moger@....com>
---
v2: Renamed the feature to "io_alloc".
Added generic texts for the feature in commit log and resctrl.rst doc.
Added resctrl_io_alloc_init_cat() to initialize io_alloc to default
values when enabled.
Fixed io_alloc show functinality to display only on L3 resource.
---
Documentation/arch/x86/resctrl.rst | 27 ++++++
arch/x86/kernel/cpu/resctrl/core.c | 2 +
arch/x86/kernel/cpu/resctrl/rdtgroup.c | 118 +++++++++++++++++++++++++
3 files changed, 147 insertions(+)
diff --git a/Documentation/arch/x86/resctrl.rst b/Documentation/arch/x86/resctrl.rst
index 6768fc1fad16..52679175ee14 100644
--- a/Documentation/arch/x86/resctrl.rst
+++ b/Documentation/arch/x86/resctrl.rst
@@ -135,6 +135,33 @@ related to allocation:
"1":
Non-contiguous 1s value in CBM is supported.
+"io_alloc":
+ The "io_alloc" feature in resctrl enables system software to
+ configure the portion of the L3 cache allocated for I/O traffic.
+
+ Smart Data Cache Injection (SDCI) is a mechanism that allows
+ direct insertion of data from I/O devices into the L3 cache.
+ By caching I/O data directly in the L3 cache, instead of writing
+ it to DRAM first, SDCI reduces DRAM bandwidth usage and lowers
+ latency for the processor consuming the I/O data.
+
+ When enabled the feature forces all SDCI lines to be placed
+ into the L3 cache partitions identified by the highest-supported
+ CLOSID (num_closids-1). This CLOSID will not be available to the
+ resctrl group.
+
+ "0":
+ I/O device L3 cache control is not enabled.
+ "1":
+ I/O device L3 cache control is enabled, allowing users
+ to manage the portions of the L3 cache allocated for
+ the I/O device.
+
+ Feature can be enabled/disabled by writing to the interface.
+ Example::
+
+ # echo 1 > /sys/fs/resctrl/info/L3/io_alloc
+
Memory bandwidth(MB) subdirectory contains the following files
with respect to allocation:
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 39e110033d96..066a7997eaf1 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -309,6 +309,8 @@ static void rdt_get_cdp_config(int level)
static void rdt_get_sdciae_alloc_cfg(struct rdt_resource *r)
{
r->cache.io_alloc_capable = true;
+ resctrl_file_fflags_init("io_alloc",
+ RFTYPE_CTRL_INFO | RFTYPE_RES_CACHE);
}
static void rdt_get_cdp_l3_config(void)
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
index 398f241b65d5..e30731ce9335 100644
--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -62,6 +62,7 @@ static char last_cmd_status_buf[512];
static int rdtgroup_setup_root(struct rdt_fs_context *ctx);
static void rdtgroup_destroy_root(void);
+static int rdtgroup_init_cat(struct resctrl_schema *s, u32 closid);
struct dentry *debugfs_resctrl;
@@ -180,6 +181,25 @@ void closid_free(int closid)
__set_bit(closid, &closid_free_map);
}
+/*
+ * io_alloc (SDCIAE) feature uses max CLOSID to route the SDCI traffic.
+ * Get the max CLOSID number
+ */
+static u32 resctrl_io_alloc_closid_get(struct rdt_resource *r)
+{
+ return resctrl_arch_get_num_closid(r) - 1;
+}
+
+static int resctrl_io_alloc_closid_alloc(struct rdt_resource *r)
+{
+ u32 io_alloc_closid = resctrl_io_alloc_closid_get(r);
+
+ if (__test_and_clear_bit(io_alloc_closid, &closid_free_map))
+ return io_alloc_closid;
+ else
+ return -ENOSPC;
+}
+
/**
* closid_allocated - test if provided closid is in use
* @closid: closid to be tested
@@ -1832,6 +1852,97 @@ int resctrl_arch_io_alloc_enable(struct rdt_resource *r, bool enable)
return 0;
}
+static int resctrl_io_alloc_show(struct kernfs_open_file *of,
+ struct seq_file *seq, void *v)
+{
+ struct resctrl_schema *s = of->kn->parent->priv;
+ struct rdt_resource *r = s->res;
+
+ seq_printf(seq, "%x\n", resctrl_arch_get_io_alloc_enabled(r->rid));
+ return 0;
+}
+
+/*
+ * Initialize the io_alloc feature default when enabled
+ */
+static int resctrl_io_alloc_init_cat(struct rdt_resource *r, u32 closid)
+{
+ struct resctrl_schema *s;
+ int ret = 0;
+
+ rdt_staged_configs_clear();
+
+ list_for_each_entry(s, &resctrl_schema_all, list) {
+ r = s->res;
+ if (r->rid == RDT_RESOURCE_L3) {
+ ret = rdtgroup_init_cat(s, closid);
+ if (ret < 0)
+ goto out_init_cat;
+
+ ret = resctrl_arch_update_domains(r, closid);
+ if (ret < 0)
+ goto out_init_cat;
+ }
+ }
+
+out_init_cat:
+ if (ret)
+ rdt_last_cmd_puts("Failed to initialize io_alloc allocations\n");
+
+ rdt_staged_configs_clear();
+ return ret;
+}
+
+static ssize_t resctrl_io_alloc_write(struct kernfs_open_file *of, char *buf,
+ size_t nbytes, loff_t off)
+{
+ struct resctrl_schema *s = of->kn->parent->priv;
+ struct rdt_resource *r = s->res;
+ u32 io_alloc_closid;
+ bool enable;
+ int ret;
+
+ if (!r->cache.io_alloc_capable)
+ return -EINVAL;
+
+ ret = kstrtobool(buf, &enable);
+ if (ret)
+ return ret;
+
+ cpus_read_lock();
+ mutex_lock(&rdtgroup_mutex);
+
+ rdt_last_cmd_clear();
+
+ io_alloc_closid = resctrl_io_alloc_closid_get(r);
+
+ if (resctrl_arch_get_io_alloc_enabled(r->rid) != enable) {
+ if (enable) {
+ ret = resctrl_io_alloc_closid_alloc(r);
+ if (ret < 0) {
+ rdt_last_cmd_puts("io_alloc CLOSID is not available\n");
+ goto out_io_alloc;
+ }
+ ret = resctrl_io_alloc_init_cat(r, io_alloc_closid);
+ if (ret) {
+ closid_free(io_alloc_closid);
+ goto out_io_alloc;
+ }
+
+ } else {
+ closid_free(io_alloc_closid);
+ }
+
+ ret = resctrl_arch_io_alloc_enable(r, enable);
+ }
+
+out_io_alloc:
+ mutex_unlock(&rdtgroup_mutex);
+ cpus_read_unlock();
+
+ return ret ?: nbytes;
+}
+
/* rdtgroup information files for one cache resource. */
static struct rftype res_common_files[] = {
{
@@ -1984,6 +2095,13 @@ static struct rftype res_common_files[] = {
.seq_show = rdtgroup_schemata_show,
.fflags = RFTYPE_CTRL_BASE,
},
+ {
+ .name = "io_alloc",
+ .mode = 0644,
+ .kf_ops = &rdtgroup_kf_single_ops,
+ .seq_show = resctrl_io_alloc_show,
+ .write = resctrl_io_alloc_write,
+ },
{
.name = "mba_MBps_event",
.mode = 0644,
--
2.34.1
Powered by blists - more mailing lists