From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id A11AEA04C4; Wed, 20 Nov 2019 21:11:02 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 733C82B87; Wed, 20 Nov 2019 21:11:02 +0100 (CET) Received: from smtp-gw.pt.net (smtp-gw.pt.net [206.210.194.15]) by dpdk.org (Postfix) with ESMTP id CBD132B87 for ; Wed, 20 Nov 2019 21:11:00 +0100 (CET) X-ASG-Debug-ID: 1574280659-09411a4c2041eb0001-TfluYd Received: from mail.pt.net (mail.pt.net [206.210.194.11]) by smtp-gw.pt.net with ESMTP id ZuqIKsfqSn7yU4rj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 20 Nov 2019 14:10:59 -0600 (CST) X-Barracuda-Envelope-From: mit@pt.net X-Barracuda-Effective-Source-IP: mail.pt.net[206.210.194.11] X-Barracuda-Apparent-Source-IP: 206.210.194.11 Received: from localhost (localhost [IPv6:::1]) by mail.pt.net (Postfix) with ESMTP id 8CECA841D8C; Wed, 20 Nov 2019 14:10:59 -0600 (CST) Received: from mail.pt.net ([IPv6:::1]) by localhost (mail.pt.net [IPv6:::1]) (amavisd-new, port 10032) with ESMTP id EWby6LxiUgQl; Wed, 20 Nov 2019 14:10:59 -0600 (CST) Received: from localhost (localhost [IPv6:::1]) by mail.pt.net (Postfix) with ESMTP id 3C1B5841DBE; Wed, 20 Nov 2019 14:10:59 -0600 (CST) X-Virus-Scanned: amavisd-new at pt.net Received: from mail.pt.net ([IPv6:::1]) by localhost (mail.pt.net [IPv6:::1]) (amavisd-new, port 10026) with ESMTP id pm03Vs0hOHHL; Wed, 20 Nov 2019 14:10:59 -0600 (CST) Received: from fbdev.perftech.com (unknown [IPv6:2001:4870:610e:1::26]) by mail.pt.net (Postfix) with ESMTP id 20143841D8C; Wed, 20 Nov 2019 14:10:59 -0600 (CST) From: Mit Matelske To: bruce.richardson@intel.com Cc: dev@dpdk.org, Mit Matelske Date: Wed, 20 Nov 2019 14:10:56 -0600 X-ASG-Orig-Subj: [PATCH] eal/freebsd: fix queuing duplicate eal_alarm_callbacks Message-Id: <20191120201056.63818-1-mit@pt.net> X-Mailer: git-send-email 2.23.0 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail.pt.net[206.210.194.11] X-Barracuda-Start-Time: 1574280659 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://smtp-gw.pt.net:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at pt.net X-Barracuda-Scan-Msg-Size: 4372 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=9.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.78136 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Subject: [dpdk-dev] [PATCH] eal/freebsd: fix queuing duplicate eal_alarm_callbacks 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 source callback list grows infinitely when more than alarm is queued. This fix recognizes that an alarm interrupt in FreeBSD should never have more than one callback on its list, so if rte_intr_callback_register() is called with an interrupt handle type of RTE_INTR_HANDLE_ALARM, so if such an interrupt type already has a non-empty list, then a new callback is not created, but the kevent timer is restarted properly. Signed-off-by: Mit Matelske --- lib/librte_eal/freebsd/eal/eal_interrupts.c | 79 +++++++++++---------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/lib/librte_eal/freebsd/eal/eal_interrupts.c b/lib/librte_eal= /freebsd/eal/eal_interrupts.c index f6831b790..3fee762be 100644 --- a/lib/librte_eal/freebsd/eal/eal_interrupts.c +++ b/lib/librte_eal/freebsd/eal/eal_interrupts.c @@ -83,9 +83,9 @@ int rte_intr_callback_register(const struct rte_intr_handle *intr_handle, rte_intr_callback_fn cb, void *cb_arg) { - struct rte_intr_callback *callback =3D NULL; - struct rte_intr_source *src =3D NULL; - int ret, add_event; + struct rte_intr_callback *callback; + struct rte_intr_source *src; + int ret, add_event =3D 0; =20 /* first do parameter checking */ if (intr_handle =3D=3D NULL || intr_handle->fd < 0 || cb =3D=3D NULL) { @@ -98,47 +98,53 @@ rte_intr_callback_register(const struct rte_intr_hand= le *intr_handle, return -ENODEV; } =20 - /* allocate a new interrupt callback entity */ - callback =3D calloc(1, sizeof(*callback)); - if (callback =3D=3D NULL) { - RTE_LOG(ERR, EAL, "Can not allocate memory\n"); - return -ENOMEM; - } - callback->cb_fn =3D cb; - callback->cb_arg =3D cb_arg; - callback->pending_delete =3D 0; - callback->ucb_fn =3D NULL; - rte_spinlock_lock(&intr_lock); =20 - /* check if there is at least one callback registered for the fd */ + /* find the source for this intr_handle */ TAILQ_FOREACH(src, &intr_sources, next) { - if (src->intr_handle.fd =3D=3D intr_handle->fd) { - /* we had no interrupts for this */ - if (TAILQ_EMPTY(&src->callbacks)) - add_event =3D 1; - - TAILQ_INSERT_TAIL(&(src->callbacks), callback, next); - ret =3D 0; + if (src->intr_handle.fd =3D=3D intr_handle->fd) break; - } } =20 - /* no existing callbacks for this - add new source */ - if (src =3D=3D NULL) { - src =3D calloc(1, sizeof(*src)); - if (src =3D=3D NULL) { + /* if this is an alarm interrupt and it already has a callback, + * then we don't want to create a new callback because the only + * thing on the list should be eal_alarm_callback() and we may + * be called just to reset the timer. + */ + if (src !=3D NULL && src->intr_handle.type =3D=3D RTE_INTR_HANDLE_ALARM= && + !TAILQ_EMPTY(&src->callbacks)) { + callback =3D NULL; + } else { + /* allocate a new interrupt callback entity */ + callback =3D calloc(1, sizeof(*callback)); + if (callback =3D=3D NULL) { RTE_LOG(ERR, EAL, "Can not allocate memory\n"); ret =3D -ENOMEM; goto fail; - } else { - src->intr_handle =3D *intr_handle; - TAILQ_INIT(&src->callbacks); - TAILQ_INSERT_TAIL(&(src->callbacks), callback, next); - TAILQ_INSERT_TAIL(&intr_sources, src, next); - add_event =3D 1; - ret =3D 0; } + callback->cb_fn =3D cb; + callback->cb_arg =3D cb_arg; + callback->pending_delete =3D 0; + callback->ucb_fn =3D NULL; + + if (src =3D=3D NULL) { + src =3D calloc(1, sizeof(*src)); + if (src =3D=3D NULL) { + RTE_LOG(ERR, EAL, "Can not allocate memory\n"); + ret =3D -ENOMEM; + goto fail; + } else { + src->intr_handle =3D *intr_handle; + TAILQ_INIT(&src->callbacks); + TAILQ_INSERT_TAIL(&intr_sources, src, next); + } + } + + /* we had no interrupts for this */ + if (TAILQ_EMPTY(&src->callbacks)) + add_event =3D 1; + + TAILQ_INSERT_TAIL(&(src->callbacks), callback, next); } =20 /* add events to the queue. timer events are special as we need to @@ -178,11 +184,12 @@ rte_intr_callback_register(const struct rte_intr_ha= ndle *intr_handle, } rte_spinlock_unlock(&intr_lock); =20 - return ret; + return 0; fail: /* clean up */ if (src !=3D NULL) { - TAILQ_REMOVE(&(src->callbacks), callback, next); + if (callback !=3D NULL) + TAILQ_REMOVE(&(src->callbacks), callback, next); if (TAILQ_EMPTY(&(src->callbacks))) { TAILQ_REMOVE(&intr_sources, src, next); free(src); --=20 2.23.0