[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 2/2] x86/cpu: Improvements to get_cpu_vendor()



Comparing 3 integers is more efficient than using strcmp(), and is more useful
to the gcv_guest case than having to fabricate a suitable string to pass.  The
gcv_host cases have both options easily to hand, and experimentally, the
resulting code is more efficient.

While modifying get_cpu_vendor(), fix a bug where this_cpu got updated even in
the gcv_guest case.

Update the cpu_dev structure to be more efficient.  c_vendor[] only needs to
be 8 bytes long to cover all the CPU drivers Xen has, which avoids storing an
8-byte pointer to 8 bytes of data.  Drop c_ident[1] as we have no CPU drivers
with a second ident string, and turn it into a transparent union to allow
access to the integer values directly.

This avoids all need for the vendor_id union in update_domain_cpuid_info().

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
---
 xen/arch/x86/cpu/common.c       | 30 +++++++++++++++---------------
 xen/arch/x86/cpu/cpu.h          | 10 +++++++---
 xen/arch/x86/domctl.c           | 15 ++-------------
 xen/include/asm-x86/processor.h |  2 +-
 4 files changed, 25 insertions(+), 32 deletions(-)

diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index a89cf07..d17a2ee 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -156,17 +156,17 @@ void display_cacheinfo(struct cpuinfo_x86 *c)
                       l2size, ecx & 0xFF);
 }
 
-int get_cpu_vendor(const char v[], enum get_cpu_vendor mode)
+int get_cpu_vendor(uint32_t b, uint32_t c, uint32_t d, enum get_cpu_vendor 
mode)
 {
        int i;
        static int printed;
 
        for (i = 0; i < X86_VENDOR_NUM; i++) {
                if (cpu_devs[i]) {
-                       if (!strcmp(v,cpu_devs[i]->c_ident[0]) ||
-                           (cpu_devs[i]->c_ident[1] && 
-                            !strcmp(v,cpu_devs[i]->c_ident[1]))) {
-                               this_cpu = cpu_devs[i];
+                       if (cpu_devs[i]->b == b && cpu_devs[i]->c == c &&
+                           cpu_devs[i]->d == d) {
+                               if (mode == gcv_host)
+                                       this_cpu = cpu_devs[i];
                                return i;
                        }
                }
@@ -233,12 +233,12 @@ static void __init early_cpu_detect(void)
        c->x86_cache_alignment = 32;
 
        /* Get vendor name */
-       cpuid(0x00000000, &c->cpuid_level,
-             (int *)&c->x86_vendor_id[0],
-             (int *)&c->x86_vendor_id[8],
-             (int *)&c->x86_vendor_id[4]);
+       cpuid(0x00000000, &c->cpuid_level, &ebx, &ecx, &edx);
+       *(u32 *)&c->x86_vendor_id[0] = ebx;
+       *(u32 *)&c->x86_vendor_id[8] = ecx;
+       *(u32 *)&c->x86_vendor_id[4] = edx;
 
-       c->x86_vendor = get_cpu_vendor(c->x86_vendor_id, gcv_host);
+       c->x86_vendor = get_cpu_vendor(ebx, ecx, edx, gcv_host);
 
        cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
        c->x86 = get_cpu_family(eax, &c->x86_model, &c->x86_mask);
@@ -276,12 +276,12 @@ static void generic_identify(struct cpuinfo_x86 *c)
        u32 eax, ebx, ecx, edx, tmp;
 
        /* Get vendor name */
-       cpuid(0x00000000, &c->cpuid_level,
-             (int *)&c->x86_vendor_id[0],
-             (int *)&c->x86_vendor_id[8],
-             (int *)&c->x86_vendor_id[4]);
+       cpuid(0x00000000, &c->cpuid_level, &ebx, &ecx, &edx);
+       *(u32 *)&c->x86_vendor_id[0] = ebx;
+       *(u32 *)&c->x86_vendor_id[8] = ecx;
+       *(u32 *)&c->x86_vendor_id[4] = edx;
 
-       c->x86_vendor = get_cpu_vendor(c->x86_vendor_id, gcv_host);
+       c->x86_vendor = get_cpu_vendor(ebx, ecx, edx, gcv_host);
        /* Initialize the standard set of capabilities */
        /* Note that the vendor-specific code below might override */
 
diff --git a/xen/arch/x86/cpu/cpu.h b/xen/arch/x86/cpu/cpu.h
index 1877e7d..5a7905c 100644
--- a/xen/arch/x86/cpu/cpu.h
+++ b/xen/arch/x86/cpu/cpu.h
@@ -1,9 +1,13 @@
 /* attempt to consolidate cpu attributes */
 struct cpu_dev {
-       char    * c_vendor;
+       char    c_vendor[8];
 
-       /* some have two possibilities for cpuid string */
-       char    * c_ident[2];   
+       union {
+               char    c_ident[13];
+               struct {
+                       uint32_t b, d, c;
+               };
+       };
 
        void            (*c_early_init)(struct cpuinfo_x86 *c);
        void            (*c_init)(struct cpuinfo_x86 * c);
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index ab9ad39..eb71c9e 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -54,21 +54,10 @@ static void update_domain_cpuid_info(struct domain *d,
     switch ( ctl->input[0] )
     {
     case 0: {
-        union {
-            typeof(boot_cpu_data.x86_vendor_id) str;
-            struct {
-                uint32_t ebx, edx, ecx;
-            } reg;
-        } vendor_id = {
-            .reg = {
-                .ebx = ctl->ebx,
-                .edx = ctl->edx,
-                .ecx = ctl->ecx
-            }
-        };
         int old_vendor = d->arch.x86_vendor;
 
-        d->arch.x86_vendor = get_cpu_vendor(vendor_id.str, gcv_guest);
+        d->arch.x86_vendor = get_cpu_vendor(
+            ctl->ebx, ctl->ecx, ctl->edx, gcv_guest);
 
         if ( is_hvm_domain(d) && (d->arch.x86_vendor != old_vendor) )
         {
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index be31586..aff115b 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -624,7 +624,7 @@ enum get_cpu_vendor {
     gcv_guest,
 };
 
-int get_cpu_vendor(const char vendor_id[], enum get_cpu_vendor);
+int get_cpu_vendor(uint32_t b, uint32_t c, uint32_t d, enum get_cpu_vendor 
mode);
 uint8_t get_cpu_family(uint32_t raw, uint8_t *model, uint8_t *stepping);
 
 void pv_cpuid(struct cpu_user_regs *regs);
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.