tcp: Recover from iob shortage with TCP_WRITE_BUFFERS #11406
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
When
CONFIG_NET_TCP_WRITE_BUFFERS
is enabled, iobs are used for both queuing data from application, and for assembling packets for sending. If there is a system-wide shortage of iobs, it could happen that there is not enough free space to form any packets to send. The buffers allocated for TCP data also can't be released until the packet is sent.Normally this should be avoided by setting suitable values for
CONFIG_IOB_NBUFFERS
andCONFIG_IOB_THROTTLE
. The default values are ok for light usage, but can run out when using multiple simultaneous TCP streams.Before this commit, iob shortage would cause TCP connections to get stuck and eventually timeout. With this change, TCP stack sends smaller packets, eventually freeing some buffers from the write queue.
Impact
In normal usage no effect. If system is running out of io buffers, TCP packet sizes will be smaller than maximum but will be sent sooner. If network warnings are enabled, notice is printed about this.
Testing
Problem first noticed on custom STM32F417 board when network performance testing with the default configuration:
Originally the TCP connection stopped transferring after a few tens of megabytes. Closing and reopening a new connection still worked. Debugger showed that there were 7 free buffers (1372 bytes), while
psock_send_eventhandler()
was trying to send the MSS of 1440 bytes.devif_iob_send()
then returnedENOMEM
and same thing repeated next time around.With this change the connection recovered from buffer shortage and continued transferring.