DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/4] Interrupts API update
@ 2026-07-23 13:19 David Marchand
  2026-07-23 13:19 ` [RFC 1/4] bus/pci: fix check on interrupt FD for FreeBSD David Marchand
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: David Marchand @ 2026-07-23 13:19 UTC (permalink / raw)
  To: dev; +Cc: hkalra

This series is a simple cleanup to have a simpler helper that close all
FD reference in an interrupt handle.
This should make life (a bit) easier on driver side.


-- 
David Marchand

David Marchand (4):
  bus/pci: fix check on interrupt FD for FreeBSD
  vdpa/mlx5: fix check on err interrupt FD
  interrupts: mark file descriptors invalid on allocation
  interrupts: close interrupt FDs

 app/test/test_interrupts.c             |  5 +++--
 doc/guides/rel_notes/release_26_11.rst |  7 +++++++
 drivers/bus/cdx/cdx_vfio.c             |  6 ------
 drivers/bus/pci/bsd/pci.c              |  7 ++-----
 drivers/bus/pci/linux/pci_uio.c        | 15 +++----------
 drivers/bus/pci/linux/pci_vfio.c       | 29 +++++---------------------
 drivers/bus/pci/pci_common_uio.c       | 18 ++--------------
 drivers/bus/vmbus/linux/vmbus_uio.c    | 13 +++---------
 drivers/bus/vmbus/vmbus_common_uio.c   | 17 ++-------------
 drivers/net/failsafe/failsafe.c        |  3 ---
 drivers/net/mana/mana.c                |  5 +----
 drivers/net/memif/memif_socket.c       | 13 +++---------
 drivers/net/memif/rte_eth_memif.c      |  6 ------
 drivers/net/mlx4/mlx4.c                |  3 ---
 drivers/net/mlx4/mlx4_intr.c           |  1 +
 drivers/net/tap/rte_eth_tap.c          |  2 +-
 drivers/vdpa/mlx5/mlx5_vdpa_event.c    |  6 ++++--
 drivers/vdpa/mlx5/mlx5_vdpa_virtq.c    |  1 +
 lib/eal/common/eal_common_interrupts.c | 29 ++++++++++++++++++++++++++
 lib/eal/freebsd/eal_alarm.c            |  3 ---
 lib/eal/include/rte_interrupts.h       | 29 ++++++++++++++++++++++++++
 lib/eal/linux/eal_dev.c                |  9 +-------
 22 files changed, 97 insertions(+), 130 deletions(-)

-- 
2.54.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RFC 1/4] bus/pci: fix check on interrupt FD for FreeBSD
  2026-07-23 13:19 [RFC 0/4] Interrupts API update David Marchand
@ 2026-07-23 13:19 ` David Marchand
  2026-07-23 13:35   ` Bruce Richardson
  2026-07-23 13:19 ` [RFC 2/4] vdpa/mlx5: fix check on err interrupt FD David Marchand
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: David Marchand @ 2026-07-23 13:19 UTC (permalink / raw)
  To: dev; +Cc: hkalra, Chenbo Xia, Nipun Gupta, Tetsuya Mukawa

A 0 file descriptor is valid. And a negative value is not.
Only close a positive file descriptor.

