Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 12: Networks


do not want to deal with the peculiarities of any real networking card, let us discuss a pseudo-function
for a very, very fast adapter that needs NAPI:

static int hyper_card_poll(struct napi_struct *napi, int budget)
{
struct nic *nic = container_of(napi, struct nic, napi);
struct net_device *netdev = nic->netdev;
int work_done;

work_done = hyper_do_poll(nic, budget);

if (work_done < budget) {
netif_rx_complete(netdev, napi);
hcard_reenable_irq(nic);
}

return work_done;
}

After obtaining device-specific information from the container ofnapi_struct, a hardware-specific
poll method — in this case,hyper_do_poll— is called to perform the required low-level actions to
obtain the packets from the network adapter and pass them to the higher networking layers using
netif_receive_skbas before.

hyper_do_pollallows processing up tobudgetpackets. The function returns as result how many packets
have actually been processed. Two cases must be distinguished:

❑ If the number of processed packets is less than the granted budget, then no more packets are
available and the Rx buffer is empty — otherwise, the remaining packets would have been pro-
cessed. As a consequence,netif_rx_completesignals this condition to the kernel, and the kernel
will remove the device from the poll list in consequence. In turn, the driver has to re-enable IRQs
by means of a suitable hardware-specific method.
❑ Although the budget has been completely used up, more packets are still waiting to be pro-
cessed. The device is left on the poll list, and interrupts arenotenabled again.

Implementing IRQ Handlers


NAPI also requires some changes in the IRQ handlers of network devices. Again, I will not resort to any
specific piece of hardware, but present code for an imaginary device:

static irqreturn_t e100_intr(int irq, void *dev_id)
{
struct net_device *netdev = dev_id;
struct nic *nic = netdev_priv(netdev);

if(likely(netif_rx_schedule_prep(netdev, &nic->napi))) {
hcard_disable_irq(nic);
__netif_rx_schedule(netdev, &nic->napi);
}

return IRQ_HANDLED;
}
Free download pdf