From patchwork Thu Oct 7 18:43:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srikanth Kaka X-Patchwork-Id: 100800 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D4144A034F; Fri, 8 Oct 2021 12:58:52 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 99632411EE; Fri, 8 Oct 2021 12:56:33 +0200 (CEST) Received: from mail-pg1-f173.google.com (mail-pg1-f173.google.com [209.85.215.173]) by mails.dpdk.org (Postfix) with ESMTP id 8E4C541217 for ; Thu, 7 Oct 2021 20:45:41 +0200 (CEST) Received: by mail-pg1-f173.google.com with SMTP id r201so661571pgr.4 for ; Thu, 07 Oct 2021 11:45:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oneconvergence.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qG+azfxLlrWvx7/G3QPcbVDyIZB7jN6oFPxBd1aznH8=; b=ImKJ5ky21sBpcyD29yVyvJTC9Ni6uJOPgpdmlkVibWRwMFgDnViFz474LHYR44EH0+ VhF+jcRJTm1rinOyS2iIekKRwca+A5hegdiOAf6PAG6Op8BdqDQnbTrZKGQDaTzb7WW3 LCve8qkmvtLozjCHtjtIY/X3Mb84CFHTznGEU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qG+azfxLlrWvx7/G3QPcbVDyIZB7jN6oFPxBd1aznH8=; b=pvg4RMITtgOKzsj1jy3XmHmYW8POhZkb2zIZ5Fa3Xh9WeFOEOn+6jRyYsP3f8OdVYk CsyXgOjHM5kiKQKpyJPOaOt1onXvr1oijgGFjCTrwBhXi6iRXjHsAQ7iJusbyHeqYalO yyN4DZjwGILkaiO2rVzAP3RhTudCPXdAuy93QZGBozXO6tfJuU/q/luoDx34jaB+RC8W DI15SIAglUJyrrCbYuZx4G2GnWmeeMAHlah5M/mmem9NZyT/Hsw7T5flmrdKFLY/aQtq MZtYjI4TrXLPR9KZzzL3sMEj/j7MpsoJ1n+Pe0siZJAK/qIfOD8CFvvDcIRuZmWREJ1n R5PQ== X-Gm-Message-State: AOAM5318uneAbIHH6b954OCsE8UfKuv7sn4b2VmOxxWfdYl6enSU0Pp1 3silV3js5GCfA4AmmzOMjBaJgg== X-Google-Smtp-Source: ABdhPJzCyPBNK5jYr6upWA1m+TsYLeWMiYsB7yryiAzWYZeI0chOrEGokzWq3woa+Q4jt8ruYivJTQ== X-Received: by 2002:a05:6a00:238a:b0:44b:e2bb:e5ff with SMTP id f10-20020a056a00238a00b0044be2bbe5ffmr5807297pfc.14.1633632340738; Thu, 07 Oct 2021 11:45:40 -0700 (PDT) Received: from srikanth-ThinkPad-T450.domain.name ([136.185.113.102]) by smtp.gmail.com with ESMTPSA id c11sm3311586pji.38.2021.10.07.11.45.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Oct 2021 11:45:40 -0700 (PDT) From: Srikanth Kaka To: Matan Azrad , Viacheslav Ovsiienko Cc: dev@dpdk.org, Vag Singh , Anand Thulasiram , Srikanth Kaka Date: Fri, 8 Oct 2021 00:13:41 +0530 Message-Id: <20211007184350.73858-33-srikanth.k@oneconvergence.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211007184350.73858-1-srikanth.k@oneconvergence.com> References: <20211007184350.73858-1-srikanth.k@oneconvergence.com> MIME-Version: 1.0 X-Mailman-Approved-At: Fri, 08 Oct 2021 12:55:54 +0200 Subject: [dpdk-dev] [PATCH v2 32/41] net/mlx5: add multiprocess support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" These routines are equivalent to their Linux counterparts Signed-off-by: Srikanth Kaka Signed-off-by: Vag Singh Signed-off-by: Anand Thulasiram --- drivers/net/mlx5/freebsd/mlx5_mp_os.c | 305 ++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 drivers/net/mlx5/freebsd/mlx5_mp_os.c diff --git a/drivers/net/mlx5/freebsd/mlx5_mp_os.c b/drivers/net/mlx5/freebsd/mlx5_mp_os.c new file mode 100644 index 0000000000..3a4aa766f8 --- /dev/null +++ b/drivers/net/mlx5/freebsd/mlx5_mp_os.c @@ -0,0 +1,305 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 6WIND S.A. + * Copyright 2019 Mellanox Technologies, Ltd + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "mlx5.h" +#include "mlx5_rxtx.h" +#include "mlx5_rx.h" +#include "mlx5_tx.h" +#include "mlx5_utils.h" + +int +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; + const struct mlx5_mp_param *param = + (const struct mlx5_mp_param *)mp_msg->param; + struct rte_eth_dev *dev; + struct mlx5_priv *priv; + struct mr_cache_entry entry; + uint32_t lkey; + int ret; + + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); + if (!rte_eth_dev_is_valid_port(param->port_id)) { + rte_errno = ENODEV; + DRV_LOG(ERR, "port %u invalid port ID", param->port_id); + return -rte_errno; + } + dev = &rte_eth_devices[param->port_id]; + priv = dev->data->dev_private; + switch (param->type) { + case MLX5_MP_REQ_CREATE_MR: + mp_init_msg(&priv->mp_id, &mp_res, param->type); + lkey = mlx5_mr_create_primary(priv->sh->pd, + &priv->sh->share_cache, + &entry, param->args.addr, + priv->config.mr_ext_memseg_en); + if (lkey == UINT32_MAX) + res->result = -rte_errno; + ret = rte_mp_reply(&mp_res, peer); + break; + case MLX5_MP_REQ_VERBS_CMD_FD: + mp_init_msg(&priv->mp_id, &mp_res, param->type); + mp_res.num_fds = 1; + mp_res.fds[0] = ((struct ibv_context *)priv->sh->ctx)->cmd_fd; + res->result = 0; + ret = rte_mp_reply(&mp_res, peer); + break; + case MLX5_MP_REQ_QUEUE_STATE_MODIFY: + mp_init_msg(&priv->mp_id, &mp_res, param->type); + res->result = mlx5_queue_state_modify_primary + (dev, ¶m->args.state_modify); + ret = rte_mp_reply(&mp_res, peer); + break; + case MLX5_MP_REQ_QUEUE_RX_STOP: + mp_init_msg(&priv->mp_id, &mp_res, param->type); + res->result = mlx5_rx_queue_stop_primary + (dev, param->args.queue_id.queue_id); + ret = rte_mp_reply(&mp_res, peer); + break; + case MLX5_MP_REQ_QUEUE_RX_START: + mp_init_msg(&priv->mp_id, &mp_res, param->type); + res->result = mlx5_rx_queue_start_primary + (dev, param->args.queue_id.queue_id); + ret = rte_mp_reply(&mp_res, peer); + break; + case MLX5_MP_REQ_QUEUE_TX_STOP: + mp_init_msg(&priv->mp_id, &mp_res, param->type); + res->result = mlx5_tx_queue_stop_primary + (dev, param->args.queue_id.queue_id); + ret = rte_mp_reply(&mp_res, peer); + break; + case MLX5_MP_REQ_QUEUE_TX_START: + mp_init_msg(&priv->mp_id, &mp_res, param->type); + res->result = mlx5_tx_queue_start_primary + (dev, param->args.queue_id.queue_id); + ret = rte_mp_reply(&mp_res, peer); + break; + default: + rte_errno = EINVAL; + DRV_LOG(ERR, "port %u invalid mp request type", + dev->data->port_id); + return -rte_errno; + } + return ret; +} + +/** + * IPC message handler of a secondary process. + * + * @param[in] dev + * Pointer to Ethernet structure. + * @param[in] peer + * Pointer to the peer socket path. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +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; + const struct mlx5_mp_param *param = + (const struct mlx5_mp_param *)mp_msg->param; + struct rte_eth_dev *dev; + struct mlx5_proc_priv *ppriv; + struct mlx5_priv *priv; + int ret; + + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY); + if (!rte_eth_dev_is_valid_port(param->port_id)) { + rte_errno = ENODEV; + DRV_LOG(ERR, "port %u invalid port ID", param->port_id); + return -rte_errno; + } + dev = &rte_eth_devices[param->port_id]; + priv = dev->data->dev_private; + switch (param->type) { + case MLX5_MP_REQ_START_RXTX: + DRV_LOG(INFO, "port %u starting datapath", dev->data->port_id); + dev->rx_pkt_burst = mlx5_select_rx_function(dev); + dev->tx_pkt_burst = mlx5_select_tx_function(dev); + ppriv = (struct mlx5_proc_priv *)dev->process_private; + /* If Tx queue number changes, re-initialize UAR. */ + if (ppriv->uar_table_sz != priv->txqs_n) { + mlx5_tx_uar_uninit_secondary(dev); + mlx5_proc_priv_uninit(dev); + ret = mlx5_proc_priv_init(dev); + if (ret) + return -rte_errno; + ret = mlx5_tx_uar_init_secondary(dev, mp_msg->fds[0]); + if (ret) { + mlx5_proc_priv_uninit(dev); + return -rte_errno; + } + } + rte_mb(); + mp_init_msg(&priv->mp_id, &mp_res, param->type); + res->result = 0; + ret = rte_mp_reply(&mp_res, peer); + break; + case MLX5_MP_REQ_STOP_RXTX: + DRV_LOG(INFO, "port %u stopping datapath", dev->data->port_id); + dev->rx_pkt_burst = removed_rx_burst; + dev->tx_pkt_burst = removed_tx_burst; + rte_mb(); + mp_init_msg(&priv->mp_id, &mp_res, param->type); + res->result = 0; + ret = rte_mp_reply(&mp_res, peer); + break; + default: + rte_errno = EINVAL; + DRV_LOG(ERR, "port %u invalid mp request type", + dev->data->port_id); + return -rte_errno; + } + return ret; +} + +/** + * Broadcast request of stopping/starting data-path to secondary processes. + * + * @param[in] dev + * Pointer to Ethernet structure. + * @param[in] type + * Request type. + */ +static void +mp_req_on_rxtx(struct rte_eth_dev *dev, enum mlx5_mp_req_type type) +{ + 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}; + struct mlx5_priv *priv = dev->data->dev_private; + int ret; + int i; + + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY); + if (!mlx5_shared_data->secondary_cnt) + return; + if (type != MLX5_MP_REQ_START_RXTX && type != MLX5_MP_REQ_STOP_RXTX) { + DRV_LOG(ERR, "port %u unknown request (req_type %d)", + dev->data->port_id, type); + return; + } + mp_init_msg(&priv->mp_id, &mp_req, type); + if (type == MLX5_MP_REQ_START_RXTX) { + mp_req.num_fds = 1; + mp_req.fds[0] = ((struct ibv_context *)priv->sh->ctx)->cmd_fd; + } + ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts); + if (ret) { + if (rte_errno != ENOTSUP) + DRV_LOG(ERR, "port %u failed to request stop/start Rx/Tx (%d)", + dev->data->port_id, type); + goto exit; + } + if (mp_rep.nb_sent != mp_rep.nb_received) { + DRV_LOG(ERR, + "port %u not all secondaries responded (req_type %d)", + dev->data->port_id, type); + goto exit; + } + for (i = 0; i < mp_rep.nb_received; i++) { + mp_res = &mp_rep.msgs[i]; + res = (struct mlx5_mp_param *)mp_res->param; + if (res->result) { + DRV_LOG(ERR, "port %u request failed on secondary #%d", + dev->data->port_id, i); + goto exit; + } + } +exit: + mlx5_free(mp_rep.msgs); +} + +/** + * Broadcast request of starting data-path to secondary processes. The request + * is synchronous. + * + * @param[in] dev + * Pointer to Ethernet structure. + */ +void +mlx5_mp_os_req_start_rxtx(struct rte_eth_dev *dev) +{ + mp_req_on_rxtx(dev, MLX5_MP_REQ_START_RXTX); +} + +/** + * Broadcast request of stopping data-path to secondary processes. The request + * is synchronous. + * + * @param[in] dev + * Pointer to Ethernet structure. + */ +void +mlx5_mp_os_req_stop_rxtx(struct rte_eth_dev *dev) +{ + mp_req_on_rxtx(dev, MLX5_MP_REQ_STOP_RXTX); +} + +/** + * Request Verbs Rx/Tx queue stop or start to the primary process. + * + * @param[in] dev + * Pointer to Ethernet structure. + * @param queue_id + * Queue ID to control. + * @param req_type + * request type + * MLX5_MP_REQ_QUEUE_RX_START - start Rx queue + * MLX5_MP_REQ_QUEUE_TX_START - stop Tx queue + * MLX5_MP_REQ_QUEUE_RX_STOP - stop Rx queue + * MLX5_MP_REQ_QUEUE_TX_STOP - stop Tx queue + * @return + * 0 on success, a negative errno value otherwise and + * rte_errno is set. + */ +int +mlx5_mp_os_req_queue_control(struct rte_eth_dev *dev, uint16_t queue_id, + enum mlx5_mp_req_type req_type) +{ + 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}; + struct mlx5_priv *priv; + int ret; + + MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY); + priv = dev->data->dev_private; + mp_init_msg(&priv->mp_id, &mp_req, req_type); + req->args.queue_id.queue_id = queue_id; + ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts); + if (ret) { + DRV_LOG(ERR, "port %u request to primary process failed", + dev->data->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; +}