net/mlx5: refactor multi-process communication
1. The shared data communication between the primary and the secondary processes is implemented using Linux API. Move the Linux API code under linux directory (file linux/mlx5_os.c). 2. File net/mlx5/mlx5_mp.c handles requests to the primary and secondary processes (e.g. start_rxtx, stop_rxtx). It is Linux based so it is moved under linux (new file linux/mlx5_mp_os.c). Signed-off-by: Ophir Munk <ophirmu@mellanox.com> Acked-by: Matan Azrad <matan@mellanox.com>
This commit is contained in:
parent
ef9ee13f6e
commit
2e86c4e5c7
@ -30,12 +30,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_meter.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_dv.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_verbs.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_mp.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_utils.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += linux/mlx5_socket.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += linux/mlx5_os.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += linux/mlx5_ethdev_os.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += linux/mlx5_verbs.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += linux/mlx5_mp_os.c
|
||||
|
||||
# Basic CFLAGS.
|
||||
CFLAGS += -O3
|
||||
|
@ -7,5 +7,6 @@ sources += files(
|
||||
'mlx5_os.c',
|
||||
'mlx5_ethdev_os.c',
|
||||
'mlx5_verbs.c',
|
||||
'mlx5_mp_os.c',
|
||||
)
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "mlx5_utils.h"
|
||||
|
||||
int
|
||||
mlx5_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
|
||||
mlx5_mp_os_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
|
||||
{
|
||||
struct rte_mp_msg mp_res;
|
||||
struct mlx5_mp_param *res = (struct mlx5_mp_param *)mp_res.param;
|
||||
@ -84,7 +84,7 @@ mlx5_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
|
||||
* 0 on success, a negative errno value otherwise and rte_errno is set.
|
||||
*/
|
||||
int
|
||||
mlx5_mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
|
||||
mlx5_mp_os_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
|
||||
{
|
||||
struct rte_mp_msg mp_res;
|
||||
struct mlx5_mp_param *res = (struct mlx5_mp_param *)mp_res.param;
|
||||
@ -193,7 +193,7 @@ mp_req_on_rxtx(struct rte_eth_dev *dev, enum mlx5_mp_req_type type)
|
||||
* Pointer to Ethernet structure.
|
||||
*/
|
||||
void
|
||||
mlx5_mp_req_start_rxtx(struct rte_eth_dev *dev)
|
||||
mlx5_mp_os_req_start_rxtx(struct rte_eth_dev *dev)
|
||||
{
|
||||
mp_req_on_rxtx(dev, MLX5_MP_REQ_START_RXTX);
|
||||
}
|
||||
@ -206,7 +206,7 @@ mlx5_mp_req_start_rxtx(struct rte_eth_dev *dev)
|
||||
* Pointer to Ethernet structure.
|
||||
*/
|
||||
void
|
||||
mlx5_mp_req_stop_rxtx(struct rte_eth_dev *dev)
|
||||
mlx5_mp_os_req_stop_rxtx(struct rte_eth_dev *dev)
|
||||
{
|
||||
mp_req_on_rxtx(dev, MLX5_MP_REQ_STOP_RXTX);
|
||||
}
|
@ -67,6 +67,14 @@
|
||||
#define MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP (1 << 4)
|
||||
#endif
|
||||
|
||||
static const char *MZ_MLX5_PMD_SHARED_DATA = "mlx5_pmd_shared_data";
|
||||
|
||||
/* Spinlock for mlx5_shared_data allocation. */
|
||||
static rte_spinlock_t mlx5_shared_data_lock = RTE_SPINLOCK_INITIALIZER;
|
||||
|
||||
/* Process local data for secondary processes. */
|
||||
static struct mlx5_local_data mlx5_local_data;
|
||||
|
||||
/**
|
||||
* Get mlx5 device attributes. The glue function query_device_ex() is called
|
||||
* with out parameter of type 'struct ibv_device_attr_ex *'. Then fill in mlx5
|
||||
@ -356,6 +364,109 @@ mlx5_os_free_shared_dr(struct mlx5_priv *priv)
|
||||
mlx5_free_table_hash_list(priv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize shared data between primary and secondary process.
|
||||
*
|
||||
* A memzone is reserved by primary process and secondary processes attach to
|
||||
* the memzone.
|
||||
*
|
||||
* @return
|
||||
* 0 on success, a negative errno value otherwise and rte_errno is set.
|
||||
*/
|
||||
static int
|
||||
mlx5_init_shared_data(void)
|
||||
{
|
||||
const struct rte_memzone *mz;
|
||||
int ret = 0;
|
||||
|
||||
rte_spinlock_lock(&mlx5_shared_data_lock);
|
||||
if (mlx5_shared_data == NULL) {
|
||||
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
|
||||
/* Allocate shared memory. */
|
||||
mz = rte_memzone_reserve(MZ_MLX5_PMD_SHARED_DATA,
|
||||
sizeof(*mlx5_shared_data),
|
||||
SOCKET_ID_ANY, 0);
|
||||
if (mz == NULL) {
|
||||
DRV_LOG(ERR,
|
||||
"Cannot allocate mlx5 shared data");
|
||||
ret = -rte_errno;
|
||||
goto error;
|
||||
}
|
||||
mlx5_shared_data = mz->addr;
|
||||
memset(mlx5_shared_data, 0, sizeof(*mlx5_shared_data));
|
||||
rte_spinlock_init(&mlx5_shared_data->lock);
|
||||
} else {
|
||||
/* Lookup allocated shared memory. */
|
||||
mz = rte_memzone_lookup(MZ_MLX5_PMD_SHARED_DATA);
|
||||
if (mz == NULL) {
|
||||
DRV_LOG(ERR,
|
||||
"Cannot attach mlx5 shared data");
|
||||
ret = -rte_errno;
|
||||
goto error;
|
||||
}
|
||||
mlx5_shared_data = mz->addr;
|
||||
memset(&mlx5_local_data, 0, sizeof(mlx5_local_data));
|
||||
}
|
||||
}
|
||||
error:
|
||||
rte_spinlock_unlock(&mlx5_shared_data_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* PMD global initialization.
|
||||
*
|
||||
* Independent from individual device, this function initializes global
|
||||
* per-PMD data structures distinguishing primary and secondary processes.
|
||||
* Hence, each initialization is called once per a process.
|
||||
*
|
||||
* @return
|
||||
* 0 on success, a negative errno value otherwise and rte_errno is set.
|
||||
*/
|
||||
static int
|
||||
mlx5_init_once(void)
|
||||
{
|
||||
struct mlx5_shared_data *sd;
|
||||
struct mlx5_local_data *ld = &mlx5_local_data;
|
||||
int ret = 0;
|
||||
|
||||
if (mlx5_init_shared_data())
|
||||
return -rte_errno;
|
||||
sd = mlx5_shared_data;
|
||||
MLX5_ASSERT(sd);
|
||||
rte_spinlock_lock(&sd->lock);
|
||||
switch (rte_eal_process_type()) {
|
||||
case RTE_PROC_PRIMARY:
|
||||
if (sd->init_done)
|
||||
break;
|
||||
LIST_INIT(&sd->mem_event_cb_list);
|
||||
rte_rwlock_init(&sd->mem_event_rwlock);
|
||||
rte_mem_event_callback_register("MLX5_MEM_EVENT_CB",
|
||||
mlx5_mr_mem_event_cb, NULL);
|
||||
ret = mlx5_mp_init_primary(MLX5_MP_NAME,
|
||||
mlx5_mp_os_primary_handle);
|
||||
if (ret)
|
||||
goto out;
|
||||
sd->init_done = true;
|
||||
break;
|
||||
case RTE_PROC_SECONDARY:
|
||||
if (ld->init_done)
|
||||
break;
|
||||
ret = mlx5_mp_init_secondary(MLX5_MP_NAME,
|
||||
mlx5_mp_os_secondary_handle);
|
||||
if (ret)
|
||||
goto out;
|
||||
++sd->secondary_cnt;
|
||||
ld->init_done = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
out:
|
||||
rte_spinlock_unlock(&sd->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn an Ethernet device from Verbs information.
|
||||
*
|
||||
|
@ -22,7 +22,6 @@ sources = files(
|
||||
'mlx5_rxmode.c',
|
||||
'mlx5_rxq.c',
|
||||
'mlx5_rxtx.c',
|
||||
'mlx5_mp.c',
|
||||
'mlx5_stats.c',
|
||||
'mlx5_trigger.c',
|
||||
'mlx5_txq.c',
|
||||
|
@ -186,16 +186,11 @@
|
||||
/* Decap will be used or not. */
|
||||
#define MLX5_DECAP_EN "decap_en"
|
||||
|
||||
static const char *MZ_MLX5_PMD_SHARED_DATA = "mlx5_pmd_shared_data";
|
||||
|
||||
/* Shared memory between primary and secondary processes. */
|
||||
struct mlx5_shared_data *mlx5_shared_data;
|
||||
|
||||
/* Spinlock for mlx5_shared_data allocation. */
|
||||
static rte_spinlock_t mlx5_shared_data_lock = RTE_SPINLOCK_INITIALIZER;
|
||||
|
||||
/* Process local data for secondary processes. */
|
||||
static struct mlx5_local_data mlx5_local_data;
|
||||
/** Driver-specific log messages type. */
|
||||
int mlx5_logtype;
|
||||
|
||||
static LIST_HEAD(, mlx5_dev_ctx_shared) mlx5_dev_ctx_list =
|
||||
LIST_HEAD_INITIALIZER();
|
||||
@ -1116,55 +1111,6 @@ mlx5_alloc_table_hash_list(struct mlx5_priv *priv)
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize shared data between primary and secondary process.
|
||||
*
|
||||
* A memzone is reserved by primary process and secondary processes attach to
|
||||
* the memzone.
|
||||
*
|
||||
* @return
|
||||
* 0 on success, a negative errno value otherwise and rte_errno is set.
|
||||
*/
|
||||
static int
|
||||
mlx5_init_shared_data(void)
|
||||
{
|
||||
const struct rte_memzone *mz;
|
||||
int ret = 0;
|
||||
|
||||
rte_spinlock_lock(&mlx5_shared_data_lock);
|
||||
if (mlx5_shared_data == NULL) {
|
||||
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
|
||||
/* Allocate shared memory. */
|
||||
mz = rte_memzone_reserve(MZ_MLX5_PMD_SHARED_DATA,
|
||||
sizeof(*mlx5_shared_data),
|
||||
SOCKET_ID_ANY, 0);
|
||||
if (mz == NULL) {
|
||||
DRV_LOG(ERR,
|
||||
"Cannot allocate mlx5 shared data");
|
||||
ret = -rte_errno;
|
||||
goto error;
|
||||
}
|
||||
mlx5_shared_data = mz->addr;
|
||||
memset(mlx5_shared_data, 0, sizeof(*mlx5_shared_data));
|
||||
rte_spinlock_init(&mlx5_shared_data->lock);
|
||||
} else {
|
||||
/* Lookup allocated shared memory. */
|
||||
mz = rte_memzone_lookup(MZ_MLX5_PMD_SHARED_DATA);
|
||||
if (mz == NULL) {
|
||||
DRV_LOG(ERR,
|
||||
"Cannot attach mlx5 shared data");
|
||||
ret = -rte_errno;
|
||||
goto error;
|
||||
}
|
||||
mlx5_shared_data = mz->addr;
|
||||
memset(&mlx5_local_data, 0, sizeof(mlx5_local_data));
|
||||
}
|
||||
}
|
||||
error:
|
||||
rte_spinlock_unlock(&mlx5_shared_data_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve integer value from environment variable.
|
||||
*
|
||||
@ -1306,7 +1252,7 @@ mlx5_dev_close(struct rte_eth_dev *dev)
|
||||
dev->tx_pkt_burst = removed_tx_burst;
|
||||
rte_wmb();
|
||||
/* Disable datapath on secondary process. */
|
||||
mlx5_mp_req_stop_rxtx(dev);
|
||||
mlx5_mp_os_req_stop_rxtx(dev);
|
||||
/* Free the eCPRI flex parser resource. */
|
||||
mlx5_flex_parser_ecpri_release(dev);
|
||||
if (priv->rxqs != NULL) {
|
||||
@ -1638,60 +1584,6 @@ mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* PMD global initialization.
|
||||
*
|
||||
* Independent from individual device, this function initializes global
|
||||
* per-PMD data structures distinguishing primary and secondary processes.
|
||||
* Hence, each initialization is called once per a process.
|
||||
*
|
||||
* @return
|
||||
* 0 on success, a negative errno value otherwise and rte_errno is set.
|
||||
*/
|
||||
int
|
||||
mlx5_init_once(void)
|
||||
{
|
||||
struct mlx5_shared_data *sd;
|
||||
struct mlx5_local_data *ld = &mlx5_local_data;
|
||||
int ret = 0;
|
||||
|
||||
if (mlx5_init_shared_data())
|
||||
return -rte_errno;
|
||||
sd = mlx5_shared_data;
|
||||
MLX5_ASSERT(sd);
|
||||
rte_spinlock_lock(&sd->lock);
|
||||
switch (rte_eal_process_type()) {
|
||||
case RTE_PROC_PRIMARY:
|
||||
if (sd->init_done)
|
||||
break;
|
||||
LIST_INIT(&sd->mem_event_cb_list);
|
||||
rte_rwlock_init(&sd->mem_event_rwlock);
|
||||
rte_mem_event_callback_register("MLX5_MEM_EVENT_CB",
|
||||
mlx5_mr_mem_event_cb, NULL);
|
||||
ret = mlx5_mp_init_primary(MLX5_MP_NAME,
|
||||
mlx5_mp_primary_handle);
|
||||
if (ret)
|
||||
goto out;
|
||||
sd->init_done = true;
|
||||
break;
|
||||
case RTE_PROC_SECONDARY:
|
||||
if (ld->init_done)
|
||||
break;
|
||||
ret = mlx5_mp_init_secondary(MLX5_MP_NAME,
|
||||
mlx5_mp_secondary_handle);
|
||||
if (ret)
|
||||
goto out;
|
||||
++sd->secondary_cnt;
|
||||
ld->init_done = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
out:
|
||||
rte_spinlock_unlock(&sd->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the minimal amount of data to inline into WQE
|
||||
* while sending packets.
|
||||
|
@ -794,7 +794,6 @@ void mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
|
||||
void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
|
||||
int mlx5_dev_check_sibling_config(struct mlx5_priv *priv,
|
||||
struct mlx5_dev_config *config);
|
||||
int mlx5_init_once(void);
|
||||
int mlx5_dev_configure(struct rte_eth_dev *dev);
|
||||
int mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info);
|
||||
int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size);
|
||||
@ -979,11 +978,13 @@ void mlx5_flow_rxq_dynf_metadata_set(struct rte_eth_dev *dev);
|
||||
int mlx5_flow_get_aged_flows(struct rte_eth_dev *dev, void **contexts,
|
||||
uint32_t nb_contexts, struct rte_flow_error *error);
|
||||
|
||||
/* mlx5_mp.c */
|
||||
int mlx5_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer);
|
||||
int mlx5_mp_secondary_handle(const struct rte_mp_msg *mp_msg, const void *peer);
|
||||
void mlx5_mp_req_start_rxtx(struct rte_eth_dev *dev);
|
||||
void mlx5_mp_req_stop_rxtx(struct rte_eth_dev *dev);
|
||||
/* mlx5_mp_os.c */
|
||||
int mlx5_mp_os_primary_handle(const struct rte_mp_msg *mp_msg,
|
||||
const void *peer);
|
||||
int mlx5_mp_os_secondary_handle(const struct rte_mp_msg *mp_msg,
|
||||
const void *peer);
|
||||
void mlx5_mp_os_req_start_rxtx(struct rte_eth_dev *dev);
|
||||
void mlx5_mp_os_req_stop_rxtx(struct rte_eth_dev *dev);
|
||||
|
||||
/* mlx5_socket.c */
|
||||
|
||||
|
@ -350,7 +350,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
|
||||
dev->tx_pkt_burst = mlx5_select_tx_function(dev);
|
||||
dev->rx_pkt_burst = mlx5_select_rx_function(dev);
|
||||
/* Enable datapath on secondary process. */
|
||||
mlx5_mp_req_start_rxtx(dev);
|
||||
mlx5_mp_os_req_start_rxtx(dev);
|
||||
if (priv->sh->intr_handle.fd >= 0) {
|
||||
priv->sh->port[priv->dev_port - 1].ih_port_id =
|
||||
(uint32_t)dev->data->port_id;
|
||||
@ -396,7 +396,7 @@ mlx5_dev_stop(struct rte_eth_dev *dev)
|
||||
dev->tx_pkt_burst = removed_tx_burst;
|
||||
rte_wmb();
|
||||
/* Disable datapath on secondary process. */
|
||||
mlx5_mp_req_stop_rxtx(dev);
|
||||
mlx5_mp_os_req_stop_rxtx(dev);
|
||||
usleep(1000 * priv->rxqs_n);
|
||||
DRV_LOG(DEBUG, "port %u stopping device", dev->data->port_id);
|
||||
mlx5_flow_stop_default(dev);
|
||||
|
Loading…
Reference in New Issue
Block a user