Fixes: 5a60a7ffc801 ("pci: introduce functions to alloc and free uio resource")

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 drivers/bus/pci/bsd/pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
index c6df31d486..bbe08605af 100644
--- a/drivers/bus/pci/bsd/pci.c
+++ b/drivers/bus/pci/bsd/pci.c
@@ -93,7 +93,7 @@ pci_uio_free_resource(struct rte_pci_device *dev,
 {
 	rte_free(uio_res);
 
-	if (rte_intr_fd_get(dev->intr_handle)) {
+	if (rte_intr_fd_get(dev->intr_handle) >= 0) {
 		close(rte_intr_fd_get(dev->intr_handle));
 		rte_intr_fd_set(dev->intr_handle, -1);
 		rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [RFC 2/4] vdpa/mlx5: fix check on err interrupt FD
  2026-07-23 13:19 [RFC 0/4] Interrupts API update David Marchand
  2026-07-23 13:19 ` [RFC 1/4] bus/pci: fix check on interrupt FD for FreeBSD David Marchand
@ 2026-07-23 13:19 ` David Marchand
  2026-07-23 13:19 ` [RFC 3/4] interrupts: mark file descriptors invalid on allocation David Marchand
  2026-07-23 13:19 ` [RFC 4/4] interrupts: close interrupt FDs David Marchand
  3 siblings, 0 replies; 10+ messages in thread
From: David Marchand @ 2026-07-23 13:19 UTC (permalink / raw)
  To: dev; +Cc: hkalra, Matan Azrad, Viacheslav Ovsiienko, Xueming Li,
	Maxime Coquelin

A 0 file descriptor is valid.
Prefer setting to -1 to indicate an invalid FD.

Fixes: 0474419bae7c ("vdpa/mlx5: handle hardware error")

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 drivers/vdpa/mlx5/mlx5_vdpa_event.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_event.c b/drivers/vdpa/mlx5/mlx5_vdpa_event.c
index 43585a94b2..dee2ccc23d 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa_event.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa_event.c
@@ -452,7 +452,7 @@ mlx5_vdpa_err_event_setup(struct mlx5_vdpa_priv *priv)
 					 mlx5_vdpa_err_interrupt_handler,
 					 priv);
 	if (ret != 0) {
-		rte_intr_fd_set(priv->err_intr_handle, 0);
+		rte_intr_fd_set(priv->err_intr_handle, -1);
 		DRV_LOG(ERR, "Failed to register error interrupt for device %d.",
 			priv->vid);
 		rte_errno = -ret;
@@ -473,7 +473,7 @@ mlx5_vdpa_err_event_unset(struct mlx5_vdpa_priv *priv)
 	int retries = MLX5_VDPA_INTR_RETRIES;
 	int ret = -EAGAIN;
 
-	if (!rte_intr_fd_get(priv->err_intr_handle))
+	if (rte_intr_fd_get(priv->err_intr_handle) < 0)
 		return;
 	while (retries-- && ret == -EAGAIN) {
 		ret = rte_intr_callback_unregister(priv->err_intr_handle,
@@ -487,6 +487,7 @@ mlx5_vdpa_err_event_unset(struct mlx5_vdpa_priv *priv)
 			rte_pause();
 		}
 	}
+	rte_intr_fd_set(priv->err_intr_handle, -1);
 	if (priv->err_chnl) {
 #ifdef HAVE_IBV_DEVX_EVENT
 		union {
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [RFC 3/4] interrupts: mark file descriptors invalid on allocation
  2026-07-23 13:19 [RFC 0/4] Interrupts API update David Marchand
  2026-07-23 13:19 ` [RFC 1/4] bus/pci: fix check on interrupt FD for FreeBSD David Marchand
  2026-07-23 13:19 ` [RFC 2/4] vdpa/mlx5: fix check on err interrupt FD David Marchand
@ 2026-07-23 13:19 ` David Marchand
  2026-07-23 13:19 ` [RFC 4/4] interrupts: close interrupt FDs David Marchand
  3 siblings, 0 replies; 10+ messages in thread
From: David Marchand @ 2026-07-23 13:19 UTC (permalink / raw)
  To: dev
  Cc: hkalra, Nipun Gupta, Nikhil Agarwal, Anatoly Burakov, Chenbo Xia,
	Long Li, Wei Hu, Gaetan Rivet, Jakub Grajciar, Matan Azrad,
	Viacheslav Ovsiienko, Stephen Hemminger, Bruce Richardson

Initialize fd, dev_fd, and all efds array elements as invalid in
rte_intr_instance_alloc().
This follows Unix convention, avoiding confusion with fd 0
which could result from zero-initialization.

Update the API documentation to reflect this behavior and add a
unit test check to verify the fd is invalid after allocation.

Remove now-redundant initialization calls that were setting the fd
invalid right after allocation.

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 app/test/test_interrupts.c             |  5 +++--
 doc/guides/rel_notes/release_26_11.rst |  5 +++++
 drivers/bus/cdx/cdx_vfio.c             |  6 ------
 drivers/bus/pci/linux/pci_vfio.c       | 11 -----------
 drivers/bus/pci/pci_common_uio.c       |  6 ------
 drivers/bus/vmbus/vmbus_common_uio.c   |  6 ------
 drivers/net/failsafe/failsafe.c        |  3 ---
 drivers/net/mana/mana.c                |  4 ----
 drivers/net/memif/rte_eth_memif.c      |  6 ------
 drivers/net/mlx4/mlx4.c                |  3 ---
 drivers/net/tap/rte_eth_tap.c          |  1 -
 lib/eal/common/eal_common_interrupts.c |  6 ++++++
 lib/eal/freebsd/eal_alarm.c            |  3 ---
 lib/eal/include/rte_interrupts.h       |  2 ++
 lib/eal/linux/eal_dev.c                |  4 ----
 15 files changed, 16 insertions(+), 55 deletions(-)

diff --git a/app/test/test_interrupts.c b/app/test/test_interrupts.c
index 3a5be92cd7..5901cec2fe 100644
--- a/app/test/test_interrupts.c
+++ b/app/test/test_interrupts.c
@@ -73,11 +73,12 @@ test_interrupt_init(void)
 			rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
 		if (!intr_handles[i])
 			return -1;
+		/* Verify fd is initialized to -1 */
+		if (rte_intr_fd_get(intr_handles[i]) != -1)
+			return -1;
 	}
 
 	test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
-	if (rte_intr_fd_set(test_intr_handle, -1))
-		return -1;
 	if (rte_intr_type_set(test_intr_handle, RTE_INTR_HANDLE_UNKNOWN))
 		return -1;
 
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 938617ca75..55368b95a6 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -84,6 +84,11 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* interrupts: Updated interrupt handle file descriptor management.
+
+  * ``rte_intr_instance_alloc()`` now initializes file descriptors
+    to invalid values instead of zero.
+
 
 ABI Changes
 -----------
diff --git a/drivers/bus/cdx/cdx_vfio.c b/drivers/bus/cdx/cdx_vfio.c
index 11fe3265d2..0e4af4e940 100644
--- a/drivers/bus/cdx/cdx_vfio.c
+++ b/drivers/bus/cdx/cdx_vfio.c
@@ -397,9 +397,6 @@ cdx_vfio_map_resource_primary(struct rte_cdx_device *dev)
 	struct cdx_map *maps;
 	int vfio_dev_fd, i, ret;
 
-	if (rte_intr_fd_set(dev->intr_handle, -1))
-		return -1;
-
 	ret = rte_vfio_setup_device(RTE_CDX_BUS_DEVICES_PATH, dev_name,
 				    &vfio_dev_fd, &device_info);
 	if (ret)
@@ -493,9 +490,6 @@ cdx_vfio_map_resource_secondary(struct rte_cdx_device *dev)
 	const char *dev_name = dev->device.name;
 	struct cdx_map *maps;
 
-	if (rte_intr_fd_set(dev->intr_handle, -1))
-		return -1;
-
 	/* if we're in a secondary process, just find our tailq entry */
 	TAILQ_FOREACH(vfio_res, vfio_res_list, next) {
 		if (strcmp(vfio_res->name, dev_name))
diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c
index bc5c5c2499..a92a0d86ec 100644
--- a/drivers/bus/pci/linux/pci_vfio.c
+++ b/drivers/bus/pci/linux/pci_vfio.c
@@ -742,12 +742,6 @@ pci_vfio_map_resource_primary(struct rte_pci_device *dev)
 
 	struct pci_map *maps;
 
-	if (rte_intr_fd_set(dev->intr_handle, -1))
-		return -1;
-
-	if (rte_intr_fd_set(dev->vfio_req_intr_handle, -1))
-		return -1;
-
 	/* store PCI address string */
 	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
 			loc->domain, loc->bus, loc->devid, loc->function);
@@ -939,11 +933,6 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
 
 	struct pci_map *maps;
 
-	if (rte_intr_fd_set(dev->intr_handle, -1))
-		return -1;
-	if (rte_intr_fd_set(dev->vfio_req_intr_handle, -1))
-		return -1;
-
 	/* store PCI address string */
 	snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
 			loc->domain, loc->bus, loc->devid, loc->function);
diff --git a/drivers/bus/pci/pci_common_uio.c b/drivers/bus/pci/pci_common_uio.c
index 71974e9f56..47d50721dc 100644
--- a/drivers/bus/pci/pci_common_uio.c
+++ b/drivers/bus/pci/pci_common_uio.c
@@ -101,12 +101,6 @@ pci_uio_map_resource(struct rte_pci_device *dev)
 	struct mapped_pci_res_list *uio_res_list =
 		RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
 
-	if (rte_intr_fd_set(dev->intr_handle, -1))
-		return -1;
-
-	if (rte_intr_dev_fd_set(dev->intr_handle, -1))
-		return -1;
-
 	/* allocate uio resource */
 	ret = pci_uio_alloc_resource(dev, &uio_res);
 	if (ret)
diff --git a/drivers/bus/vmbus/vmbus_common_uio.c b/drivers/bus/vmbus/vmbus_common_uio.c
index c6e7e07302..7459f4ea7a 100644
--- a/drivers/bus/vmbus/vmbus_common_uio.c
+++ b/drivers/bus/vmbus/vmbus_common_uio.c
@@ -173,12 +173,6 @@ vmbus_uio_map_resource(struct rte_vmbus_device *dev)
 	int ret;
 
 	/* TODO: handle rescind */
-	if (rte_intr_fd_set(dev->intr_handle, -1))
-		return -1;
-
-	if (rte_intr_dev_fd_set(dev->intr_handle, -1))
-		return -1;
-
 	if (rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN))
 		return -1;
 
diff --git a/drivers/net/failsafe/failsafe.c b/drivers/net/failsafe/failsafe.c
index aa3fe53b22..3ba143924d 100644
--- a/drivers/net/failsafe/failsafe.c
+++ b/drivers/net/failsafe/failsafe.c
@@ -279,9 +279,6 @@ fs_eth_dev_create(struct rte_vdev_device *vdev)
 		goto cancel_alarm;
 	}
 
-	if (rte_intr_fd_set(PRIV(dev)->intr_handle, -1))
-		goto cancel_alarm;
-
 	if (rte_intr_type_set(PRIV(dev)->intr_handle, RTE_INTR_HANDLE_EXT))
 		goto cancel_alarm;
 
diff --git a/drivers/net/mana/mana.c b/drivers/net/mana/mana.c
index 0b72f711a1..1864ba2a2b 100644
--- a/drivers/net/mana/mana.c
+++ b/drivers/net/mana/mana.c
@@ -1946,10 +1946,6 @@ mana_intr_install(struct rte_eth_dev *eth_dev, struct mana_priv *priv)
 		return -ENOMEM;
 	}
 
-	ret = rte_intr_fd_set(priv->intr_handle, -1);
-	if (ret)
-		goto free_intr;
-
 	ret = mana_fd_set_non_blocking(ctx->async_fd);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to change async_fd to NONBLOCK");
diff --git a/drivers/net/memif/rte_eth_memif.c b/drivers/net/memif/rte_eth_memif.c
index 5d153c3a5a..04e12b8ffa 100644
--- a/drivers/net/memif/rte_eth_memif.c
+++ b/drivers/net/memif/rte_eth_memif.c
@@ -1496,9 +1496,6 @@ memif_tx_queue_setup(struct rte_eth_dev *dev,
 	mq->n_pkts = 0;
 	mq->n_bytes = 0;
 
-	if (rte_intr_fd_set(mq->intr_handle, -1))
-		return -rte_errno;
-
 	if (rte_intr_type_set(mq->intr_handle, RTE_INTR_HANDLE_EXT))
 		return -rte_errno;
 
@@ -1536,9 +1533,6 @@ memif_rx_queue_setup(struct rte_eth_dev *dev,
 	mq->n_pkts = 0;
 	mq->n_bytes = 0;
 
-	if (rte_intr_fd_set(mq->intr_handle, -1))
-		return -rte_errno;
-
 	if (rte_intr_type_set(mq->intr_handle, RTE_INTR_HANDLE_EXT))
 		return -rte_errno;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 28f1116891..dbcd98d49f 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -1062,9 +1062,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			goto port_error;
 		}
 
-		if (rte_intr_fd_set(priv->intr_handle, -1))
-			goto port_error;
-
 		if (rte_intr_type_set(priv->intr_handle, RTE_INTR_HANDLE_EXT))
 			goto port_error;
 
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index b93452f168..13114edba5 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -2191,7 +2191,6 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
 	dev->tx_pkt_burst = pmd_tx_burst;
 
 	rte_intr_type_set(pmd->intr_handle, RTE_INTR_HANDLE_EXT);
-	rte_intr_fd_set(pmd->intr_handle, -1);
 	dev->intr_handle = pmd->intr_handle;
 
 	/* Presetup the fds to -1 as being not valid */
diff --git a/lib/eal/common/eal_common_interrupts.c b/lib/eal/common/eal_common_interrupts.c
index a2a310750a..4e31a71319 100644
--- a/lib/eal/common/eal_common_interrupts.c
+++ b/lib/eal/common/eal_common_interrupts.c
@@ -68,6 +68,8 @@ struct rte_intr_handle *rte_intr_instance_alloc(uint32_t flags)
 		rte_errno = ENOMEM;
 		goto fail;
 	}
+	for (int i = 0; i < RTE_MAX_RXTX_INTR_VEC_ID; i++)
+		intr_handle->efds[i] = -1;
 
 	if (uses_rte_memory) {
 		intr_handle->elist = rte_zmalloc(NULL,
@@ -83,6 +85,8 @@ struct rte_intr_handle *rte_intr_instance_alloc(uint32_t flags)
 		goto fail;
 	}
 
+	intr_handle->fd = -1;
+	intr_handle->dev_fd = -1;
 	intr_handle->alloc_flags = flags;
 	intr_handle->nb_intr = RTE_MAX_RXTX_INTR_VEC_ID;
 
@@ -153,6 +157,8 @@ int rte_intr_event_list_update(struct rte_intr_handle *intr_handle, int size)
 		goto fail;
 	}
 	intr_handle->efds = tmp_efds;
+	for (int i = intr_handle->nb_intr; i < size; i++)
+		intr_handle->efds[i] = -1;
 
 	if (uses_rte_memory) {
 		tmp_elist = rte_realloc(intr_handle->elist,
diff --git a/lib/eal/freebsd/eal_alarm.c b/lib/eal/freebsd/eal_alarm.c
index c03e281e67..f7480d2802 100644
--- a/lib/eal/freebsd/eal_alarm.c
+++ b/lib/eal/freebsd/eal_alarm.c
@@ -73,9 +73,6 @@ rte_eal_alarm_init(void)
 	if (rte_intr_type_set(intr_handle, RTE_INTR_HANDLE_ALARM))
 		goto error;
 
-	if (rte_intr_fd_set(intr_handle, -1))
-		goto error;
-
 	/* on FreeBSD, timers don't use fd's, and their identifiers are stored
 	 * in separate namespace from fd's, so using any value is OK. however,
 	 * EAL interrupts handler expects fd's to be unique, so use an actual fd
diff --git a/lib/eal/include/rte_interrupts.h b/lib/eal/include/rte_interrupts.h
index 0ae16bbe19..1cfb9d3f8e 100644
--- a/lib/eal/include/rte_interrupts.h
+++ b/lib/eal/include/rte_interrupts.h
@@ -225,6 +225,8 @@ uint32_t rte_intr_active_events_flags(void);
  * can be realloced later based on size of MSIX interrupts supported by a PCI
  * device.
  *
+ * All file descriptors (fd, dev_fd, efds) are initialized to -1.
+ *
  * This function should be called from application or driver, before calling
  * any of the interrupt APIs.
  *
diff --git a/lib/eal/linux/eal_dev.c b/lib/eal/linux/eal_dev.c
index ec408649d0..c78e565427 100644
--- a/lib/eal/linux/eal_dev.c
+++ b/lib/eal/linux/eal_dev.c
@@ -326,10 +326,6 @@ rte_dev_event_monitor_start(void)
 	if (ret)
 		goto exit;
 
-	ret = rte_intr_fd_set(intr_handle, -1);
-	if (ret)
-		goto exit;
-
 	ret = dev_uev_socket_fd_create();
 	if (ret) {
 		EAL_LOG(ERR, "error create device event fd.");
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [RFC 4/4] interrupts: close interrupt FDs
  2026-07-23 13:19 [RFC 0/4] Interrupts API update David Marchand
                   ` (2 preceding siblings ...)
  2026-07-23 13:19 ` [RFC 3/4] interrupts: mark file descriptors invalid on allocation David Marchand
@ 2026-07-23 13:19 ` David Marchand
  3 siblings, 0 replies; 10+ messages in thread
From: David Marchand @ 2026-07-23 13:19 UTC (permalink / raw)
  To: dev
  Cc: hkalra, Chenbo Xia, Nipun Gupta, Anatoly Burakov, Long Li, Wei Hu,
	Jakub Grajciar, Matan Azrad, Viacheslav Ovsiienko,
	Stephen Hemminger

Add rte_intr_fd_close() and rte_intr_dev_fd_close() helpers to
encapsulate the common pattern of closing an interrupt handle's
file descriptor and resetting it to -1.

This simplifies code in multiple drivers that previously had to:
  if (rte_intr_fd_get(handle) >= 0) {
      close(rte_intr_fd_get(handle));
      rte_intr_fd_set(handle, -1);
  }

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 doc/guides/rel_notes/release_26_11.rst |  2 ++
 drivers/bus/pci/bsd/pci.c              |  7 ++-----
 drivers/bus/pci/linux/pci_uio.c        | 15 +++-----------
 drivers/bus/pci/linux/pci_vfio.c       | 18 +++++------------
 drivers/bus/pci/pci_common_uio.c       | 12 ++----------
 drivers/bus/vmbus/linux/vmbus_uio.c    | 13 +++----------
 drivers/bus/vmbus/vmbus_common_uio.c   | 11 ++---------
 drivers/net/mana/mana.c                |  1 +
 drivers/net/memif/memif_socket.c       | 13 +++----------
 drivers/net/mlx4/mlx4_intr.c           |  1 +
 drivers/net/tap/rte_eth_tap.c          |  1 +
 drivers/vdpa/mlx5/mlx5_vdpa_event.c    |  1 +
 drivers/vdpa/mlx5/mlx5_vdpa_virtq.c    |  1 +
 lib/eal/common/eal_common_interrupts.c | 23 ++++++++++++++++++++++
 lib/eal/include/rte_interrupts.h       | 27 ++++++++++++++++++++++++++
 lib/eal/linux/eal_dev.c                |  5 +----
 16 files changed, 78 insertions(+), 73 deletions(-)

diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 55368b95a6..221aea45d2 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -88,6 +88,8 @@ API Changes
 
   * ``rte_intr_instance_alloc()`` now initializes file descriptors
     to invalid values instead of zero.
+  * Added ``rte_intr_fd_close()`` and ``rte_intr_dev_fd_close()``
+    helpers to close file descriptors and reset them to -1.
 
 
 ABI Changes
diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
index bbe08605af..f1012bb91b 100644
--- a/drivers/bus/pci/bsd/pci.c
+++ b/drivers/bus/pci/bsd/pci.c
@@ -93,11 +93,8 @@ pci_uio_free_resource(struct rte_pci_device *dev,
 {
 	rte_free(uio_res);
 
-	if (rte_intr_fd_get(dev->intr_handle) >= 0) {
-		close(rte_intr_fd_get(dev->intr_handle));
-		rte_intr_fd_set(dev->intr_handle, -1);
-		rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
-	}
+	rte_intr_fd_close(dev->intr_handle);
+	rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
 }
 
 int
diff --git a/drivers/bus/pci/linux/pci_uio.c b/drivers/bus/pci/linux/pci_uio.c
index 40e96b1c67..0983474994 100644
--- a/drivers/bus/pci/linux/pci_uio.c
+++ b/drivers/bus/pci/linux/pci_uio.c
@@ -197,20 +197,11 @@ void
 pci_uio_free_resource(struct rte_pci_device *dev,
 		struct mapped_pci_resource *uio_res)
 {
-	int uio_cfg_fd = rte_intr_dev_fd_get(dev->intr_handle);
-
 	rte_free(uio_res);
 
-	if (uio_cfg_fd >= 0) {
-		close(uio_cfg_fd);
-		rte_intr_dev_fd_set(dev->intr_handle, -1);
-	}
-
-	if (rte_intr_fd_get(dev->intr_handle) >= 0) {
-		close(rte_intr_fd_get(dev->intr_handle));
-		rte_intr_fd_set(dev->intr_handle, -1);
-		rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
-	}
+	rte_intr_dev_fd_close(dev->intr_handle);
+	rte_intr_fd_close(dev->intr_handle);
+	rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
 }
 
 int
diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c
index a92a0d86ec..b5f05e9f9f 100644
--- a/drivers/bus/pci/linux/pci_vfio.c
+++ b/drivers/bus/pci/linux/pci_vfio.c
@@ -354,10 +354,9 @@ pci_vfio_enable_notifier(struct rte_pci_device *dev, int vfio_dev_fd)
 
 	return 0;
 error:
-	close(fd);
-
-	rte_intr_fd_set(dev->vfio_req_intr_handle, -1);
+	rte_intr_fd_close(dev->vfio_req_intr_handle);
 	rte_intr_type_set(dev->vfio_req_intr_handle, RTE_INTR_HANDLE_UNKNOWN);
+	/* vfio_dev_fd is managed by VFIO layer, only clear reference here. */
 	rte_intr_dev_fd_set(dev->vfio_req_intr_handle, -1);
 
 	return -1;
@@ -383,10 +382,9 @@ pci_vfio_disable_notifier(struct rte_pci_device *dev)
 		return -1;
 	}
 
-	close(rte_intr_fd_get(dev->vfio_req_intr_handle));
-
-	rte_intr_fd_set(dev->vfio_req_intr_handle, -1);
+	rte_intr_fd_close(dev->vfio_req_intr_handle);
 	rte_intr_type_set(dev->vfio_req_intr_handle, RTE_INTR_HANDLE_UNKNOWN);
+	/* vfio_dev_fd is managed by VFIO layer, only clear reference here. */
 	rte_intr_dev_fd_set(dev->vfio_req_intr_handle, -1);
 
 	return 0;
@@ -1073,13 +1071,7 @@ pci_vfio_unmap_resource_primary(struct rte_pci_device *dev)
 		return -1;
 	}
 
-	if (rte_intr_fd_get(dev->intr_handle) < 0)
-		return -1;
-
-	if (close(rte_intr_fd_get(dev->intr_handle)) < 0) {
-		PCI_LOG(INFO, "Error when closing eventfd file descriptor for %s", pci_addr);
-		return -1;
-	}
+	rte_intr_fd_close(dev->intr_handle);
 
 	vfio_dev_fd = rte_intr_dev_fd_get(dev->intr_handle);
 	if (vfio_dev_fd < 0)
diff --git a/drivers/bus/pci/pci_common_uio.c b/drivers/bus/pci/pci_common_uio.c
index 47d50721dc..52a10f806a 100644
--- a/drivers/bus/pci/pci_common_uio.c
+++ b/drivers/bus/pci/pci_common_uio.c
@@ -211,7 +211,6 @@ pci_uio_unmap_resource(struct rte_pci_device *dev)
 	struct mapped_pci_resource *uio_res;
 	struct mapped_pci_res_list *uio_res_list =
 			RTE_TAILQ_CAST(rte_uio_tailq.head, mapped_pci_res_list);
-	int uio_cfg_fd;
 
 	if (dev == NULL)
 		return;
@@ -222,15 +221,8 @@ pci_uio_unmap_resource(struct rte_pci_device *dev)
 		return;
 
 	/* close fd */
-	if (rte_intr_fd_get(dev->intr_handle) >= 0)
-		close(rte_intr_fd_get(dev->intr_handle));
-	uio_cfg_fd = rte_intr_dev_fd_get(dev->intr_handle);
-	if (uio_cfg_fd >= 0) {
-		close(uio_cfg_fd);
-		rte_intr_dev_fd_set(dev->intr_handle, -1);
-	}
-
-	rte_intr_fd_set(dev->intr_handle, -1);
+	rte_intr_fd_close(dev->intr_handle);
+	rte_intr_dev_fd_close(dev->intr_handle);
 	rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
 
 	/* secondary processes - just free maps */
diff --git a/drivers/bus/vmbus/linux/vmbus_uio.c b/drivers/bus/vmbus/linux/vmbus_uio.c
index fbafc5027d..c52d6738a5 100644
--- a/drivers/bus/vmbus/linux/vmbus_uio.c
+++ b/drivers/bus/vmbus/linux/vmbus_uio.c
@@ -67,16 +67,9 @@ vmbus_uio_free_resource(struct rte_vmbus_device *dev,
 {
 	rte_free(uio_res);
 
-	if (rte_intr_dev_fd_get(dev->intr_handle) >= 0) {
-		close(rte_intr_dev_fd_get(dev->intr_handle));
-		rte_intr_dev_fd_set(dev->intr_handle, -1);
-	}
-
-	if (rte_intr_fd_get(dev->intr_handle) >= 0) {
-		close(rte_intr_fd_get(dev->intr_handle));
-		rte_intr_fd_set(dev->intr_handle, -1);
-		rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
-	}
+	rte_intr_dev_fd_close(dev->intr_handle);
+	rte_intr_fd_close(dev->intr_handle);
+	rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
 }
 
 int
diff --git a/drivers/bus/vmbus/vmbus_common_uio.c b/drivers/bus/vmbus/vmbus_common_uio.c
index 7459f4ea7a..9765f5f609 100644
--- a/drivers/bus/vmbus/vmbus_common_uio.c
+++ b/drivers/bus/vmbus/vmbus_common_uio.c
@@ -254,14 +254,7 @@ vmbus_uio_unmap_resource(struct rte_vmbus_device *dev)
 	rte_free(uio_res);
 
 	/* close fd */
-	if (rte_intr_fd_get(dev->intr_handle) >= 0)
-		close(rte_intr_fd_get(dev->intr_handle));
-
-	if (rte_intr_dev_fd_get(dev->intr_handle) >= 0) {
-		close(rte_intr_dev_fd_get(dev->intr_handle));
-		rte_intr_dev_fd_set(dev->intr_handle, -1);
-	}
-
-	rte_intr_fd_set(dev->intr_handle, -1);
+	rte_intr_fd_close(dev->intr_handle);
+	rte_intr_dev_fd_close(dev->intr_handle);
 	rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
 }
diff --git a/drivers/net/mana/mana.c b/drivers/net/mana/mana.c
index 1864ba2a2b..f51598ea68 100644
--- a/drivers/net/mana/mana.c
+++ b/drivers/net/mana/mana.c
@@ -1964,6 +1964,7 @@ mana_intr_install(struct rte_eth_dev *eth_dev, struct mana_priv *priv)
 					 mana_intr_handler, priv);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to register intr callback");
