|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 4/6] x86: add scheduling support for Intel CAT
On context switch, write the the domain's Class of Service(COS) to MSR
IA32_PQR_ASSOC, to notify hardware to use the new COS. Both CMT and CAT
writes IA32_PQR_ASSOC, so integrate them into one routine.
For performance reason, IA32_PQR_ASSOC is updated lazily based on the change
of RMID and COS. The socket number and COS mask for current cpu is also
cached in the local per-CPU variable.
Signed-off-by: Chao Peng <chao.p.peng@xxxxxxxxxxxxxxx>
---
xen/arch/x86/psr.c | 90 +++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 68 insertions(+), 22 deletions(-)
diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c
index 8c96c1b..4e50106 100644
--- a/xen/arch/x86/psr.c
+++ b/xen/arch/x86/psr.c
@@ -37,6 +37,8 @@ struct psr_cat_socket_info {
struct psr_assoc {
uint64_t val;
bool_t initialized;
+ unsigned int socket;
+ uint64_t cos_mask;
};
struct psr_cmt *__read_mostly psr_cmt;
@@ -193,27 +195,6 @@ void psr_free_rmid(struct domain *d)
d->arch.psr_rmid = 0;
}
-void psr_assoc_rmid(unsigned int rmid)
-{
- uint64_t val;
- uint64_t new_val;
- struct psr_assoc *psra = &this_cpu(psr_assoc);
-
- if ( !psra->initialized )
- {
- rdmsrl(MSR_IA32_PSR_ASSOC, psra->val);
- psra->initialized = 1;
- }
- val = psra->val;
-
- new_val = (val & ~rmid_mask) | (rmid & rmid_mask);
- if ( val != new_val )
- {
- wrmsrl(MSR_IA32_PSR_ASSOC, new_val);
- psra->val = new_val;
- }
-}
-
static int get_cat_socket_info(unsigned int socket,
struct psr_cat_socket_info **info)
{
@@ -407,10 +388,75 @@ void psr_domain_free(struct domain *d)
psr_free_cos(d);
}
+static void psr_assoc_init(struct psr_assoc *psra)
+{
+ unsigned int socket;
+ struct psr_cat_socket_info *info;
+
+ socket = cpu_to_socket(smp_processor_id());
+ psra->socket = socket;
+ if ( cat_socket_info && socket < opt_socket_num )
+ {
+ info = cat_socket_info + socket;
+ if ( info->enabled )
+ psra->cos_mask = (~(~0ull << (get_count_order(info->cos_max)
+ + 32))) & (~0ull << 32);
+ }
+
+ if ( psr_cmt_enabled() || psra->cos_mask )
+ rdmsrl(MSR_IA32_PSR_ASSOC, psra->val);
+
+ psra->initialized = 1;
+}
+
+static inline void psr_assoc_reg_read(struct psr_assoc *psra, uint64_t *reg)
+{
+ if ( !psra->initialized )
+ psr_assoc_init(psra);
+
+ *reg = psra->val;
+}
+
+static inline void psr_assoc_reg_write(struct psr_assoc *psra, uint64_t reg)
+{
+ if ( reg != psra->val )
+ {
+ wrmsrl(MSR_IA32_PSR_ASSOC, reg);
+ psra->val = reg;
+ }
+}
+
+static inline void psr_assoc_rmid(uint64_t *reg, unsigned int rmid)
+{
+ *reg = (*reg & ~rmid_mask) | (rmid & rmid_mask);
+}
+
+static inline void psr_assoc_cos(uint64_t *reg, unsigned int cos,
+ uint64_t cos_mask)
+{
+ *reg = (*reg & ~cos_mask) | (((uint64_t)cos << 32) & cos_mask);
+}
+
void psr_ctxt_switch_to(struct domain *d)
{
+ uint64_t reg;
+ struct psr_assoc *psra = &this_cpu(psr_assoc);
+
+ psr_assoc_reg_read(psra, ®);
+
if ( psr_cmt_enabled() )
- psr_assoc_rmid(d->arch.psr_rmid);
+ psr_assoc_rmid(®, d->arch.psr_rmid);
+
+ if ( psra->cos_mask )
+ {
+ if ( d->arch.psr_cos_ids )
+ psr_assoc_cos(®, d->arch.psr_cos_ids[psra->socket],
+ psra->cos_mask);
+ else
+ psr_assoc_cos(®, 0, psra->cos_mask);
+ }
+
+ psr_assoc_reg_write(psra, reg);
}
static void do_cat_cpu_init(void* data)
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |