Threading model
The default mode of operation is for io-pkt to create one thread per CPU.
The io-pkt stack is fully multithreaded at layer 2.
However, only one thread may acquire the stack context
for
upper-layer packet processing.
If multiple interrupt sources require servicing at the same time,
these may be serviced by multiple threads.
Only one thread will be servicing a particular interrupt source at any
point in time.
Typically an interrupt on a network device indicates that there are
packets to be received.
The same thread that handles the receive processing may later transmit
the received packets out another interface.
Examples of this are layer-2 bridging and the ipflow
fastforwarding of IP packets.
The stack uses a thread pool to service events that are generated from other parts of the system. These events may be:
- timeouts
- ISR events
- other things generated by the stack or protocol modules
You can use a command-line option to the driver to control the priority at which the thread is run to receive packets. Client connection requests are handled in a floating-priority mode (i.e., the thread priority matches that of the client application thread accessing the stack resource manager).
Once a thread receives an event, it examines the event type to see if it's
a hardware event, stack event, or other
event:
- If the event is a hardware event, the hardware is serviced and, for a receive packet, the thread determines whether bridging or fast-forwarding is required. If so, the thread performs the appropriate lookup to determine which interface the packet should be queued for, and then takes care of transmitting it, after which it goes back to check and see if the hardware needs to be serviced again.
- If the packet is meant for the local stack, the thread queues the packet on the stack queue. The thread then goes back and continues checking and servicing hardware events until there are no more events.
- Once a thread has completed servicing the hardware, it checks to see
if there's currently a stack thread
running to service stack events that may have been generated as a result
of its actions.
If there's no stack thread running, the thread becomes the
stack thread and loops, processing stack events until there are none
remaining.
It then returns to the
wait for event
state in the thread pool.
This capability of having a thread change directly from being a hardware-servicing thread to being the stack thread eliminates context switching and greatly improves the receive performance for locally terminated IP flows.
