Linux – Excessively high memory usage reported (3 GB) after reboot

gentoolinuxmemory

Brief problem description: A 64-bit Gentoo on Intel Core-2 Q6600 reports about 3GB used out of 8GB total memory after reboot. This memory is neither claimed by any process, nor is it used by buffers/cache.

Context: I have first noticed this behavior after the OOM killed the emerge process when trying to build octave from source. When the system became responsive again, there still remained about 3GB of reportedly used memory that was not used by any process. (Please note, that I can't say for sure that this was really on the beginning – maybe I just didn't notice before.)

I tried reboot, as I am not familiar with the OOM possible issues, but the memory was reportedly used again.

Then I tried Memcheck86+ which reported one "failing address" error on 3246.3MB (test repeated 5x). I lowered the RAM frequency and the error disappeared (test repeated 3x).

However, on my Gentoo, 3GB is persistently reported as used with no apparent explanation (please see the diagnostic reports below).

I have also tried a live distro (Parted Magic), which apparently behaves normally (about several hundreds of used memory after boot up).

Any suggestions about the possible cause or even solution?

Edit: I am now able to overcome the problem, but still could not explain it. I describe what I've tracked so far:

  • The 3GB of memory is not used when started in a single-user mode.
  • Starting iptables results in the 3GB usage, while dmesg reports:

    nf_conntrack: falling back to vmalloc

  • subsequent stopping iptables does not revert the process, the memory remains used.

Then I changed my kernel configuration so that the nf_conntrack is no longer built-in, but rather it is loaded as module. After reboot, iptables starts without the falling back to vmalloc message and also without consuming the 3GB.

I have no idea, how this can be explained. Maybe some kernel developer can help explaining, what exactly could have caused this behavior?

Relevant reports:

enter image description here
enter image description here

Best Answer

This problem might be caused by an incorrect sizing of the maximum size of the connection tracking table and the hash table. The Linux kernel tries to allocate contiguous pages to track the connection tables for the iptables nf_conntrack module. As you don't have enough physical memory, conntrack fails back to vmalloc.

This table is not dynamically created based on established connections but, rather, fully allocated based on some kernel parameters.

Some additional symptoms might be finding a large number of nf_conntrack: falling back to vmalloc. messages in the /var/log/messages (or /var/log/kern.log, or in both).

This is easily solvable by just fine tuning your connection track table and sizing it down. Proper sizing has to be done based on the system usage. The connection track table needs to be high if you are running a dedicated network firewall in this system, but can be much lower if you are just using iptables to protect it from network intrusions.

For more information on connection tracking tuning please refer to https://wiki.khnet.info/index.php/Conntrack_tuning

To fine tune the values for your system, you can first evaluate the number of connections your system keeps open by running conntrack -L (or /sbin/sysctl net.netfilter.nf_conntrack_count). Better yet, keep a statistic of tracked connections over time (munin does this nicely) and use the maximum number of tracked connections as a baseline. Based on this information you can configure /etc/sysctl.conf accordingly.

When fine tuning make sure you also review how much time do you keep connections in the tracking table. Sometimes conntrack tables contain spurious data connections due to network misconfiguration or errors. For example, when the server receives SYN connections that are never closed or when client disconnects abruptly and leave open sockets for a long time.

Second, check if your conntrack entries make sense. Sometimes conntrack tables are filled with rubbish because of some network or firewall mis-configuration. Usually those are entries for connections which were never fully established. That may happen e.g. when the server gets incoming connection SYN packets, but the server replies are always lost somewhere on the network.

When fine tuning these values running sysctl -a | grep conntrack | grep timeout might be provide some insight. The default values are quite conservative: 600 (10 minutes) for generic timeouts and 432000 (5 days) for an established TCP connection. Depending on the system purpose and network behaviour those might need to be fined tuned to reduce the number of active connections in the conntrack table. Which will help define a lower value to it.

Make sure, however, that you do not size the conntrack table down too much as you can have the opposite effect: connections being dropped by iptables because they cannot be tracked and you will start having messages such as this in your log files: 'kernel: ip_conntrack: table full, dropping packet.'

In order to confirm if that is the problem please provide the output of the following:

cat /proc/sys/net/ipv4/ip_conntrack_max
cat /proc/sys/net/ipv4/netfilter/ip_conntrack_buckets
Related Question