加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0195-virtio-create-and-init-virtio_port.patch 13.80 KB
一键复制 编辑 原始数据 按行查看 历史
From 696cd69752032e55ef301f3eb4f7ad42693137ab Mon Sep 17 00:00:00 2001
From: hantwofish <hankangkang5@huawei.com>
Date: Mon, 17 Jun 2024 14:33:50 +0800
Subject: [PATCH] [virtio]: create and init virtio_port
---
src/lstack/core/dir.mk | 2 +-
src/lstack/core/lstack_dpdk.c | 6 +-
src/lstack/core/lstack_port_map.c | 43 ++++++
src/lstack/core/lstack_virtio.c | 201 +++++++++++++++++++++++++++
src/lstack/include/lstack_port_map.h | 20 +++
src/lstack/include/lstack_virtio.h | 36 +++++
6 files changed, 306 insertions(+), 2 deletions(-)
create mode 100644 src/lstack/core/lstack_port_map.c
create mode 100644 src/lstack/core/lstack_virtio.c
create mode 100644 src/lstack/include/lstack_port_map.h
create mode 100644 src/lstack/include/lstack_virtio.h
diff --git a/src/lstack/core/dir.mk b/src/lstack/core/dir.mk
index e2d10a5..21b0d22 100644
--- a/src/lstack/core/dir.mk
+++ b/src/lstack/core/dir.mk
@@ -8,6 +8,6 @@
# PURPOSE.
# See the Mulan PSL v2 for more details.
-SRC = lstack_preload.c lstack_init.c lstack_cfg.c lstack_dpdk.c lstack_control_plane.c lstack_stack_stat.c lstack_lwip.c lstack_protocol_stack.c lstack_thread_rpc.c
+SRC = lstack_preload.c lstack_init.c lstack_cfg.c lstack_dpdk.c lstack_control_plane.c lstack_stack_stat.c lstack_lwip.c lstack_protocol_stack.c lstack_thread_rpc.c lstack_virtio.c lstack_port_map.c
$(eval $(call register_dir, core, $(SRC)))
diff --git a/src/lstack/core/lstack_dpdk.c b/src/lstack/core/lstack_dpdk.c
index 785431f..b0d76bf 100644
--- a/src/lstack/core/lstack_dpdk.c
+++ b/src/lstack/core/lstack_dpdk.c
@@ -49,6 +49,7 @@
#include "lstack_thread_rpc.h"
#include "lstack_lwip.h"
#include "lstack_cfg.h"
+#include "lstack_virtio.h"
#include "lstack_dpdk.h"
struct eth_params {
@@ -771,7 +772,7 @@ int32_t init_dpdk_ethdev(void)
{
int32_t ret;
int slave_port_id[GAZELLE_MAX_BOND_NUM] = {-1};
- int port_id;
+ int port_id = 0;
struct cfg_params *cfg = get_global_cfg_params();
int i;
@@ -813,6 +814,9 @@ int32_t init_dpdk_ethdev(void)
}
}
#endif
+ if (get_global_cfg_params()->flow_bifurcation && virtio_port_create(port_id) != 0) {
+ return -1;
+ }
return 0;
}
diff --git a/src/lstack/core/lstack_port_map.c b/src/lstack/core/lstack_port_map.c
new file mode 100644
index 0000000..e5008b3
--- /dev/null
+++ b/src/lstack/core/lstack_port_map.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved.
+ * gazelle is licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+#include <pthread.h>
+#include <stdint.h>
+#include "lstack_port_map.h"
+
+#define PORT_MAP_UNIX_TCP_PORT_MAX 65535
+#define PORT_MAP_EIGHT_BIT 8
+
+static uint8_t g_rule_port[(PORT_MAP_UNIX_TCP_PORT_MAX + 1) / PORT_MAP_EIGHT_BIT]; // 8k byte
+static pthread_mutex_t g_rule_map_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void port_map_set(uint32_t modBit, int setVal)
+{
+ pthread_mutex_lock(&g_rule_map_mutex);
+ g_rule_port[modBit / PORT_MAP_EIGHT_BIT] &= ~(1 << (modBit % PORT_MAP_EIGHT_BIT));
+ g_rule_port[modBit / PORT_MAP_EIGHT_BIT] |= (setVal << (modBit % PORT_MAP_EIGHT_BIT));
+ pthread_mutex_unlock(&g_rule_map_mutex);
+}
+
+int port_map_get(int bit_index)
+{
+ int bit_val = 0;
+ int byte_index = bit_index / PORT_MAP_EIGHT_BIT;
+ int bit_offset = bit_index % PORT_MAP_EIGHT_BIT;
+ uint8_t mask = 1 << bit_offset;
+ pthread_mutex_lock(&g_rule_map_mutex);
+ if ((g_rule_port[byte_index] & mask) != 0) {
+ bit_val = 1;
+ }
+ pthread_mutex_unlock(&g_rule_map_mutex);
+ return bit_val;
+}
\ No newline at end of file
diff --git a/src/lstack/core/lstack_virtio.c b/src/lstack/core/lstack_virtio.c
new file mode 100644
index 0000000..810e343
--- /dev/null
+++ b/src/lstack/core/lstack_virtio.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved.
+ * gazelle is licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+#include <rte_ethdev.h>
+#include "lstack_cfg.h"
+#include "lstack_log.h"
+#include "lstack_port_map.h"
+#include "lstack_virtio.h"
+
+#define VIRTIO_USER_NAME "virtio_user0"
+#define VIRTIO_DPDK_PARA_LEN 256
+#define VIRTIO_TX_RX_RING_SIZE 1024
+
+static struct virtio_instance g_virtio_instance = {0};
+
+struct virtio_instance* virtio_instance_get(void)
+{
+ return &g_virtio_instance;
+}
+
+static int virtio_set_ipv6_addr(void)
+{
+ return 0;
+}
+
+static int virtio_cfg_ip(void)
+{
+ // set ipv4 adr()
+
+ // set ipv6 addr
+ virtio_set_ipv6_addr();
+ return 0;
+}
+
+void virtio_tap_process_rx(uint16_t port, uint32_t queue_id)
+{
+ struct rte_mbuf *pkts_burst[VIRTIO_TX_RX_RING_SIZE];
+ uint16_t lstack_net_port = port;
+ uint32_t pkg_num;
+
+ pkg_num = rte_eth_rx_burst(g_virtio_instance.virtio_port_id, queue_id, pkts_burst, VIRTIO_TX_RX_RING_SIZE);
+ if (pkg_num > 0) {
+ g_virtio_instance.rx_pkg[queue_id] += pkg_num;
+ uint16_t nb_rx = rte_eth_tx_burst(lstack_net_port, queue_id, pkts_burst, pkg_num);
+ for (uint16_t i = nb_rx; i < pkg_num; ++i) {
+ rte_pktmbuf_free(pkts_burst[i]);
+ g_virtio_instance.rx_drop[queue_id]++;
+ }
+ }
+}
+
+void virtio_tap_process_tx(uint16_t queue_id, struct rte_mbuf *mbuf_copy)
+{
+ int tx_num = rte_eth_tx_burst(g_virtio_instance.virtio_port_id, queue_id, &(mbuf_copy), 1);
+ if (tx_num < 0) {
+ rte_pktmbuf_free(mbuf_copy);
+ g_virtio_instance.tx_drop[queue_id]++;
+ LSTACK_LOG(ERR, LSTACK, "virtio_tap_process_tx failed %d, %d\n", queue_id, tx_num);
+ }
+ g_virtio_instance.tx_pkg[queue_id]++;
+}
+
+static int virtio_port_init(uint16_t port)
+{
+ int retval;
+ uint16_t rx_queue_num = g_virtio_instance.rx_queue_num;
+ uint16_t tx_queue_num = g_virtio_instance.tx_queue_num;
+
+ LSTACK_LOG(INFO, LSTACK, "virtio_port_init port= %u rx_queue_num=%u tx_queue_num=%u \n",
+ port, rx_queue_num, tx_queue_num);
+
+ struct rte_eth_conf port_conf;
+ memset(&port_conf, 0, sizeof(struct rte_eth_conf));
+
+ struct rte_eth_dev_info dev_info;
+ retval = rte_eth_dev_info_get(port, &dev_info);
+ if (retval != 0) {
+ LSTACK_LOG(ERR, LSTACK, "rte_eth_dev_info_get failed(port %u) info: %d\n", port, retval);
+ return retval;
+ }
+
+ retval = rte_eth_dev_configure(port, rx_queue_num, tx_queue_num, &port_conf);
+ if (retval != 0) {
+ LSTACK_LOG(ERR, LSTACK, "rte_eth_dev_configure failed retval=%d\n", retval);
+ return retval;
+ }
+
+ for (uint16_t q = 0; q < tx_queue_num; q++) {
+ retval = rte_eth_tx_queue_setup(port, q, VIRTIO_TX_RX_RING_SIZE, rte_eth_dev_socket_id(port), NULL);
+ if (retval < 0) {
+ LSTACK_LOG(ERR, LSTACK, "rte_eth_tx_queue_setup failed (queue %u) retval=%d \n", q, retval);
+ return retval;
+ }
+ }
+
+ for (uint16_t q = 0; q < rx_queue_num; q++) {
+ struct rte_mempool *rxtx_mbuf_pool = get_protocol_stack_group()->total_rxtx_pktmbuf_pool[q];
+ retval = rte_eth_rx_queue_setup(port, q, VIRTIO_TX_RX_RING_SIZE, rte_eth_dev_socket_id(port),
+ NULL, rxtx_mbuf_pool);
+ if (retval < 0) {
+ LSTACK_LOG(ERR, LSTACK, "rte_eth_rx_queue_setup failed (queue %u) retval=%d \n", q, retval);
+ return retval;
+ }
+ }
+ return 0;
+}
+
+static int32_t virtio_port_start(uint16_t virtio_port)
+{
+ int retval = 0;
+ if (virtio_port_init(virtio_port) < 0) {
+ LSTACK_LOG(ERR, LSTACK, "virtio_port_init failed \n");
+ return -1;
+ }
+
+ retval = rte_eth_dev_start(virtio_port);
+ if (retval < 0) {
+ LSTACK_LOG(ERR, LSTACK, "rte_eth_dev_start failed retval=%d\n", retval);
+ return retval;
+ }
+
+ if (virtio_cfg_ip() != 0) {
+ LSTACK_LOG(ERR, LSTACK, "virtio_cfg_ip_mac failed\n");
+ return -1;
+ }
+ LSTACK_LOG(INFO, LSTACK, "virtio_user lstack_net_port=%u virtio_port=%u rx_queue_num = %u tx_queue_num = %u\n",
+ g_virtio_instance.lstack_port_id, g_virtio_instance.virtio_port_id,
+ g_virtio_instance.rx_queue_num, g_virtio_instance.tx_queue_num);
+ return 0;
+}
+int virtio_port_create(int lstack_net_port)
+{
+ char portargs[VIRTIO_DPDK_PARA_LEN] = {0};
+
+ struct rte_ether_addr addr;
+ uint16_t virtio_port_id = 0xffff; // invalid val
+
+ struct rte_eth_dev_info dev_info;
+ int ret = rte_eth_dev_info_get(lstack_net_port, &dev_info);
+ if (ret != 0) {
+ LSTACK_LOG(ERR, LSTACK, "get dev info ret=%d\n", ret);
+ return ret;
+ }
+
+ g_virtio_instance.rx_queue_num = dev_info.nb_rx_queues;
+ g_virtio_instance.tx_queue_num = dev_info.nb_tx_queues;
+
+ if (g_virtio_instance.rx_queue_num > VIRTIO_MAX_QUEUE_NUM ||
+ g_virtio_instance.tx_queue_num > VIRTIO_MAX_QUEUE_NUM) {
+ LSTACK_LOG(ERR, LSTACK, "virtio_port_create failed queue_num (%u %u) is bigger than %u\n",
+ g_virtio_instance.rx_queue_num, g_virtio_instance.tx_queue_num, VIRTIO_MAX_QUEUE_NUM);
+ return -1;
+ }
+
+ int retval = rte_eth_macaddr_get(lstack_net_port, &addr); // virtio_user0'mac is same with lstack.conf MAC addr
+ if (retval != 0) {
+ LSTACK_LOG(ERR, LSTACK, " rte_eth_macaddr_get failed ret = %d\n", retval);
+ return retval;
+ }
+
+ retval = snprintf(portargs, sizeof(portargs),
+ "path=/dev/vhost-net,queues=%u,queue_size=%u,iface=%s,mac=" RTE_ETHER_ADDR_PRT_FMT,
+ VIRTIO_MAX_QUEUE_NUM, VIRTIO_TX_RX_RING_SIZE, VIRTIO_USER_NAME, RTE_ETHER_ADDR_BYTES(&addr));
+ if (retval < 0) {
+ LSTACK_LOG(ERR, LSTACK, "virtio portargs snprintf failed ret=%d \n", retval);
+ return retval;
+ }
+ LSTACK_LOG(INFO, LSTACK, "virtio portargs=%s \n", portargs);
+
+ retval = rte_eal_hotplug_add("vdev", VIRTIO_USER_NAME, portargs);
+ if (retval < 0) {
+ LSTACK_LOG(ERR, LSTACK, "rte_eal_hotplug_add failed retval=%d : %s\n", retval, strerror(-retval));
+ return retval;
+ }
+
+ retval = rte_eth_dev_get_port_by_name(VIRTIO_USER_NAME, &virtio_port_id);
+ if (retval != 0) {
+ rte_eal_hotplug_remove("vdev", VIRTIO_USER_NAME);
+ LSTACK_LOG(ERR, LSTACK, "virtio_user0 not found\n");
+ return -1;
+ }
+
+ g_virtio_instance.virtio_port_id = virtio_port_id;
+ g_virtio_instance.lstack_port_id = lstack_net_port;
+
+ retval = virtio_port_start(virtio_port_id);
+ if (retval != 0) {
+ LSTACK_LOG(ERR, LSTACK, "virtio_port_start failed ret=%d\n", retval);
+ rte_eal_hotplug_remove("vdev", VIRTIO_USER_NAME);
+ return retval;
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/src/lstack/include/lstack_port_map.h b/src/lstack/include/lstack_port_map.h
new file mode 100644
index 0000000..24ef53a
--- /dev/null
+++ b/src/lstack/include/lstack_port_map.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved.
+ * gazelle is licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+#ifndef __LSTACK_PORT_MAP_H__
+#define __LSTACK_PORT_MAP_H__
+
+#include <stdint.h>
+
+void port_map_set(uint32_t modBit, int setVal);
+int port_map_get(int bit_index);
+
+#endif
\ No newline at end of file
diff --git a/src/lstack/include/lstack_virtio.h b/src/lstack/include/lstack_virtio.h
new file mode 100644
index 0000000..5e001ca
--- /dev/null
+++ b/src/lstack/include/lstack_virtio.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved.
+ * gazelle is licensed under the Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+ * PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+#ifndef __LSTACK_VIRTIO_H__
+#define __LSTACK_VIRTIO_H__
+
+#include <stdint.h>
+
+#define VIRTIO_MAX_QUEUE_NUM 8
+struct virtio_instance {
+ uint16_t lstack_port_id;
+ uint16_t virtio_port_id;
+ uint16_t rx_queue_num;
+ uint16_t tx_queue_num;
+
+ uint64_t rx_pkg[VIRTIO_MAX_QUEUE_NUM];
+ uint64_t rx_drop[VIRTIO_MAX_QUEUE_NUM];
+ uint64_t tx_pkg[VIRTIO_MAX_QUEUE_NUM];
+ uint64_t tx_drop[VIRTIO_MAX_QUEUE_NUM];
+};
+
+void virtio_tap_process_rx(uint16_t port, uint32_t queue_id);
+void virtio_tap_process_tx(uint16_t queue_id, struct rte_mbuf *mbuf_copy);
+
+int virtio_port_create(int lstack_net_port);
+
+struct virtio_instance* virtio_instance_get(void);
+#endif
\ No newline at end of file
--
2.33.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化