// SPDX-License-Identifier: GPL-2.0-only
/*
 * Resource Director Technology(RDT)
 * - Cache Allocation code.
 *
 * Copyright (C) 2016 Intel Corporation
 *
 * Authors:
 *    Fenghua Yu <fenghua.yu@intel.com>
 *    Tony Luck <tony.luck@intel.com>
 *
 * More information about RDT be found in the Intel (R) x86 Architecture
 * Software Developer Manual June 2016, volume 3, section 17.17.
 */

#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt

#include <linux/cpu.h>
#include <linux/kernfs.h>
#include <linux/math.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/tick.h>

#include "internal.h"

struct rdt_parse_data {
	u32			closid;
	enum rdtgrp_mode	mode;
	char			*buf;
};

typedef int (ctrlval_parser_t)(struct rdt_parse_data *data,
			       struct resctrl_schema *s,
			       struct rdt_ctrl_domain *d);

/*
 * Check whether MBA bandwidth percentage value is correct. The value is
 * checked against the minimum and max bandwidth values specified by the
 * hardware. The allocated bandwidth percentage is rounded to the next
 * control step available on the hardware.
 */
static bool bw_validate(char *buf, u32 *data, struct rdt_resource *r)
{
	int ret;
	u32 bw;

	/*
	 * Only linear delay values is supported for current Intel SKUs.
	 */
	if (!r->membw.delay_linear && r->membw.arch_needs_linear) {
		rdt_last_cmd_puts("No support for non-linear MB domains\n");
		return false;
	}

	ret = kstrtou32(buf, 10, &bw);
	if (ret) {
		rdt_last_cmd_printf("Invalid MB value %s\n", buf);
		return false;
	}

	/* Nothing else to do if software controller is enabled. */
	if (is_mba_sc(r)) {
		*data = bw;
		return true;
	}

	if (bw < r->membw.min_bw || bw > r->membw.max_bw) {
		rdt_last_cmd_printf("MB value %u out of range [%d,%d]\n",
				    bw, r->membw.min_bw, r->membw.max_bw);
		return false;
	}

	*data = roundup(bw, (unsigned long)r->membw.bw_gran);
	return true;
}

static int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s,
		    struct rdt_ctrl_domain *d)
{
	struct resctrl_staged_config *cfg;
	struct rdt_resource *r = s->res;
	u32 closid = data->closid;
	u32 bw_val;

	cfg = &d->staged_config[s->conf_type];
	if (cfg->have_new_ctrl) {
		rdt_last_cmd_printf("Duplicate domain %d\n", d->hdr.id);
		return -EINVAL;
	}

	if (!bw_validate(data->buf, &bw_val, r))
		return -EINVAL;

	if (is_mba_sc(r)) {
		d->mbps_val[closid] = bw_val;
		return 0;
	}

	cfg->new_ctrl = bw_val;
	cfg->have_new_ctrl = true;

	return 0;
}

/*
 * Check whether a cache bit mask is valid.
 * On Intel CPUs, non-contiguous 1s value support is indicated by CPUID:
 *   - CPUID.0x10.1:ECX[3]: L3 non-contiguous 1s value supported if 1
 *   - CPUID.0x10.2:ECX[3]: L2 non-contiguous 1s value supported if 1
 *
 * Haswell does not support a non-contiguous 1s value and additionally
 * requires at least two bits set.
 * AMD allows non-contiguous bitmasks.
 */
