interrupts: extend event list
authorHarman Kalra <hkalra@marvell.com>
Fri, 22 Oct 2021 20:49:32 +0000 (02:19 +0530)
committerDavid Marchand <david.marchand@redhat.com>
Mon, 25 Oct 2021 19:20:12 +0000 (21:20 +0200)
Dynamically allocating the efds and elist array of intr_handle
structure, based on size provided by user. Eg size can be
MSIX interrupts supported by a PCI device.

Signed-off-by: Harman Kalra <hkalra@marvell.com>
Signed-off-by: David Marchand <david.marchand@redhat.com>
Acked-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Tested-by: Raslan Darawsheh <rasland@nvidia.com>
drivers/bus/pci/linux/pci_vfio.c
drivers/common/cnxk/roc_platform.h
lib/eal/common/eal_common_interrupts.c
lib/eal/common/eal_interrupts.h
lib/eal/include/rte_interrupts.h
lib/eal/version.map

index 7b2f829..f622e7f 100644 (file)
@@ -266,6 +266,12 @@ pci_vfio_setup_interrupts(struct rte_pci_device *dev, int vfio_dev_fd)
                        return -1;
                }
 
+               /* Reallocate the efds and elist fields of intr_handle based
+                * on PCI device MSIX size.
+                */
+               if (rte_intr_event_list_update(dev->intr_handle, irq.count))
+                       return -1;
+
                /* if this vector cannot be used with eventfd, fail if we explicitly
                 * specified interrupt type, otherwise continue */
                if ((irq.flags & VFIO_IRQ_INFO_EVENTFD) == 0) {
index 60227b7..5da23fe 100644 (file)
 #define plt_intr_instance_alloc                rte_intr_instance_alloc
 #define plt_intr_instance_dup          rte_intr_instance_dup
 #define plt_intr_instance_free         rte_intr_instance_free
+#define plt_intr_event_list_update     rte_intr_event_list_update
 #define plt_intr_max_intr_get          rte_intr_max_intr_get
 #define plt_intr_max_intr_set          rte_intr_max_intr_set
 #define plt_intr_nb_efd_get            rte_intr_nb_efd_get
index 3f3cfc1..97b64fe 100644 (file)
@@ -53,10 +53,46 @@ struct rte_intr_handle *rte_intr_instance_alloc(uint32_t flags)
                return NULL;
        }
 
+       if (uses_rte_memory) {
+               intr_handle->efds = rte_zmalloc(NULL,
+                       RTE_MAX_RXTX_INTR_VEC_ID * sizeof(int), 0);
+       } else {
+               intr_handle->efds = calloc(RTE_MAX_RXTX_INTR_VEC_ID,
+                       sizeof(int));
+       }
+       if (intr_handle->efds == NULL) {
+               RTE_LOG(ERR, EAL, "Fail to allocate event fd list\n");
+               rte_errno = ENOMEM;
+               goto fail;
+       }
+
+       if (uses_rte_memory) {
+               intr_handle->elist = rte_zmalloc(NULL,
+                       RTE_MAX_RXTX_INTR_VEC_ID * sizeof(struct rte_epoll_event),
+                       0);
+       } else {
+               intr_handle->elist = calloc(RTE_MAX_RXTX_INTR_VEC_ID,
+                       sizeof(struct rte_epoll_event));
+       }
+       if (intr_handle->elist == NULL) {
+               RTE_LOG(ERR, EAL, "fail to allocate event fd list\n");
+               rte_errno = ENOMEM;
+               goto fail;
+       }
+
        intr_handle->alloc_flags = flags;
        intr_handle->nb_intr = RTE_MAX_RXTX_INTR_VEC_ID;
 
        return intr_handle;
+fail:
+       if (uses_rte_memory) {
+               rte_free(intr_handle->efds);
+               rte_free(intr_handle);
+       } else {
+               free(intr_handle->efds);
+               free(intr_handle);
+       }
+       return NULL;
 }
 
 struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src)
@@ -84,14 +120,69 @@ struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src)
        return intr_handle;
 }
 
+int rte_intr_event_list_update(struct rte_intr_handle *intr_handle, int size)
+{
+       struct rte_epoll_event *tmp_elist;
+       bool uses_rte_memory;
+       int *tmp_efds;
+
+       CHECK_VALID_INTR_HANDLE(intr_handle);
+
+       if (size == 0) {
+               RTE_LOG(DEBUG, EAL, "Size can't be zero\n");
+               rte_errno = EINVAL;
+               goto fail;
+       }
+
+       uses_rte_memory =
+               RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags);
+       if (uses_rte_memory) {
+               tmp_efds = rte_realloc(intr_handle->efds, size * sizeof(int),
+                       0);
+       } else {
+               tmp_efds = realloc(intr_handle->efds, size * sizeof(int));
+       }
+       if (tmp_efds == NULL) {
+               RTE_LOG(ERR, EAL, "Failed to realloc the efds list\n");
+               rte_errno = ENOMEM;
+               goto fail;
+       }
+       intr_handle->efds = tmp_efds;
+
+       if (uses_rte_memory) {
+               tmp_elist = rte_realloc(intr_handle->elist,
+                       size * sizeof(struct rte_epoll_event), 0);
+       } else {
+               tmp_elist = realloc(intr_handle->elist,
+                       size * sizeof(struct rte_epoll_event));
+       }
+       if (tmp_elist == NULL) {
+               RTE_LOG(ERR, EAL, "Failed to realloc the event list\n");
+               rte_errno = ENOMEM;
+               goto fail;
+       }
+       intr_handle->elist = tmp_elist;
+
+       intr_handle->nb_intr = size;
+
+       return 0;
+fail:
+       return -rte_errno;
+}
+
 void rte_intr_instance_free(struct rte_intr_handle *intr_handle)
 {
        if (intr_handle == NULL)
                return;
-       if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
+       if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags)) {
+               rte_free(intr_handle->efds);
+               rte_free(intr_handle->elist);
                rte_free(intr_handle);
-       else
+       } else {
+               free(intr_handle->efds);
+               free(intr_handle->elist);
                free(intr_handle);
+       }
 }
 
 int rte_intr_fd_set(struct rte_intr_handle *intr_handle, int fd)
index 1a4e557..482781b 100644 (file)
@@ -21,9 +21,8 @@ struct rte_intr_handle {
        uint8_t efd_counter_size;      /**< size of efd counter, used for vdev */
        uint16_t nb_intr;
                /**< Max vector count, default RTE_MAX_RXTX_INTR_VEC_ID */
-       int efds[RTE_MAX_RXTX_INTR_VEC_ID];  /**< intr vectors/efds mapping */
-       struct rte_epoll_event elist[RTE_MAX_RXTX_INTR_VEC_ID];
-                                      /**< intr vector epoll event */
+       int *efds;  /**< intr vectors/efds mapping */
+       struct rte_epoll_event *elist; /**< intr vector epoll event */
        uint16_t vec_list_size;
        int *intr_vec;                 /**< intr vector number array */
 };
index bcf6aba..edbf0fa 100644 (file)
@@ -755,6 +755,28 @@ __rte_internal
 void
 rte_intr_vec_list_free(struct rte_intr_handle *intr_handle);
 
+/**
+ * @internal
+ * Reallocates the size efds and elist array based on size provided by user.
+ * By default efds and elist array are allocated with default size
+ * RTE_MAX_RXTX_INTR_VEC_ID on interrupt handle array creation. Later on device
+ * probe, device may have capability of more interrupts than
+ * RTE_MAX_RXTX_INTR_VEC_ID. Using this API, PMDs can reallocate the arrays as
+ * per the max interrupts capability of device.
+ *
+ * @param intr_handle
+ *  pointer to the interrupt handle.
+ * @param size
+ *  efds and elist array size.
+ *
+ * @return
+ *  - On success, zero
+ *  - On failure, a negative value and rte_errno is set.
+ */
+__rte_internal
+int
+rte_intr_event_list_update(struct rte_intr_handle *intr_handle, int size);
+
 /**
  * @internal
  * This API returns the Windows handle of the given interrupt instance.
index 569e9d9..9d43655 100644 (file)
@@ -439,6 +439,7 @@ INTERNAL {
        rte_intr_efds_index_set;
        rte_intr_elist_index_get;
        rte_intr_elist_index_set;
+       rte_intr_event_list_update;
        rte_intr_free_epoll_fd;
        rte_intr_instance_dup;
        rte_intr_instance_windows_handle_get;