Projects
Eulaceura:Factory
gazelle
_service:obs_scm:0195-virtio-create-and-init-vi...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:0195-virtio-create-and-init-virtio_port.patch of Package gazelle
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
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2