Skip to content

Commit

Permalink
vmmon: fix page accounting
Browse files Browse the repository at this point in the history
global_page_state() was renamed to global_zone_page_state() by commit
c41f012ade0b ("mm: rename global_page_state to global_zone_page_state").
However, some more changes are needed (and were in fact needed even with
kernels older than 4.14.

Since commit 385386cff4c6 ("mm: vmstat: move slab statistics from zone to
node counters") in v4.13-rc1, NR_SLAB_UNRECLAIMABLE needs to be used with
global_node_page_state(), in-tree callers were fixed by commit d507e2ebd2c7
("mm: fix global NR_SLAB_.*CLAIMABLE counter reads").

Since commit 599d0c954f91 ("mm, vmscan: move LRU lists to node") in
v4.8-rc1, NR_UNEVICTABLE needs global_node_page_state() rather than
global_page_state().

Since commit 50658e2e04c1 ("mm: move page mapped accounting to the node")
in v4.8-rc1, NR_ANON_PAGES needs global_node_page_state() as well. This was
shortly before it was renamed to NR_ANON_MAPPED but as both got into
mainline in v4.8-rc1, we can do with one #ifdef.

To keep HostIF_EstimateLockedPageLimit() readable, extract the version
dependent calls into inline helpers.
  • Loading branch information
mkubecek committed Sep 10, 2017
1 parent 23313c6 commit 770c7ff
Showing 1 changed file with 35 additions and 9 deletions.
44 changes: 35 additions & 9 deletions vmmon-only/linux/hostif.c
Expand Up @@ -99,6 +99,37 @@
#include "vmmonInt.h"
#include "versioned_atomic.h"

#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
# define global_zone_page_state global_page_state
#endif

static unsigned long get_nr_slab_unreclaimable(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
return global_node_page_state(NR_SLAB_UNRECLAIMABLE);
#else
return global_page_state(NR_SLAB_UNRECLAIMABLE);
#endif
}

static unsigned long get_nr_unevictable(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
return global_node_page_state(NR_UNEVICTABLE);
#else
return global_page_state(NR_UNEVICTABLE);
#endif
}

static unsigned long get_nr_anon_mapped(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
return global_node_page_state(NR_ANON_MAPPED);
#else
return global_page_state(NR_ANON_PAGES);
#endif
}

/*
* Determine if we can use high resolution timers.
*/
Expand Down Expand Up @@ -1594,16 +1625,11 @@ HostIF_EstimateLockedPageLimit(const VMDriver* vm, // IN
unsigned int reservedPages = MEMDEFAULTS_MIN_HOST_PAGES;
unsigned int hugePages = (vm == NULL) ? 0 :
BYTES_2_PAGES(vm->memInfo.hugePageBytes);
unsigned int lockedPages = global_page_state(NR_PAGETABLE) +
global_page_state(NR_SLAB_UNRECLAIMABLE) +
global_page_state(NR_UNEVICTABLE) +
unsigned int lockedPages = global_zone_page_state(NR_PAGETABLE) +
get_nr_slab_unreclaimable() +
get_nr_unevictable() +
hugePages + reservedPages;
unsigned int anonPages =
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
global_page_state(NR_ANON_MAPPED);
#else
global_page_state(NR_ANON_PAGES);
#endif
unsigned int anonPages = get_nr_anon_mapped();
unsigned int swapPages = BYTES_2_PAGES(linuxState.swapSize);

if (anonPages > swapPages) {
Expand Down

11 comments on commit 770c7ff

@PabloZafra
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This works for me solving "Not enough physical memory is available to power on this virtual machine with its configured settings." problem.

Using Ubuntu 17.10 kernel 4.13.0-16-generic x64
VMware Workstation 14.0.0

@silverqx
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Diff applied, hope it helps :)

@vinhnxv
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much! Works for me.

Using Linux pop-os 4.13.0-17-generic x86_64
VMware Workstation 14.0.0

@red-rhett
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this worked a treat! The problem started only after I imported an ova. Before that VMware Workstation 14 was working well.
On Ubuntu 17.10, gnome; and before on Fedora 26; Ubuntu 16.04; Arch

@RipperSK
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the patch - it works great 👍 :)

@backtoback1
Copy link

@backtoback1 backtoback1 commented on 770c7ff Dec 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mkubecek
please help it's not working with me
with VM 14(The latest)
and kernel 4.14
OS kali linux

@ALoGeNo
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello guys, I have same problem that @mkubecek in kali with latest kernel update 14.4.0 and VM Workstation 14, I was downloaded latest vmmon and I have this issue building the module.

Using kernel build system.
make -C /lib/modules/4.14.0-kali1-amd64/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/.
MODULEBUILDDIR= modules
make[1]: Entering directory '/usr/src/linux-headers-4.14.0-kali1-amd64'
CC [M] /root/vmware-host-modules-workstation-14.0.0/vmmon-only/linux/driver.o
In file included from /root/vmware-host-modules-workstation-14.0.0/vmmon-only/linux/driver.c:24:0:
/root/vmware-host-modules-workstation-14.0.0/vmmon-only/./include/compat_timer.h:10:20: error: conflicting types for ‘timer_setup’
static inline void timer_setup(struct timer_list *timer,
^~~~~~~~~~~
In file included from /root/vmware-host-modules-workstation-14.0.0/vmmon-only/./include/compat_timer.h:4:0,
from /root/vmware-host-modules-workstation-14.0.0/vmmon-only/linux/driver.c:24:
/usr/src/linux-headers-4.14.0-kali1-common/include/linux/timer.h:175:20: note: previous definition of ‘timer_setup’ was here
static inline void timer_setup(struct timer_list *timer,
^~~~~~~~~~~
/root/vmware-host-modules-workstation-14.0.0/vmmon-only/linux/driver.c:980:1: warning: always_inline function might not be inlinable [-Wattributes]
LinuxDriverSyncReadTSCs(uint64 *delta) // OUT: TSC max - TSC min
^~~~~~~~~~~~~~~~~~~~~~~
/usr/src/linux-headers-4.14.0-kali1-common/scripts/Makefile.build:319: recipe for target '/root/vmware-host-modules-workstation-14.0.0/vmmon-only/linux/driver.o' failed
make[4]: *** [/root/vmware-host-modules-workstation-14.0.0/vmmon-only/linux/driver.o] Error 1
/usr/src/linux-headers-4.14.0-kali1-common/Makefile:1520: recipe for target 'module/root/vmware-host-modules-workstation-14.0.0/vmmon-only' failed
make[3]: *** [module/root/vmware-host-modules-workstation-14.0.0/vmmon-only] Error 2
Makefile:146: recipe for target 'sub-make' failed
make[2]: *** [sub-make] Error 2
Makefile:8: recipe for target 'all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.14.0-kali1-amd64'
Makefile:110: recipe for target 'vmmon.ko' failed
make: *** [vmmon.ko] Error 2

Thank you, Cheers.

@coseos
Copy link

@coseos coseos commented on 770c7ff Jan 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Thanks a lot - worked on my machine: LinuxMint 18.3 kernel 4.13.0-26-generic with VMware Workstation 12.5.9

@chandulaushan
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, I would really appreciate it if someone can guide me on how to apply this patch! Thank you

@Epeius
Copy link

@Epeius Epeius commented on 770c7ff Jan 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joaquin386
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one. Work like a charm.

Please sign in to comment.