[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v10 03/13] x86: maintain COS to CBM mapping for each socket
For each socket, a COS to CBM mapping structure is maintained for each COS. The mapping is indexed by COS and the value is the corresponding CBM. Different VMs may use the same CBM, a reference count is used to indicate if the CBM is available. Signed-off-by: Chao Peng <chao.p.peng@xxxxxxxxxxxxxxx> --- Changes in v10: * Check socket < nr_sockets in cat_cpu_prepare(). Changes in v9: * Allocate cos_to_cbm with opt_cos_max instead the actual cos_max from cpuid. * Move CAT initialization code back to CPU_STARTING. * Correct initialization logic for boot cpu. Changes in v8: * Move the memory allocation and CAT initialization code to CPU_UP_PREPARE. * Add memory freeing code in CPU_DEAD path. Changes in v5: * rename cos_cbm_map to cos_to_cbm. --- xen/arch/x86/psr.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c index c1bf7d7..623aca1 100644 --- a/xen/arch/x86/psr.c +++ b/xen/arch/x86/psr.c @@ -21,9 +21,15 @@ #define PSR_CMT (1<<0) #define PSR_CAT (1<<1) +struct psr_cat_cbm { + uint64_t cbm; + unsigned int ref; +}; + struct psr_cat_socket_info { unsigned int cbm_len; unsigned int cos_max; + struct psr_cat_cbm *cos_to_cbm; }; struct psr_assoc { @@ -209,6 +215,26 @@ void psr_ctxt_switch_to(struct domain *d) } } +static int cat_cpu_prepare(unsigned int cpu) +{ + struct psr_cat_socket_info *info; + unsigned int socket; + + if ( !cat_socket_info ) + return 0; + + socket = cpu_to_socket(cpu); + if ( socket >= nr_sockets ) + return -ENOSPC; + + info = cat_socket_info + socket; + if ( info->cos_to_cbm ) + return 0; + + info->cos_to_cbm = xzalloc_array(struct psr_cat_cbm, opt_cos_max + 1UL); + return info->cos_to_cbm ? 0 : -ENOMEM; +} + static void cat_cpu_init(void) { unsigned int eax, ebx, ecx, edx; @@ -232,6 +258,9 @@ static void cat_cpu_init(void) info->cbm_len = (eax & 0x1f) + 1; info->cos_max = min(opt_cos_max, edx & 0xffff); + /* cos=0 is reserved as default cbm(all ones). */ + info->cos_to_cbm[0].cbm = (1ull << info->cbm_len) - 1; + set_bit(socket, cat_socket_enable); printk(XENLOG_INFO "CAT: enabled on socket %u, cos_max:%u, cbm_len:%u\n", socket, info->cos_max, info->cbm_len); @@ -243,7 +272,24 @@ static void cat_cpu_fini(unsigned int cpu) unsigned int socket = cpu_to_socket(cpu); if ( !socket_cpumask[socket] || cpumask_empty(socket_cpumask[socket]) ) + { + struct psr_cat_socket_info *info = cat_socket_info + socket; + + if ( info->cos_to_cbm ) + { + xfree(info->cos_to_cbm); + info->cos_to_cbm = NULL; + } clear_bit(socket, cat_socket_enable); + } +} + +static void __init psr_cat_free(void) +{ + xfree(cat_socket_enable); + cat_socket_enable = NULL; + xfree(cat_socket_info); + cat_socket_info = NULL; } static void __init init_psr_cat(void) @@ -258,12 +304,12 @@ static void __init init_psr_cat(void) cat_socket_info = xzalloc_array(struct psr_cat_socket_info, nr_sockets); if ( !cat_socket_enable || !cat_socket_info ) - { - xfree(cat_socket_enable); - cat_socket_enable = NULL; - xfree(cat_socket_info); - cat_socket_info = NULL; - } + psr_cat_free(); +} + +static int psr_cpu_prepare(unsigned int cpu) +{ + return cat_cpu_prepare(cpu); } static void psr_cpu_init(void) @@ -283,19 +329,24 @@ static void psr_cpu_fini(unsigned int cpu) static int cpu_callback( struct notifier_block *nfb, unsigned long action, void *hcpu) { + int rc = 0; unsigned int cpu = (unsigned long)hcpu; switch ( action ) { + case CPU_UP_PREPARE: + rc = psr_cpu_prepare(cpu); + break; case CPU_STARTING: psr_cpu_init(); break; + case CPU_UP_CANCELED: case CPU_DEAD: psr_cpu_fini(cpu); break; } - return NOTIFY_DONE; + return !rc ? NOTIFY_DONE : notifier_from_errno(rc); } static struct notifier_block cpu_nfb = { @@ -316,6 +367,9 @@ static int __init psr_presmp_init(void) if ( opt_psr & PSR_CAT ) init_psr_cat(); + if ( psr_cpu_prepare(0) ) + psr_cat_free(); + psr_cpu_init(); if ( psr_cmt_enabled() || cat_socket_info ) register_cpu_notifier(&cpu_nfb); -- 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 |