Summary
Whenever the system attempts to access the swap partition, the system completely freezes for a long time.
Hardware
CPU: AMD Ryzen 7 3700X 8-Core Processor
Motherboard: Asus PRIME B450M-A
RAM: 32 GB
Storage: Samsung SSD 860 1TB (Fedora)
Storage: Samsung SSD 860 512GB (Windows)
GPU: Radeon RX 5700 XT
Operating system configuration
Plain Fedora 31 installation. The main partition as well as swap is encrypted using dmcrypt.
# lvs
/dev/sdc: open failed: No medium found
/dev/sdc: open failed: No medium found
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root fedora_localhost-live -wi-ao---- <914.77g
swap fedora_localhost-live -wi-ao---- 15.74g
Problem description
I noticed that my computer completely hung when I had made a programming error in my code, causing the program to allocate infinite amounts of memory. When this happened, everything froze, and I was unable to move the mouse, or even ping the machine.
Since the problem was related to my program allocating a lot of memory, I wrote a small test program that mapped and accessed 32 GB of memory. I have included the program at the end of this post.
My test program can reliably reproduce the problem. Once the counter reaches around 27 GB or so (i.e. pretty close to the point where I’d expect it to start swapping) the machine hung with the exact same behaviour. At this time I waited to see if anything happened, and sure enough, after about 10 minutes the machine continued running as normal.
I then completely disabled swap and set /proc/sys/vm/overcommit_memory
to 1
. I then ran my test program again and this time the OOM killer killed the program at the time it would otherwise have started swapping. This confirms that the issue occurs when the system attempts to swap.
I have searched for similar issues, and I have seen people mention having problems with hangs when having swap on an encrypted LVM volume. I haven’t seen any explanations as to how to fix it though.
Is there anything I can test here? I’m out of ideas.
Test program source
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
size_t size = 1024L * 1024L * 1024L * 32L;
char *p = malloc(size);
if(p == NULL) {
fprintf(stderr, "more memory please\n");
exit(1);
}
unsigned char v = 0;
int pz = getpagesize();
for(size_t i = 0 ; i < size ; i += pz) {
p[i] = v++;
if(i % (pz * 1024) == 0) {
printf("0x%016lx (of 0x%016lx)\n", (long)i, (long)size);
}
}
return 0;
}