diff options
author | Bert Muthalaly <stijlist@google.com> | 2018-09-05 17:33:18 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-09-05 17:34:25 -0700 |
commit | 5685d6b5add2acce9618aa908b846f5ce3658346 (patch) | |
tree | ca93fb55c83ebf77806957c73c3951fc01844560 /pkg/tcpip/link/sharedmem | |
parent | fe8ca76c22ff03c9ae8bf524031553d65b30f53d (diff) |
Update {LinkEndpoint,NetworkEndpoint}#WritePacket to take a VectorisedView
Makes it possible to avoid copying or allocating in cases where DeliverNetworkPacket (rx)
needs to turn around and call WritePacket (tx) with its VectorisedView.
Also removes the restriction on having VectorisedViews with multiple views in the write path.
PiperOrigin-RevId: 211728717
Change-Id: Ie03a65ecb4e28bd15ebdb9c69f05eced18fdfcff
Diffstat (limited to 'pkg/tcpip/link/sharedmem')
-rw-r--r-- | pkg/tcpip/link/sharedmem/sharedmem.go | 5 | ||||
-rw-r--r-- | pkg/tcpip/link/sharedmem/sharedmem_test.go | 35 |
2 files changed, 22 insertions, 18 deletions
diff --git a/pkg/tcpip/link/sharedmem/sharedmem.go b/pkg/tcpip/link/sharedmem/sharedmem.go index 824cab093..6bd5441f6 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem.go +++ b/pkg/tcpip/link/sharedmem/sharedmem.go @@ -184,7 +184,7 @@ func (e *endpoint) LinkAddress() tcpip.LinkAddress { // WritePacket writes outbound packets to the file descriptor. If it is not // currently writable, the packet is dropped. -func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.View, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { +func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload buffer.VectorisedView, protocol tcpip.NetworkProtocolNumber) *tcpip.Error { // Add the ethernet header here. eth := header.Ethernet(hdr.Prepend(header.EthernetMinimumSize)) eth.Encode(&header.EthernetFields{ @@ -193,9 +193,10 @@ func (e *endpoint) WritePacket(r *stack.Route, hdr *buffer.Prependable, payload Type: protocol, }) + v := payload.ToView() // Transmit the packet. e.mu.Lock() - ok := e.tx.transmit(hdr.UsedBytes(), payload) + ok := e.tx.transmit(hdr.UsedBytes(), v) e.mu.Unlock() if !ok { diff --git a/pkg/tcpip/link/sharedmem/sharedmem_test.go b/pkg/tcpip/link/sharedmem/sharedmem_test.go index 1e229279a..69d4ef29f 100644 --- a/pkg/tcpip/link/sharedmem/sharedmem_test.go +++ b/pkg/tcpip/link/sharedmem/sharedmem_test.go @@ -270,8 +270,8 @@ func TestSimpleSend(t *testing.T) { randomFill(buf) proto := tcpip.NetworkProtocolNumber(rand.Intn(0x10000)) - err := c.ep.WritePacket(&r, &hdr, buf, proto) - if err != nil { + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) + if err := c.ep.WritePacket(&r, &hdr, vv, proto); err != nil { t.Fatalf("WritePacket failed: %v", err) } @@ -330,13 +330,15 @@ func TestFillTxQueue(t *testing.T) { } buf := buffer.NewView(100) + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Each packet is uses no more than 40 bytes, so write that many packets // until the tx queue if full. ids := make(map[uint64]struct{}) for i := queuePipeSize / 40; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -351,8 +353,7 @@ func TestFillTxQueue(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber) - if want := tcpip.ErrWouldBlock; err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -373,11 +374,12 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { } buf := buffer.NewView(100) + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Send two packets so that the id slice has at least two slots. for i := 2; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } } @@ -397,7 +399,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { ids := make(map[uint64]struct{}) for i := queuePipeSize / 40; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -412,8 +414,7 @@ func TestFillTxQueueAfterBadCompletion(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber) - if want := tcpip.ErrWouldBlock; err != want { + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } } @@ -430,13 +431,14 @@ func TestFillTxMemory(t *testing.T) { } buf := buffer.NewView(100) + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Each packet is uses up one buffer, so write as many as possible until // we fill the memory. ids := make(map[uint64]struct{}) for i := queueDataSize / bufferSize; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -452,7 +454,7 @@ func TestFillTxMemory(t *testing.T) { // Next attempt to write must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber) + err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber) if want := tcpip.ErrWouldBlock; err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } @@ -472,12 +474,13 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { } buf := buffer.NewView(100) + vv := buffer.NewVectorisedView(len(buf), []buffer.View{buf}) // Each packet is uses up one buffer, so write as many as possible // until there is only one buffer left. for i := queueDataSize/bufferSize - 1; i > 0; i-- { hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } @@ -488,14 +491,14 @@ func TestFillTxMemoryWithMultiBuffer(t *testing.T) { // Attempt to write a two-buffer packet. It must fail. hdr := buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - err := c.ep.WritePacket(&r, &hdr, buffer.NewView(bufferSize), header.IPv4ProtocolNumber) - if want := tcpip.ErrWouldBlock; err != want { + uu := buffer.NewVectorisedView(bufferSize, []buffer.View{buffer.NewView(bufferSize)}) + if want, err := tcpip.ErrWouldBlock, c.ep.WritePacket(&r, &hdr, uu, header.IPv4ProtocolNumber); err != want { t.Fatalf("WritePacket return unexpected result: got %v, want %v", err, want) } - // Attempt to write a one-buffer packet. It must succeed. + // Attempt to write the one-buffer packet again. It must succeed. hdr = buffer.NewPrependable(int(c.ep.MaxHeaderLength())) - if err := c.ep.WritePacket(&r, &hdr, buf, header.IPv4ProtocolNumber); err != nil { + if err := c.ep.WritePacket(&r, &hdr, vv, header.IPv4ProtocolNumber); err != nil { t.Fatalf("WritePacket failed unexpectedly: %v", err) } } |