From nobody Fri Jul 4 23:37:46 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.24 as permitted sender) client-ip=209.132.183.24; envelope-from=libvir-list-bounces@redhat.com; helo=mx3-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.24 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) by mx.zohomail.com with SMTPS id 1487095816543470.82725640687613; Tue, 14 Feb 2017 10:10:16 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx3-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1EI6CMe002245; Tue, 14 Feb 2017 13:06:12 -0500 Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1EI6BY0016209 for ; Tue, 14 Feb 2017 13:06:11 -0500 Received: by smtp.corp.redhat.com (Postfix) id 3E62A6E902; Tue, 14 Feb 2017 18:06:11 +0000 (UTC) Received: from mx1.redhat.com (ext-mx02.extmail.prod.ext.phx2.redhat.com [10.5.110.26]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 371366E7A9 for ; Tue, 14 Feb 2017 18:06:11 +0000 (UTC) Received: from relay.sw.ru (mailhub.sw.ru [195.214.232.25]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E2EC47E9F8 for ; Tue, 14 Feb 2017 18:06:08 +0000 (UTC) Received: from localhost.localdomain (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v1EI63DS028411; Tue, 14 Feb 2017 21:06:03 +0300 (MSK) From: Derbyshev Dmitriy To: libvir-list@redhat.com Date: Tue, 14 Feb 2017 21:04:21 +0300 Message-Id: <1487095461-12268-3-git-send-email-dderbyshev@virtuozzo.com> In-Reply-To: <1487095461-12268-1-git-send-email-dderbyshev@virtuozzo.com> References: <1487095461-12268-1-git-send-email-dderbyshev@virtuozzo.com> X-Greylist: Delayed for 100:34:54 by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 14 Feb 2017 18:06:09 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 14 Feb 2017 18:06:09 +0000 (UTC) for IP:'195.214.232.25' DOMAIN:'mailhub.sw.ru' HELO:'relay.sw.ru' FROM:'dderbyshev@virtuozzo.com' RCPT:'' X-RedHat-Spam-Score: 0.799 (BAYES_50, SPF_PASS) 195.214.232.25 mailhub.sw.ru 195.214.232.25 mailhub.sw.ru X-Scanned-By: MIMEDefang 2.78 on 10.5.110.26 X-Scanned-By: MIMEDefang 2.74 on 10.5.11.28 X-loop: libvir-list@redhat.com Cc: redkoi@virtuozzo.com, Derbyshev Dmitry , den@virtuozzo.com, kneumoin@virtuozzo.com, mnestratov@virtuozzo.com, nshirokovskiy@virtuozzo.com Subject: [libvirt] [RFC v2 2/2] vireventpoll implimentation using epoll X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Derbyshev Dmitry This makes it possible to avoid allocations in virEventPollMakePollFDs, as well as generally reduces time spent in kernel if handles remain the same, which should generally be true. --- configure.ac | 28 ++++ src/Makefile.am | 10 +- src/util/vireventepoll.c | 201 +++++++++++++++++++= ++++ tests/commanddata/{test14.log =3D> test3epoll.log} | 2 + tests/commandtest.c | 4 + 5 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 src/util/vireventepoll.c copy tests/commanddata/{test14.log =3D> test3epoll.log} (94%) diff --git a/configure.ac b/configure.ac index a995a05..9a6a810 100644 --- a/configure.ac +++ b/configure.ac @@ -877,6 +877,34 @@ AC_DEFINE_UNQUOTED([isbase64],[libvirt_gl_isbase64],[H= ack to avoid symbol clash] AC_DEFINE_UNQUOTED([base64_encode],[libvirt_gl_base64_encode],[Hack to avo= id symbol clash]) AC_DEFINE_UNQUOTED([base64_encode_alloc],[libvirt_gl_base64_encode_alloc],= [Hack to avoid symbol clash]) =20 +AC_ARG_ENABLE([epoll], + [AS_HELP_STRING([--enable-epoll],[use epoll(4) on Linux])], + [enable_epoll=3D$enableval], [enable_epoll=3Dauto]) +if test x$enable_epoll =3D xno; then + have_linux_epoll=3Dno +else + AC_MSG_CHECKING([for Linux epoll(4)]) + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [ + #ifndef __linux__ + #error This is not Linux + #endif + #include + ], + [epoll_create1 (EPOLL_CLOEXEC);])], + [have_linux_epoll=3Dyes], + [have_linux_epoll=3Dno]) + AC_MSG_RESULT([$have_linux_epoll]) +fi +if test x$enable_epoll,$have_linux_epoll =3D xyes,no; then + AC_MSG_ERROR([epoll support explicitly enabled but not available]) +fi +if test "x$have_linux_epoll" =3D xyes; then + AC_DEFINE_UNQUOTED([HAVE_LINUX_EPOLL], 1, [whether epoll is supported]) +fi + +AM_CONDITIONAL([HAVE_LINUX_EPOLL], [test "x$have_linux_epoll" =3D xyes]) + AC_CONFIG_FILES([run], [chmod +x,-w run]) AC_CONFIG_FILES([\ diff --git a/src/Makefile.am b/src/Makefile.am index f2643ea..9ad39cb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -89,6 +89,12 @@ augeas_DATA =3D augeastestdir =3D $(datadir)/augeas/lenses/tests augeastest_DATA =3D =20 +if HAVE_LINUX_EPOLL +poll_src=3Dutil/vireventepoll.c +else !HAVE_LINUX_EPOLL +poll_src=3Dutil/vireventpoll.c +endif !HAVE_LINUX_EPOLL + # These files are not related to driver APIs. Simply generic # helper APIs for various purposes UTIL_SOURCES =3D \ @@ -113,7 +119,7 @@ UTIL_SOURCES =3D \ util/virerror.c util/virerror.h \ util/virevent.c util/virevent.h \ util/vireventpollcommon.c util/vireventpoll.h \ - util/vireventpoll.c util/vireventpollinternal.h \ + $(poll_src) util/vireventpollinternal.h \ util/virfile.c util/virfile.h \ util/virfirewall.c util/virfirewall.h \ util/virfirewallpriv.h \ @@ -2376,7 +2382,7 @@ libvirt_setuid_rpc_client_la_SOURCES =3D \ util/virdbus.c \ util/virerror.c \ util/virevent.c \ - util/vireventpoll.c \ + $(poll_src) \ util/vireventpollcommon.c \ util/virfile.c \ util/virgettext.c \ diff --git a/src/util/vireventepoll.c b/src/util/vireventepoll.c new file mode 100644 index 0000000..5e2a0f5 --- /dev/null +++ b/src/util/vireventepoll.c @@ -0,0 +1,201 @@ +/* + * vireventpoll.c: Poll based event loop for monitoring file handles + * + * Copyright (C) 2007, 2010-2014 Red Hat, Inc. + * Copyright (C) 2007 Daniel P. Berrange + * + * 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; either + * version 2.1 of the License, or (at your option) any later version. + * + * 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, see + * . + * + * Author: Daniel P. Berrange + */ + +#include + +#include + +#include "virfile.h" +#include "virlog.h" +#include "vireventpoll.h" +#include "vireventpollinternal.h" + +#define EVENT_DEBUG(fmt, ...) VIR_DEBUG(fmt, __VA_ARGS__) + +#define VIR_FROM_THIS VIR_FROM_EVENT + +VIR_LOG_INIT("util.eventpoll"); + +/* Maximum number of events that are returned by epoll in virEventPollRunO= nce */ +#define MAX_POLL_EVENTS_AT_ONCE 10 + +int epollfd; + +int virEventPollAddHandleInternal(int watch ATTRIBUTE_UNUSED, + int fd, + int nativeevents) +{ + size_t i; + struct epoll_event ev; + ev.events =3D nativeevents; + ev.data.fd =3D fd; + if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) < 0) { + if (errno =3D=3D EEXIST) { + for (i =3D 0; i < eventLoop.handlesCount; i++) { + if (eventLoop.handles[i].fd =3D=3D fd && + !eventLoop.handles[i].deleted) { + ev.events |=3D eventLoop.handles[i].events; + } + } + if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &ev) < 0) { + return -1; + } + } + else { + return -1; + } + } + return 0; +} + +int virEventPollUpdateHandleInternal(int watch, int fd, int nativeevents) +{ + struct epoll_event ev; + size_t i; + + ev.events =3D nativeevents; + ev.data.fd =3D fd; + for (i =3D 0; i < eventLoop.handlesCount; i++) { + if (eventLoop.handles[i].fd =3D=3D fd && + !eventLoop.handles[i].deleted && + eventLoop.handles[i].watch !=3D watch) { + ev.events |=3D eventLoop.handles[i].events; + } + } + + if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &ev) < 0) { + return -1; + } + return 0; +} + +int virEventPollRemoveHandleInternal(int watch, int fd) +{ + + struct epoll_event ev; + size_t i; + + ev.events =3D 0; + ev.data.fd =3D fd; + for (i =3D 0; i < eventLoop.handlesCount; i++) { + if (eventLoop.handles[i].fd =3D=3D fd && + !eventLoop.handles[i].deleted && + eventLoop.handles[i].watch !=3D watch) { + ev.events |=3D eventLoop.handles[i].events; + } + } + + if (ev.events) { + if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &ev) < 0) { + return -1; + } + } + else { + if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev) < 0) { + return -1; + } + } + + return 0; +} + +int virEventPollInitInternal(void) +{ + epollfd =3D epoll_create1(0); + if (epollfd < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to initialize epoll")); + return -1; + } + return 0; +} + +void virEventPollDeinitInternal(void) +{ + VIR_FORCE_CLOSE(epollfd); +} + +int +virEventPollToNativeEvents(int events) +{ + int ret =3D 0; + if (events & VIR_EVENT_HANDLE_READABLE) + ret |=3D EPOLLIN; + if (events & VIR_EVENT_HANDLE_WRITABLE) + ret |=3D EPOLLOUT; + if (events & VIR_EVENT_HANDLE_ERROR) + ret |=3D EPOLLERR; + if (events & VIR_EVENT_HANDLE_HANGUP) + ret |=3D EPOLLHUP; + return ret; +} + +int +virEventPollFromNativeEvents(int events) +{ + int ret =3D 0; + if (events & EPOLLIN) + ret |=3D VIR_EVENT_HANDLE_READABLE; + if (events & EPOLLOUT) + ret |=3D VIR_EVENT_HANDLE_WRITABLE; + if (events & EPOLLERR) + ret |=3D VIR_EVENT_HANDLE_ERROR; + if (events & EPOLLHUP) + ret |=3D VIR_EVENT_HANDLE_HANGUP; + return ret; +} + +struct epoll_event events[MAX_POLL_EVENTS_AT_ONCE]; + +int virEventPollWait(int timeout, void **opaque) +{ + int ret; + *opaque =3D events; + + retry: + ret =3D epoll_wait(epollfd, events, + MAX_POLL_EVENTS_AT_ONCE, timeout); + if (ret < 0) { + EVENT_DEBUG("Poll got error event %d", errno); + if (errno =3D=3D EINTR || errno =3D=3D EAGAIN) + goto retry; + virReportSystemError(errno, "%s", + _("Unable to poll on file handles")); + } + return ret; +} + +void virEventPollOpaqueFree(void *opaque ATTRIBUTE_UNUSED) +{ + return; +} + +int VirWokenFD(void *opaque, size_t n) +{ + return ((struct epoll_event *)opaque)[n].data.fd; +} + +int VirWokenEvents(void *opaque, size_t n) +{ + return ((struct epoll_event *)opaque)[n].events; +} diff --git a/tests/commanddata/test14.log b/tests/commanddata/test3epoll.log similarity index 94% copy from tests/commanddata/test14.log copy to tests/commanddata/test3epoll.log index 703e6da..e4619b3 100644 --- a/tests/commanddata/test14.log +++ b/tests/commanddata/test3epoll.log @@ -8,6 +8,8 @@ ENV:USER=3Dtest FD:0 FD:1 FD:2 +FD:6 +FD:8 DAEMON:no CWD:/tmp UMASK:0022 diff --git a/tests/commandtest.c b/tests/commandtest.c index 7bf5447..6b23659 100644 --- a/tests/commandtest.c +++ b/tests/commandtest.c @@ -227,7 +227,11 @@ static int test3(const void *unused ATTRIBUTE_UNUSED) goto cleanup; } =20 +#ifdef HAVE_LINUX_EPOLL + ret =3D checkoutput("test3epoll", NULL); +#else ret =3D checkoutput("test3", NULL); +#endif =20 cleanup: virCommandFree(cmd); --=20 1.9.5.msysgit.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list