]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[OPTIM] stream_sock: don't retry to read after a large read
authorWilly Tarreau <w@1wt.eu>
Sat, 21 Mar 2009 19:43:57 +0000 (20:43 +0100)
committerWilly Tarreau <w@1wt.eu>
Sat, 21 Mar 2009 19:43:57 +0000 (20:43 +0100)
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.

include/common/defaults.h
include/types/global.h
src/haproxy.c
src/stream_sock.c

index acba5c6eed8209457b641dc437e828888c688233..fb8d188bd2f67e7a7dc93ae76c60d9402adef717 100644 (file)
 #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.
index 0c3c8adb1b9a4c4583c8eea551c188d647c5c02b..d0c22bcb45705edec5719a6bc8bca5488b663805 100644 (file)
@@ -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 */
index d5d61251b72defbada2af015f52b27bfff32025e..4a9795b357c7b3a4d896da358d606d49757bda34 100644 (file)
@@ -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);
index ed53ca08af32f76033ece874ec75ff5f45177b7d..a942d408178d2eebeaf01230b586bbddd744f758 100644 (file)
@@ -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;