]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[OPTIM] move some rarely used fields out of fdtab
authorWilly Tarreau <w@1wt.eu>
Sun, 18 Oct 2009 05:25:52 +0000 (07:25 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 18 Oct 2009 06:17:33 +0000 (08:17 +0200)
Some rarely information are stored in fdtab, making it larger for no
reason (source port ranges, remote address, ...). Such information
lie there because the checks can't find them anywhere else. The goal
will be to move these information to the stream interface once the
checks make use of it.

For now, we move them to an fdinfo array. This simple change might
have improved the cache hit ratio a little bit because a 0.5% of
performance increase has measured.

include/types/fd.h
src/checks.c
src/client.c
src/fd.c
src/haproxy.c
src/proto_tcp.c
src/proto_uxst.c
src/stream_sock.c

index 3ab89feba8254ed7455eecfae31fee11966bb7bc..63c59eead72fce669cf60cbcfdf31ecd4edfd1a5 100644 (file)
@@ -1,23 +1,23 @@
 /*
-  include/types/fd.h
-  File descriptors states.
-
 Copyright (C) 2000-2008 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/fd.h
* File descriptors states.
+ *
* Copyright (C) 2000-2009 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_FD_H
 #define _TYPES_FD_H
@@ -75,10 +75,14 @@ struct fdtab {
        unsigned short flags;                /* various flags precising the exact status of this fd */
        unsigned char state;                 /* the state of this fd */
        unsigned char ev;                    /* event seen in return of poll() : FD_POLL_* */
-       struct sockaddr *peeraddr;           /* pointer to peer's network address, or NULL if unset */
-       socklen_t peerlen;                   /* peer's address length, or 0 if unset */
-       int local_port;                      /* optional local port */
+};
+
+/* less often used information */
+struct fdinfo {
        struct port_range *port_range;       /* optional port range to bind to */
+       int local_port;                      /* optional local port */
+       struct sockaddr *peeraddr;   /* pointer to peer's network address, or NULL if unset */
+       socklen_t peerlen;           /* peer's address length, or 0 if unset */
 };
 
 /*
@@ -123,6 +127,7 @@ extern int nbpollers;
 extern struct poller pollers[MAX_POLLERS];   /* all registered pollers */
 
 extern struct fdtab *fdtab;             /* array of all the file descriptors */
+extern struct fdinfo *fdinfo;           /* less-often used infos for file descriptors */
 extern int maxfd;                       /* # of the highest fd + 1 */
 extern int totalconn;                   /* total # of terminated sessions */
 extern int actconn;                     /* # of active sessions */
index 0e9aca5e830c6c6876b0435fb3617f87feae970d..e7aefb49338c3cd3a3d73fe9542c55a7630a4787 100644 (file)
@@ -838,19 +838,19 @@ struct task *process_chk(struct task *t)
                                                        /* note: in case of retry, we may have to release a previously
                                                         * allocated port, hence this loop's construct.
                                                         */
-                                                       port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port);
-                                                       fdtab[fd].port_range = NULL;
+                                                       port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port);
+                                                       fdinfo[fd].port_range = NULL;
 
                                                        if (!bind_attempts)
                                                                break;
                                                        bind_attempts--;
 
-                                                       fdtab[fd].local_port = port_range_alloc_port(s->sport_range);
-                                                       if (!fdtab[fd].local_port)
+                                                       fdinfo[fd].local_port = port_range_alloc_port(s->sport_range);
+                                                       if (!fdinfo[fd].local_port)
                                                                break;
 
-                                                       fdtab[fd].port_range = s->sport_range;
-                                                       src.sin_port = htons(fdtab[fd].local_port);
+                                                       fdinfo[fd].port_range = s->sport_range;
+                                                       src.sin_port = htons(fdinfo[fd].local_port);
 
                                                        ret = tcpv4_bind_socket(fd, flags, &src, remote);
                                                } while (ret != 0); /* binding NOK */
@@ -926,8 +926,8 @@ struct task *process_chk(struct task *t)
                                                fdtab[fd].cb[DIR_RD].b = NULL;
                                                fdtab[fd].cb[DIR_WR].f = &event_srv_chk_w;
                                                fdtab[fd].cb[DIR_WR].b = NULL;
-                                               fdtab[fd].peeraddr = (struct sockaddr *)&sa;
-                                               fdtab[fd].peerlen = sizeof(sa);
+                                               fdinfo[fd].peeraddr = (struct sockaddr *)&sa;
+                                               fdinfo[fd].peerlen = sizeof(sa);
                                                fdtab[fd].state = FD_STCONN; /* connection in progress */
                                                fdtab[fd].flags = FD_FL_TCP | FD_FL_TCP_NODELAY;
                                                EV_FD_SET(fd, DIR_WR);  /* for connect status */
