All modern device drivers should be doing two things, firstthey should use NAPI for interrupt mitigation plus simplermutual exclusion (all RX code paths run in software interruptcontext just like TX), and use the GRO NAPI interfaces forfeeding packets into the network stack.
Like just about anything else in the networking, GRO isall about increasing performance. The idea is that wecan accumulate consequetive packets (based upon protocolspecific sequence number checks etc.) into one huge packet.Then process the whole group as one packet object. (inNetwork Algorithmics this would be principle P2c,Shift computation in time, Share expenses, batch)
GRO help significantly on everyday systems, but it helpseven more strongly on machines making use of virtualizationsince bridging streams of packets is very common and GRObatching decreases the number of switching operations.
Each NAPI instance maintains a list of GRO packets we aretrying to accumulate to, called napi->gro_list.The GRO layer dispatches to the network layer protocolthat the packet is for. Each network layer that supportsGRO implements both a ptype->gro_receive and aptype->gro_complete method.
->gro_receive attempts to match the incoming skbwith ones that have already been queued onto the ->gro_listAt this time, the IP and TCP headers are popped from the front of thepackets (from GRO's perspective, that actual normal skbpacket header pointers are left alone). Also, the GRO'ability stateof all packets in the GRO list and the new incoming SKB are updated.
Once we've committed to receiving a GRO skb, we invoke the->gro_complete method. It is at this point thatwe make the collection of individual packets look truly like onehuge one. Checksums are updated, as are various private GSOstate flags in the head 'skb' given to the network stack.
We do not try to accumulate GRO packets infinitely. At theend of a NAPI poll quantum, we force flush the GRO packetlist.
For ipv4 TCP there are various criteria for GRO matching.
- Source and destination address must match
- TOS and protocol fields must be the same
- Source and destination ports must match
- ID field not being in sequence with existing packets
- Don't fragment bit clear
- TCP CWR congestion indication being set
- TCP ACK sequence mis-match
- Any TCP option mis-match
- TCP sequence not being in-order
The most important attribute of GRO is that it preservesthe received packets in their entirety, such that if wedon't actually receive the packets locally (for examplewe want to bridge or route them) they can be perfectlyand accurately reconstituted to the transmit path. Thisis because none of the packet headers are modified (theyare entirely preserved) and since GRO requires completelyregular packet streams for merging, the packet boundarypoints are known precisely as well. The GRO mergedpacket can be completely unraveled and it will mimmickexactly the incoming packet sequence.
GRO mainly the work of Herbert Xu. Various driver authorsand others helped him tune and optimize the implementation.