xref: /linux/arch/x86/kernel/cpu/resctrl/rdtgroup.c (revision 664a231d90aa450f9f6f029bee3a94dd08e1aac6)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * User interface for Resource Allocation in Resource Director Technology(RDT)
4  *
5  * Copyright (C) 2016 Intel Corporation
6  *
7  * Author: Fenghua Yu <fenghua.yu@intel.com>
8  *
9  * More information about RDT be found in the Intel (R) x86 Architecture
10  * Software Developer Manual.
11  */
12 
13 #define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
14 
15 #include <linux/cpu.h>
16 #include <linux/debugfs.h>
17 #include <linux/fs.h>
18 #include <linux/fs_parser.h>
19 #include <linux/sysfs.h>
20 #include <linux/kernfs.h>
21 #include <linux/resctrl.h>
22 #include <linux/seq_buf.h>
23 #include <linux/seq_file.h>
24 #include <linux/sched/signal.h>
25 #include <linux/sched/task.h>
26 #include <linux/slab.h>
27 #include <linux/task_work.h>
28 #include <linux/user_namespace.h>
29 
30 #include <uapi/linux/magic.h>
31 
32 #include <asm/msr.h>
33 #include "internal.h"
34 
35 DEFINE_STATIC_KEY_FALSE(rdt_enable_key);
36 
37 DEFINE_STATIC_KEY_FALSE(rdt_mon_enable_key);
38 
39 DEFINE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
40 
41 /*
42  * This is safe against resctrl_arch_sched_in() called from __switch_to()
43  * because __switch_to() is executed with interrupts disabled. A local call
44  * from update_closid_rmid() is protected against __switch_to() because
45  * preemption is disabled.
46  */
resctrl_arch_sync_cpu_closid_rmid(void * info)47 void resctrl_arch_sync_cpu_closid_rmid(void *info)
48 {
49 	struct resctrl_cpu_defaults *r = info;
50 
51 	if (r) {
52 		this_cpu_write(pqr_state.default_closid, r->closid);
53 		this_cpu_write(pqr_state.default_rmid, r->rmid);
54 	}
55 
56 	/*
57 	 * We cannot unconditionally write the MSR because the current
58 	 * executing task might have its own closid selected. Just reuse
59 	 * the context switch code.
60 	 */
61 	resctrl_arch_sched_in(current);
62 }
63 
64 #define INVALID_CONFIG_INDEX   UINT_MAX
65 
66 /**
67  * mon_event_config_index_get - get the hardware index for the
68  *                              configurable event
69  * @evtid: event id.
70  *
71  * Return: 0 for evtid == QOS_L3_MBM_TOTAL_EVENT_ID
72  *         1 for evtid == QOS_L3_MBM_LOCAL_EVENT_ID
73  *         INVALID_CONFIG_INDEX for invalid evtid
74  */
mon_event_config_index_get(u32 evtid)75 static inline unsigned int mon_event_config_index_get(u32 evtid)
76 {
77 	switch (evtid) {
78 	case QOS_L3_MBM_TOTAL_EVENT_ID:
79 		return 0;
80 	case QOS_L3_MBM_LOCAL_EVENT_ID:
81 		return 1;
82 	default:
83 		/* Should never reach here */
84 		return INVALID_CONFIG_INDEX;
85 	}
86 }
87 
resctrl_arch_mon_event_config_read(void * _config_info)88 void resctrl_arch_mon_event_config_read(void *_config_info)
89 {
90 	struct resctrl_mon_config_info *config_info = _config_info;
91 	unsigned int index;
92 	u64 msrval;
93 
94 	index = mon_event_config_index_get(config_info->evtid);
95 	if (index == INVALID_CONFIG_INDEX) {
96 		pr_warn_once("Invalid event id %d\n", config_info->evtid);
97 		return;
98 	}
99 	rdmsrq(MSR_IA32_EVT_CFG_BASE + index, msrval);
100 
101 	/* Report only the valid event configuration bits */
102 	config_info->mon_config = msrval & MAX_EVT_CONFIG_BITS;
103 }
104 
resctrl_arch_mon_event_config_write(void * _config_info)105 void resctrl_arch_mon_event_config_write(void *_config_info)
106 {
107 	struct resctrl_mon_config_info *config_info = _config_info;
108 	unsigned int index;
109 
110 	index = mon_event_config_index_get(config_info->evtid);
111 	if (index == INVALID_CONFIG_INDEX) {
112 		pr_warn_once("Invalid event id %d\n", config_info->evtid);
113 		return;
114 	}
115 	wrmsrq(MSR_IA32_EVT_CFG_BASE + index, config_info->mon_config);
116 }
117 
l3_qos_cfg_update(void * arg)118 static void l3_qos_cfg_update(void *arg)
119 {
120 	bool *enable = arg;
121 
122 	wrmsrq(MSR_IA32_L3_QOS_CFG, *enable ? L3_QOS_CDP_ENABLE : 0ULL);
123 }
124 
l2_qos_cfg_update(void * arg)125 static void l2_qos_cfg_update(void *arg)
126 {
127 	bool *enable = arg;
128 
129 	wrmsrq(MSR_IA32_L2_QOS_CFG, *enable ? L2_QOS_CDP_ENABLE : 0ULL);
130 }
131 
set_cache_qos_cfg(int level,bool enable)132 static int set_cache_qos_cfg(int level, bool enable)
133 {
134 	void (*update)(void *arg);
135 	struct rdt_ctrl_domain *d;
136 	struct rdt_resource *r_l;
137 	cpumask_var_t cpu_mask;
138 	int cpu;
139 
140 	/* Walking r->domains, ensure it can't race with cpuhp */
141 	lockdep_assert_cpus_held();
142 
143 	if (level == RDT_RESOURCE_L3)
144 		update = l3_qos_cfg_update;
145 	else if (level == RDT_RESOURCE_L2)
146 		update = l2_qos_cfg_update;
147 	else
148 		return -EINVAL;
149 
150 	if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL))
151 		return -ENOMEM;
152 
153 	r_l = &rdt_resources_all[level].r_resctrl;
154 	list_for_each_entry(d, &r_l->ctrl_domains, hdr.list) {
155 		if (r_l->cache.arch_has_per_cpu_cfg)
156 			/* Pick all the CPUs in the domain instance */
157 			for_each_cpu(cpu, &d->hdr.cpu_mask)
158 				cpumask_set_cpu(cpu, cpu_mask);
159 		else
160 			/* Pick one CPU from each domain instance to update MSR */
161 			cpumask_set_cpu(cpumask_any(&d->hdr.cpu_mask), cpu_mask);
162 	}
163 
164 	/* Update QOS_CFG MSR on all the CPUs in cpu_mask */
165 	on_each_cpu_mask(cpu_mask, update, &enable, 1);
166 
167 	free_cpumask_var(cpu_mask);
168 
169 	return 0;
170 }
171 
172 /* Restore the qos cfg state when a domain comes online */
rdt_domain_reconfigure_cdp(struct rdt_resource * r)173 void rdt_domain_reconfigure_cdp(struct rdt_resource *r)
174 {
175 	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
176 
177 	if (!r->cdp_capable)
178 		return;
179 
180 	if (r->rid == RDT_RESOURCE_L2)
181 		l2_qos_cfg_update(&hw_res->cdp_enabled);
182 
183 	if (r->rid == RDT_RESOURCE_L3)
184 		l3_qos_cfg_update(&hw_res->cdp_enabled);
185 }
186 
cdp_enable(int level)187 static int cdp_enable(int level)
188 {
189 	struct rdt_resource *r_l = &rdt_resources_all[level].r_resctrl;
190 	int ret;
191 
192 	if (!r_l->alloc_capable)
193 		return -EINVAL;
194 
195 	ret = set_cache_qos_cfg(level, true);
196 	if (!ret)
197 		rdt_resources_all[level].cdp_enabled = true;
198 
199 	return ret;
200 }
201 
cdp_disable(int level)202 static void cdp_disable(int level)
203 {
204 	struct rdt_hw_resource *r_hw = &rdt_resources_all[level];
205 
206 	if (r_hw->cdp_enabled) {
207 		set_cache_qos_cfg(level, false);
208 		r_hw->cdp_enabled = false;
209 	}
210 }
211 
resctrl_arch_set_cdp_enabled(enum resctrl_res_level l,bool enable)212 int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable)
213 {
214 	struct rdt_hw_resource *hw_res = &rdt_resources_all[l];
215 
216 	if (!hw_res->r_resctrl.cdp_capable)
217 		return -EINVAL;
218 
219 	if (enable)
220 		return cdp_enable(l);
221 
222 	cdp_disable(l);
223 
224 	return 0;
225 }
226 
resctrl_arch_get_cdp_enabled(enum resctrl_res_level l)227 bool resctrl_arch_get_cdp_enabled(enum resctrl_res_level l)
228 {
229 	return rdt_resources_all[l].cdp_enabled;
230 }
231 
resctrl_arch_reset_all_ctrls(struct rdt_resource * r)232 void resctrl_arch_reset_all_ctrls(struct rdt_resource *r)
233 {
234 	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
235 	struct rdt_hw_ctrl_domain *hw_dom;
236 	struct msr_param msr_param;
237 	struct rdt_ctrl_domain *d;
238 	int i;
239 
240 	/* Walking r->domains, ensure it can't race with cpuhp */
241 	lockdep_assert_cpus_held();
242 
243 	msr_param.res = r;
244 	msr_param.low = 0;
245 	msr_param.high = hw_res->num_closid;
246 
247 	/*
248 	 * Disable resource control for this resource by setting all
249 	 * CBMs in all ctrl_domains to the maximum mask value. Pick one CPU
250 	 * from each domain to update the MSRs below.
251 	 */
252 	list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
253 		hw_dom = resctrl_to_arch_ctrl_dom(d);
254 
255 		for (i = 0; i < hw_res->num_closid; i++)
256 			hw_dom->ctrl_val[i] = resctrl_get_default_ctrl(r);
257 		msr_param.dom = d;
258 		smp_call_function_any(&d->hdr.cpu_mask, rdt_ctrl_update, &msr_param, 1);
259 	}
260 
261 	return;
262 }
263