mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 05:41:26 +02:00
[OPTIM] stream_sock: don't retry to read after a large read
If we get very large data at once, it's almost certain that it's worthless trying to read again, because we got everything we could get. Doing this has made all -EAGAIN disappear from splice reads. The threshold has been put in the global tunable structures so that if we one day want to make it accessible from user config, it will be easy to do so.
This commit is contained in:
parent
e38388033f
commit
6f4a82c7af
@ -82,6 +82,15 @@
|
||||
#define MAX_READ_POLL_LOOPS 4
|
||||
#endif
|
||||
|
||||
// minimum number of bytes read at once above which we don't try to read
|
||||
// more, in order not to risk facing an EAGAIN. Most often, if we read
|
||||
// at least 10 kB, we can consider that the system has tried to read a
|
||||
// full buffer and got multiple segments (>1 MSS for jumbo frames, >7 MSS
|
||||
// for normal frames) did not bother truncating the last segment.
|
||||
#ifndef MIN_RECV_AT_ONCE_ENOUGH
|
||||
#define MIN_RECV_AT_ONCE_ENOUGH (7*1448)
|
||||
#endif
|
||||
|
||||
// same, but for writes. Generally, it's enough to write twice: one time for
|
||||
// first half of the buffer, and a second time for the last half after a
|
||||
// wrap-around.
|
||||
|
@ -77,6 +77,7 @@ struct global {
|
||||
int maxpollevents; /* max number of poll events at once */
|
||||
int maxaccept; /* max number of consecutive accept() */
|
||||
int options; /* various tuning options */
|
||||
int recv_enough; /* how many input bytes at once are "enough" */
|
||||
} tune;
|
||||
struct listener stats_sock; /* unix socket listener for statistics */
|
||||
int stats_timeout; /* in ticks */
|
||||
|
@ -592,6 +592,9 @@ void init(int argc, char **argv)
|
||||
global.tune.maxaccept = 100; /* accept many incoming conns at once */
|
||||
}
|
||||
|
||||
if (global.tune.recv_enough == 0)
|
||||
global.tune.recv_enough = MIN_RECV_AT_ONCE_ENOUGH;
|
||||
|
||||
if (arg_mode & (MODE_DEBUG | MODE_FOREGROUND)) {
|
||||
/* command line debug mode inhibits configuration mode */
|
||||
global.mode &= ~(MODE_DAEMON | MODE_QUIET);
|
||||
|
@ -197,7 +197,8 @@ static int stream_sock_splice_in(struct buffer *b, struct stream_interface *si)
|
||||
b->flags |= BF_READ_PARTIAL;
|
||||
b->flags &= ~BF_EMPTY; /* to prevent shutdowns */
|
||||
|
||||
if (b->pipe->data >= SPLICE_FULL_HINT) {
|
||||
if (b->pipe->data >= SPLICE_FULL_HINT ||
|
||||
ret >= global.tune.recv_enough) {
|
||||
/* We've read enough of it for this time. */
|
||||
retval = 1;
|
||||
break;
|
||||
@ -400,18 +401,25 @@ int stream_sock_read(int fd) {
|
||||
*/
|
||||
if (b->flags & BF_STREAMER)
|
||||
break;
|
||||
}
|
||||
|
||||
/* generally if we read something smaller than 1 or 2 MSS,
|
||||
* it means that either we have exhausted the system's
|
||||
* buffers (streamer or question-response protocol) or that
|
||||
* the connection will be closed. Streamers are easily
|
||||
* detected so we return early. For other cases, it's still
|
||||
* better to perform a last read to be sure, because it may
|
||||
* save one complete poll/read/wakeup cycle in case of shutdown.
|
||||
*/
|
||||
if (ret < MIN_RET_FOR_READ_LOOP && b->flags & BF_STREAMER)
|
||||
break;
|
||||
/* generally if we read something smaller than 1 or 2 MSS,
|
||||
* it means that either we have exhausted the system's
|
||||
* buffers (streamer or question-response protocol) or
|
||||
* that the connection will be closed. Streamers are
|
||||
* easily detected so we return early. For other cases,
|
||||
* it's still better to perform a last read to be sure,
|
||||
* because it may save one complete poll/read/wakeup cycle
|
||||
* in case of shutdown.
|
||||
*/
|
||||
if (ret < MIN_RET_FOR_READ_LOOP && b->flags & BF_STREAMER)
|
||||
break;
|
||||
|
||||
/* if we read a large block smaller than what we requested,
|
||||
* it's almost certain we'll never get anything more.
|
||||
*/
|
||||
if (ret >= global.tune.recv_enough)
|
||||
break;
|
||||
}
|
||||
|
||||
if (--read_poll <= 0)
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user