From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 8DB2DA0577; Tue, 7 Apr 2020 19:01:12 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 4EA8E1BEE0; Tue, 7 Apr 2020 19:01:11 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 8E856FFA for ; Tue, 7 Apr 2020 19:01:09 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE2 (envelope-from vuhuong@mellanox.com) with ESMTPS (AES256-SHA encrypted); 7 Apr 2020 20:01:06 +0300 Received: from mti-swat6.mti.labs.mlnx. (mti-swat6.mti.labs.mlnx [10.9.20.106]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 037H12eK016779; Tue, 7 Apr 2020 20:01:04 +0300 From: Vu Pham To: dev@dpdk.org Cc: viacheslavo@mellanox.com, orika@mellanox.com, matan@mellanox.com, rasland@mellanox.com, Vu Pham Date: Tue, 7 Apr 2020 10:00:55 -0700 Message-Id: <20200407170058.9274-2-vuhuong@mellanox.com> X-Mailer: git-send-email 2.16.6 In-Reply-To: <20200407170058.9274-1-vuhuong@mellanox.com> References: <20200402192105.11606-1-vuhuoong@mellanox.com> <20200407170058.9274-1-vuhuong@mellanox.com> Subject: [dpdk-dev] [PATCH v3 1/4] common/mlx5: refactor multi-process IPC handling codes to common driver X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Refactor common multi-process handling codes from net PMD to common driver. Using tuple mp_id{name, port_id} as standard input parameter for all multi-process IPC APIs instead of using rte_eth_dev. Signed-off-by: Vu Pham --- drivers/common/mlx5/mlx5_common_mp.c | 188 ++++++++++++++++++++++++ drivers/common/mlx5/mlx5_common_mp.h | 98 ++++++++++++ drivers/common/mlx5/rte_common_mlx5_version.map | 13 ++ 3 files changed, 299 insertions(+) create mode 100644 drivers/common/mlx5/mlx5_common_mp.c create mode 100644 drivers/common/mlx5/mlx5_common_mp.h diff --git a/drivers/common/mlx5/mlx5_common_mp.c b/drivers/common/mlx5/mlx5_common_mp.c new file mode 100644 index 0000000000..da55143bc1 --- /dev/null +++ b/drivers/common/mlx5/mlx5_common_mp.c @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 6WIND S.A. + * Copyright 2019 Mellanox Technologies, Ltd + */ + +#include +#include + +#include +#include + +#include "mlx5_common_mp.h" +#include "mlx5_common_utils.h" + +/** + * Request Memory Region creation to the primary process. + * + * @param[in] mp_id + * ID of the MP process. + * @param addr + * Target virtual address to register. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_mp_req_mr_create(struct mlx5_mp_id *mp_id, uintptr_t addr) +{ + struct rte_mp_msg mp_req; + struct rte_mp_msg *mp_res; + struct rte_mp_reply mp_rep; + struct mlx5_mp_param *req = (struct mlx5_mp_param *)mp_req.param; + struct mlx5_mp_param *res; + struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0}; + int ret; + + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY); + mp_init_msg(mp_id, &mp_req, MLX5_MP_REQ_CREATE_MR); + req->args.addr = addr; + ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts); + if (ret) { + DRV_LOG(ERR, "port %u request to primary process failed", + mp_id->port_id); + return -rte_errno; + } + MLX5_ASSERT(mp_rep.nb_received == 1); + mp_res = &mp_rep.msgs[0]; + res = (struct mlx5_mp_param *)mp_res->param; + ret = res->result; + if (ret) + rte_errno = -ret; + free(mp_rep.msgs); + return ret; +} + +/** + * Request Verbs queue state modification to the primary process. + * + * @param[in] mp_id + * ID of the MP process. + * @param sm + * State modify parameters. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_mp_req_queue_state_modify(struct mlx5_mp_id *mp_id, + struct mlx5_mp_arg_queue_state_modify *sm) +{ + struct rte_mp_msg mp_req; + struct rte_mp_msg *mp_res; + struct rte_mp_reply mp_rep; + struct mlx5_mp_param *req = (struct mlx5_mp_param *)mp_req.param; + struct mlx5_mp_param *res; + struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0}; + int ret; + + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY); + mp_init_msg(mp_id, &mp_req, MLX5_MP_REQ_QUEUE_STATE_MODIFY); + req->args.state_modify = *sm; + ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts); + if (ret) { + DRV_LOG(ERR, "port %u request to primary process failed", + mp_id->port_id); + return -rte_errno; + } + MLX5_ASSERT(mp_rep.nb_received == 1); + mp_res = &mp_rep.msgs[0]; + res = (struct mlx5_mp_param *)mp_res->param; + ret = res->result; + free(mp_rep.msgs); + return ret; +} + +/** + * Request Verbs command file descriptor for mmap to the primary process. + * + * @param[in] mp_id + * ID of the MP process. + * + * @return + * fd on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_mp_req_verbs_cmd_fd(struct mlx5_mp_id *mp_id) +{ + struct rte_mp_msg mp_req; + struct rte_mp_msg *mp_res; + struct rte_mp_reply mp_rep; + struct mlx5_mp_param *res; + struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0}; + int ret; + + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY); + mp_init_msg(mp_id, &mp_req, MLX5_MP_REQ_VERBS_CMD_FD); + ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts); + if (ret) { + DRV_LOG(ERR, "port %u request to primary process failed", + mp_id->port_id); + return -rte_errno; + } + MLX5_ASSERT(mp_rep.nb_received == 1); + mp_res = &mp_rep.msgs[0]; + res = (struct mlx5_mp_param *)mp_res->param; + if (res->result) { + rte_errno = -res->result; + DRV_LOG(ERR, + "port %u failed to get command FD from primary process", + mp_id->port_id); + ret = -rte_errno; + goto exit; + } + MLX5_ASSERT(mp_res->num_fds == 1); + ret = mp_res->fds[0]; + DRV_LOG(DEBUG, "port %u command FD from primary is %d", + mp_id->port_id, ret); +exit: + free(mp_rep.msgs); + return ret; +} + +/** + * Initialize by primary process. + */ +int +mlx5_mp_init_primary(const char *name, const rte_mp_t primary_action) +{ + int ret; + + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); + + /* primary is allowed to not support IPC */ + ret = rte_mp_action_register(name, primary_action); + if (ret && rte_errno != ENOTSUP) + return -1; + return 0; +} + +/** + * Un-initialize by primary process. + */ +void +mlx5_mp_uninit_primary(const char *name) +{ + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); + rte_mp_action_unregister(name); +} + +/** + * Initialize by secondary process. + */ +int +mlx5_mp_init_secondary(const char *name, const rte_mp_t secondary_action) +{ + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY); + return rte_mp_action_register(name, secondary_action); +} + +/** + * Un-initialize by secondary process. + */ +void +mlx5_mp_uninit_secondary(const char *name) +{ + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY); + rte_mp_action_unregister(name); +} diff --git a/drivers/common/mlx5/mlx5_common_mp.h b/drivers/common/mlx5/mlx5_common_mp.h new file mode 100644 index 0000000000..7aab77acb2 --- /dev/null +++ b/drivers/common/mlx5/mlx5_common_mp.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018 6WIND S.A. + * Copyright 2018 Mellanox Technologies, Ltd + */ + +#ifndef RTE_PMD_MLX5_COMMON_MP_H_ +#define RTE_PMD_MLX5_COMMON_MP_H_ + +/* Verbs header. */ +/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ +#ifdef PEDANTIC +#pragma GCC diagnostic ignored "-Wpedantic" +#endif +#include +#ifdef PEDANTIC +#pragma GCC diagnostic error "-Wpedantic" +#endif + +#include +#include + +/* Request types for IPC. */ +enum mlx5_mp_req_type { + MLX5_MP_REQ_VERBS_CMD_FD = 1, + MLX5_MP_REQ_CREATE_MR, + MLX5_MP_REQ_START_RXTX, + MLX5_MP_REQ_STOP_RXTX, + MLX5_MP_REQ_QUEUE_STATE_MODIFY, +}; + +struct mlx5_mp_arg_queue_state_modify { + uint8_t is_wq; /* Set if WQ. */ + uint16_t queue_id; /* DPDK queue ID. */ + enum ibv_wq_state state; /* WQ requested state. */ +}; + +/* Pameters for IPC. */ +struct mlx5_mp_param { + enum mlx5_mp_req_type type; + int port_id; + int result; + RTE_STD_C11 + union { + uintptr_t addr; /* MLX5_MP_REQ_CREATE_MR */ + struct mlx5_mp_arg_queue_state_modify state_modify; + /* MLX5_MP_REQ_QUEUE_STATE_MODIFY */ + } args; +}; + +/* Identifier of a MP process */ +struct mlx5_mp_id { + char name[RTE_MP_MAX_NAME_LEN]; + uint16_t port_id; +}; + +/** Request timeout for IPC. */ +#define MLX5_MP_REQ_TIMEOUT_SEC 5 + +/** + * Initialize IPC message. + * + * @param[in] port_id + * Port ID of the device. + * @param[out] msg + * Pointer to message to fill in. + * @param[in] type + * Message type. + */ +static inline void +mp_init_msg(struct mlx5_mp_id *mp_id, struct rte_mp_msg *msg, + enum mlx5_mp_req_type type) +{ + struct mlx5_mp_param *param = (struct mlx5_mp_param *)msg->param; + + memset(msg, 0, sizeof(*msg)); + strlcpy(msg->name, mp_id->name, sizeof(msg->name)); + msg->len_param = sizeof(*param); + param->type = type; + param->port_id = mp_id->port_id; +} + +__rte_experimental +int mlx5_mp_init_primary(const char *name, const rte_mp_t primary_action); +__rte_experimental +void mlx5_mp_uninit_primary(const char *name); +__rte_experimental +int mlx5_mp_init_secondary(const char *name, const rte_mp_t secondary_action); +__rte_experimental +void mlx5_mp_uninit_secondary(const char *name); +__rte_experimental +int mlx5_mp_req_mr_create(struct mlx5_mp_id *mp_id, uintptr_t addr); +__rte_experimental +int mlx5_mp_req_queue_state_modify(struct mlx5_mp_id *mp_id, + struct mlx5_mp_arg_queue_state_modify *sm); +__rte_experimental +int mlx5_mp_req_verbs_cmd_fd(struct mlx5_mp_id *mp_id); + +#endif /* RTE_PMD_MLX5_COMMON_MP_H_ */ diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map index aede2a0a51..265703d1c9 100644 --- a/drivers/common/mlx5/rte_common_mlx5_version.map +++ b/drivers/common/mlx5/rte_common_mlx5_version.map @@ -48,4 +48,17 @@ DPDK_20.0.1 { mlx5_nl_vlan_vmwa_delete; mlx5_translate_port_name; + +}; + +EXPERIMENTAL { + global: + + mlx5_mp_init_primary; + mlx5_mp_uninit_primary; + mlx5_mp_init_secondary; + mlx5_mp_uninit_secondary; + mlx5_mp_req_mr_create; + mlx5_mp_req_queue_state_modify; + mlx5_mp_req_verbs_cmd_fd; }; -- 2.16.6