[dpdk-dev] [PATCH v7 03/14] eal/pci, ethdev: Remove assumption that port will not be detached
To remove assumption, do like followings. This patch adds "RTE_PCI_DRV_DETACHABLE" to drv_flags of rte_pci_driver structure. The flags indicate the driver can detach devices at runtime. Also, remove assumption that port will not be detached. To remove the assumption. - Add 'attached' member to rte_eth_dev structure. This member is used for indicating the port is attached, or not. - Add rte_eth_dev_allocate_new_port(). This function is used for allocating new port. v5: - Change parameters of rte_eth_dev_validate_port() to cleanup code. v4: - Use braces with 'for' loop. - Fix indent of 'if' statement. Signed-off-by: Tetsuya Mukawa --- lib/librte_eal/common/include/rte_pci.h | 2 + lib/librte_ether/rte_ethdev.c | 454 +--- lib/librte_ether/rte_ethdev.h | 5 + 3 files changed, 186 insertions(+), 275 deletions(-) diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h index 7b48b55..7f2d699 100644 --- a/lib/librte_eal/common/include/rte_pci.h +++ b/lib/librte_eal/common/include/rte_pci.h @@ -207,6 +207,8 @@ struct rte_pci_driver { #define RTE_PCI_DRV_FORCE_UNBIND 0x0004 /** Device driver supports link state interrupt */ #define RTE_PCI_DRV_INTR_LSC 0x0008 +/** Device driver supports detaching capability */ +#define RTE_PCI_DRV_DETACHABLE 0x0010 /**< Internal use only - Macro used by pci addr parsing functions **/ #define GET_PCIADDR_FIELD(in, fd, lim, dlm) \ diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index ea3a1fb..d70854f 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -175,6 +175,16 @@ enum { STAT_QMAP_RX }; +enum { + DEV_INVALID = 0, + DEV_VALID, +}; + +enum { + DEV_DISCONNECTED = 0, + DEV_CONNECTED +}; + static inline void rte_eth_dev_data_alloc(void) { @@ -201,19 +211,34 @@ rte_eth_dev_allocated(const char *name) { unsigned i; - for (i = 0; i < nb_ports; i++) { - if (strcmp(rte_eth_devices[i].data->name, name) == 0) + for (i = 0; i < RTE_MAX_ETHPORTS; i++) { + if ((rte_eth_devices[i].attached == DEV_CONNECTED) && + strcmp(rte_eth_devices[i].data->name, name) == 0) return _eth_devices[i]; } return NULL; } +static uint8_t +rte_eth_dev_allocate_new_port(void) +{ + unsigned i; + + for (i = 0; i < RTE_MAX_ETHPORTS; i++) { + if (rte_eth_devices[i].attached == DEV_DISCONNECTED) + return i; + } + return RTE_MAX_ETHPORTS; +} + struct rte_eth_dev * rte_eth_dev_allocate(const char *name) { + uint8_t port_id; struct rte_eth_dev *eth_dev; - if (nb_ports == RTE_MAX_ETHPORTS) { + port_id = rte_eth_dev_allocate_new_port(); + if (port_id == RTE_MAX_ETHPORTS) { PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports\n"); return NULL; } @@ -226,10 +251,12 @@ rte_eth_dev_allocate(const char *name) return NULL; } - eth_dev = _eth_devices[nb_ports]; - eth_dev->data = _eth_dev_data[nb_ports]; + eth_dev = _eth_devices[port_id]; + eth_dev->data = _eth_dev_data[port_id]; snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name); - eth_dev->data->port_id = nb_ports++; + eth_dev->data->port_id = port_id; + eth_dev->attached = DEV_CONNECTED; + nb_ports++; return eth_dev; } @@ -283,6 +310,7 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv, (unsigned) pci_dev->id.device_id); if (rte_eal_process_type() == RTE_PROC_PRIMARY) rte_free(eth_dev->data->dev_private); + eth_dev->attached = DEV_DISCONNECTED; nb_ports--; return diag; } @@ -308,10 +336,28 @@ rte_eth_driver_register(struct eth_driver *eth_drv) rte_eal_pci_register(_drv->pci_drv); } +enum { + NONE_TRACE = 0, + TRACE +}; + +static int +rte_eth_dev_validate_port(uint8_t port_id, int trace) +{ + if (port_id >= RTE_MAX_ETHPORTS || + rte_eth_devices[port_id].attached != DEV_CONNECTED) { + if (trace) { + PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id); + } + return DEV_INVALID; + } else + return DEV_VALID; +} + int rte_eth_dev_socket_id(uint8_t port_id) { - if (port_id >= nb_ports) + if (rte_eth_dev_validate_port(port_id, NONE_TRACE) == DEV_INVALID) return -1; return rte_eth_devices[port_id].pci_dev->numa_node; } @@ -369,10 +415,8 @@ rte_eth_dev_rx_queue_start(uint8_t port_id, uint16_t rx_queue_id) * in a multi-process setup*/ PROC_PRIMARY_OR_ERR_RET(-E_RTE_SECONDARY); - if (port_id >= nb_ports) { - PMD_DEBUG_TRACE("Invalid port_id=%d\n",
[dpdk-dev] [PATCH v7 03/14] eal/pci, ethdev: Remove assumption that port will not be detached
> -Original Message- > From: Tetsuya Mukawa [mailto:mukawa at igel.co.jp] > Sent: Monday, February 9, 2015 8:30 AM > To: dev at dpdk.org > Cc: Iremonger, Bernard; Qiu, Michael; Tetsuya Mukawa > Subject: [PATCH v7 03/14] eal/pci,ethdev: Remove assumption that port will > not be detached > > To remove assumption, do like followings. > > This patch adds "RTE_PCI_DRV_DETACHABLE" to drv_flags of rte_pci_driver > structure. The flags > indicate the driver can detach devices at runtime. > Also, remove assumption that port will not be detached. > > To remove the assumption. > - Add 'attached' member to rte_eth_dev structure. > This member is used for indicating the port is attached, or not. > - Add rte_eth_dev_allocate_new_port(). > This function is used for allocating new port. > > v5: > - Change parameters of rte_eth_dev_validate_port() to cleanup code. > v4: > - Use braces with 'for' loop. > - Fix indent of 'if' statement. > > Signed-off-by: Tetsuya Mukawa > --- > lib/librte_eal/common/include/rte_pci.h | 2 + > lib/librte_ether/rte_ethdev.c | 454 > +--- > lib/librte_ether/rte_ethdev.h | 5 + > 3 files changed, 186 insertions(+), 275 deletions(-) > > diff --git a/lib/librte_eal/common/include/rte_pci.h > b/lib/librte_eal/common/include/rte_pci.h > index 7b48b55..7f2d699 100644 > --- a/lib/librte_eal/common/include/rte_pci.h > +++ b/lib/librte_eal/common/include/rte_pci.h > @@ -207,6 +207,8 @@ struct rte_pci_driver { #define RTE_PCI_DRV_FORCE_UNBIND > 0x0004 > /** Device driver supports link state interrupt */ > #define RTE_PCI_DRV_INTR_LSC 0x0008 > +/** Device driver supports detaching capability */ > +#define RTE_PCI_DRV_DETACHABLE 0x0010 > > /**< Internal use only - Macro used by pci addr parsing functions **/ > #define GET_PCIADDR_FIELD(in, fd, lim, dlm) \ > diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c > index ea3a1fb..d70854f > 100644 > --- a/lib/librte_ether/rte_ethdev.c > +++ b/lib/librte_ether/rte_ethdev.c > @@ -175,6 +175,16 @@ enum { > STAT_QMAP_RX > }; > > +enum { > + DEV_INVALID = 0, > + DEV_VALID, > +}; > + > +enum { > + DEV_DISCONNECTED = 0, > + DEV_CONNECTED > +}; > + > static inline void > rte_eth_dev_data_alloc(void) > { > @@ -201,19 +211,34 @@ rte_eth_dev_allocated(const char *name) { > unsigned i; > > - for (i = 0; i < nb_ports; i++) { > - if (strcmp(rte_eth_devices[i].data->name, name) == 0) > + for (i = 0; i < RTE_MAX_ETHPORTS; i++) { > + if ((rte_eth_devices[i].attached == DEV_CONNECTED) && > + strcmp(rte_eth_devices[i].data->name, name) == 0) > return _eth_devices[i]; > } > return NULL; > } > > +static uint8_t > +rte_eth_dev_allocate_new_port(void) > +{ > + unsigned i; > + > + for (i = 0; i < RTE_MAX_ETHPORTS; i++) { > + if (rte_eth_devices[i].attached == DEV_DISCONNECTED) > + return i; > + } > + return RTE_MAX_ETHPORTS; > +} > + > struct rte_eth_dev * > rte_eth_dev_allocate(const char *name) > { > + uint8_t port_id; > struct rte_eth_dev *eth_dev; > > - if (nb_ports == RTE_MAX_ETHPORTS) { > + port_id = rte_eth_dev_allocate_new_port(); > + if (port_id == RTE_MAX_ETHPORTS) { > PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports\n"); > return NULL; > } > @@ -226,10 +251,12 @@ rte_eth_dev_allocate(const char *name) > return NULL; > } > > - eth_dev = _eth_devices[nb_ports]; > - eth_dev->data = _eth_dev_data[nb_ports]; > + eth_dev = _eth_devices[port_id]; > + eth_dev->data = _eth_dev_data[port_id]; > snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name); > - eth_dev->data->port_id = nb_ports++; > + eth_dev->data->port_id = port_id; > + eth_dev->attached = DEV_CONNECTED; > + nb_ports++; > return eth_dev; > } > > @@ -283,6 +310,7 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv, > (unsigned) pci_dev->id.device_id); > if (rte_eal_process_type() == RTE_PROC_PRIMARY) > rte_free(eth_dev->data->dev_private); > + eth_dev->attached = DEV_DISCONNECTED; > nb_ports--; > return diag; > } > @@ -308,10 +336,28 @@ rte_eth_driver_register(struct eth_driver *eth_drv) > rte_eal_pci_register(_drv->pci_drv); > } > > +enum { > + NONE_TRACE = 0, Hi Tetsuya, NO_TRACE would be clearer that NONE_TRACE Regards, Bernard. > + TRACE > +}; > + > +static int > +rte_eth_dev_validate_port(uint8_t port_id, int trace) { > + if (port_id >= RTE_MAX_ETHPORTS || > + rte_eth_devices[port_id].attached != DEV_CONNECTED) { > + if (trace) { > + PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id); > + } > + return DEV_INVALID; > + } else > +
[dpdk-dev] [PATCH v7 03/14] eal/pci, ethdev: Remove assumption that port will not be detached
On 2/9/2015 4:31 PM, Tetsuya Mukawa wrote: > To remove assumption, do like followings. [...] > struct rte_eth_dev_sriov { > @@ -1604,6 +1605,10 @@ extern struct rte_eth_dev rte_eth_devices[]; > * initialized by the [matching] Ethernet driver during the PCI probing > phase. > * All devices whose port identifier is in the range > * [0, rte_eth_dev_count() - 1] can be operated on by network applications. > + * immediately after invoking rte_eal_init(). > + * If the application unplugs a port using hotplug function, The enabled port > + * numbers may be noncontiguous. In the case, the applications need to manage > + * enabled port by themselves. > * > * @return > * - The total number of usable Ethernet devices. Acked-by: Michael Qiu