SMP and hardware task switching technique
Posted: Sun Jul 05, 2009 7:47 pm
I've been hacking on a small hobby OS to add SMP support. The OS currently uses hardware task switching on a single processor. The way it works is that when the timer IRQ fires, it places the current task at the end of a runqueue, pulls off the next task, and uses a far jump to the TSS selector to switch tasks (if necessary).
This seems fairly simple, so I thought I would generalize it to SMP. I broadcast an IPI and all the processors (with a lock) place their current task on the queue, and get a new task and far jump to it. I know it's not a good protocol, but I thought it would be a simple way to start. It actually works in Bochs, sometimes, though I have not handled exiting back to the idle state well yet.
A common issue that arises is when Processor 1 is running Task 1, and Processor 2 is running Task 2, and they want to swap tasks. The problem is that Task 1 is busy until the far jump executes on Processor 1, and Task 2 is also busy until the far jump executes on Processor 2. This causes a GPF on both processors because both tasks are busy.
I have looked through the Intel System programming manual and I don't see any discussion about proper technique for task switching in SMP configurations. I've thought about manually clearing the Busy bit, but this seems like a dangerous hack, since you would at some point have the task being run in two processors. I could possibly also create some kind of "trampolining" task, but this seems like an awful lot of overhead. Does anyone know a better way?
This seems fairly simple, so I thought I would generalize it to SMP. I broadcast an IPI and all the processors (with a lock) place their current task on the queue, and get a new task and far jump to it. I know it's not a good protocol, but I thought it would be a simple way to start. It actually works in Bochs, sometimes, though I have not handled exiting back to the idle state well yet.
A common issue that arises is when Processor 1 is running Task 1, and Processor 2 is running Task 2, and they want to swap tasks. The problem is that Task 1 is busy until the far jump executes on Processor 1, and Task 2 is also busy until the far jump executes on Processor 2. This causes a GPF on both processors because both tasks are busy.
I have looked through the Intel System programming manual and I don't see any discussion about proper technique for task switching in SMP configurations. I've thought about manually clearing the Busy bit, but this seems like a dangerous hack, since you would at some point have the task being run in two processors. I could possibly also create some kind of "trampolining" task, but this seems like an awful lot of overhead. Does anyone know a better way?