+		/* fd is owned by ibverbs, only clear reference here. */
 		rte_intr_fd_set(priv->intr_handle, -1);
 		goto free_intr;
 	}
diff --git a/drivers/net/memif/memif_socket.c b/drivers/net/memif/memif_socket.c
index 649f8d0e61..94cd70fb89 100644
--- a/drivers/net/memif/memif_socket.c
+++ b/drivers/net/memif/memif_socket.c
@@ -510,8 +510,7 @@ memif_intr_unregister_handler(struct rte_intr_handle *intr_handle, void *arg)
 	struct memif_control_channel *cc = arg;
 
 	/* close control channel fd */
-	if (rte_intr_fd_get(intr_handle) >= 0)
-		close(rte_intr_fd_get(intr_handle));
+	rte_intr_fd_close(intr_handle);
 	/* clear message queue */
 	while ((elt = TAILQ_FIRST(&cc->msg_queue)) != NULL) {
 		TAILQ_REMOVE(&cc->msg_queue, elt, next);
@@ -596,10 +595,7 @@ memif_disconnect(struct rte_eth_dev *dev)
 				continue;
 		}
 
-		if (rte_intr_fd_get(mq->intr_handle) > 0) {
-			close(rte_intr_fd_get(mq->intr_handle));
-			rte_intr_fd_set(mq->intr_handle, -1);
-		}
+		rte_intr_fd_close(mq->intr_handle);
 	}
 	for (i = 0; i < pmd->cfg.num_s2c_rings; i++) {
 		if (pmd->role == MEMIF_ROLE_SERVER) {
@@ -614,10 +610,7 @@ memif_disconnect(struct rte_eth_dev *dev)
 				continue;
 		}
 
-		if (rte_intr_fd_get(mq->intr_handle) > 0) {
-			close(rte_intr_fd_get(mq->intr_handle));
-			rte_intr_fd_set(mq->intr_handle, -1);
-		}
+		rte_intr_fd_close(mq->intr_handle);
 	}
 
 	memif_free_regions(dev);
