diff --git a/CHANGELOG.md b/CHANGELOG.md index b2870d05e..7721c7f81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,9 @@ they did not account for PCI devices being inserted or removed while the caller returned from these APIs. Existing users of these APIs should switch to spdk_pci_for_each_device instead. +Added 3 experimental APIs to handle PCI device interrupts (`spdk_pci_device_enable_interrupt`, +`spdk_pci_device_disable_interrupt`, `spdk_pci_device_get_interrupt_efd`). + ### nvmf Added a 'subsystem' parameter to spdk_nvmf_transport_stop_listen_async. When not NULL, diff --git a/include/spdk/env.h b/include/spdk/env.h index 1f627efe8..e84947f78 100644 --- a/include/spdk/env.h +++ b/include/spdk/env.h @@ -823,6 +823,34 @@ int spdk_pci_device_map_bar(struct spdk_pci_device *dev, uint32_t bar, int spdk_pci_device_unmap_bar(struct spdk_pci_device *dev, uint32_t bar, void *mapped_addr); +/** + * Enable PCI device interrupts. (Experimental) + * + * \param dev PCI device. + * + * \return 0 on success, negative value on error. + */ +int spdk_pci_device_enable_interrupt(struct spdk_pci_device *dev); + +/** + * Disable PCI device interrupts. (Experimental) + * + * \param dev PCI device. + * + * \return 0 on success, negative value on error. + */ +int spdk_pci_device_disable_interrupt(struct spdk_pci_device *dev); + +/** + * Get an event file descriptor assosiated with a PCI device interrupt. + * (Experimental) + * + * \param dev PCI device. + * + * \return Event file descriptor on success, negative value on error. + */ +int spdk_pci_device_get_interrupt_efd(struct spdk_pci_device *dev); + /** * Get the domain of a PCI device. * diff --git a/lib/env_dpdk/pci.c b/lib/env_dpdk/pci.c index 5d9c48a55..06f67d587 100644 --- a/lib/env_dpdk/pci.c +++ b/lib/env_dpdk/pci.c @@ -787,6 +787,39 @@ spdk_pci_device_unmap_bar(struct spdk_pci_device *dev, uint32_t bar, void *addr) return dev->unmap_bar(dev, bar, addr); } +int +spdk_pci_device_enable_interrupt(struct spdk_pci_device *dev) +{ + struct rte_pci_device *rte_dev = dev->dev_handle; +#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) + return rte_intr_enable(&rte_dev->intr_handle); +#else + return rte_intr_enable(rte_dev->intr_handle); +#endif +} + +int +spdk_pci_device_disable_interrupt(struct spdk_pci_device *dev) +{ + struct rte_pci_device *rte_dev = dev->dev_handle; +#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) + return rte_intr_disable(&rte_dev->intr_handle); +#else + return rte_intr_disable(rte_dev->intr_handle); +#endif +} + +int +spdk_pci_device_get_interrupt_efd(struct spdk_pci_device *dev) +{ + struct rte_pci_device *rte_dev = dev->dev_handle; +#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) + return rte_dev->intr_handle.fd; +#else + return rte_intr_fd_get(rte_dev->intr_handle); +#endif +} + uint32_t spdk_pci_device_get_domain(struct spdk_pci_device *dev) { diff --git a/lib/env_dpdk/spdk_env_dpdk.map b/lib/env_dpdk/spdk_env_dpdk.map index 1e7679922..d6be0394b 100644 --- a/lib/env_dpdk/spdk_env_dpdk.map +++ b/lib/env_dpdk/spdk_env_dpdk.map @@ -62,6 +62,9 @@ spdk_pci_for_each_device; spdk_pci_device_map_bar; spdk_pci_device_unmap_bar; + spdk_pci_device_enable_interrupt; + spdk_pci_device_disable_interrupt; + spdk_pci_device_get_interrupt_efd; spdk_pci_device_get_domain; spdk_pci_device_get_bus; spdk_pci_device_get_dev;