Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 12: Networks


The kernel handles all devices on the list in a round robin fashion: One device is polled after another,
and when a certain amount of time has elapsed in processing one device, the next device is selected and
processed. Additionally, each device carries a relative weight that denotes the importance in contrast to
other devices on the poll list. Large weights are used for faster devices, while slower devices get lower
weights. Since the weight specifies how many packets are processed in one polling round, this ensures
that faster devices receive more attention than slower ones.

Now that the basic principle of NAPI is clear, let’s discuss the details of implementation. The key
change in contrast to the old API is that a network device that supports NAPI must provide a
pollfunction. The device-specific method is specified when the network card is registered with
netif_napi_add. Calling this function also indicates that the devices can and must be handled with the
new methods.

<netdevice.h>
static inline void netif_napi_add(struct net_device *dev,
struct napi_struct *napi,
int (*poll)(struct napi_struct *, int),
int weight);

devpoints to thenet_deviceinstance for the device in question,pollspecifies which function is used
to poll the device with IRQs disabled, andweightdoes what you expect it to do: It specifies a relative
weight for the interface. In principle, an arbitrary integer value can be specified. Usually 10- and 100-MBit
drivers specify 16, while 1,000- and 10,000-MBit drivers use 64. In any case, the weight must not exceed
the number of packets that can be stored by the device in the Rx buffer.

netif_napi_addrequires one more parameter, a pointer to an instance ofstruct napi_struct.The
structure is used to manage the device on the poll list. It is defined as follows:

<netdevice.h>
struct napi_struct {
struct list_head poll_list;

unsigned long state;
int weight;
int (*poll)(struct napi_struct *, int);
};

The poll list is implemented by means of a standard doubly linked kernel list, andpoll_listis used
as the list element.weightandpollhave the same meaning as described above.statecan either be
NAPI_STATE_SCHEDwhen the device has to be polled next time the kernel comes around to doing so, or
NAPI_STATE_DISABLEonce polling is finished and no more packets are waiting to be processed, but the
device has not yet been taken off the poll list.

Note thatstruct napi_structis often embedded inside a bigger structure containing driver-specific
information about the network card. This allows for using thecontainer_ofmechanism to obtain the
information when the kernel polls the card with thepollfunction.

Implementing Poll Functions


The poll function requires two arguments: a pointer to thenapi_structinstance and an integer that
specifies the budget, that is, how many packets the kernel allows to be processed by the driver. Since we
Free download pdf