diff --git a/drivers/net/mlx4/mlx4_intr.c b/drivers/net/mlx4/mlx4_intr.c
index 01057482ec..c278dd5ecc 100644
--- a/drivers/net/mlx4/mlx4_intr.c
+++ b/drivers/net/mlx4/mlx4_intr.c
@@ -265,6 +265,7 @@ mlx4_intr_uninstall(struct mlx4_priv *priv)
 					     (void (*)(void *))
 					     mlx4_interrupt_handler,
 					     priv);
+		/* fd is owned by ibverbs, only clear reference here. */
 		if (rte_intr_fd_set(priv->intr_handle, -1))
 			return -rte_errno;
 	}
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 13114edba5..8a186c4ee6 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -1946,6 +1946,7 @@ tap_lsc_intr_handle_set(struct rte_eth_dev *dev, int set)
 	} while (true);
 
 	if (rte_intr_fd_get(pmd->intr_handle) >= 0) {
+		/* Netlink socket closed via tap_nl_final(). */
 		tap_nl_final(rte_intr_fd_get(pmd->intr_handle));
 		rte_intr_fd_set(pmd->intr_handle, -1);
 	}
diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_event.c b/drivers/vdpa/mlx5/mlx5_vdpa_event.c
index dee2ccc23d..d18cf7d7e5 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa_event.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa_event.c
@@ -487,6 +487,7 @@ mlx5_vdpa_err_event_unset(struct mlx5_vdpa_priv *priv)
 			rte_pause();
 		}
 	}
