Commit fb56b299 authored by James Morse's avatar James Morse
Browse files

arm_mpam: resctrl: Add resctrl_arch_rmid_read()



resctrl uses resctrl_arch_rmid_read() to read counters. CDP emulation means
the counter may need reading in three different ways.

The helpers behind the resctrl_arch_ functions will be re-used for the ABMC
equivalent functions.

Add the rounding helper for checking monitor values while we're here.

Tested-by: default avatarGavin Shan <gshan@redhat.com>
Tested-by: default avatarShaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Tested-by: default avatarPeter Newman <peternewman@google.com>
Tested-by: default avatarZeng Heng <zengheng4@huawei.com>
Tested-by: default avatarJesse Chick <jessechick@os.amperecomputing.com>
Reviewed-by: default avatarShaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Reviewed-by: default avatarJonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: default avatarGavin Shan <gshan@redhat.com>
Co-developed-by: default avatarBen Horgan <ben.horgan@arm.com>
Signed-off-by: default avatarBen Horgan <ben.horgan@arm.com>
Signed-off-by: default avatarJames Morse <james.morse@arm.com>
parent 2a3c79c6
Loading
Loading
Loading
Loading
+82 −0
Original line number Diff line number Diff line
@@ -356,6 +356,88 @@ void resctrl_arch_mon_ctx_free(struct rdt_resource *r,
	resctrl_arch_mon_ctx_free_no_wait(evtid, mon_idx);
}

static int __read_mon(struct mpam_resctrl_mon *mon, struct mpam_component *mon_comp,
		      enum mpam_device_features mon_type,
		      int mon_idx,
		      enum resctrl_conf_type cdp_type, u32 closid, u32 rmid, u64 *val)
{
	struct mon_cfg cfg;

	if (!mpam_is_enabled())
		return -EINVAL;

	/* Shift closid to account for CDP */
	closid = resctrl_get_config_index(closid, cdp_type);

	if (irqs_disabled()) {
		/* Check if we can access this domain without an IPI */
		return -EIO;
	}

	cfg = (struct mon_cfg) {
		.mon = mon_idx,
		.match_pmg = true,
		.partid = closid,
		.pmg = rmid,
	};

	return mpam_msmon_read(mon_comp, &cfg, mon_type, val);
}

static int read_mon_cdp_safe(struct mpam_resctrl_mon *mon, struct mpam_component *mon_comp,
			     enum mpam_device_features mon_type,
			     int mon_idx, u32 closid, u32 rmid, u64 *val)
{
	if (cdp_enabled) {
		u64 code_val = 0, data_val = 0;
		int err;

		err = __read_mon(mon, mon_comp, mon_type, mon_idx,
				 CDP_CODE, closid, rmid, &code_val);
		if (err)
			return err;

		err = __read_mon(mon, mon_comp, mon_type, mon_idx,
				 CDP_DATA, closid, rmid, &data_val);
		if (err)
			return err;

		*val += code_val + data_val;
		return 0;
	}

	return __read_mon(mon, mon_comp, mon_type, mon_idx,
			  CDP_NONE, closid, rmid, val);
}

/* MBWU when not in ABMC mode (not supported), and CSU counters. */
int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain_hdr *hdr,
			   u32 closid, u32 rmid, enum resctrl_event_id eventid,
			   void *arch_priv, u64 *val, void *arch_mon_ctx)
{
	struct mpam_resctrl_dom *l3_dom;
	struct mpam_component *mon_comp;
	u32 mon_idx = *(u32 *)arch_mon_ctx;
	enum mpam_device_features mon_type;
	struct mpam_resctrl_mon *mon = &mpam_resctrl_counters[eventid];

	resctrl_arch_rmid_read_context_check();

	if (eventid >= QOS_NUM_EVENTS || !mon->class)
		return -EINVAL;

	l3_dom = container_of(hdr, struct mpam_resctrl_dom, resctrl_mon_dom.hdr);
	mon_comp = l3_dom->mon_comp[eventid];

	if (eventid != QOS_L3_OCCUP_EVENT_ID)
		return -EINVAL;

	mon_type = mpam_feat_msmon_csu;

	return read_mon_cdp_safe(mon, mon_comp, mon_type, mon_idx,
				 closid, rmid, val);
}

static bool cache_has_usable_cpor(struct mpam_class *class)
{
	struct mpam_props *cprops = &class->props;
+5 −0
Original line number Diff line number Diff line
@@ -67,6 +67,11 @@ struct rdt_resource;
void *resctrl_arch_mon_ctx_alloc(struct rdt_resource *r, enum resctrl_event_id evtid);
void resctrl_arch_mon_ctx_free(struct rdt_resource *r, enum resctrl_event_id evtid, void *ctx);

static inline unsigned int resctrl_arch_round_mon_val(unsigned int val)
{
	return val;
}

/**
 * mpam_register_requestor() - Register a requestor with the MPAM driver
 * @partid_max:		The maximum PARTID value the requestor can generate.