@@ -25,51 +25,31 @@ import (
2525 "golang.org/x/sys/unix"
2626)
2727
28- // BufConfig defines the shape of the buffer used to read packets from the NIC.
29- var BufConfig = []int {4 , 128 , 256 , 256 , 512 , 1024 , 2048 , 4096 , 8192 , 16384 , 32768 }
30-
31- // +stateify savable
3228type iovecBuffer struct {
33- // buffer is the actual buffer that holds the packet contents. Some contents
34- // are reused across calls to pullBuffer if number of requested bytes is
35- // smaller than the number of bytes allocated in the buffer.
36- views []* buffer.View
37-
38- // iovecs are initialized with base pointers/len of the corresponding
39- // entries in the views defined above, except when GSO is enabled
40- // (skipsVnetHdr) then the first iovec points to a buffer for the vnet header
41- // which is stripped before the views are passed up the stack for further
42- // processing.
29+ mtu int
30+ views []* buffer.View
4331 iovecs []unix.Iovec `state:"nosave"`
44-
45- // sizes is an array of buffer sizes for the underlying views. sizes is
46- // immutable.
47- sizes []int
48-
49- // pulledIndex is the index of the last []byte buffer pulled from the
50- // underlying buffer storage during a call to pullBuffers. It is -1
51- // if no buffer is pulled.
52- pulledIndex int
5332}
5433
55- func newIovecBuffer (sizes [] int ) * iovecBuffer {
34+ func newIovecBuffer (mtu uint32 ) * iovecBuffer {
5635 b := & iovecBuffer {
57- views : make ([] * buffer. View , len ( sizes ) ),
58- iovecs : make ([]unix. Iovec , len ( sizes ) ),
59- sizes : sizes ,
36+ mtu : int ( mtu ),
37+ views : make ([]* buffer. View , 2 ),
38+ iovecs : make ([]unix. Iovec , 2 ) ,
6039 }
6140 return b
6241}
6342
6443func (b * iovecBuffer ) nextIovecs () []unix.Iovec {
65- for i := range b .views {
66- if b .views [i ] != nil {
67- break
68- }
69- v := buffer .NewViewSize (b .sizes [i ])
70- b .views [i ] = v
71- b .iovecs [i ] = unix.Iovec {Base : v .BasePtr ()}
72- b .iovecs [i ].SetLen (v .Size ())
44+ if b .views [0 ] == nil {
45+ b .views [0 ] = buffer .NewViewSize (4 )
46+ b .iovecs [0 ] = unix.Iovec {Base : b .views [0 ].BasePtr ()}
47+ b .iovecs [0 ].SetLen (4 )
48+ }
49+ if b .views [1 ] == nil {
50+ b .views [1 ] = buffer .NewViewSize (b .mtu )
51+ b .iovecs [1 ] = unix.Iovec {Base : b .views [1 ].BasePtr ()}
52+ b .iovecs [1 ].SetLen (b .mtu )
7353 }
7454 return b .iovecs
7555}
@@ -80,25 +60,13 @@ func (b *iovecBuffer) nextIovecs() []unix.Iovec {
8060// of b.buffer's storage must be reallocated during the next call to
8161// nextIovecs.
8262func (b * iovecBuffer ) pullBuffer (n int ) buffer.Buffer {
83- var views []* buffer.View
84- c := 0
85- // Remove the used views from the buffer.
86- for i , v := range b .views {
87- c += v .Size ()
88- if c >= n {
89- b .views [i ].CapLength (v .Size () - (c - n ))
90- views = append (views , b .views [:i + 1 ]... )
91- break
92- }
93- }
94- for i := range views {
95- b .views [i ] = nil
96- }
9763 pulled := buffer.Buffer {}
98- for _ , v := range views {
99- pulled .Append (v )
100- }
64+ pulled .Append (b .views [0 ])
65+ pulled .Append (b .views [1 ])
10166 pulled .Truncate (int64 (n ))
67+ pulled .TrimFront (4 )
68+ b .views [0 ] = nil
69+ b .views [1 ] = nil
10270 return pulled
10371}
10472
@@ -140,7 +108,7 @@ func newReadVDispatcher(fd int, e *endpoint, opts *Options) (linkDispatcher, err
140108 fd : fd ,
141109 e : e ,
142110 }
143- d .buf = newIovecBuffer (BufConfig )
111+ d .buf = newIovecBuffer (opts . MTU )
144112 d .mgr = newProcessorManager (opts , e )
145113 d .mgr .start ()
146114 return d , nil
@@ -158,8 +126,9 @@ func (d *readVDispatcher) dispatch() (bool, tcpip.Error) {
158126 return false , TranslateErrno (errno )
159127 }
160128
129+ payload := d .buf .pullBuffer (n )
161130 pkt := stack .NewPacketBuffer (stack.PacketBufferOptions {
162- Payload : d . buf . pullBuffer ( n ) ,
131+ Payload : payload ,
163132 })
164133 defer pkt .DecRef ()
165134
@@ -210,17 +179,21 @@ func newRecvMMsgDispatcher(fd int, e *endpoint, opts *Options) (linkDispatcher,
210179 if err != nil {
211180 return nil , err
212181 }
213- batchSize := int ((512 * 1024 )/ (opts .MTU )) + 1
182+ var batchSize int
183+ if opts .MTU < 49152 {
184+ batchSize = int ((512 * 1024 )/ (opts .MTU )) + 1
185+ } else {
186+ batchSize = 1
187+ }
214188 d := & recvMMsgDispatcher {
215189 StopFD : stopFD ,
216190 fd : fd ,
217191 e : e ,
218192 bufs : make ([]* iovecBuffer , batchSize ),
219193 msgHdrs : make ([]rawfile.MsgHdrX , batchSize ),
220194 }
221- bufConfig := []int {4 , int (opts .MTU )}
222195 for i := range d .bufs {
223- d .bufs [i ] = newIovecBuffer (bufConfig )
196+ d .bufs [i ] = newIovecBuffer (opts . MTU )
224197 }
225198 d .gro .Init (false )
226199 d .mgr = newProcessorManager (opts , e )
@@ -241,9 +214,6 @@ func (d *recvMMsgDispatcher) release() {
241214func (d * recvMMsgDispatcher ) dispatch () (bool , tcpip.Error ) {
242215 // Fill message headers.
243216 for k := range d .msgHdrs {
244- if d .msgHdrs [k ].Msg .Iovlen > 0 {
245- break
246- }
247217 iovecs := d .bufs [k ].nextIovecs ()
248218 iovLen := len (iovecs )
249219 d .msgHdrs [k ].DataLen = 0
@@ -272,7 +242,6 @@ func (d *recvMMsgDispatcher) dispatch() (bool, tcpip.Error) {
272242 for k := 0 ; k < nMsgs ; k ++ {
273243 n := int (d .msgHdrs [k ].DataLen )
274244 payload := d .bufs [k ].pullBuffer (n )
275- payload .TrimFront (4 )
276245 pkt := stack .NewPacketBuffer (stack.PacketBufferOptions {
277246 Payload : payload ,
278247 })
0 commit comments