hashbangcode / vlad

Vlad - Vagrant LAMP Ansible Drupal
173 stars 53 forks source link

VirtualBox CPUs allocated exceeds Ubuntu/Intel x64 host cores #350

Closed christopher-hopper closed 8 years ago

christopher-hopper commented 8 years ago

Problem

The number of CPUs allocated to my Vlad VirtualBox machine is 4, even though my desktop computer (the host OS) only has 2 physical cores. As a result, VirtualBox reports this as a problem with performance impacts.

Steps to Reproduce

  1. Boot into an Ubuntu 14.04 LTS host, running on an Intel x64 chipset
  2. Download and Install Vlad and VirtualBox 4.3.36
  3. Follow the Getting Started instructions with VirtualBox as your virtual machine provider
  4. Add the following line to the Vlad settings file vlad_guts/vlad_settings.yml

    vlad_os: "centos67"
  5. Run vagrant up
  6. Once vagrant has finished, open the VirtualBox Manager
  7. Find the running Vlad VM and view its settings [CTRL] + S
  8. View the System > Processor tab

    Expected Result

VirtualBox shows the number of Processors assigned to the VirtualBox Vlad VM as 2, which does not exceed the 2 CPUs (real or physical cores) available.

Actual Result

VirtualBox shows the number of Processors assigned to the VirtualBox Vlad VM as 4, even though it also shows that only 2 are available.

VitualBox also displays a warning, at the bottom of the window, titled Invalid settings detected. This warning reports more virtual CPUs are assigned to the virtual machine than the number of physical CPUs on the host system

Suggested Solution

Currently the Vlad Vagrantfile tries to detect the number of CPUs available on my Linux host machine using nproc. This reports the number of processing units available, which includes both real cores and hyperthreaded or psuedo-cores.

/usr/bin/nproc
4

VirtualBox can only use real cores as CPUs for Vitualization purposes, not hyperthreaded cores, on my Intel chipset. So the value returned by nproc is exactly twice as many as can be used. Each of my real cores has 2 threads per core, as reported by lscpu:

/usr/bin/lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    2
Core(s) per socket:    2
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 69
Stepping:              1
CPU MHz:               2100.000
BogoMIPS:              5387.49
Virtualisation:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              4096K
NUMA node0 CPU(s):     0-3

As you can see, I have 1 Socket, with 2 Cores per socket and, 2 Threads per core. So the number of Cores available to VirtualBox is actually the 2 Cores. Not the 4 hyperthreaded cores (or CPUs).

I did a bit of searching and found that most people are now using nproc divided by 2, as a reasonable default value when auto detecting CPUs in a Vagrantfile. This can be overridden in the Vlad settings file if someone has a chipset that provides more CPUs for Virtualization than that number. However for most Linux Hosts, on modern Intel chipsets, nproc divided by 2 will be correct for VirtualBox 4.3+.

Patch

The following patch fixes the problem.

diff --git a/Vagrantfile b/Vagrantfile
index 6f4fdfe..376c9e8 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -158,7 +158,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
     # sysctl returns Bytes and we need to convert to MB
     auto_memory = `sysctl -n hw.memsize`.to_i / 1024 / 1024 / 4
   elsif host =~ /linux/
-    auto_cpus = `nproc`.to_i
+    auto_cpus = `nproc`.to_i / 2
     # meminfo shows KB and we need to convert to MB
     auto_memory = `grep 'MemTotal' /proc/meminfo | sed -e 's/MemTotal://' -e 's/ kB//'`.to_i / 1024 / 4
   else
christopher-hopper commented 8 years ago

Merged PR #351 fixes this for me.