Swap flapping between 0k and 4Gs available?

This might be an LXCFS bug, but I thought I’d start here to see if anyone has a good explanation as to why this might not be a bug (or at least not an LXCFS one).

On one particular host, when inside of an LXC container (Ubuntu 18.04), I’m seeing swap jump from 4GB free to 0GB free for fractions of a second. Consider these results:

# for ((n=0;n<20;n++)); do cat /proc/meminfo|grep SwapFree; done
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:              0 kB
SwapFree:        4194044 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB
SwapFree:              0 kB
SwapFree:        4194300 kB
SwapFree:        4194300 kB 

What could cause available swap to occasionally “flap” between “0” and 4GB available so quickly? This happens with any LXC container on this physical host, even if it’s the only container running at the time and is completely idle. I am unable to reproduce this behavior on the physical host or other LXC containers on another physical host that has the same specs and nearly identical containers running on it.

I realize that this is not enough information to go off of… what additional details can I share here that would be helpful in solving this?

Thanks,

Curtis

@brauner any idea?

I think it’s simply raciness caused by the fact that we’re parsing some files line-by-line while having the file open. So the values might change while parsing and then you e.g. hit:

		} else if (startswith(line, "SwapTotal:") && memswlimit > 0) {
			sscanf(line+sizeof("SwapTotal:")-1, "%lu", &hostswtotal);
			if (hostswtotal < memswlimit)
				memswlimit = hostswtotal;
			snprintf(lbuf, 100, "SwapTotal:      %8lu kB\n", memswlimit);
			printme = lbuf;
		} else if (startswith(line, "SwapFree:") && memswlimit > 0 && memswusage > 0) {
			unsigned long swaptotal = memswlimit,
					swapusage = memswusage - memusage,
					swapfree = swapusage < swaptotal ? swaptotal - swapusage : 0;
                    /* ^^^^ That's the current culprit. */
			snprintf(lbuf, 100, "SwapFree:       %8lu kB\n", swapfree);
			printme = lbuf;

Thanks for taking a look at this. The issue causes some false alerts in a monitoring system we have. For now, I’ve made the monitoring system retry a couple times to make sure the number is reliable. That seems to have solved the immediate issue. Of course, it would be cool if this could be fixed, but we’re good now. :slight_smile: