xref: /linux/arch/riscv/include/asm/qos.h (revision 073e62fd33fe9cec754cb89e60c0ebbab781a50a)
1*326ba66dSDrew Fustini /* SPDX-License-Identifier: GPL-2.0 */
2*326ba66dSDrew Fustini #ifndef _ASM_RISCV_QOS_H
3*326ba66dSDrew Fustini #define _ASM_RISCV_QOS_H
4*326ba66dSDrew Fustini 
5*326ba66dSDrew Fustini #include <linux/percpu-defs.h>
6*326ba66dSDrew Fustini 
7*326ba66dSDrew Fustini #ifdef CONFIG_RISCV_ISA_SSQOSID
8*326ba66dSDrew Fustini 
9*326ba66dSDrew Fustini #include <linux/bitfield.h>
10*326ba66dSDrew Fustini #include <linux/cpufeature.h>
11*326ba66dSDrew Fustini #include <linux/sched.h>
12*326ba66dSDrew Fustini 
13*326ba66dSDrew Fustini #include <asm/csr.h>
14*326ba66dSDrew Fustini #include <asm/hwcap.h>
15*326ba66dSDrew Fustini 
16*326ba66dSDrew Fustini /* cached value of srmcfg csr for each cpu */
17*326ba66dSDrew Fustini DECLARE_PER_CPU(u32, cpu_srmcfg);
18*326ba66dSDrew Fustini 
19*326ba66dSDrew Fustini /* default srmcfg value for each cpu, set via resctrl cpu assignment */
20*326ba66dSDrew Fustini DECLARE_PER_CPU(u32, cpu_srmcfg_default);
21*326ba66dSDrew Fustini 
__switch_to_srmcfg(struct task_struct * next)22*326ba66dSDrew Fustini static inline void __switch_to_srmcfg(struct task_struct *next)
23*326ba66dSDrew Fustini {
24*326ba66dSDrew Fustini 	u32 thread_srmcfg, default_srmcfg;
25*326ba66dSDrew Fustini 
26*326ba66dSDrew Fustini 	thread_srmcfg = READ_ONCE(next->thread.srmcfg);
27*326ba66dSDrew Fustini 	default_srmcfg = __this_cpu_read(cpu_srmcfg_default);
28*326ba66dSDrew Fustini 
29*326ba66dSDrew Fustini 	/*
30*326ba66dSDrew Fustini 	 * RCID and MCID inherit from cpu_srmcfg_default independently.
31*326ba66dSDrew Fustini 	 * RESCTRL_RESERVED_CLOSID and RESCTRL_RESERVED_RMID are both 0, so a
32*326ba66dSDrew Fustini 	 * zero field means "unassigned" and takes the CPU default.
33*326ba66dSDrew Fustini 	 */
34*326ba66dSDrew Fustini 	if (thread_srmcfg == 0) {
35*326ba66dSDrew Fustini 		thread_srmcfg = default_srmcfg;
36*326ba66dSDrew Fustini 	} else {
37*326ba66dSDrew Fustini 		u32 rcid = FIELD_GET(SRMCFG_RCID_MASK, thread_srmcfg);
38*326ba66dSDrew Fustini 		u32 mcid = FIELD_GET(SRMCFG_MCID_MASK, thread_srmcfg);
39*326ba66dSDrew Fustini 
40*326ba66dSDrew Fustini 		if (rcid == 0 || mcid == 0) {
41*326ba66dSDrew Fustini 			if (rcid == 0)
42*326ba66dSDrew Fustini 				rcid = FIELD_GET(SRMCFG_RCID_MASK, default_srmcfg);
43*326ba66dSDrew Fustini 			if (mcid == 0)
44*326ba66dSDrew Fustini 				mcid = FIELD_GET(SRMCFG_MCID_MASK, default_srmcfg);
45*326ba66dSDrew Fustini 			thread_srmcfg = FIELD_PREP(SRMCFG_RCID_MASK, rcid) |
46*326ba66dSDrew Fustini 					FIELD_PREP(SRMCFG_MCID_MASK, mcid);
47*326ba66dSDrew Fustini 		}
48*326ba66dSDrew Fustini 	}
49*326ba66dSDrew Fustini 
50*326ba66dSDrew Fustini 	if (thread_srmcfg != __this_cpu_read(cpu_srmcfg)) {
51*326ba66dSDrew Fustini 		/*
52*326ba66dSDrew Fustini 		 * No fence around the csrw. Ssqosid is silent on srmcfg
53*326ba66dSDrew Fustini 		 * ordering versus memory accesses, so a few accesses at the
54*326ba66dSDrew Fustini 		 * switch boundary may carry the previous RCID/MCID. The
55*326ba66dSDrew Fustini 		 * tagging inaccuracy is bounded and acceptable for QoS.
56*326ba66dSDrew Fustini 		 */
57*326ba66dSDrew Fustini 		__this_cpu_write(cpu_srmcfg, thread_srmcfg);
58*326ba66dSDrew Fustini 		csr_write(CSR_SRMCFG, thread_srmcfg);
59*326ba66dSDrew Fustini 	}
60*326ba66dSDrew Fustini }
61*326ba66dSDrew Fustini 
has_srmcfg(void)62*326ba66dSDrew Fustini static __always_inline bool has_srmcfg(void)
63*326ba66dSDrew Fustini {
64*326ba66dSDrew Fustini 	return riscv_has_extension_unlikely(RISCV_ISA_EXT_SSQOSID);
65*326ba66dSDrew Fustini }
66*326ba66dSDrew Fustini 
67*326ba66dSDrew Fustini #else /* ! CONFIG_RISCV_ISA_SSQOSID  */
68*326ba66dSDrew Fustini 
69*326ba66dSDrew Fustini struct task_struct;
has_srmcfg(void)70*326ba66dSDrew Fustini static __always_inline bool has_srmcfg(void) { return false; }
__switch_to_srmcfg(struct task_struct * next)71*326ba66dSDrew Fustini static inline void __switch_to_srmcfg(struct task_struct *next) { }
72*326ba66dSDrew Fustini 
73*326ba66dSDrew Fustini #endif /* CONFIG_RISCV_ISA_SSQOSID */
74*326ba66dSDrew Fustini #endif /* _ASM_RISCV_QOS_H */
75