static bool cbm_validate(char *buf, u32 *data, struct rdt_resource *r)
{
	u32 supported_bits = BIT_MASK(r->cache.cbm_len) - 1;
	unsigned int cbm_len = r->cache.cbm_len;
	unsigned long first_bit, zero_bit, val;
	int ret;

	ret = kstrtoul(buf, 16, &val);
	if (ret) {
		rdt_last_cmd_printf("Non-hex character in the mask %s\n", buf);
		return false;
	}

	if ((r->cache.min_cbm_bits > 0 && val == 0) || val > supported_bits) {
		rdt_last_cmd_puts("Mask out of range\n");
		return false;
	}

	first_bit = find_first_bit(&val, cbm_len);
	zero_bit = find_next_zero_bit(&val, cbm_len, first_bit);

	/* Are non-contiguous bitmasks allowed? */
	if (!r->cache.arch_has_sparse_bitmasks &&
	    (find_next_bit(&val, cbm_len, zero_bit) < cbm_len)) {
		rdt_last_cmd_printf("The mask %lx has non-consecutive 1-bits\n", val);
		return false;
	}

	if ((zero_bit - first_bit) < r->cache.min_cbm_bits) {
		rdt_last_cmd_printf("Need at least %d bits in the mask\n",
				    r->cache.min_cbm_bits);
		return false;
	}

	*data = val;
	return true;
}

/*
 * Read one cache bit mask (hex). Check that it is valid for the current
 * resource type.
 */
static int parse_cbm(struct rdt_parse_data *data, struct resctrl_schema *s,
		     struct rdt_ctrl_domain *d)
{
	enum rdtgrp_mode mode = data->mode;
	struct resctrl_staged_config *cfg;
	struct rdt_resource *r = s->res;
	u32 closid = data->closid;
	u32 cbm_val;

	cfg = &d->staged_config[s->conf_type];
	if (cfg->have_new_ctrl) {
		rdt_last_cmd_printf("Duplicate domain %d\n", d->hdr.id);
		return -EINVAL;
	}

	/*
	 * Cannot set up more than one pseudo-locked region in a cache
	 * hierarchy.
	 */
	if (mode == RDT_MODE_PSEUDO_LOCKSETUP &&
	    rdtgroup_pseudo_locked_in_hierarchy(d)) {
		rdt_last_cmd_puts("Pseudo-locked region in hierarchy\n");
		return -EINVAL;
	}

	if (!cbm_validate(data->buf, &cbm_val, r))
		return -EINVAL;

	if ((mode == RDT_MODE_EXCLUSIVE || mode == RDT_MODE_SHAREABLE) &&
	    rdtgroup_cbm_overlaps_pseudo_locked(d, cbm_val)) {
		rdt_last_cmd_puts("CBM overlaps with pseudo-locked region\n");
		return -EINVAL;
	}

	/*
	 * The CBM may not overlap with the CBM of another closid if
	 * either is exclusive.
	 */
	if (rdtgroup_cbm_overlaps(s, d, cbm_val, closid, true)) {
		rdt_last_cmd_puts("Overlaps with exclusive group\n");
		return -EINVAL;
	}

	if (rdtgroup_cbm_overlaps(s, d, cbm_val, closid, false)) {
		if (mode == RDT_MODE_EXCLUSIVE ||
		    mode == RDT_MODE_PSEUDO_LOCKSETUP) {
			rdt_last_cmd_puts("Overlaps with other group\n");
			return -EINVAL;
		}
	}

	cfg->new_ctrl = cbm_val;
	cfg->have_new_ctrl = true;

	return 0;
}

/*
 * For each domain in this resource we expect to find a series of:
 *	id=mask
 * separated by ";". The "id" is in decimal, and must match one of
 * the "id"s for this resource.
 */
static int parse_line(char *line, struct resctrl_schema *s,
		      struct rdtgroup *rdtgrp)
{
	enum resctrl_conf_type t = s->conf_type;
	ctrlval_parser_t *parse_ctrlval = NULL;
	struct resctrl_staged_config *cfg;
	struct rdt_resource *r = s->res;
	struct rdt_parse_data data;
	struct rdt_ctrl_domain *d;
	char *dom = NULL, *id;
	unsigned long dom_id;

	/* Walking r->domains, ensure it can't race with cpuhp */
	lockdep_assert_cpus_held();

