From patchwork Wed Jul 24 17:20:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 57047 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id BB8BA1C236; Wed, 24 Jul 2019 19:20:52 +0200 (CEST) Received: from mail-pg1-f193.google.com (mail-pg1-f193.google.com [209.85.215.193]) by dpdk.org (Postfix) with ESMTP id 118051C000 for ; Wed, 24 Jul 2019 19:20:50 +0200 (CEST) Received: by mail-pg1-f193.google.com with SMTP id i70so10811386pgd.4 for ; Wed, 24 Jul 2019 10:20:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=vU4+nNmg8qRPbw50HdOvOdU2lhcADhEPpe0HhzYlBQs=; b=y48HeUX46WvDEVDz8s4tiFTo1PkTtr3/fIfj3rfSt3EZ7+Jpc/XwrUseBXOTvQ8vfx Y3QHlhpWJ9UVXBvbPjEZrLcVGtijRewoWEGc4d8rzQM6AE5K6S2yFvbGgvFX+nnfuEwn wMt5p1xoj6gISUzmGs1X5CR1vBidadNemjMxicErjB3/CmaZNPPMBhE4oHKYxKBKqiz7 uTpMUd2/AAJ4FDpKLkM+fORfatGqiYFeq8bcdijMD8l0PbB4NA3BrKyAv5M504g7w3Rg QZWwwUV0qrwBjfiSGx9CRLB5NalCKJOp1BbfoqctXEw+Fmo1HIAdBoNWZCB24Jr6OPDy chIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=vU4+nNmg8qRPbw50HdOvOdU2lhcADhEPpe0HhzYlBQs=; b=q1JbOKisbyfQZgF7mKiVzFrvS9fa4nHmfoGq/rtCIjDZrLL7nwqJEUQvlCNOxJIfdO zF+vGA3KHn0RpvlHQms2rQn7QZPY60XCFd6hQMlKVZPQB72N5C0PenJD8q2ksuMYgInT 5DuP104Dh4E4iSlXYZhI7BY8bnDySwzLeZfQuOy0zM8mLmGwGPgUJJhttuLOwhshBoqu qnvNvY9fcaaCBpFpidk3i/Pvm7PX8WhZRh6H8H4P1SnwaGvu5H1zZ1K/+0MnHvuyGSvt lYmz5t7haCEAEUXscGpdVyz+8WPSEYPo8GtoO3+IbkU2gxmA4UPZL3lWrRGa5Zs9Bbw6 UMIA== X-Gm-Message-State: APjAAAX+RYKbkBfAk47B40kE9GW5zLXbeIspo1IB1QBS77lqPglsOTaR 44MZziHX2eohDPFLHbDJSvVqzwT/ X-Google-Smtp-Source: APXvYqzo61IdDNPa81MQslfx3JT0JgXZRoardD6HLLEJDun6P4ggNIv/M3oIreDSQ2SWhHAzlusT7Q== X-Received: by 2002:aa7:82da:: with SMTP id f26mr12474329pfn.82.1563988849852; Wed, 24 Jul 2019 10:20:49 -0700 (PDT) Received: from hermes.lan (204-195-22-127.wavecable.com. [204.195.22.127]) by smtp.gmail.com with ESMTPSA id z13sm39656744pjn.32.2019.07.24.10.20.48 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 24 Jul 2019 10:20:49 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Date: Wed, 24 Jul 2019 10:20:37 -0700 Message-Id: <20190724172037.7776-1-stephen@networkplumber.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH] eal/interrupts: add function to allow interruptible epoll X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The existing definition of rte_epoll_wait retries if interrupted by a signal. This behavior makes it hard to use rte_epoll_wait for applications that want to use signals do do things like exit polling loop and shutdown. Since changing existing semantic might break applications, add a new rte_epoll_wait_interruptible() function that does the same thing as rte_epoll_wait but will return -1 and errno of EINTR if it receives a signal. Signed-off-by: Stephen Hemminger Reviewed-by: Harman Kalra --- .../common/include/rte_eal_interrupts.h | 23 +++++++++ lib/librte_eal/freebsd/eal/eal_interrupts.c | 12 +++++ lib/librte_eal/linux/eal/eal_interrupts.c | 47 ++++++++++++------- lib/librte_eal/rte_eal_version.map | 1 + 4 files changed, 65 insertions(+), 18 deletions(-) diff --git a/lib/librte_eal/common/include/rte_eal_interrupts.h b/lib/librte_eal/common/include/rte_eal_interrupts.h index b370c0d26458..ac1c830f37a1 100644 --- a/lib/librte_eal/common/include/rte_eal_interrupts.h +++ b/lib/librte_eal/common/include/rte_eal_interrupts.h @@ -87,6 +87,7 @@ struct rte_intr_handle { /** * It waits for events on the epoll instance. + * Retries if signal received. * * @param epfd * Epoll instance fd on which the caller wait for events. @@ -105,6 +106,28 @@ int rte_epoll_wait(int epfd, struct rte_epoll_event *events, int maxevents, int timeout); +/** + * It waits for events on the epoll instance. + * Does not retry if signal received. + * + * @param epfd + * Epoll instance fd on which the caller wait for events. + * @param events + * Memory area contains the events that will be available for the caller. + * @param maxevents + * Up to maxevents are returned, must greater than zero. + * @param timeout + * Specifying a timeout of -1 causes a block indefinitely. + * Specifying a timeout equal to zero cause to return immediately. + * @return + * - On success, returns the number of available event. + * - On failure, a negative value. + */ +__rte_experimental +int +rte_epoll_wait_interruptible(int epfd, struct rte_epoll_event *events, + int maxevents, int timeout); + /** * It performs control operations on epoll instance referred by the epfd. * It requests that the operation op be performed for the target fd. diff --git a/lib/librte_eal/freebsd/eal/eal_interrupts.c b/lib/librte_eal/freebsd/eal/eal_interrupts.c index f6831b7902c5..d3f8fd78a1ee 100644 --- a/lib/librte_eal/freebsd/eal/eal_interrupts.c +++ b/lib/librte_eal/freebsd/eal/eal_interrupts.c @@ -649,6 +649,18 @@ rte_epoll_wait(int epfd, struct rte_epoll_event *events, return -ENOTSUP; } +int +rte_epoll_wait_interruptible(int epfd, struct rte_epoll_event *events, + int maxevents, int timeout) +{ + RTE_SET_USED(epfd); + RTE_SET_USED(events); + RTE_SET_USED(maxevents); + RTE_SET_USED(timeout); + + return -ENOTSUP; +} + int rte_epoll_ctl(int epfd, int op, int fd, struct rte_epoll_event *event) { diff --git a/lib/librte_eal/linux/eal/eal_interrupts.c b/lib/librte_eal/linux/eal/eal_interrupts.c index 1955324d3045..b6ae12a282e7 100644 --- a/lib/librte_eal/linux/eal/eal_interrupts.c +++ b/lib/librte_eal/linux/eal/eal_interrupts.c @@ -1239,9 +1239,9 @@ rte_intr_tls_epfd(void) return RTE_PER_LCORE(_epfd); } -int -rte_epoll_wait(int epfd, struct rte_epoll_event *events, - int maxevents, int timeout) +static int +eal_epoll_wait(int epfd, struct rte_epoll_event *events, + int maxevents, int timeout, bool interruptible) { struct epoll_event evs[maxevents]; int rc; @@ -1255,29 +1255,40 @@ rte_epoll_wait(int epfd, struct rte_epoll_event *events, if (epfd == RTE_EPOLL_PER_THREAD) epfd = rte_intr_tls_epfd(); - while (1) { - rc = epoll_wait(epfd, evs, maxevents, timeout); - if (likely(rc > 0)) { - /* epoll_wait has at least one fd ready to read */ - rc = eal_epoll_process_event(evs, rc, events); - break; - } else if (rc < 0) { - if (errno == EINTR) - continue; +retry: + rc = epoll_wait(epfd, evs, maxevents, timeout); + if (likely(rc > 0)) { + /* epoll_wait has at least one fd ready to read */ + rc = eal_epoll_process_event(evs, rc, events); + } else if (rc < 0) { + if (errno == EINTR) { + if (!interruptible) + goto retry; + } else { /* epoll_wait fail */ - RTE_LOG(ERR, EAL, "epoll_wait returns with fail %s\n", + RTE_LOG(ERR, EAL, + "epoll_wait returns with fail %s\n", strerror(errno)); - rc = -1; - break; - } else { - /* rc == 0, epoll_wait timed out */ - break; } } return rc; } +int +rte_epoll_wait(int epfd, struct rte_epoll_event *events, + int maxevents, int timeout) +{ + return eal_epoll_wait(epfd, events, maxevents, timeout, false); +} + +int +rte_epoll_wait_interruptible(int epfd, struct rte_epoll_event *events, + int maxevents, int timeout) +{ + return eal_epoll_wait(epfd, events, maxevents, timeout, true); +} + static inline void eal_epoll_data_safe_free(struct rte_epoll_event *ev) { diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 234487787994..e1aeb99ba9c8 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -331,6 +331,7 @@ EXPERIMENTAL { rte_dev_hotplug_handle_enable; rte_dev_iterator_init; rte_dev_iterator_next; + rte_epoll_wait_interruptible; rte_extmem_attach; rte_extmem_detach; rte_extmem_register;