+	/* fd is owned by err_chnl, only clear reference here. */
 	rte_intr_fd_set(priv->err_intr_handle, -1);
 	if (priv->err_chnl) {
 #ifdef HAVE_IBV_DEVX_EVENT
diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c
index 093cdd08d2..9cad7e1df4 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c
@@ -96,6 +96,7 @@ mlx5_vdpa_virtq_unregister_intr_handle(struct mlx5_vdpa_virtq *virtq)
 				pthread_mutex_lock(&virtq->virtq_lock);
 			}
 		}
+		/* fd is owned by vhost, only clear reference here. */
 		(void)rte_intr_fd_set(virtq->intr_handle, -1);
 	}
 	rte_intr_instance_free(virtq->intr_handle);
diff --git a/lib/eal/common/eal_common_interrupts.c b/lib/eal/common/eal_common_interrupts.c
index 4e31a71319..8176eb089a 100644
--- a/lib/eal/common/eal_common_interrupts.c
+++ b/lib/eal/common/eal_common_interrupts.c
@@ -4,6 +4,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <rte_errno.h>
 #include <rte_interrupts.h>
@@ -219,6 +220,17 @@ int rte_intr_fd_get(const struct rte_intr_handle *intr_handle)
 	return -1;
 }
 
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_intr_fd_close, 26.11)
+void rte_intr_fd_close(struct rte_intr_handle *intr_handle)
+{
+	int fd = rte_intr_fd_get(intr_handle);
+
+	if (fd >= 0) {
+		close(fd);
+		rte_intr_fd_set(intr_handle, -1);
+	}
+}
+
 RTE_EXPORT_SYMBOL(rte_intr_type_set)
 int rte_intr_type_set(struct rte_intr_handle *intr_handle,
 	enum rte_intr_handle_type type)
