net: Add accounting to help TSO/LSO/GSO
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 2 Jun 2017 22:21:44 +0000 (18:21 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 2 Jun 2017 22:30:31 +0000 (18:30 -0400)
The NIC will need to know how big the transport headers are.  The easiest
way is to just have the protocol tell us.  I used the same style as the
checksum_start, where we track the relative value from bp->rp.

Note that although I track the transport_header_end in UDP, we don't have
UDP GSO support elsewhere in the stack.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/ns.h
kern/src/net/tcp.c
kern/src/net/udp.c
kern/src/ns/qio.c

index e36b711..f421b1a 100644 (file)
@@ -387,6 +387,7 @@ struct block {
        uint16_t checksum_start;                /* off from start of block to start csum */
        uint16_t checksum_offset;               /* off from checksum_start to store csum */
        uint16_t mss;               /* TCP MSS for TSO */
+       uint16_t transport_header_end;  /* off from start to headers end */
        /* might want something to track the next free extra_data slot */
        size_t extra_len;
        unsigned int nr_extra_bufs;
index 33d1a09..80e8136 100644 (file)
@@ -998,6 +998,8 @@ struct block *htontcp6(Tcp * tcph, struct block *data, Tcp6hdr * ph,
                        return NULL;
                data->wp += hdrlen + TCP6_PKT;
        }
+       /* relative to the block start (bp->rp) */
+       data->transport_header_end = hdrlen + TCP4_PKT;
 
        /* copy in pseudo ip header plus port numbers */
        h = (Tcp6hdr *) (data->rp);
@@ -1082,6 +1084,8 @@ struct block *htontcp4(Tcp * tcph, struct block *data, Tcp4hdr * ph,
                        return NULL;
                data->wp += hdrlen + TCP4_PKT;
        }
+       /* relative to the block start (bp->rp) */
+       data->transport_header_end = hdrlen + TCP4_PKT;
 
        /* copy in pseudo ip header plus port numbers */
        h = (Tcp4hdr *) (data->rp);
index 6e6b643..da58226 100644 (file)
@@ -331,6 +331,7 @@ void udpkick(void *x, struct block *bp)
                                   ~ptclcsum(bp, UDP4_PHDR_OFF, UDP4_PHDR_SZ));
                        bp->checksum_start = UDP4_IPHDR_SZ;
                        bp->checksum_offset = uh4->udpcksum - uh4->udpsport;
+                       bp->transport_header_end = UDP4_IPHDR_SZ;
                        bp->flag |= Budpck;
                        uh4->vihl = IP_VER4;
                        ipoput4(f, bp, 0, c->ttl, c->tos, rc);
@@ -369,6 +370,7 @@ void udpkick(void *x, struct block *bp)
                                   ptclcsum(bp, UDP6_PHDR_OFF,
                                                        dlen + UDP_UDPHDR_SZ + UDP6_PHDR_SZ));
                        memset(uh6, 0, 8);
+                       bp->transport_header_end = UDP6_IPHDR_SZ;
                        uh6->viclfl[0] = IP_VER6;
                        hnputs(uh6->len, ptcllen);
                        uh6->nextheader = IP_UDPPROTO;
index 4b0d930..7234d02 100644 (file)
@@ -135,11 +135,13 @@ struct block *padblock(struct block *bp, int size)
        uint16_t checksum_start = bp->checksum_start;
        uint16_t checksum_offset = bp->checksum_offset;
        uint16_t mss = bp->mss;
+       uint16_t transport_header_end = bp->transport_header_end;
 
        QDEBUG checkb(bp, "padblock 1");
        if (size >= 0) {
                if (bp->rp - bp->base >= size) {
                        bp->checksum_start += size;
+                       bp->transport_header_end += size;
                        bp->rp -= size;
                        return bp;
                }
@@ -179,6 +181,7 @@ struct block *padblock(struct block *bp, int size)
                nbp->checksum_start = checksum_start;
                nbp->checksum_offset = checksum_offset;
                nbp->mss = mss;
+               nbp->transport_header_end = transport_header_end;
        }
        QDEBUG checkb(nbp, "padblock 1");
        return nbp;
@@ -269,6 +272,7 @@ struct block *copyblock(struct block *bp, int mem_flags)
                newb->checksum_start = bp->checksum_start;
                newb->checksum_offset = bp->checksum_offset;
                newb->mss = bp->mss;
+               newb->transport_header_end = bp->transport_header_end;
        }
        copyblockcnt++;
        QDEBUG checkb(newb, "copyblock 1");