[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 |