	switch (r->schema_fmt) {
	case RESCTRL_SCHEMA_BITMAP:
		parse_ctrlval = &parse_cbm;
		break;
	case RESCTRL_SCHEMA_RANGE:
		parse_ctrlval = &parse_bw;
		break;
	}

	if (WARN_ON_ONCE(!parse_ctrlval))
		return -EINVAL;

	if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP &&
	    (r->rid == RDT_RESOURCE_MBA || r->rid == RDT_RESOURCE_SMBA)) {
		rdt_last_cmd_puts("Cannot pseudo-lock MBA resource\n");
		return -EINVAL;
	}

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_rcu(d, &r->ctrl_domains, hdr.list, lockdep_is_cpus_held()) {
		if (d->hdr.id == dom_id) {
			data.buf = dom;
			data.closid = rdtgrp->closid;
			data.mode = rdtgrp->mode;
			if (parse_ctrlval(&data, s, d))
				return -EINVAL;
			if (rdtgrp->mode ==  RDT_MODE_PSEUDO_LOCKSETUP) {
				cfg = &d->staged_config[t];
				/*
				 * In pseudo-locking setup mode and just
				 * parsed a valid CBM that should be
				 * pseudo-locked. Only one locked region per
				 * resource group and domain so just do
				 * the required initialization for single
				 * region and return.
				 */
				rdtgrp->plr->s = s;
				rdtgrp->plr->d = d;
				rdtgrp->plr->cbm = cfg->new_ctrl;
				d->plr = rdtgrp->plr;
				return 0;
			}
			goto next;
		}
	}
	return -EINVAL;
}

static int rdtgroup_parse_resource(char *resname, char *tok,
				   struct rdtgroup *rdtgrp)
{
	struct resctrl_schema *s;

	list_for_each_entry(s, &resctrl_schema_all, list) {
		if (!strcmp(resname, s->name) && rdtgrp->closid < s->num_closid)
			return parse_line(tok, s, rdtgrp);
	}
	rdt_last_cmd_printf("Unknown or unsupported resource name '%s'\n", resname);
	return -EINVAL;
}

ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
				char *buf, size_t nbytes, loff_t off)
{
	struct resctrl_schema *s;
	struct rdtgroup *rdtgrp;
	struct rdt_resource *r;
	char *tok, *resname;
	int ret = 0;

	rdtgrp = rdtgroup_kn_lock_live(of->kn);
	if (!rdtgrp) {
		rdtgroup_kn_unlock(of->kn);
		return -ENOENT;
	}

	/* Valid input requires a trailing newline */
	if (nbytes == 0 || buf[nbytes - 1] != '\n') {
		rdt_last_cmd_puts("schemata: Invalid input\n");
		ret = -EINVAL;
		goto out_unlock;
	}

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

	/*
	 * No changes to pseudo-locked region allowed. It has to be removed
	 * and re-created instead.
	 */
	if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) {
		ret = -EINVAL;
		rdt_last_cmd_puts("Resource group is pseudo-locked\n");
		goto out_unlock;
	}

	rdt_staged_configs_clear();

	while ((tok = strsep(&buf, "\n")) != NULL) {
		resname = strim(strsep(&tok, ":"));
		if (!tok) {
			rdt_last_cmd_puts("Missing ':'\n");
			ret = -EINVAL;
			goto out_clear_staged;
		}
		if (tok[0] == '\0') {
			rdt_last_cmd_printf("Missing '%s' value\n", resname);
			ret = -EINVAL;
			goto out_clear_staged;
		}
		ret = rdtgroup_parse_resource(resname, tok, rdtgrp);
		if (ret)
			goto out_clear_staged;
	}

	list_for_each_entry(s, &resctrl_schema_all, list) {
		r = s->res;

		/*
		 * Writes to mba_sc resources update the software controller,
		 * not the control MSR.
		 */
		if (is_mba_sc(r))
			continue;

		ret = resctrl_arch_update_domains(r, rdtgrp->closid);
		if (ret)
			goto out_clear_staged;
	}

	if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
		/*
		 * If pseudo-locking fails we keep the resource group in
		 * mode RDT_MODE_PSEUDO_LOCKSETUP with its class of service
		 * active and updated for just the domain the pseudo-locked
		 * region was requested for.
		 */
		ret = rdtgroup_pseudo_lock_create(rdtgrp);
	}

out_clear_staged:
	rdt_staged_configs_clear();
out_unlock:
	rdtgroup_kn_unlock(of->kn);
	return ret ?: nbytes;
}

static void show_doms(struct seq_file *s, struct resctrl_schema *schema,
		      char *resource_name, int closid)
{
	struct rdt_resource *r = schema->res;
	struct rdt_ctrl_domain *dom;
	bool sep = false;
	u32 ctrl_val;

	/* Walking r->domains, ensure it can't race with cpuhp */
	lockdep_assert_cpus_held();

	if (resource_name)
		seq_printf(s, "%*s:", max_name_width, resource_name);
	list_for_each_entry_rcu(dom, &r->ctrl_domains, hdr.list, lockdep_is_cpus_held()) {
		if (sep)
			seq_puts(s, ";");

		if (is_mba_sc(r))
			ctrl_val = dom->mbps_val[closid];
		else
			ctrl_val = resctrl_arch_get_config(r, dom, closid,
							   schema->conf_type);

		seq_printf(s, schema->fmt_str, dom->hdr.id, ctrl_val);
		sep = true;
	}
	seq_puts(s, "\n");
}

int rdtgroup_schemata_show(struct kernfs_open_file *of,
			   struct seq_file *s, void *v)
{
	struct resctrl_schema *schema;
	struct rdtgroup *rdtgrp;
	int ret = 0;
	u32 closid;

	rdtgrp = rdtgroup_kn_lock_live(of->kn);
	if (rdtgrp) {
		if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
			list_for_each_entry(schema, &resctrl_schema_all, list) {
				seq_printf(s, "%s:uninitialized\n", schema->name);
			}
		} else if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) {
			if (!rdtgrp->plr->d) {
				rdt_last_cmd_puts("Cache domain offline\n");
				ret = -ENODEV;
			} else {
				seq_printf(s, "%s:%d=%x\n",
					   rdtgrp->plr->s->res->name,
					   rdtgrp->plr->d->hdr.id,
					   rdtgrp->plr->cbm);
			}
		} else {
			closid = rdtgrp->closid;
			list_for_each_entry(schema, &resctrl_schema_all, list) {
				if (closid < schema->num_closid)
					show_doms(s, schema, schema->name, closid);
			}
		}
	} else {
		ret = -ENOENT;
	}
	rdtgroup_kn_unlock(of->kn);
	return ret;
}

static int smp_mon_event_count(void *arg)
{
	mon_event_count(arg);

	return 0;
}

ssize_t rdtgroup_mba_mbps_event_write(struct kernfs_open_file *of,
				      char *buf, size_t nbytes, loff_t off)
{
	struct rdtgroup *rdtgrp;
	int ret = 0;

	rdtgrp = rdtgroup_kn_lock_live(of->kn);
	if (!rdtgrp) {
		rdtgroup_kn_unlock(of->kn);
		return -ENOENT;
	}

	/* Valid input requires a trailing newline */
	if (nbytes == 0 || buf[nbytes - 1] != '\n') {
		rdt_last_cmd_puts("mba_MBps_event: Invalid input\n");
		ret = -EINVAL;
		goto out_unlock;
	}

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

	if (!strcmp(buf, "mbm_local_bytes")) {
		if (resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID))
			rdtgrp->mba_mbps_event = QOS_L3_MBM_LOCAL_EVENT_ID;
		else
			ret = -EINVAL;
	} else if (!strcmp(buf, "mbm_total_bytes")) {
		if (resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID))
			rdtgrp->mba_mbps_event = QOS_L3_MBM_TOTAL_EVENT_ID;
		else
			ret = -EINVAL;
	} else {
		ret = -EINVAL;
	}

	if (ret)
		rdt_last_cmd_printf("Unsupported event id '%s'\n", buf);

