Re: [Qemu-devel] Re: [RFC] allow multi-core guests: introduce cores= option to -cpu

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: Andre Przywara <andre.przywara@...>
Cc: Brian Jackson <iggy@...>, <qemu-devel@...>, <kvm@...>
Date: Saturday, July 4, 2009 - 3:18 am

On Sat, Jul 04, 2009 at 12:52:30AM +0200, Andre Przywara wrote:

There is not point in [,sockets=1] option -smp socketnum[,cores=n][,threads=n]
is backwards compatible already if default for cores and threads is 1.
I have a similar patch locally that does that. What I think is missing
for KVM (and in the future for QEMU) is hotplug support. The current
hotplug code can't hotplug the socket, only one vcpu. What is missing is
the ability to specify number of available sockets vs number of
populated sockets and specify base apic id for each available socket.
Cpu hotplug will get base apic id as a parameter and will hotplug all
logical cpus simultaneously.

BTW I don't see that you change cpulevel to 4 in your patch. Guest
will not use cpu topology information without it.

diff --git a/sysemu.h b/sysemu.h
index 5582633..7187920 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -120,6 +120,8 @@ extern int usb_enabled;
 extern int virtio_balloon;
 extern const char *virtio_balloon_devaddr;
 extern int smp_cpus;
+extern int cpu_cores;
+extern int core_threads;
 extern int cursor_hide;
 extern int graphic_rotate;
 extern int no_quit;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 87c04e5..585af4c 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -24,6 +24,8 @@
 #include <inttypes.h>
 #include <signal.h>
 
+#include "qemu-common.h"
+#include "sysemu.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "qemu-common.h"
@@ -122,7 +124,7 @@ static x86_def_t x86_defs[] = {
 #ifdef TARGET_X86_64
     {
         .name = "qemu64",
-        .level = 2,
+        .level = 4,
         .vendor1 = CPUID_VENDOR_AMD_1,
         .vendor2 = CPUID_VENDOR_AMD_2,
         .vendor3 = CPUID_VENDOR_AMD_3,
@@ -194,7 +196,7 @@ static x86_def_t x86_defs[] = {
 #endif
     {
         .name = "qemu32",
-        .level = 2,
+        .level = 4,
         .family = 6,
         .model = 3,
         .stepping = 3,
@@ -260,7 +262,7 @@ static x86_def_t x86_defs[] = {
     },
     {
         .name = "athlon",
-        .level = 2,
+        .level = 4,
         .vendor1 = CPUID_VENDOR_AMD_1,
         .vendor2 = CPUID_VENDOR_AMD_2,
         .vendor3 = CPUID_VENDOR_AMD_3,
@@ -483,6 +485,8 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
     env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
     env->cpuid_version |= def->stepping;
     env->cpuid_features = def->features;
+    if (cpu_cores * core_threads > 1)
+        env->cpuid_features |= CPUID_HT;
     env->pat = 0x0007040600070406ULL;
     env->cpuid_ext_features = def->ext_features;
     env->cpuid_ext2_features = def->ext2_features;
@@ -1564,7 +1568,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         break;
     case 1:
         *eax = env->cpuid_version;
-        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
+        *ebx = (env->cpuid_apic_id << 24) | (cpu_cores*core_threads) << 16
+            | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
         *ecx = env->cpuid_ext_features;
         *edx = env->cpuid_features;
         break;
@@ -1579,7 +1584,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         /* cache info: needed for Core compatibility */
         switch (count) {
             case 0: /* L1 dcache info */
-                *eax = 0x0000121;
+                *eax = 0x0000121 | ((cpu_cores - 1) << 26);
                 *ebx = 0x1c0003f;
                 *ecx = 0x000003f;
                 *edx = 0x0000001;
diff --git a/vl.c b/vl.c
index 5d86e69..9098603 100644
--- a/vl.c
+++ b/vl.c
@@ -244,6 +244,8 @@ int singlestep = 0;
 const char *assigned_devices[MAX_DEV_ASSIGN_CMDLINE];
 int assigned_devices_index;
 int smp_cpus = 1;
+int cpu_cores = 1;
+int core_threads = 1;
 const char *vnc_display;
 int acpi_enabled = 1;
 int no_hpet = 0;
@@ -5696,12 +5698,23 @@ int main(int argc, char **argv, char **envp)
                 usb_devices_index++;
                 break;
             case QEMU_OPTION_smp:
-                smp_cpus = atoi(optarg);
+            {
+                char *p;
+                char option[128];
+                smp_cpus = strtol(optarg, &p, 10);
                 if (smp_cpus < 1) {
-                    fprintf(stderr, "Invalid number of CPUs\n");
+                    fprintf(stderr, "Invalid number of slots\n");
                     exit(1);
                 }
+                if (*p++ != ',')
+                    break;
+                if (get_param_value(option, 128, "cores", p))
+                    cpu_cores = strtol(option, NULL, 0);
+                if (get_param_value(option, 128, "threads", p))
+                    core_threads = strtol(option, NULL, 0);
+                smp_cpus *= (cpu_cores * core_threads);
                 break;
+            }
 	    case QEMU_OPTION_vnc:
                 display_type = DT_VNC;
 		vnc_display = optarg;
--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: [Qemu-devel] Re: [RFC] allow multi-core guests: introduc..., Gleb Natapov, (Sat Jul 4, 3:18 am)