Hi all,
We have a question regarding best practices and recommended settings for NUMA and the number of CPU sockets assigned to a VM.
We need to support memory hot-plug, which means we are currently running these VMs with NUMA=1. Our hypervisors typically have 2–4 CPU sockets, and for many years we have created VMs with the same number of virtual sockets as the underlying hypervisor, while adjusting the number of vCPUs according to the VM's requirements.
Is this the recommended approach, or would it generally be better to use NUMA=1, SOCKETS=1, and simply increase the number of vCPUs as required? Then, only increase the number of virtual sockets when the VM requires more CPU or memory than can reasonably be provided by a single NUMA node/socket.
The reason we are asking is that, from time to time, we see an issue on some Ubuntu VMs where nfs-kernel-serverfails to restart after an unattended upgrade, with an error such as:
rpc.nfsd[1212027]: error starting threads: errno 12 (Cannot allocate memory)
The VM has sufficient memory configured, so at first glance this does not appear to be a memory capacity issue. When debugging the problem, however, it appears that the kernel has difficulty allocating sufficiently large contiguous memory blocks (higher-order allocations) from Node 0.
Our understanding is that kernel allocations are subject to NUMA locality and, depending on the allocation, may require memory from the local NUMA node, unlike ordinary user-space processes which can generally allocate memory from other nodes when allowed by their NUMA policy.
Looking at /proc/buddyinfo, we typically see that, immediately after the failure, the higher-order contiguous memory on one of the NUMA nodes is very low or unavailable. This leads us to suspect that memory fragmentation may be the underlying cause.
During an apt update/apt upgrade, memory usage changes significantly and may result in increased fragmentation. The higher-order blocks required by nfsd are then temporarily unavailable, causing the restart to fail. If we wait a minute or two and try again, the kernel appears to have had time to compact/defragment memory, and nfs-kernel-server starts successfully. The issue then typically does not occur again for another couple of weeks.
For example, the following is typical /proc/buddyinfo output immediately after a failure:
Node 0, zone DMA 25 12 5 3 8 7 5 2 1 2 0
Node 0, zone DMA32 207 28 26 103 78 27 20 6 3 5 4
Node 0, zone Normal 409 733 137 94 148 67 23 104 42 1 0
Node 1, zone DMA32 4312 2915 2234 1623 860 332 86 16 11 6 6
Node 1, zone Normal 2132 1029 1034 1126 497 315 226 57 14 7 7
As can be seen, the distribution of available blocks between Node 0 and Node 1 is quite uneven. This is what led us to our current theory.
Does this sound like a plausible explanation for the nfsd allocation failure? And, more importantly, could our VM socket/NUMA configuration be contributing to the problem?
Any thoughts or recommendations regarding the preferred NUMA/socket configuration for VMs would be appreciated.
We have a question regarding best practices and recommended settings for NUMA and the number of CPU sockets assigned to a VM.
We need to support memory hot-plug, which means we are currently running these VMs with NUMA=1. Our hypervisors typically have 2–4 CPU sockets, and for many years we have created VMs with the same number of virtual sockets as the underlying hypervisor, while adjusting the number of vCPUs according to the VM's requirements.
Is this the recommended approach, or would it generally be better to use NUMA=1, SOCKETS=1, and simply increase the number of vCPUs as required? Then, only increase the number of virtual sockets when the VM requires more CPU or memory than can reasonably be provided by a single NUMA node/socket.
The reason we are asking is that, from time to time, we see an issue on some Ubuntu VMs where nfs-kernel-serverfails to restart after an unattended upgrade, with an error such as:
rpc.nfsd[1212027]: error starting threads: errno 12 (Cannot allocate memory)
The VM has sufficient memory configured, so at first glance this does not appear to be a memory capacity issue. When debugging the problem, however, it appears that the kernel has difficulty allocating sufficiently large contiguous memory blocks (higher-order allocations) from Node 0.
Our understanding is that kernel allocations are subject to NUMA locality and, depending on the allocation, may require memory from the local NUMA node, unlike ordinary user-space processes which can generally allocate memory from other nodes when allowed by their NUMA policy.
Looking at /proc/buddyinfo, we typically see that, immediately after the failure, the higher-order contiguous memory on one of the NUMA nodes is very low or unavailable. This leads us to suspect that memory fragmentation may be the underlying cause.
During an apt update/apt upgrade, memory usage changes significantly and may result in increased fragmentation. The higher-order blocks required by nfsd are then temporarily unavailable, causing the restart to fail. If we wait a minute or two and try again, the kernel appears to have had time to compact/defragment memory, and nfs-kernel-server starts successfully. The issue then typically does not occur again for another couple of weeks.
For example, the following is typical /proc/buddyinfo output immediately after a failure:
Node 0, zone DMA 25 12 5 3 8 7 5 2 1 2 0
Node 0, zone DMA32 207 28 26 103 78 27 20 6 3 5 4
Node 0, zone Normal 409 733 137 94 148 67 23 104 42 1 0
Node 1, zone DMA32 4312 2915 2234 1623 860 332 86 16 11 6 6
Node 1, zone Normal 2132 1029 1034 1126 497 315 226 57 14 7 7
As can be seen, the distribution of available blocks between Node 0 and Node 1 is quite uneven. This is what led us to our current theory.
Does this sound like a plausible explanation for the nfsd allocation failure? And, more importantly, could our VM socket/NUMA configuration be contributing to the problem?
Any thoughts or recommendations regarding the preferred NUMA/socket configuration for VMs would be appreciated.