Commit 28fa2cce authored by Babu Moger's avatar Babu Moger Committed by Borislav Petkov (AMD)
Browse files

fs/resctrl: Introduce interface to modify io_alloc capacity bitmasks



The io_alloc feature in resctrl enables system software to configure the
portion of the cache allocated for I/O traffic. When supported, the
io_alloc_cbm file in resctrl provides access to capacity bitmasks (CBMs)
allocated for I/O devices.

Enable users to modify io_alloc CBMs by writing to the io_alloc_cbm resctrl
file when the io_alloc feature is enabled.

Mirror the CBMs between CDP_CODE and CDP_DATA when CDP is enabled to present
consistent I/O allocation information to user space.

Signed-off-by: default avatarBabu Moger <babu.moger@amd.com>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Link: https://patch.msgid.link/67609641b03ccfba18a8ee0bf9dbd1f3dcbecda3.1762995456.git.babu.moger@amd.com
parent af1242ee
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -196,6 +196,18 @@ related to allocation:
			# cat /sys/fs/resctrl/info/L3/io_alloc_cbm
			0=ffff;1=ffff

		CBMs can be configured by writing to the interface.

		Example::

			# echo 1=ff > /sys/fs/resctrl/info/L3/io_alloc_cbm
			# cat /sys/fs/resctrl/info/L3/io_alloc_cbm
			0=ffff;1=00ff

			# echo "0=ff;1=f" > /sys/fs/resctrl/info/L3/io_alloc_cbm
			# cat /sys/fs/resctrl/info/L3/io_alloc_cbm
			0=00ff;1=000f

		When CDP is enabled "io_alloc_cbm" associated with the CDP_DATA and CDP_CODE
		resources may reflect the same values. For example, values read from and
		written to /sys/fs/resctrl/info/L3DATA/io_alloc_cbm may be reflected by
+93 −0
Original line number Diff line number Diff line
@@ -864,3 +864,96 @@ int resctrl_io_alloc_cbm_show(struct kernfs_open_file *of, struct seq_file *seq,
	cpus_read_unlock();
	return ret;
}

static int resctrl_io_alloc_parse_line(char *line,  struct rdt_resource *r,
				       struct resctrl_schema *s, u32 closid)
{
	enum resctrl_conf_type peer_type;
	struct rdt_parse_data data;
	struct rdt_ctrl_domain *d;
	char *dom = NULL, *id;
	unsigned long dom_id;

next:
	if (!line || line[0] == '\0')
		return 0;

	dom = strsep(&line, ";");
	id = strsep(&dom, "=");
	if (!dom || kstrtoul(id, 10, &dom_id)) {
		rdt_last_cmd_puts("Missing '=' or non-numeric domain\n");
		return -EINVAL;
	}

	dom = strim(dom);
	list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
		if (d->hdr.id == dom_id) {
			data.buf = dom;
			data.mode = RDT_MODE_SHAREABLE;
			data.closid = closid;
			if (parse_cbm(&data, s, d))
				return -EINVAL;
			/*
			 * Keep io_alloc CLOSID's CBM of CDP_CODE and CDP_DATA
			 * in sync.
			 */
			if (resctrl_arch_get_cdp_enabled(r->rid)) {
				peer_type = resctrl_peer_type(s->conf_type);
				memcpy(&d->staged_config[peer_type],
				       &d->staged_config[s->conf_type],
				       sizeof(d->staged_config[0]));
			}
			goto next;
		}
	}

	return -EINVAL;
}

ssize_t resctrl_io_alloc_cbm_write(struct kernfs_open_file *of, char *buf,
				   size_t nbytes, loff_t off)
{
	struct resctrl_schema *s = rdt_kn_parent_priv(of->kn);
	struct rdt_resource *r = s->res;
	u32 io_alloc_closid;
	int ret = 0;

	/* Valid input requires a trailing newline */
	if (nbytes == 0 || buf[nbytes - 1] != '\n')
		return -EINVAL;

	buf[nbytes - 1] = '\0';

	cpus_read_lock();
	mutex_lock(&rdtgroup_mutex);
	rdt_last_cmd_clear();

	if (!r->cache.io_alloc_capable) {
		rdt_last_cmd_printf("io_alloc is not supported on %s\n", s->name);
		ret = -ENODEV;
		goto out_unlock;
	}

	if (!resctrl_arch_get_io_alloc_enabled(r)) {
		rdt_last_cmd_printf("io_alloc is not enabled on %s\n", s->name);
		ret = -EINVAL;
		goto out_unlock;
	}

	io_alloc_closid = resctrl_io_alloc_closid(r);

	rdt_staged_configs_clear();
	ret = resctrl_io_alloc_parse_line(buf, r, s, io_alloc_closid);
	if (ret)
		goto out_clear_configs;

	ret = resctrl_arch_update_domains(r, io_alloc_closid);

out_clear_configs:
	rdt_staged_configs_clear();
out_unlock:
	mutex_unlock(&rdtgroup_mutex);
	cpus_read_unlock();

	return ret ?: nbytes;
}
+2 −0
Original line number Diff line number Diff line
@@ -440,6 +440,8 @@ ssize_t resctrl_io_alloc_write(struct kernfs_open_file *of, char *buf,
const char *rdtgroup_name_by_closid(u32 closid);
int resctrl_io_alloc_cbm_show(struct kernfs_open_file *of, struct seq_file *seq,
			      void *v);
ssize_t resctrl_io_alloc_cbm_write(struct kernfs_open_file *of, char *buf,
				   size_t nbytes, loff_t off);

#ifdef CONFIG_RESCTRL_FS_PSEUDO_LOCK
int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp);
+2 −1
Original line number Diff line number Diff line
@@ -1973,9 +1973,10 @@ static struct rftype res_common_files[] = {
	},
	{
		.name		= "io_alloc_cbm",
		.mode		= 0444,
		.mode		= 0644,
		.kf_ops		= &rdtgroup_kf_single_ops,
		.seq_show	= resctrl_io_alloc_cbm_show,
		.write		= resctrl_io_alloc_cbm_write,
	},
	{
		.name		= "max_threshold_occupancy",