[dpdk-dev] [PATCH v7 03/14] eal/pci, ethdev: Remove assumption that port will not be detached

2015-02-09 Thread Tetsuya Mukawa
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

2015-02-09 Thread Iremonger, Bernard
> -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

2015-02-09 Thread Qiu, Michael
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