Checksum offloading A look at how the Pro

  • Slides: 22
Download presentation
Checksum ‘offloading’ A look at how the Pro 1000 NICs can be programmed to

Checksum ‘offloading’ A look at how the Pro 1000 NICs can be programmed to compute and insert TCP/IP checksums

Network efficiency • Last time (in our ‘nictcp. c’ demo) we saw the amount

Network efficiency • Last time (in our ‘nictcp. c’ demo) we saw the amount of work a CPU would need to do when setting up an ethernet packet for transmission with TCP/IP protocol format • In a busy network this amount of packetcomputation becomes a ‘bottleneck’ that degrades overall system performance • But a lot of that work can be ‘offloaded’!

The ‘loops’ are costly • To prepare for a packet-transmission, the device-driver has to

The ‘loops’ are costly • To prepare for a packet-transmission, the device-driver has to execute a few dozen assignment-statements, to set up fields in the packet’s ‘headers’ and in the Transmit Descriptor that will be used by the NIC • Most of these assignments involve simple memory-to-memory copying of parameters • But the ‘checksum’ fields require ‘loops’

Can’t ‘unroll’ checksum-loops • One programming technique for speeding up loop-execution is known as

Can’t ‘unroll’ checksum-loops • One programming technique for speeding up loop-execution is known as ‘unrolling’, to avoid the ‘test-and-branch’ inefficiency: int sum = 0; sum += wp[0]; sum += wp[1]; sum += wp[2]; … sum += wp[99]; • But it requires knowing in advance what number of loop-iterations will be needed

The ‘offload’ solution • Modern network controllers can be built to perform TCP/IP checksum

The ‘offload’ solution • Modern network controllers can be built to perform TCP/IP checksum calculations on packet-data as it is being fetched from ram • This relieves a CPU from having to do the most intense portion of packet preparation • But ‘checksum offloading’ is an optional capability that has to be ‘enabled’ – and ‘programmed’ for a specific packet-layout

‘Context’ descriptors • Intel’s Pro 1000 network controllers employ special ‘Context’ Transmit-Descriptors for enabling

‘Context’ descriptors • Intel’s Pro 1000 network controllers employ special ‘Context’ Transmit-Descriptors for enabling and configuring the ‘checksumoffloading’ capability • Two kinds of Context Descriptor are used: – An ‘Offload’ Context Descriptor (Type 0) – A ‘Data’ Context Descriptor (Type 1)

Context descriptor (type 0) 63 48 47 40 39 TUCSE TUCSO MSS HDRLEN 32

Context descriptor (type 0) 63 48 47 40 39 TUCSE TUCSO MSS HDRLEN 32 31 TUCSS RSV 16 15 IPCSE STA TUCMD DTYP =0 8 IPCSO 7 0 IPCSS PAYLEN DEXT=1 (Extended Descriptor) Legend: IPCSS (IP Check. Sum Start) IPCSO (IP Check. Sum Offset) IPCSE (IP Check. Sum Ending) PAYLEN (Payload Length) TUCMD (TCP/UCP Command) HDRLEN (Header Length) TUCSS (TCP/UDP Check. Sum Start) TUCSO (TCP/UDP Check. Sum Offset) TUCSE (TCP/UDP Check. Sum Ending) DTYP (Descriptor Type) STA (TCP/UDP Status) MSS (Maximum Segment Size)

The TUCMD byte 7 IDE 6 5 4 SNAP DEXT (=1) reserved (=0) 3

The TUCMD byte 7 IDE 6 5 4 SNAP DEXT (=1) reserved (=0) 3 RS 2 TSE Legend: IDE (Interrupt Delay Enable) SNAP (Sub-Network Access Protocol) DEXT (Descriptor Extension) RS (Report Status) TSE (TCP-Segmentation Enable) IP (Internet Protocol) TCP (Transport Control Protocol) always valid only when TSE=1 1 IP 0 TCP

Context descriptor (type 1) 63 48 47 40 39 32 31 16 15 8

Context descriptor (type 1) 63 48 47 40 39 32 31 16 15 8 7 ADDRESS VLAN POPTS RSV STA DCMD DTYP =1 DTALEN DEXT=1 (Extended Descriptor) Legend: DTALEN (Data Length) DTYP (Descriptor Type) DCMD (Descriptor Command) STA (Status) RSV (Reserved) POPTS (Packet Options) VLAN (VLAN tag) 0

The DCMD byte 7 IDE 6 5 4 VLE DEXT (=1) reserved (=0) 3

The DCMD byte 7 IDE 6 5 4 VLE DEXT (=1) reserved (=0) 3 RS 2 TSE Legend: IDE (Interrupt Delay Enable) VLE (VLAN Enable) DEXT (Descriptor Extension) RS (Report Status) TSE (TCP-Segmentation Enable) IFCS (Insert Frame Check. Sum) EOP (End Of Packet)) always valid only when EOP=1 1 IFCS 0 EOP

Our usage example • We’ve created a module named ‘offload. c’ which demonstrates the

Our usage example • We’ve created a module named ‘offload. c’ which demonstrates the NIC’s checksumoffloading capability for TCP/IP packets • It’s a modification of our earlier ‘nictcp. c’ character-mode device-driver module • We have excerpted the main changes in a class-handout – the full version is online

Data-type definitions // Our type-definition for the ‘Type 0’ Context-Descriptor typedef struct { unsigned

