From: heitzenberger@astaro.com
To: netfilter-devel@vger.kernel.org
Cc: holger@eitzenberger.org
Subject: [ULOGD 10/15] Improve select performance
Date: Sat, 02 Feb 2008 21:48:36 +0100 [thread overview]
Message-ID: <20080202205108.605422040@astaro.com> (raw)
In-Reply-To: 20080202204826.267107164@astaro.com
Hi,
Content-Disposition: inline; filename=ulogd-select-performance-improvement.diff
The previous code consumed quite lots of CPU cycles because of
inefficiently handling fd_sets.
This patch corrects that.
Signed-off-by: Holger Eitzenberger <holger@eitzenberger.org>
Index: ulogd-netfilter/src/select.c
===================================================================
--- ulogd-netfilter.orig/src/select.c
+++ ulogd-netfilter/src/select.c
@@ -24,86 +24,125 @@
#include <fcntl.h>
#include <ulogd/ulogd.h>
#include <ulogd/common.h>
+#include <ulogd/signal.h>
#include <ulogd/linuxlist.h>
-static int maxfd = 0;
+static fd_set readset, writeset, exceptset;
+static int maxfd = -1;
static LLIST_HEAD(ulogd_fds);
-int ulogd_register_fd(struct ulogd_fd *fd)
+
+static int
+set_nonblock(int fd)
{
int flags;
- /* make FD nonblocking */
- flags = fcntl(fd->fd, F_GETFL);
- if (flags < 0)
+ if ((flags = fcntl(fd, F_GETFL)) < 0)
return -1;
+
flags |= O_NONBLOCK;
- flags = fcntl(fd->fd, F_SETFL, flags);
- if (flags < 0)
+
+ if ((flags = fcntl(fd, F_SETFL, flags)) < 0)
+ return -1;
+
+ return 0;
+}
+
+int
+ulogd_register_fd(struct ulogd_fd *ufd)
+{
+ if (set_nonblock(ufd->fd) < 0)
return -1;
- /* Register FD */
- if (fd->fd > maxfd)
- maxfd = fd->fd;
+ if (ufd->when & ULOGD_FD_READ)
+ FD_SET(ufd->fd, &readset);
+
+ if (ufd->when & ULOGD_FD_WRITE)
+ FD_SET(ufd->fd, &writeset);
+
+ if (ufd->when & ULOGD_FD_EXCEPT)
+ FD_SET(ufd->fd, &exceptset);
+
+ if (ufd->fd > maxfd)
+ maxfd = ufd->fd;
- llist_add_tail(&fd->list, &ulogd_fds);
+ llist_add_tail(&ufd->list, &ulogd_fds);
return 0;
}
-void ulogd_unregister_fd(struct ulogd_fd *fd)
+void
+ulogd_unregister_fd(struct ulogd_fd *ufd)
{
- llist_del(&fd->list);
+ if (ufd->when & ULOGD_FD_READ)
+ FD_CLR(ufd->fd, &readset);
+
+ if (ufd->when & ULOGD_FD_WRITE)
+ FD_CLR(ufd->fd, &writeset);
+
+ if (ufd->when & ULOGD_FD_EXCEPT)
+ FD_CLR(ufd->fd, &exceptset);
+
+ llist_del(&ufd->list);
+
+ maxfd = -1;
+ llist_for_each_entry(ufd, &ulogd_fds, list) {
+ assert(ufd->fd >= 0);
+
+ if (ufd->fd > maxfd)
+ maxfd = ufd->fd;
+ }
}
-int ulogd_select_main()
+/* ulogd_dispatch() - dispatch events */
+int
+ulogd_dispatch(void)
{
- struct ulogd_fd *ufd;
- fd_set readset, writeset, exceptset;
- struct timeval tv = { .tv_sec = 1, };
- int i;
-
- FD_ZERO(&readset);
- FD_ZERO(&writeset);
- FD_ZERO(&exceptset);
+ fd_set rds_tmp, wrs_tmp, exs_tmp;
+ sigset_t curr_ss;
- /* prepare read and write fdsets */
- llist_for_each_entry(ufd, &ulogd_fds, list) {
- if (ufd->when & ULOGD_FD_READ)
- FD_SET(ufd->fd, &readset);
+ ulogd_get_sigset(&curr_ss);
- if (ufd->when & ULOGD_FD_WRITE)
- FD_SET(ufd->fd, &writeset);
+ pthread_sigmask(SIG_UNBLOCK, &curr_ss, NULL);
- if (ufd->when & ULOGD_FD_EXCEPT)
- FD_SET(ufd->fd, &exceptset);
- }
+ for (;;) {
+ struct ulogd_fd *ufd;
+ int n;
- again:
- i = select(maxfd+1, &readset, &writeset, &exceptset, &tv);
- if (i < 0) {
- if (errno == EINTR)
- goto again;
- }
+ again:
+ rds_tmp = readset;
+ wrs_tmp = writeset;
+ exs_tmp = exceptset;
- if (i > 0) {
- /* call registered callback functions */
- llist_for_each_entry(ufd, &ulogd_fds, list) {
- int flags = 0;
-
- if (FD_ISSET(ufd->fd, &readset))
- flags |= ULOGD_FD_READ;
+ n = select(maxfd+1, &rds_tmp, &wrs_tmp, &exs_tmp, NULL);
+ if (n < 0) {
+ if (errno == EINTR)
+ goto again;
- if (FD_ISSET(ufd->fd, &writeset))
- flags |= ULOGD_FD_WRITE;
+ ulogd_log(ULOGD_FATAL, "select: %m\n");
- if (FD_ISSET(ufd->fd, &exceptset))
- flags |= ULOGD_FD_EXCEPT;
+ break;
+ }
- if (flags)
- ufd->cb(ufd->fd, flags, ufd->data);
+ if (n > 0) {
+ /* call registered callback functions */
+ llist_for_each_entry(ufd, &ulogd_fds, list) {
+ int flags = 0;
+
+ if (FD_ISSET(ufd->fd, &rds_tmp))
+ flags |= ULOGD_FD_READ;
+
+ if (FD_ISSET(ufd->fd, &wrs_tmp))
+ flags |= ULOGD_FD_WRITE;
+
+ if (FD_ISSET(ufd->fd, &exs_tmp))
+ flags |= ULOGD_FD_EXCEPT;
+
+ if (flags)
+ ufd->cb(ufd->fd, flags, ufd->data);
+ }
}
}
- return i;
+ return 0;
}
Index: ulogd-netfilter/src/ulogd.c
===================================================================
--- ulogd-netfilter.orig/src/ulogd.c
+++ ulogd-netfilter/src/ulogd.c
@@ -727,32 +727,6 @@ out_buf:
return ret;
}
-
-static int ulogd_main_loop(void)
-{
- sigset_t curr;
- int ret = 0;
-
- ulogd_get_sigset(&curr);
-
- pthread_sigmask(SIG_UNBLOCK, &curr, NULL);
-
- for (;;) {
- ret = ulogd_select_main();
- if (ret == 0)
- continue;
-
- if (ret < 0) {
- ulogd_log(ULOGD_ERROR, "select returned %s\n",
- strerror(errno));
- break;
- }
- }
-
- return ret;
-}
-
-/* open the logfile */
static int logfile_open(const char *name)
{
if (name)
@@ -1112,7 +1086,7 @@ main(int argc, char* argv[])
ulogd_log(ULOGD_INFO, "entering main loop\n");
- ulogd_main_loop();
+ ulogd_dispatch();
return 0;
}
Index: ulogd-netfilter/include/ulogd/ulogd.h
===================================================================
--- ulogd-netfilter.orig/include/ulogd/ulogd.h
+++ ulogd-netfilter/include/ulogd/ulogd.h
@@ -243,7 +243,7 @@ struct ulogd_fd {
int ulogd_register_fd(struct ulogd_fd *ufd);
void ulogd_unregister_fd(struct ulogd_fd *ufd);
-int ulogd_select_main();
+int ulogd_dispatch(void);
/***********************************************************************
* timer handling (timer.c)
--
next prev parent reply other threads:[~2008-02-02 20:51 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-02 20:48 [ULOGD 00/15] ulogd V2 improvements, round 2 heitzenberger
2008-02-02 20:48 ` [ULOGD 01/15] Add NACCT output plugin heitzenberger
2008-02-02 21:24 ` Pablo Neira Ayuso
2008-02-02 20:48 ` [ULOGD 02/15] common.h: added heitzenberger
2008-02-02 21:30 ` Pablo Neira Ayuso
2008-02-02 20:48 ` [ULOGD 03/15] Replace timer code by working version heitzenberger
2008-02-02 22:45 ` Pablo Neira Ayuso
2008-02-02 20:48 ` [ULOGD 04/15] Add IFI list heitzenberger
2008-02-02 21:36 ` Pablo Neira Ayuso
2008-02-02 21:50 ` Holger Eitzenberger
2008-02-02 22:56 ` Pablo Neira Ayuso
2008-02-02 20:48 ` [ULOGD 05/15] Add signalling subsystem heitzenberger
2008-02-19 19:38 ` Pablo Neira Ayuso
2008-02-20 8:43 ` Holger Eitzenberger
2008-02-20 12:20 ` Patrick McHardy
2008-02-20 12:23 ` Pablo Neira Ayuso
2008-02-02 20:48 ` [ULOGD 06/15] Conffile cleanup, use common pr_debug() heitzenberger
2008-02-02 21:43 ` Pablo Neira Ayuso
2008-02-02 20:48 ` [ULOGD 07/15] Renice to -1 on startup heitzenberger
2008-02-02 21:47 ` Pablo Neira Ayuso
2008-02-02 20:48 ` [ULOGD 08/15] Initial round to make plugins reconfigurable heitzenberger
2008-02-02 20:48 ` [ULOGD 09/15] llist: add llist_for_each_prev_safe() heitzenberger
2008-02-02 20:48 ` heitzenberger [this message]
2008-02-19 19:58 ` [ULOGD 10/15] Improve select performance Pablo Neira Ayuso
2008-02-02 20:48 ` [ULOGD 11/15] Add set_sockbuf_len() heitzenberger
2008-02-19 19:57 ` Pablo Neira Ayuso
2008-02-02 20:48 ` [ULOGD 12/15] Introduce global state, skip some stacks during reconfiguration heitzenberger
2008-02-02 20:48 ` [ULOGD 13/15] llist: turn poisoning off by default heitzenberger
2008-02-02 20:48 ` [ULOGD 14/15] SQLITE3: port to ulogd 2.00, mostly a rewrite heitzenberger
2008-02-02 20:48 ` [ULOGD 15/15] NFCT: rework and let it scale heitzenberger
2008-02-02 22:52 ` [ULOGD 00/15] ulogd V2 improvements, round 2 Pablo Neira Ayuso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080202205108.605422040@astaro.com \
--to=heitzenberger@astaro.com \
--cc=holger@eitzenberger.org \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.