]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] http: revert to use a swap buffer for realignment
authorWilly Tarreau <w@1wt.eu>
Fri, 26 Feb 2010 10:12:27 +0000 (11:12 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 26 Feb 2010 10:12:27 +0000 (11:12 +0100)
The bounce realign function was algorithmically good but as expected
it was not cache-friendly. Using it with large requests caused so many
cache thrashing that the function itself could drain 70% of the total
CPU time for only 0.5% of the calls !

Revert back to a standard memcpy() using a specially allocated swap
buffer. We're now back to 2M req/s on pipelined requests.

include/types/global.h
src/haproxy.c
src/proto_http.c

index 463bd3876d4576874cd7498a7dde491cb036dc6c..9c62461d54ab61c787eb196d2440dcf975996f17 100644 (file)
@@ -1,23 +1,23 @@
 /*
-  include/types/global.h
-  Global variables.
-
 Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
-  
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation, version 2.1
-  exclusively.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*/
* include/types/global.h
* Global variables.
+ *
* Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, version 2.1
* exclusively.
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
 
 #ifndef _TYPES_GLOBAL_H
 #define _TYPES_GLOBAL_H
@@ -103,6 +103,7 @@ extern int  relative_pid;       /* process id starting at 1 */
 extern int  actconn;            /* # of active sessions */
 extern int listeners;
 extern char trash[BUFSIZE];
+extern char *swap_buffer;
 extern const int zero;
 extern const int one;
 extern const struct linger nolinger;
index d8c584c5c3805508e7168ae95071dfad3b03a056..e82ab5656a82e0c648bb4233cf9c0bbd32f1b5ab 100644 (file)
@@ -138,6 +138,11 @@ static int oldpids_sig; /* use USR1 or TERM */
 /* this is used to drain data, and as a temporary buffer for sprintf()... */
 char trash[BUFSIZE];
 
+/* this buffer is always the same size as standard buffers and is used for
+ * swapping data inside a buffer.
+ */
+char *swap_buffer = NULL;
+
 const int zero = 0;
 const int one = 1;
 const struct linger nolinger = { .l_onoff = 1, .l_linger = 0 };
@@ -653,6 +658,8 @@ void init(int argc, char **argv)
        if (global.nbproc < 1)
                global.nbproc = 1;
 
+       swap_buffer = (char *)calloc(1, global.tune.bufsize);
+
        fdinfo = (struct fdinfo *)calloc(1,
                                       sizeof(struct fdinfo) * (global.maxsock));
        fdtab = (struct fdtab *)calloc(1,
index cb5120526c5b9c335d1c7ebd94b140977e14e5a8..aff5ca363dc0722579fe7e3dd5400dc4f08ddb35 100644 (file)
@@ -2259,14 +2259,21 @@ void http_buffer_heavy_realign(struct buffer *buf, struct http_msg *msg)
 
        /* two possible cases :
         *   - the buffer is in one contiguous block, we move it in-place
-        *   - the buffer is in two blocks, we move it via the trash
+        *   - the buffer is in two blocks, we move it via the swap_buffer
         */
        if (buf->l) {
-               if (buf->r <= buf->w)
+               int block1 = buf->l;
+               int block2 = 0;
+               if (buf->r <= buf->w) {
                        /* non-contiguous block */
-                       buffer_bounce_realign(buf);
-               else
-                       memmove(buf->data, buf->w, buf->l);
+                       block1 = buf->data + buf->size - buf->w;
+                       block2 = buf->r - buf->data;
+               }
+               if (block2)
+                       memcpy(swap_buffer, buf->data, block2);
+               memmove(buf->data, buf->w, block1);
+               if (block2)
+                       memcpy(buf->data + block1, swap_buffer, block2);
        }
 
        /* adjust all known pointers */