out_unlock:
	rdtgroup_kn_unlock(of->kn);

	return ret ?: nbytes;
}

int rdtgroup_mba_mbps_event_show(struct kernfs_open_file *of,
				 struct seq_file *s, void *v)
{
	struct rdtgroup *rdtgrp;
	int ret = 0;

	rdtgrp = rdtgroup_kn_lock_live(of->kn);

	if (rdtgrp) {
		switch (rdtgrp->mba_mbps_event) {
		case QOS_L3_MBM_LOCAL_EVENT_ID:
			seq_puts(s, "mbm_local_bytes\n");
			break;
		case QOS_L3_MBM_TOTAL_EVENT_ID:
			seq_puts(s, "mbm_total_bytes\n");
			break;
		default:
			pr_warn_once("Bad event %d\n", rdtgrp->mba_mbps_event);
			ret = -EINVAL;
			break;
		}
	} else {
		ret = -ENOENT;
	}

	rdtgroup_kn_unlock(of->kn);

	return ret;
}

struct rdt_domain_hdr *resctrl_find_domain(struct list_head *h, int id,
					   struct list_head **pos)
{
	struct rdt_domain_hdr *d;
	struct list_head *l;

	lockdep_assert_cpus_held();

	list_for_each(l, h) {
		d = list_entry(l, struct rdt_domain_hdr, list);
		/* When id is found, return its domain. */
		if (id == d->id)
			return d;
		/* Stop searching when finding id's position in sorted list. */
		if (id < d->id)
			break;
	}

	if (pos)
		*pos = l;

	return NULL;
}

void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
		    struct rdt_domain_hdr *hdr, struct rdtgroup *rdtgrp,
		    cpumask_t *cpumask, struct mon_evt *evt, int first)
{
	int cpu;

	/* When picking a CPU from cpu_mask, ensure it can't race with cpuhp */
	lockdep_assert_cpus_held();

	/*
	 * Setup the parameters to pass to mon_event_count() to read the data.
	 */
	rr->rgrp = rdtgrp;
	rr->evt = evt;
	rr->r = r;
	rr->hdr = hdr;
	rr->first = first;
	if (resctrl_arch_mbm_cntr_assign_enabled(r) &&
	    resctrl_is_mbm_event(evt->evtid)) {
		rr->is_mbm_cntr = true;
	} else {
		rr->arch_mon_ctx = resctrl_arch_mon_ctx_alloc(r, evt->evtid);
		if (IS_ERR(rr->arch_mon_ctx)) {
			rr->err = -EINVAL;
			return;
		}
	}

	if (evt->any_cpu) {
		mon_event_count(rr);
		goto out_ctx_free;
	}

	cpu = cpumask_any_housekeeping(cpumask, RESCTRL_PICK_ANY_CPU);

	/*
	 * cpumask_any_housekeeping() prefers housekeeping CPUs, but
	 * are all the CPUs nohz_full? If yes, pick a CPU to IPI.
	 * MPAM's resctrl_arch_rmid_read() is unable to read the
	 * counters on some platforms if its called in IRQ context.
	 */
	if (tick_nohz_full_cpu(cpu))
		smp_call_function_any(cpumask, mon_event_count, rr, 1);
	else
		smp_call_on_cpu(cpu, smp_mon_event_count, rr, false);

out_ctx_free:
	if (rr->arch_mon_ctx)
		resctrl_arch_mon_ctx_free(r, evt->evtid, rr->arch_mon_ctx);
}

/*
 * Decimal place precision to use for each number of fixed-point
 * binary bits computed from ceil(binary_bits * log10(2)) except
 * binary_bits == 0 which will print "value.0"
 */