@@ -963,8 +963,8 @@ struct task *process_chk(struct task *t)
                                        }
                                }
                        }
-                       port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port);
-                       fdtab[fd].port_range = NULL;
+                       port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port);
+                       fdinfo[fd].port_range = NULL;
                        close(fd); /* socket creation error */
                }
 
index b9e304a12c702c5dbc452e76f57d00ac3182a9ac..68a192d2675a8737d2d48393ae02cab45774de8a 100644 (file)
@@ -449,8 +449,8 @@ int event_accept(int fd) {
                fdtab[cfd].cb[DIR_RD].b = s->req;
                fdtab[cfd].cb[DIR_WR].f = l->proto->write;
                fdtab[cfd].cb[DIR_WR].b = s->rep;
-               fdtab[cfd].peeraddr = (struct sockaddr *)&s->cli_addr;
-               fdtab[cfd].peerlen = sizeof(s->cli_addr);
+               fdinfo[cfd].peeraddr = (struct sockaddr *)&s->cli_addr;
+               fdinfo[cfd].peerlen = sizeof(s->cli_addr);
 
                if ((p->mode == PR_MODE_HTTP && (s->flags & SN_MONITOR)) ||
                    (p->mode == PR_MODE_HEALTH && (p->options & PR_O_HTTP_CHK))) {
index 9dd365a50b9d87123da3a3679fffd4f77c115244..c850efa7971294b181f6173197a6524cf685aeb8 100644 (file)
--- a/src/fd.c
+++ b/src/fd.c
@@ -22,6 +22,7 @@
 #include <proto/port_range.h>
 
 struct fdtab *fdtab = NULL;     /* array of all the file descriptors */
+struct fdinfo *fdinfo = NULL;   /* less-often used infos for file descriptors */
 int maxfd;                      /* # of the highest fd + 1 */
 int totalconn;                  /* total # of terminated sessions */
 int actconn;                    /* # of active sessions */
@@ -37,8 +38,8 @@ int nbpollers = 0;
 void fd_delete(int fd)
 {
        EV_FD_CLO(fd);
-       port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port);
-       fdtab[fd].port_range = NULL;
+       port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port);
+       fdinfo[fd].port_range = NULL;
        close(fd);
        fdtab[fd].state = FD_STCLOSE;
 
index 83df0925e715b77fb6b86b4291d9db2e719b15c7..43aee22a5f4b00a2a50cbebe64294fd886e481f0 100644 (file)
@@ -641,6 +641,8 @@ void init(int argc, char **argv)
        if (global.nbproc < 1)
                global.nbproc = 1;
 
+       fdinfo = (struct fdinfo *)calloc(1,
+                                      sizeof(struct fdinfo) * (global.maxsock));
        fdtab = (struct fdtab *)calloc(1,
                                       sizeof(struct fdtab) * (global.maxsock));
        for (i = 0; i < global.maxsock; i++) {
index 884016f5afc0ea4bd2137472110055017c4aa8a0..68da06336e431ce326e060f912e7be1f0d8f77d5 100644 (file)
@@ -279,19 +279,19 @@ int tcpv4_connect_server(struct stream_interface *si,
                                /* note: in case of retry, we may have to release a previously
                                 * allocated port, hence this loop's construct.
                                 */
-                               port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port);
-                               fdtab[fd].port_range = NULL;
+                               port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port);
+                               fdinfo[fd].port_range = NULL;
 
                                if (!attempts)
                                        break;
                                attempts--;
 
-                               fdtab[fd].local_port = port_range_alloc_port(srv->sport_range);
-                               if (!fdtab[fd].local_port)
+                               fdinfo[fd].local_port = port_range_alloc_port(srv->sport_range);
+                               if (!fdinfo[fd].local_port)
                                        break;
 
-                               fdtab[fd].port_range = srv->sport_range;
-                               src.sin_port = htons(fdtab[fd].local_port);
+                               fdinfo[fd].port_range = srv->sport_range;
+                               src.sin_port = htons(fdinfo[fd].local_port);
 
                                ret = tcpv4_bind_socket(fd, flags, &src, remote);
                        } while (ret != 0); /* binding NOK */
