I'm currently working on an educational operating system called Pintos. While implementing virtual memory, one of the issues that I'm having is writing data to swap in a page fault that happened while reading data from the file system.
The problem is that both the swap and file system partitions use the same controller, and thus only one can be accessed at a time. When I try to evict a page to swap in a page fault caused by a file system read, I get deadlock (each device is waiting for the other to become idle, so neither can make progress).
I'm wondering how real-world operating systems such as Linux solve this problem. One solution that I'm thinking is to maybe write the swapped page to kernel memory first, manage it in a queue, then schedule the write back to swap some time later when the device is available. However, this is expensive as the write has to be done twice. Also, it's much more likely that I would run out of RAM, as there is a lot more available swap space than physical memory.
Another solution is to maybe "force" the device to become idle in the page fault? I know that the device controller uses some bits (BSY and DRQ) to determine the device status. However, this is most likely implementation dependent, and I'm not sure if I should be touching these bits as they could be set by the hardware.
Any advice would be greatly appreciated.