Data-type definitions // Our type-definition for the ‘Type 0’ Context-Descriptor typedef struct { unsigned char unsigned short ipcss; ipcso; ipcse; unsigned char unsigned short tucss; tucso; tucse; unsigned int paylen: 20; dtyp: 4; tucmd: 8; unsigned char status; unsigned char hdrlen; unsigned short mss; } TX_CONTEXT_OFFLOAD;

Definitions (continued) // Our type-definition for the ‘Type 1’ Context-Descriptor typedef struct { unsigned

Definitions (continued) // Our type-definition for the ‘Type 1’ Context-Descriptor typedef struct { unsigned long base_addr; unsigned int dtalen: 20; dtyp: 4; dcmd: 8; unsigned char status; unsigned char pkt_opts; unsigned short vlan_tag; } TX_CONTEXT_DATA; typedef union { TX_CONTEXT_OFFLOAD TX_CONTEXT_DATA } TX_DESCRIPTOR; off; dat;

Our packets’ layout Ethernet Header (14 bytes) IP Header (20 bytes) TCP Header (20

Our packets’ layout Ethernet Header (14 bytes) IP Header (20 bytes) TCP Header (20 bytes) Packet-Data (length varies) 14 bytes 10 bytes 16 bytes (no options) HDR CKSUM TCP CKSUM (no options)

How we use contexts • Our ‘offload. c’ driver will send a ‘Type 0’

How we use contexts • Our ‘offload. c’ driver will send a ‘Type 0’ Context Descriptor within ‘module_init()’ txring[ 0 ]. off. ipcss = 14; txring[ 0 ]. off. ipcso = 24; txring[ 0 ]. off. ipcse = 34; // IP-header Check. Sum Start // IP-header Check. Sum Offset // IP-header Check. Sum Ending txring[ 0 ]. off. tucss = 34; txring[ 0 ]. off. tucso = 50; txring[ 0 ]. off. tucse = 0; // TCP/UDP-segment Check. Sum Start // TCP/UDP-segment Checksum Offset // TCP/UDP-segment Checksum Ending txring[ 0 ]. dtyp = 0; // Type 0 Context Descriptor txring[ 0 ]. tucmd = (1<<5)|(1<<3); // DEXT=1, RS=1 iowrite 32( 1, io + E 1000_TDT ); // give ownership to NIC

Using contexts (continued) • Our ‘offload. c’ driver will then use a Type 1

Using contexts (continued) • Our ‘offload. c’ driver will then use a Type 1 context descriptor every time its ‘write()’ function is called to transmit user-data • The network controller ‘remembers’ the checksum-offloading parameters that we sent during module-initialization, and so it continues to apply them to every outgoing packet (we keep our same packet-layout)

Sequence of ‘write()’ steps • • Adjust the ‘len’ argument (if necessary) Copy ‘len’

Sequence of ‘write()’ steps • • Adjust the ‘len’ argument (if necessary) Copy ‘len’ bytes from the user’s ‘buf’ array Prepend the packet’s TCP Header Insert the pseudo-header’s checksum Prepend the packet’s IP Header Prepend the packet’s Ethernet Header Initialize the Data-Context Tx-Descriptor Give descriptor-ownership to the NIC

The TCP pseudo-header • We do initialize the TCP Checksum field, (but this only

The TCP pseudo-header • We do initialize the TCP Checksum field, (but this only needs a short computation) Zero Protocol-ID TCP Segment-length (= 6) Source IP-address Destination IP-address • The one’s complement sum of these six words is placed into ‘TCP Checksum’

Setting up the Type-1 Context int txtail = ioread 32( io + E 1000_TDT

Setting up the Type-1 Context int txtail = ioread 32( io + E 1000_TDT ); txring[ txtail ]. dat. base_addr = tx_desc + (txtail * TX_BUFSIZ); txring[ txtail ]. dat. dtalen = 54 + len; txring[ txtail ]. dat. dtyp = 1; txring[ txtail ]. dat. dcmd = 0; txring[ txtail ]. dat. status = 0; txring[ txtail ]. dat. pkt_opts = 3; // IXSM=1, TXSM=1 txring[ txtail ]. dat. vlan_tag = vlan_id; txring[ txtail ]. dat. dcmd |= (1<<0); txring[ txtail ]. dat. dcmd |= (1<<3); txring[ txtail ]. dat. dcmd |= (1<<5); txring[ txtail ]. dat. dcmd |= (1<<6); txtail = (1 + txtail) % N_TX_DESC; iowrite 32( txtail, io + E 1000_TDT ); // EOP (End-Of-Packet) // RS (Report Status) // DEXT (Descriptor Extension) // VLE (VLAN Enable)

In-class demonstration • We can demonstrate checksum-offloading by using our ‘dram. c’ device-driver to

In-class demonstration • We can demonstrate checksum-offloading by using our ‘dram. c’ device-driver to look at the packet that is being transmitted from one of our ‘anchor’ machines, and to look at the packet that gets received by another ‘anchor’ machine • The checksum-fields (at offsets 24 and 50) do get modified by the network hardware!

In-class exercise • The NIC can also deal with packets having the UDP protocol-format

In-class exercise • The NIC can also deal with packets having the UDP protocol-format – but you need to employ different parameters in the Type 0 Context Descriptor and arrange a ‘header’ for the UDP segment that has a different length and arrangement of parameters • Also the UDP protocol-ID is 17 (=0 x 11)

UDP Header 0 0 0 0 0 1 1 1 1 1 2 2

UDP Header 0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 0 1 2 3 4 5 6 7 8 9 0 1 0 Source Port Destination Port Length Checksum Data : : : Traditional ‘Big-Endian’ representation