static const unsigned int decplaces[MAX_BINARY_BITS + 1] = {
	[0]  =  1,
	[1]  =  1,
	[2]  =  1,
	[3]  =  1,
	[4]  =  2,
	[5]  =  2,
	[6]  =  2,
	[7]  =  3,
	[8]  =  3,
	[9]  =  3,
	[10] =  4,
	[11] =  4,
	[12] =  4,
	[13] =  4,
	[14] =  5,
	[15] =  5,
	[16] =  5,
	[17] =  6,
	[18] =  6,
	[19] =  6,
	[20] =  7,
	[21] =  7,
	[22] =  7,
	[23] =  7,
	[24] =  8,
	[25] =  8,
	[26] =  8,
	[27] =  9
};

static void print_event_value(struct seq_file *m, unsigned int binary_bits, u64 val)
{
	unsigned long long frac = 0;

	if (binary_bits) {
		/* Mask off the integer part of the fixed-point value. */
		frac = val & GENMASK_ULL(binary_bits - 1, 0);

		/*
		 * Multiply by 10^{desired decimal places}. The integer part of
		 * the fixed point value is now almost what is needed.
		 */
		frac *= int_pow(10ull, decplaces[binary_bits]);

		/*
		 * Round to nearest by adding a value that would be a "1" in the
		 * binary_bits + 1 place.  Integer part of fixed point value is
		 * now the needed value.
		 */
		frac += 1ull << (binary_bits - 1);

		/*
		 * Extract the integer part of the value. This is the decimal
		 * representation of the original fixed-point fractional value.
		 */
		frac >>= binary_bits;
	}

	/*
	 * "frac" is now in the range [0 .. 10^decplaces).  I.e. string
	 * representation will fit into chosen number of decimal places.
	 */
	seq_printf(m, "%llu.%0*llu\n", val >> binary_bits, decplaces[binary_bits], frac);
}

int rdtgroup_mondata_show(struct seq_file *m, void *arg)
{
	struct kernfs_open_file *of = m->private;
	enum resctrl_res_level resid;
	struct rdt_domain_hdr *hdr;
	struct rmid_read rr = {0};
	struct rdtgroup *rdtgrp;
	int domid, cpu, ret = 0;
	struct rdt_resource *r;
	struct cacheinfo *ci;
	struct mon_evt *evt;
	struct mon_data *md;

	rdtgrp = rdtgroup_kn_lock_live(of->kn);
	if (!rdtgrp) {
		ret = -ENOENT;
		goto out;
	}

	md = of->kn->priv;
	if (WARN_ON_ONCE(!md)) {
		ret = -EIO;
		goto out;
	}

	resid = md->rid;
	domid = md->domid;
	evt = md->evt;
	r = resctrl_arch_get_resource(resid);

	if (md->sum) {
		struct rdt_l3_mon_domain *d;

		if (WARN_ON_ONCE(resid != RDT_RESOURCE_L3)) {
			ret = -EINVAL;
			goto out;
		}

		/*
		 * This file requires summing across all domains that share
		 * the L3 cache id that was provided in the "domid" field of the
		 * struct mon_data. Search all domains in the resource for
		 * one that matches this cache id.
		 */
		list_for_each_entry_rcu(d, &r->mon_domains, hdr.list, lockdep_is_cpus_held()) {
			if (d->ci_id == domid) {
				cpu = cpumask_any(&d->hdr.cpu_mask);
				ci = get_cpu_cacheinfo_level(cpu, RESCTRL_L3_CACHE);
				if (!ci)
					continue;
				rr.ci = ci;
				mon_event_read(&rr, r, NULL, rdtgrp,
					       &ci->shared_cpu_map, evt, false);
				goto checkresult;
			}
		}
		ret = -ENOENT;
		goto out;
	} else {
		/*
		 * This file provides data from a single domain. Search
		 * the resource to find the domain with "domid".
		 */
		hdr = resctrl_find_domain(&r->mon_domains, domid, NULL);
		if (!hdr) {
			ret = -ENOENT;
			goto out;
		}
		mon_event_read(&rr, r, hdr, rdtgrp, &hdr->cpu_mask, evt, false);
	}

checkresult:

	/*
	 * -ENOENT is a special case, set only when "mbm_event" counter assignment
	 * mode is enabled and no counter has been assigned.
	 */
	if (rr.err == -EIO)
		seq_puts(m, "Error\n");
	else if (rr.err == -EINVAL)
		seq_puts(m, "Unavailable\n");
	else if (rr.err == -ENOENT)
		seq_puts(m, "Unassigned\n");
	else if (evt->is_floating_point)
		print_event_value(m, evt->binary_bits, rr.val);
	else
		seq_printf(m, "%llu\n", rr.val);

out:
	rdtgroup_kn_unlock(of->kn);
	return ret;
}

