Sending Packets to the Network Card
A network card device driver is usually started either when the kernel inserts a packet in its transmit queue (as described in the previous section), or when a packet is received from the communication channel. Let’s focus here on packet transmission.
As we have seen, the qdisc_run( ) function is
invoked whenever the kernel wishes to activate a network card device
driver; it is also executed by the NET_TX_SOFTIRQ
softirq, which is implemented by the net_tx_action( ) function (see Section 4.7).
Essentially, the qdisc_run( ) function checks
whether the network card device is idle and can thus transmit the
packets in the queue. If the device cannot do this — for
instance, because the card is already busy in transmitting or
receiving a packet, the queue has been stopped to avoid flooding the
communication channel, or for whatever other reason — the
NET_TX_SOFTIRQ softirq is activated and the
current execution of qdisc_run( ) is terminated.
At a later time, when the scheduler selects a
ksoftirqd_CPUn kernel thread, the
net_tx_action( ) function invokes
qdisc_run( ) again to retry the packet
transmission.
In particular, qdisc_run( ) performs the following
actions:
Checks whether the packet queue is “stopped” — that is, whether a suitable bit in the
statefield of thenet_devicenetwork card object is set. If it is stopped, the function returns immediately.Invokes the
qdisc_restart( )function, which in turn performs the following actions:Invokes ...