Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _ASM_X86_RESCTRL_H
0003 #define _ASM_X86_RESCTRL_H
0004 
0005 #ifdef CONFIG_X86_CPU_RESCTRL
0006 
0007 #include <linux/sched.h>
0008 #include <linux/jump_label.h>
0009 
0010 #define IA32_PQR_ASSOC  0x0c8f
0011 
0012 /**
0013  * struct resctrl_pqr_state - State cache for the PQR MSR
0014  * @cur_rmid:       The cached Resource Monitoring ID
0015  * @cur_closid: The cached Class Of Service ID
0016  * @default_rmid:   The user assigned Resource Monitoring ID
0017  * @default_closid: The user assigned cached Class Of Service ID
0018  *
0019  * The upper 32 bits of IA32_PQR_ASSOC contain closid and the
0020  * lower 10 bits rmid. The update to IA32_PQR_ASSOC always
0021  * contains both parts, so we need to cache them. This also
0022  * stores the user configured per cpu CLOSID and RMID.
0023  *
0024  * The cache also helps to avoid pointless updates if the value does
0025  * not change.
0026  */
0027 struct resctrl_pqr_state {
0028     u32         cur_rmid;
0029     u32         cur_closid;
0030     u32         default_rmid;
0031     u32         default_closid;
0032 };
0033 
0034 DECLARE_PER_CPU(struct resctrl_pqr_state, pqr_state);
0035 
0036 DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
0037 DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
0038 DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key);
0039 
0040 /*
0041  * __resctrl_sched_in() - Writes the task's CLOSid/RMID to IA32_PQR_MSR
0042  *
0043  * Following considerations are made so that this has minimal impact
0044  * on scheduler hot path:
0045  * - This will stay as no-op unless we are running on an Intel SKU
0046  *   which supports resource control or monitoring and we enable by
0047  *   mounting the resctrl file system.
0048  * - Caches the per cpu CLOSid/RMID values and does the MSR write only
0049  *   when a task with a different CLOSid/RMID is scheduled in.
0050  * - We allocate RMIDs/CLOSids globally in order to keep this as
0051  *   simple as possible.
0052  * Must be called with preemption disabled.
0053  */
0054 static void __resctrl_sched_in(void)
0055 {
0056     struct resctrl_pqr_state *state = this_cpu_ptr(&pqr_state);
0057     u32 closid = state->default_closid;
0058     u32 rmid = state->default_rmid;
0059     u32 tmp;
0060 
0061     /*
0062      * If this task has a closid/rmid assigned, use it.
0063      * Else use the closid/rmid assigned to this cpu.
0064      */
0065     if (static_branch_likely(&rdt_alloc_enable_key)) {
0066         tmp = READ_ONCE(current->closid);
0067         if (tmp)
0068             closid = tmp;
0069     }
0070 
0071     if (static_branch_likely(&rdt_mon_enable_key)) {
0072         tmp = READ_ONCE(current->rmid);
0073         if (tmp)
0074             rmid = tmp;
0075     }
0076 
0077     if (closid != state->cur_closid || rmid != state->cur_rmid) {
0078         state->cur_closid = closid;
0079         state->cur_rmid = rmid;
0080         wrmsr(IA32_PQR_ASSOC, rmid, closid);
0081     }
0082 }
0083 
0084 static inline void resctrl_sched_in(void)
0085 {
0086     if (static_branch_likely(&rdt_enable_key))
0087         __resctrl_sched_in();
0088 }
0089 
0090 void resctrl_cpu_detect(struct cpuinfo_x86 *c);
0091 
0092 #else
0093 
0094 static inline void resctrl_sched_in(void) {}
0095 static inline void resctrl_cpu_detect(struct cpuinfo_x86 *c) {}
0096 
0097 #endif /* CONFIG_X86_CPU_RESCTRL */
0098 
0099 #endif /* _ASM_X86_RESCTRL_H */