int resctrl_io_alloc_show(struct kernfs_open_file *of, struct seq_file *seq, void *v)
{
	struct resctrl_schema *s = rdt_kn_parent_priv(of->kn);
	struct rdt_resource *r;

	if (!info_kn_lock(of->kn))
		return -ENOENT;

	r = s->res;
	if (r->cache.io_alloc_capable) {
		if (resctrl_arch_get_io_alloc_enabled(r))
			seq_puts(seq, "enabled\n");
		else
			seq_puts(seq, "disabled\n");
	} else {
		seq_puts(seq, "not supported\n");
	}

	info_kn_unlock(of->kn);

	return 0;
}

/*
 * resctrl_io_alloc_closid_supported() - io_alloc feature utilizes the
 * highest CLOSID value to direct I/O traffic. Ensure that io_alloc_closid
 * is in the supported range.
 */
static bool resctrl_io_alloc_closid_supported(u32 io_alloc_closid)
{
	return io_alloc_closid < closids_supported();
}

/*
 * Initialize io_alloc CLOSID cache resource CBM with all usable (shared
 * and unused) cache portions.
 */
static int resctrl_io_alloc_init_cbm(struct resctrl_schema *s, u32 closid)
{
	enum resctrl_conf_type peer_type;
	struct rdt_resource *r = s->res;
	struct rdt_ctrl_domain *d;
	int ret;

	rdt_staged_configs_clear();

	ret = rdtgroup_init_cat(s, closid);
	if (ret < 0)
		goto out;

	/* Keep CDP_CODE and CDP_DATA of io_alloc CLOSID's CBM in sync. */
	if (resctrl_arch_get_cdp_enabled(r->rid)) {
		peer_type = resctrl_peer_type(s->conf_type);
		list_for_each_entry_rcu(d, &s->res->ctrl_domains, hdr.list, lockdep_is_cpus_held())
			memcpy(&d->staged_config[peer_type],
			       &d->staged_config[s->conf_type],
			       sizeof(d->staged_config[0]));
	}

	ret = resctrl_arch_update_domains(r, closid);
out:
	rdt_staged_configs_clear();
	return ret;
}

/*
 * resctrl_io_alloc_closid() - io_alloc feature routes I/O traffic using
 * the highest available CLOSID. Retrieve the maximum CLOSID supported by the
 * resource. Note that if Code Data Prioritization (CDP) is enabled, the number
 * of available CLOSIDs is reduced by half.
 */
u32 resctrl_io_alloc_closid(struct rdt_resource *r)
{
	if (resctrl_arch_get_cdp_enabled(r->rid))
		return resctrl_arch_get_num_closid(r) / 2  - 1;
	else
		return resctrl_arch_get_num_closid(r) - 1;
}