@@ -265,6 +277,17 @@ int rte_intr_dev_fd_get(const struct rte_intr_handle *intr_handle)
 	return -1;
 }
 
+RTE_EXPORT_INTERNAL_SYMBOL(rte_intr_dev_fd_close)
+void rte_intr_dev_fd_close(struct rte_intr_handle *intr_handle)
+{
+	int fd = rte_intr_dev_fd_get(intr_handle);
+
+	if (fd >= 0) {
+		close(fd);
+		rte_intr_dev_fd_set(intr_handle, -1);
+	}
+}
+
 RTE_EXPORT_INTERNAL_SYMBOL(rte_intr_max_intr_set)
 int rte_intr_max_intr_set(struct rte_intr_handle *intr_handle,
 				 int max_intr)
diff --git a/lib/eal/include/rte_interrupts.h b/lib/eal/include/rte_interrupts.h
index 1cfb9d3f8e..d04c0c7b15 100644
--- a/lib/eal/include/rte_interrupts.h
+++ b/lib/eal/include/rte_interrupts.h
@@ -279,6 +279,19 @@ rte_intr_fd_set(struct rte_intr_handle *intr_handle, int fd);
 int
 rte_intr_fd_get(const struct rte_intr_handle *intr_handle);
 
+/**
+ * Close the FD of the given interrupt handle instance,
+ * and set FD to -1.
+ *
+ * If FD is not valid (< 0), nothing is done.
+ *
+ * @param intr_handle
+ *  pointer to the interrupt handle.
+ */
+__rte_experimental
+void
+rte_intr_fd_close(struct rte_intr_handle *intr_handle);
+
 /**
  * Set the type field of interrupt handle with user provided
  * interrupt type.
@@ -467,6 +480,20 @@ __rte_internal
 int
 rte_intr_dev_fd_get(const struct rte_intr_handle *intr_handle);
 
+/**
+ * @internal
+ * Close the device FD of the given interrupt handle instance,
+ * and set device FD to -1.
+ *
+ * If device FD is not valid (< 0), nothing is done.
+ *
+ * @param intr_handle
+ *  pointer to the interrupt handle.
+ */
+__rte_internal
+void
+rte_intr_dev_fd_close(struct rte_intr_handle *intr_handle);
+
 /**
  * @internal
  * Set the max intr field of interrupt handle with user
diff --git a/lib/eal/linux/eal_dev.c b/lib/eal/linux/eal_dev.c
index c78e565427..4f55dcc4e7 100644
--- a/lib/eal/linux/eal_dev.c
+++ b/lib/eal/linux/eal_dev.c
@@ -217,10 +217,7 @@ static void
 dev_delayed_unregister(void *param)
 {
 	rte_intr_callback_unregister(intr_handle, dev_uev_handler, param);
-	if (rte_intr_fd_get(intr_handle) >= 0) {
-		close(rte_intr_fd_get(intr_handle));
-		rte_intr_fd_set(intr_handle, -1);
-	}
+	rte_intr_fd_close(intr_handle);
 }
 
 static void
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [RFC 1/4] bus/pci: fix check on interrupt FD for FreeBSD
  2026-07-23 13:19 ` [RFC 1/4] bus/pci: fix check on interrupt FD for FreeBSD David Marchand
@ 2026-07-23 13:35   ` Bruce Richardson
  2026-07-23 13:54     ` David Marchand
  0 siblings, 1 reply; 10+ messages in thread
From: Bruce Richardson @ 2026-07-23 13:35 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, hkalra, Chenbo Xia, Nipun Gupta, Tetsuya Mukawa

On Thu, Jul 23, 2026 at 03:19:04PM +0200, David Marchand wrote:
> A 0 file descriptor is valid. And a negative value is not.
> Only close a positive file descriptor.
> 
> Fixes: 5a60a7ffc801 ("pci: introduce functions to alloc and free uio resource")
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
>  drivers/bus/pci/bsd/pci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
> index c6df31d486..bbe08605af 100644
> --- a/drivers/bus/pci/bsd/pci.c
> +++ b/drivers/bus/pci/bsd/pci.c
> @@ -93,7 +93,7 @@ pci_uio_free_resource(struct rte_pci_device *dev,
>  {
>  	rte_free(uio_res);
>  
> -	if (rte_intr_fd_get(dev->intr_handle)) {
> +	if (rte_intr_fd_get(dev->intr_handle) >= 0) {
>  		close(rte_intr_fd_get(dev->intr_handle));
>  		rte_intr_fd_set(dev->intr_handle, -1);
>  		rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);

Unlikely that we actually have fd as 0 for this call, but change is
technically correct.

Acked-by: Bruce Richardson <bruce.richardson@intel.com>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC 1/4] bus/pci: fix check on interrupt FD for FreeBSD
  2026-07-23 13:35   ` Bruce Richardson
@ 2026-07-23 13:54     ` David Marchand
  2026-07-23 14:31       ` Marat Khalili
  0 siblings, 1 reply; 10+ messages in thread
From: David Marchand @ 2026-07-23 13:54 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev, hkalra, Chenbo Xia, Nipun Gupta, Tetsuya Mukawa

On Thu, 23 Jul 2026 at 15:35, Bruce Richardson
<bruce.richardson@intel.com> wrote:
>
> On Thu, Jul 23, 2026 at 03:19:04PM +0200, David Marchand wrote:
> > A 0 file descriptor is valid. And a negative value is not.
> > Only close a positive file descriptor.
> >
> > Fixes: 5a60a7ffc801 ("pci: introduce functions to alloc and free uio resource")
> >
> > Signed-off-by: David Marchand <david.marchand@redhat.com>
> > ---
> >  drivers/bus/pci/bsd/pci.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
> > index c6df31d486..bbe08605af 100644
> > --- a/drivers/bus/pci/bsd/pci.c
> > +++ b/drivers/bus/pci/bsd/pci.c
> > @@ -93,7 +93,7 @@ pci_uio_free_resource(struct rte_pci_device *dev,
> >  {
> >       rte_free(uio_res);
> >
> > -     if (rte_intr_fd_get(dev->intr_handle)) {
> > +     if (rte_intr_fd_get(dev->intr_handle) >= 0) {
> >               close(rte_intr_fd_get(dev->intr_handle));
> >               rte_intr_fd_set(dev->intr_handle, -1);
> >               rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
>
> Unlikely that we actually have fd as 0 for this call, but change is
> technically correct.

Yes, this is why I did not Cc: stable.
Thanks.


-- 
David Marchand


^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [RFC 1/4] bus/pci: fix check on interrupt FD for FreeBSD
  2026-07-23 13:54     ` David Marchand
@ 2026-07-23 14:31       ` Marat Khalili
  2026-07-23 14:38         ` Bruce Richardson
  0 siblings, 1 reply; 10+ messages in thread
From: Marat Khalili @ 2026-07-23 14:31 UTC (permalink / raw)
  To: David Marchand, Bruce Richardson
  Cc: dev@dpdk.org, hkalra@marvell.com, Chenbo Xia, Nipun Gupta,
	Tetsuya Mukawa

> > > --- a/drivers/bus/pci/bsd/pci.c
> > > +++ b/drivers/bus/pci/bsd/pci.c
> > > @@ -93,7 +93,7 @@ pci_uio_free_resource(struct rte_pci_device *dev,
> > >  {
> > >       rte_free(uio_res);
> > >
> > > -     if (rte_intr_fd_get(dev->intr_handle)) {
> > > +     if (rte_intr_fd_get(dev->intr_handle) >= 0) {
> > >               close(rte_intr_fd_get(dev->intr_handle));
> > >               rte_intr_fd_set(dev->intr_handle, -1);
> > >               rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
> >
> > Unlikely that we actually have fd as 0 for this call, but change is
> > technically correct.
> 
> Yes, this is why I did not Cc: stable.
> Thanks.

Just trying to understand what's going on here out of curiosity.

Zero fd is valid and negative (typically -1) indicating error is a standard
logic in Linux, but here intr_handle->fd is zero-filled by
rte_intr_instance_alloc, so its initial state is 0 instead of -1. Do we have
reasons to believe that something always sets fd to non-zero value before
pci_uio_free_resource is called? Should rte_intr_instance_alloc set it to -1?

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFC 1/4] bus/pci: fix check on interrupt FD for FreeBSD
  2026-07-23 14:31       ` Marat Khalili
@ 2026-07-23 14:38         ` Bruce Richardson
  2026-07-23 14:46           ` Marat Khalili
  0 siblings, 1 reply; 10+ messages in thread
From: Bruce Richardson @ 2026-07-23 14:38 UTC (permalink / raw)
  To: Marat Khalili
  Cc: David Marchand, dev@dpdk.org, hkalra@marvell.com, Chenbo Xia,
	Nipun Gupta, Tetsuya Mukawa

On Thu, Jul 23, 2026 at 02:31:23PM +0000, Marat Khalili wrote:
> > > > --- a/drivers/bus/pci/bsd/pci.c
> > > > +++ b/drivers/bus/pci/bsd/pci.c
> > > > @@ -93,7 +93,7 @@ pci_uio_free_resource(struct rte_pci_device *dev,
> > > >  {
> > > >       rte_free(uio_res);
> > > >
> > > > -     if (rte_intr_fd_get(dev->intr_handle)) {
> > > > +     if (rte_intr_fd_get(dev->intr_handle) >= 0) {
> > > >               close(rte_intr_fd_get(dev->intr_handle));
> > > >               rte_intr_fd_set(dev->intr_handle, -1);
> > > >               rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
> > >
> > > Unlikely that we actually have fd as 0 for this call, but change is
> > > technically correct.
> > 
> > Yes, this is why I did not Cc: stable.
> > Thanks.
> 
> Just trying to understand what's going on here out of curiosity.
> 
> Zero fd is valid and negative (typically -1) indicating error is a standard
> logic in Linux, but here intr_handle->fd is zero-filled by
> rte_intr_instance_alloc, so its initial state is 0 instead of -1. Do we have
> reasons to believe that something always sets fd to non-zero value before
> pci_uio_free_resource is called? Should rte_intr_instance_alloc set it to -1?

I believe that's what patch 3 of this set does, initializing each to -1.
Perhaps that patch should appear before this one in the set, to avoid the
possibility of temporary breakage.

/Bruce

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [RFC 1/4] bus/pci: fix check on interrupt FD for FreeBSD
  2026-07-23 14:38         ` Bruce Richardson
@ 2026-07-23 14:46           ` Marat Khalili
  0 siblings, 0 replies; 10+ messages in thread
From: Marat Khalili @ 2026-07-23 14:46 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: David Marchand, dev@dpdk.org, hkalra@marvell.com, Chenbo Xia,
	Nipun Gupta, Tetsuya Mukawa

> -----Original Message-----
> From: Bruce Richardson <bruce.richardson@intel.com>
> Sent: Thursday 23 July 2026 15:39
> To: Marat Khalili <marat.khalili@huawei.com>
> Cc: David Marchand <david.marchand@redhat.com>; dev@dpdk.org; hkalra@marvell.com; Chenbo Xia
> <chenbox@nvidia.com>; Nipun Gupta <nipun.gupta@amd.com>; Tetsuya Mukawa <mtetsuyah@gmail.com>
> Subject: Re: [RFC 1/4] bus/pci: fix check on interrupt FD for FreeBSD
> 
> On Thu, Jul 23, 2026 at 02:31:23PM +0000, Marat Khalili wrote:
> > > > > --- a/drivers/bus/pci/bsd/pci.c
> > > > > +++ b/drivers/bus/pci/bsd/pci.c
> > > > > @@ -93,7 +93,7 @@ pci_uio_free_resource(struct rte_pci_device *dev,
> > > > >  {
> > > > >       rte_free(uio_res);
> > > > >
> > > > > -     if (rte_intr_fd_get(dev->intr_handle)) {
> > > > > +     if (rte_intr_fd_get(dev->intr_handle) >= 0) {
> > > > >               close(rte_intr_fd_get(dev->intr_handle));
> > > > >               rte_intr_fd_set(dev->intr_handle, -1);
> > > > >               rte_intr_type_set(dev->intr_handle, RTE_INTR_HANDLE_UNKNOWN);
> > > >
> > > > Unlikely that we actually have fd as 0 for this call, but change is
> > > > technically correct.
> > >
> > > Yes, this is why I did not Cc: stable.
> > > Thanks.
> >
> > Just trying to understand what's going on here out of curiosity.
> >
> > Zero fd is valid and negative (typically -1) indicating error is a standard
> > logic in Linux, but here intr_handle->fd is zero-filled by
> > rte_intr_instance_alloc, so its initial state is 0 instead of -1. Do we have
> > reasons to believe that something always sets fd to non-zero value before
> > pci_uio_free_resource is called? Should rte_intr_instance_alloc set it to -1?
> 
> I believe that's what patch 3 of this set does, initializing each to -1.
> Perhaps that patch should appear before this one in the set, to avoid the
> possibility of temporary breakage.

I see it now, question withdrawn.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-07-23 14:46 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-23 13:19 [RFC 0/4] Interrupts API update David Marchand
2026-07-23 13:19 ` [RFC 1/4] bus/pci: fix check on interrupt FD for FreeBSD David Marchand
2026-07-23 13:35   ` Bruce Richardson
2026-07-23 13:54     ` David Marchand
2026-07-23 14:31       ` Marat Khalili
2026-07-23 14:38         ` Bruce Richardson
2026-07-23 14:46           ` Marat Khalili
2026-07-23 13:19 ` [RFC 2/4] vdpa/mlx5: fix check on err interrupt FD David Marchand
2026-07-23 13:19 ` [RFC 3/4] interrupts: mark file descriptors invalid on allocation David Marchand
2026-07-23 13:19 ` [RFC 4/4] interrupts: close interrupt FDs David Marchand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox