From nobody Mon Jul 20 20:53:28 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4h3t5j0ft8z6dQ5j for ; Mon, 20 Jul 2026 20:53:29 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4h3t5h5x1Bz479H for ; Mon, 20 Jul 2026 20:53:28 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1784580808; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=n4U45RqsKBBxrAQKoK9Xc3Z0S9QscILbtG4j5vJlNuM=; b=nQsBHeFfLJY4sfqbbLWbp1A5rk23Wu5ppp8gmsMdxpk1Thzakfnn+1DDJuaDjf2RMNId/+ rhwYhLpkDsd5HfBf3R4IeKxaElXO3gynoM+R84pNiHZd9SWSQPYj/3eg15IzpVcHE+/BOv +NvHjVNzVbtgOxNKiw3bho9epC2ZdXzTzDXZMD59dAJRNOhtVWRJSbNbhoWNWZeZvaMTYR 0YiyQYtcxK6/ia9Z4NG3yR7Fn07zI8RmEjP+JdczjeEOiIwDzPr3eMmD2gK5A8Jkr+/uAi cpjlu7F35VEFajWc5Od2XgI1Yp2tWVJ0+LzDduh1qmGRo0t3rfdCBSIOMfiogw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1784580808; a=rsa-sha256; cv=none; b=nDd3YgOdMi6Wzfg12NlLXhV1W+SSHjxW67fA+O8IxPt6VxAwydtamLrClJSQQKYkmFtExX 6i4RAH0Lpq2RhTTEj5glqLVxs4NavJqmrmXm09CF/zkS0HvgrKrBz3KmB1w6VApLhpTh9W 2YaN4wDVy5pd0P8EoSUusiug+tRhAFc8eZQEK4DOrOSMVUG5rKFQsaJepAl5bYCxqrcLMH VY1wQQq+1vnQzIlNygOM+pQd/daaGCy9OZIRqGnTDwwWMkxKy1gFBemB+1HiojBk+2yz4/ BJUPrayFi5FKX3KNOxwyPHzIQJL8xuZxhi1X0eUqX1MP5Fs5Vh2nB3z3k00NQQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1784580808; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=n4U45RqsKBBxrAQKoK9Xc3Z0S9QscILbtG4j5vJlNuM=; b=lEJ3J/4QcsXU1eksd8Zn9R3DmK/MRtt5dskwkYfbbDAPfRMKdpKA8wEyBpeKvlRLRD5IhY kgyHpw4vbX3s0gxz3HY+yxm22iOaJovOgJQ7hzLJUGUMogie/2flc84V+2Iru0L4+Zrii2 N28zfEGMnw4v/ISrh6oTTaCHLB0dvgr7QCW2FW8Yz1YIKxIEECw3e7OX3PfCE4Y3963Ppc XPeAGfbVDNPz282pzoex2IWks0d/jrpI1BhbE1NrD7Xd23wTkdx/BLzoUgubl3o2cRBUsF lQ2+TMi7mDPlxV+4AAy+VgpWHGQfwfh5R2HGgiAcB969U1q1mEHdlOC2UeUeqg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4h3t5h4GFYz3Ng for ; Mon, 20 Jul 2026 20:53:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1de17 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 20 Jul 2026 20:53:28 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: Ariel Ehrenberg From: Konstantin Belousov Subject: git: 8d518f4b482f - stable/15 - mlx5_ib: do not consume CMD/PAGE_REQUEST events in the DEVX notifier List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 8d518f4b482f64449b2bbb36a7c4627e80a3a93a Auto-Submitted: auto-generated Date: Mon, 20 Jul 2026 20:53:28 +0000 Message-Id: <6a5e8ac8.1de17.3ff79b40@gitrepo.freebsd.org> The branch stable/15 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=8d518f4b482f64449b2bbb36a7c4627e80a3a93a commit 8d518f4b482f64449b2bbb36a7c4627e80a3a93a Author: Ariel Ehrenberg AuthorDate: 2026-06-09 11:20:08 +0000 Commit: Konstantin Belousov CommitDate: 2026-07-20 20:26:05 +0000 mlx5_ib: do not consume CMD/PAGE_REQUEST events in the DEVX notifier (cherry picked from commit 2e3b3ce881490adcef17905450d0402030975051) --- sys/dev/mlx5/mlx5_core/mlx5_eq.c | 33 ++++++++++++++++++++++++++++++--- sys/dev/mlx5/mlx5_ib/mlx5_ib_devx.c | 35 ++++++++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/sys/dev/mlx5/mlx5_core/mlx5_eq.c b/sys/dev/mlx5/mlx5_core/mlx5_eq.c index 1090f8638171..f564b88c48b4 100644 --- a/sys/dev/mlx5/mlx5_core/mlx5_eq.c +++ b/sys/dev/mlx5/mlx5_core/mlx5_eq.c @@ -238,6 +238,10 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq) u8 port; while ((eqe = next_eqe_sw(eq))) { + bool (*devx_cb)(struct mlx5_core_dev *mdev, + uint8_t event_type, void *data); + bool devx_consumed = false; + /* * Make sure we read EQ entry contents after we've * checked the ownership bit. @@ -247,9 +251,32 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq) mlx5_core_dbg(eq->dev, "eqn %d, eqe type %s\n", eq->eqn, eqe_type_str(eqe->type)); - if (dev->priv.eq_table.cb != NULL && - dev->priv.eq_table.cb(dev, eqe->type, &eqe->data)) { - /* FALLTHROUGH */ + /* + * The DEVX event notifier can be (un)registered concurrently. + * Fast path: when no notifier is registered (the common case + * with DEVX unused) skip RCU entirely - on FreeBSD LinuxKPI + * rcu_read_lock() pins the thread and starts an epoch section, + * which is not free per EQE. If a notifier appears registered, + * re-load the callback under rcu_read_lock() before calling it. + * The acquire load pairs with the store-release in + * mlx5_ib_devx_init_event_table() so eq_table.dev is visible + * once cb is; the re-check under RCU pairs with synchronize_rcu() + * in mlx5_ib_devx_cleanup_event_table() so the callback only + * ever runs inside an RCU section and none is in flight when the + * notifier (and its event table) is torn down. + */ + devx_cb = smp_load_acquire(&dev->priv.eq_table.cb); + if (devx_cb != NULL) { + rcu_read_lock(); + devx_cb = smp_load_acquire(&dev->priv.eq_table.cb); + if (devx_cb != NULL) + devx_consumed = + devx_cb(dev, eqe->type, &eqe->data); + rcu_read_unlock(); + } + + if (devx_consumed) { + /* event consumed by the DEVX notifier */ } else switch (eqe->type) { case MLX5_EVENT_TYPE_COMP: mlx5_cq_completion(dev, eqe); diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_devx.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_devx.c index 835a7fd8cfa4..6522a0aa6daf 100644 --- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_devx.c +++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_devx.c @@ -2357,12 +2357,21 @@ static bool mlx5_devx_event_notifier(struct mlx5_core_dev *mdev, bool is_unaffiliated; u32 obj_id; - /* Explicit filtering to kernel events which may occur frequently */ + /* + * Command completions and page requests must be processed by the + * mlx5_core default EQ handler. Returning true here tells + * mlx5_eq_int() the event was consumed and skips core processing, + * which stalls the firmware command interface and page supply and + * wedges the device. Return false so the core handler runs for + * these frequent kernel events. + */ if (event_type == MLX5_EVENT_TYPE_CMD || event_type == MLX5_EVENT_TYPE_PAGE_REQUEST) - return true; + return false; - dev = mdev->priv.eq_table.dev; + dev = READ_ONCE(mdev->priv.eq_table.dev); + if (dev == NULL) + return false; table = &dev->devx_event_table; is_unaffiliated = is_unaffiliated_event(dev->mdev, event_type); @@ -2401,8 +2410,14 @@ void mlx5_ib_devx_init_event_table(struct mlx5_ib_dev *dev) xa_init_flags(&table->event_xa, 0); mutex_init(&table->event_xa_lock); - dev->mdev->priv.eq_table.dev = dev; - dev->mdev->priv.eq_table.cb = mlx5_devx_event_notifier; + /* + * Publish dev before cb. The EQ interrupt handler loads cb with + * acquire semantics and the notifier then dereferences eq_table.dev, + * so dev must be visible to that handler once cb is observed. + */ + WRITE_ONCE(dev->mdev->priv.eq_table.dev, dev); + smp_store_release(&dev->mdev->priv.eq_table.cb, + mlx5_devx_event_notifier); } void mlx5_ib_devx_cleanup_event_table(struct mlx5_ib_dev *dev) @@ -2413,8 +2428,14 @@ void mlx5_ib_devx_cleanup_event_table(struct mlx5_ib_dev *dev) void *entry; unsigned long id; - dev->mdev->priv.eq_table.cb = NULL; - dev->mdev->priv.eq_table.dev = NULL; + /* + * Stop new dispatch by clearing cb, then wait for any in-flight EQ + * callback to finish its RCU read section before clearing dev and + * tearing down the event table. + */ + WRITE_ONCE(dev->mdev->priv.eq_table.cb, NULL); + synchronize_rcu(); + WRITE_ONCE(dev->mdev->priv.eq_table.dev, NULL); mutex_lock(&dev->devx_event_table.event_xa_lock); xa_for_each(&table->event_xa, id, entry) { event = entry;