ssize_t resctrl_io_alloc_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;
	char const *grp_name;
	u32 io_alloc_closid;
	bool enable;
	int ret;

	if (!info_kn_lock(of->kn))
		return -ENOENT;

	r = s->res;
	rdt_last_cmd_clear();

	ret = kstrtobool(buf, &enable);
	if (ret) {
		rdt_last_cmd_puts("io_alloc: Invalid input\n");
		goto out_unlock;
	}

	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 the feature is already up to date, no action is needed. */
	if (resctrl_arch_get_io_alloc_enabled(r) == enable)
		goto out_unlock;

	io_alloc_closid = resctrl_io_alloc_closid(r);
	if (!resctrl_io_alloc_closid_supported(io_alloc_closid)) {
		rdt_last_cmd_printf("io_alloc CLOSID (ctrl_hw_id) %u is not available\n",
				    io_alloc_closid);
		ret = -EINVAL;
		goto out_unlock;
	}

	if (enable) {
		if (!closid_alloc_fixed(io_alloc_closid)) {
			grp_name = rdtgroup_name_by_closid(io_alloc_closid);
			WARN_ON_ONCE(!grp_name);
			rdt_last_cmd_printf("CLOSID (ctrl_hw_id) %u for io_alloc is used by %s group\n",
					    io_alloc_closid, grp_name ? grp_name : "another");
			ret = -ENOSPC;
			goto out_unlock;
		}

		ret = resctrl_io_alloc_init_cbm(s, io_alloc_closid);
		if (ret) {
			rdt_last_cmd_puts("Failed to initialize io_alloc allocations\n");
			closid_free(io_alloc_closid);
			goto out_unlock;
		}
	} else {
		closid_free(io_alloc_closid);
	}

	ret = resctrl_arch_io_alloc_enable(r, enable);
	if (enable && ret) {
		rdt_last_cmd_puts("Failed to enable io_alloc feature\n");
		closid_free(io_alloc_closid);
	}

out_unlock:
	info_kn_unlock(of->kn);

	return ret ?: nbytes;
}

int resctrl_io_alloc_cbm_show(struct kernfs_open_file *of, struct seq_file *seq, void *v)
{
	struct resctrl_schema *s = rdt_kn_parent_priv(of->kn);
	struct rdt_resource *r;
	int ret = 0;

	if (!info_kn_lock(of->kn))
		return -ENOENT;

	rdt_last_cmd_clear();

	r = s->res;
	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;
	}

	/*
	 * When CDP is enabled, the CBMs of the highest CLOSID of CDP_CODE and
	 * CDP_DATA are kept in sync. As a result, the io_alloc CBMs shown for
	 * either CDP resource are identical and accurately represent the CBMs
	 * used for I/O.
	 */
	show_doms(seq, s, NULL, resctrl_io_alloc_closid(r));

out_unlock:
	info_kn_unlock(of->kn);
	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;
	unsigned long dom_id = ULONG_MAX;
	struct rdt_parse_data data;
	struct rdt_ctrl_domain *d;
	bool update_all = false;
	char *dom = NULL, *id;

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

	if (update_all) {
		rdt_last_cmd_puts("Configurations after global '*'\n");
		return -EINVAL;
	}

	dom = strsep(&line, ";");
	id = strsep(&dom, "=");

	if (dom && !strcmp(id, "*")) {
		update_all = true;
	} else 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_rcu(d, &r->ctrl_domains, hdr.list, lockdep_is_cpus_held()) {
		if (update_all || 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]));
			}
			if (!update_all)
				goto next;
		}
	}

	if (update_all)
		goto next;

	rdt_last_cmd_printf("Invalid domain %lu\n", dom_id);
	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;
	u32 io_alloc_closid;
	int ret = 0;

	if (!info_kn_lock(of->kn))
		return -ENOENT;
	rdt_last_cmd_clear();

	r = s->res;

	/* Valid input requires a trailing newline */
	if (nbytes == 0 || buf[nbytes - 1] != '\n') {
		rdt_last_cmd_puts("io_alloc_cbm: Invalid input\n");
		ret = -EINVAL;
		goto out_unlock;
	}

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

	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:
	info_kn_unlock(of->kn);

	return ret ?: nbytes;
}