@@ -301,8 +301,8 @@ int tcpv4_connect_server(struct stream_interface *si,
                }
 
                if (ret) {
-                       port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port);
-                       fdtab[fd].port_range = NULL;
+                       port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port);
+                       fdinfo[fd].port_range = NULL;
                        close(fd);
 
                        if (ret == 1) {
@@ -388,8 +388,8 @@ int tcpv4_connect_server(struct stream_interface *si,
                                msg = "local address already in use";
 
                        qfprintf(stderr,"Cannot connect: %s.\n",msg);
-                       port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port);
-                       fdtab[fd].port_range = NULL;
+                       port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port);
+                       fdinfo[fd].port_range = NULL;
                        close(fd);
                        send_log(be, LOG_EMERG,
                                 "Connect() failed for server %s/%s: %s.\n",
@@ -397,15 +397,15 @@ int tcpv4_connect_server(struct stream_interface *si,
                        return SN_ERR_RESOURCE;
                } else if (errno == ETIMEDOUT) {
                        //qfprintf(stderr,"Connect(): ETIMEDOUT");
-                       port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port);
-                       fdtab[fd].port_range = NULL;
+                       port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port);
+                       fdinfo[fd].port_range = NULL;
                        close(fd);
                        return SN_ERR_SRVTO;
                } else {
                        // (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EACCES || errno == EPERM)
                        //qfprintf(stderr,"Connect(): %d", errno);
-                       port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port);
-                       fdtab[fd].port_range = NULL;
+                       port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port);
+                       fdinfo[fd].port_range = NULL;
                        close(fd);
                        return SN_ERR_SRVCL;
                }
@@ -419,8 +419,8 @@ int tcpv4_connect_server(struct stream_interface *si,
        fdtab[fd].cb[DIR_WR].f = &stream_sock_write;
        fdtab[fd].cb[DIR_WR].b = si->ob;
 
-       fdtab[fd].peeraddr = (struct sockaddr *)srv_addr;
-       fdtab[fd].peerlen = sizeof(struct sockaddr_in);
+       fdinfo[fd].peeraddr = (struct sockaddr *)srv_addr;
+       fdinfo[fd].peerlen = sizeof(struct sockaddr_in);
 
        fd_insert(fd);
        EV_FD_SET(fd, DIR_WR);  /* for connect status */
@@ -562,8 +562,8 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
        if (listener->options & LI_O_NOLINGER)
                fdtab[fd].flags |= FD_FL_TCP_NOLING;
 
-       fdtab[fd].peeraddr = NULL;
-       fdtab[fd].peerlen = 0;
+       fdinfo[fd].peeraddr = NULL;
+       fdinfo[fd].peerlen = 0;
  tcp_return:
        if (msg && errlen)
                strlcpy2(errmsg, msg, errlen);
index 4fceadcd07b2f9cfeeea1c2e9e1398482d08f02a..186ddda54c68e4f178c75e9be61c107770e77ce0 100644 (file)
@@ -267,8 +267,8 @@ static int uxst_bind_listener(struct listener *listener)
        fdtab[fd].cb[DIR_RD].b = fdtab[fd].cb[DIR_WR].b = NULL;
        fdtab[fd].owner = listener; /* reference the listener instead of a task */
        fdtab[fd].state = FD_STLISTEN;
-       fdtab[fd].peeraddr = NULL;
-       fdtab[fd].peerlen = 0;
+       fdinfo[fd].peeraddr = NULL;
+       fdinfo[fd].peerlen = 0;
        return ERR_NONE;
 }
 
@@ -537,8 +537,8 @@ int uxst_event_accept(int fd) {
                fdtab[cfd].cb[DIR_RD].b = s->req;
                fdtab[cfd].cb[DIR_WR].f = l->proto->write;
                fdtab[cfd].cb[DIR_WR].b = s->rep;
-               fdtab[cfd].peeraddr = (struct sockaddr *)&s->cli_addr;
-               fdtab[cfd].peerlen = sizeof(s->cli_addr);
+               fdinfo[cfd].peeraddr = (struct sockaddr *)&s->cli_addr;
+               fdinfo[cfd].peerlen = sizeof(s->cli_addr);
 
                EV_FD_SET(cfd, DIR_RD);
 
index 2846b3604294fe2e2361b5b3aeb06c384b7c1ace..65b790a0b1f31dca57566b6e2e1a14e04500c594 100644 (file)
@@ -712,7 +712,7 @@ int stream_sock_write(int fd)
                         *  - connecting (EALREADY, EINPROGRESS)
                         *  - connected (EISCONN, 0)
                         */
-                       if ((connect(fd, fdtab[fd].peeraddr, fdtab[fd].peerlen) == 0))
+                       if ((connect(fd, fdinfo[fd].peeraddr, fdinfo[fd].peerlen) == 0))
                                errno = 0;
 
                        if (errno == EALREADY || errno == EINPROGRESS) {