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 1E66FA054F for ; Tue, 18 Feb 2020 07:37:43 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 141091DA1E; Tue, 18 Feb 2020 07:37:43 +0100 (CET) Received: from dish-sg.nttdocomo.co.jp (dish-sg.nttdocomo.co.jp [202.19.227.74]) by dpdk.org (Postfix) with ESMTP id 88DF31DA1B for ; Tue, 18 Feb 2020 07:37:41 +0100 (CET) X-dD-Source: Outbound Received: from zssg-mailmd101.ddreams.local (zssg-mailmd900.ddreams.local [10.160.172.63]) by zssg-mailou103.ddreams.local (Postfix) with ESMTP id C75C112014D; Tue, 18 Feb 2020 15:37:40 +0900 (JST) Received: from zssg-mailmf104.ddreams.local (zssg-mailmf900.ddreams.local [10.160.172.84]) by zssg-mailmd101.ddreams.local (dDREAMS) with ESMTP id <0Q5V00K0KX2SB990@dDREAMS>; Tue, 18 Feb 2020 15:37:40 +0900 (JST) Received: from zssg-mailmf104.ddreams.local (unknown [127.0.0.1]) by zssg-mailmf104.ddreams.local (Postfix) with ESMTP id A2C0E7E6038; Tue, 18 Feb 2020 15:37:40 +0900 (JST) Received: from zssg-mailmf104.ddreams.local (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A14378E6050; Tue, 18 Feb 2020 15:37:40 +0900 (JST) Received: from localhost (unknown [127.0.0.1]) by IMSVA (Postfix) with SMTP id 964AB8E605A; Tue, 18 Feb 2020 15:37:40 +0900 (JST) X-IMSS-HAND-OFF-DIRECTIVE: localhost:10026 Received: from zssg-mailmf104.ddreams.local (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 111F58E6050; Tue, 18 Feb 2020 15:37:40 +0900 (JST) Received: from davinci.ntt-tx.co.jp (unknown [10.160.183.139]) by zssg-mailmf104.ddreams.local (Postfix) with ESMTP; Tue, 18 Feb 2020 15:37:40 +0900 (JST) From: x-fn-spp-ml@ntt-tx.co.jp To: ferruh.yigit@intel.com, yasufum.o@gmail.com Cc: spp@dpdk.org Date: Tue, 18 Feb 2020 15:37:20 +0900 Message-id: <20200218063720.6597-18-x-fn-spp-ml@ntt-tx.co.jp> X-Mailer: git-send-email 2.18.0 In-reply-to: <20200218063720.6597-1-x-fn-spp-ml@ntt-tx.co.jp> References: <20200218063720.6597-1-x-fn-spp-ml@ntt-tx.co.jp> X-TM-AS-GCONF: 00 Subject: [spp] [PATCH 17/17] spp_nfv: add support of multi-queue X-BeenThere: spp@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Soft Patch Panel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: spp-bounces@dpdk.org Sender: "spp" From: Hideyuki Yamashita To achieve hardware offload in secondary process, multi-queue should be supported. Multi-queue support is divided into several changes like following: - add queue number parameter in patch command - parse newly added parameter - add queue number parameter in status response Signed-off-by: Hideyuki Yamashita Signed-off-by: Yasufumi Ogawa --- src/nfv/commands.h | 71 +++++++--- src/nfv/main.c | 18 ++- src/nfv/nfv_status.c | 315 +++++++++++++++++++------------------------ src/nfv/nfv_status.h | 12 +- 4 files changed, 207 insertions(+), 209 deletions(-) diff --git a/src/nfv/commands.h b/src/nfv/commands.h index e5b25be..6b3a935 100644 --- a/src/nfv/commands.h +++ b/src/nfv/commands.h @@ -17,7 +17,7 @@ */ static int -do_del(char *p_type, int p_id) +do_del(char *p_type, int p_id, uint16_t queue_id) { uint16_t port_id = PORT_RESET; @@ -55,7 +55,7 @@ do_del(char *p_type, int p_id) } - forward_array_remove(port_id); + forward_array_remove(port_id, queue_id); port_map_init_one(port_id); return 0; @@ -66,7 +66,7 @@ do_del(char *p_type, int p_id) * combination of port type and ID like as 'ring:0'. */ static int -do_add(char *p_type, int p_id) +do_add(char *p_type, int p_id, uint16_t queue_id) { enum port_type type = UNDEF; uint16_t port_id = PORT_RESET; @@ -105,9 +105,11 @@ do_add(char *p_type, int p_id) * other than RING. There is no support to show/clear this stats * at the moment. */ + port_map[port_id].queue_info = NULL; - /* Update ports_fwd_array with port id */ - ports_fwd_array[port_id].in_port_id = port_id; + /* Update ports_fwd_array with port id and queue id */ + ports_fwd_array[port_id][queue_id].in_port_id = port_id; + ports_fwd_array[port_id][queue_id].in_queue_id = queue_id; return 0; } @@ -164,6 +166,7 @@ parse_command(char *str) char port_set[128] = { 0 }; char *p_type; int p_id; + uint16_t queue_id; if (!str) return 0; @@ -185,12 +188,10 @@ parse_command(char *str) memset(str, '\0', MSG_SIZE); if (cmd == FORWARD) get_sec_stats_json(str, get_client_id(), "running", - lcore_id_used, - ports_fwd_array, port_map); + lcore_id_used); else get_sec_stats_json(str, get_client_id(), "idling", - lcore_id_used, - ports_fwd_array, port_map); + lcore_id_used); RTE_ETH_FOREACH_DEV(dev_id) { rte_eth_dev_get_name_by_port(dev_id, dev_name); @@ -245,11 +246,12 @@ parse_command(char *str) } else if (!strcmp(token_list[0], "add")) { RTE_LOG(DEBUG, SPP_NFV, "Received add command\n"); - ret = parse_resource_uid(token_list[1], &p_type, &p_id); + ret = parse_resource_uid(token_list[1], &p_type, &p_id, + &queue_id); if (ret < 0) return ret; - if (do_add(p_type, p_id) < 0) { + if (do_add(p_type, p_id, queue_id) < 0) { RTE_LOG(ERR, SPP_NFV, "Failed to do_add()\n"); sprintf(result, "%s", "\"failed\""); } else @@ -282,13 +284,23 @@ parse_command(char *str) char *out_p_type; int in_p_id; int out_p_id; - - parse_resource_uid(token_list[1], &in_p_type, &in_p_id); + uint16_t in_queue_id, out_queue_id; + int res_uid_str_size = 32; + char in_res_uid[res_uid_str_size]; + char out_res_uid[res_uid_str_size]; + + strncpy(in_res_uid, token_list[1], + res_uid_str_size - 1); + strncpy(out_res_uid, token_list[2], + res_uid_str_size - 1); + + parse_resource_uid(token_list[1], &in_p_type, &in_p_id, + &in_queue_id); in_port = find_port_id(in_p_id, get_port_type(in_p_type)); parse_resource_uid(token_list[2], - &out_p_type, &out_p_id); + &out_p_type, &out_p_id, &out_queue_id); out_port = find_port_id(out_p_id, get_port_type(out_p_type)); @@ -314,13 +326,27 @@ parse_command(char *str) "Patch not found, out_port", out_p_type, out_p_id); RTE_LOG(ERR, SPP_NFV, "%s\n", err_msg); + } else if (is_valid_port_rxq(in_port, in_queue_id)) { + RTE_LOG(ERR, SPP_NFV, + "Queue number of in_port" + " exceeds definition" + " %s:%d nq %d(%s:%d)\n", + in_p_type, in_p_id, in_queue_id, + __func__, __LINE__); + } else if (is_valid_port_txq(out_port, out_queue_id)) { + RTE_LOG(ERR, SPP_NFV, + "Queue number of out_port" + " exceeds definition" + " %s:%d nq %d(%s:%d)\n", + out_p_type, out_p_id, out_queue_id, + __func__, __LINE__); } - if (add_patch(in_port, out_port) == 0) { + if (add_patch(in_port, in_queue_id, out_port, + out_queue_id) == 0) { RTE_LOG(INFO, SPP_NFV, - "Patched '%s:%d' and '%s:%d'\n", - in_p_type, in_p_id, - out_p_type, out_p_id); + "Patched '%s' and '%s'\n", + in_res_uid, out_res_uid); sprintf(result, "%s", "\"succeeded\""); } else { RTE_LOG(ERR, SPP_NFV, "Failed to patch\n"); @@ -328,8 +354,8 @@ parse_command(char *str) } sprintf(port_set, - "{\"src\":\"%s:%d\",\"dst\":\"%s:%d\"}", - in_p_type, in_p_id, out_p_type, out_p_id); + "{\"src\":\"%s\",\"dst\":\"%s\"}", + in_res_uid, out_res_uid); memset(str, '\0', MSG_SIZE); sprintf(str, "{%s:%s,%s:%s,%s:%s}", @@ -345,11 +371,12 @@ parse_command(char *str) cmd = STOP; - ret = parse_resource_uid(token_list[1], &p_type, &p_id); + ret = parse_resource_uid(token_list[1], &p_type, &p_id, + &queue_id); if (ret < 0) return ret; - if (do_del(p_type, p_id) < 0) { + if (do_del(p_type, p_id, queue_id) < 0) { RTE_LOG(ERR, SPP_NFV, "Failed to do_del()\n"); sprintf(result, "%s", "\"failed\""); } else diff --git a/src/nfv/main.c b/src/nfv/main.c index f2c6bfc..32f1074 100644 --- a/src/nfv/main.c +++ b/src/nfv/main.c @@ -145,13 +145,14 @@ main(int argc, char *argv[]) unsigned int nb_ports; int connected = 0; char str[MSG_SIZE] = { 0 }; - unsigned int i; + unsigned int i, j; int flg_exit; // used as res of parse_command() to exit if -1 int ret; char dev_name[RTE_DEV_NAME_MAX_LEN] = { 0 }; int port_type; int nof_phy_port = 0; char log_msg[1024] = { 0 }; /* temporary log message */ + uint16_t max_queue; ret = rte_eal_init(argc, argv); if (ret < 0) @@ -218,11 +219,22 @@ main(int argc, char *argv[]) * not display to avoid confusion. */ - /* Update ports_fwd_array with phy port. */ - ports_fwd_array[i].in_port_id = i; port_map[i].port_type = port_type; port_map[i].id = port_id; port_map[i].stats = &ports->port_stats[i]; + port_map[i].queue_info = &ports->queue_info[i]; + + /* Update ports_fwd_array with phy port. */ + if (port_map[i].queue_info->rxq >= + port_map[i].queue_info->txq) + max_queue = port_map[i].queue_info->rxq; + else + max_queue = port_map[i].queue_info->txq; + + for (j = 0; j < max_queue; j++) { + ports_fwd_array[i][j].in_port_id = i; + ports_fwd_array[i][j].in_queue_id = j; + } /* TODO(yasufum) convert from int of port_type to char */ RTE_LOG(DEBUG, SPP_NFV, "Add port, type: %d, id: %d\n", diff --git a/src/nfv/nfv_status.c b/src/nfv/nfv_status.c index 3947a84..d5d7f44 100644 --- a/src/nfv/nfv_status.c +++ b/src/nfv/nfv_status.c @@ -6,6 +6,8 @@ #include #include "shared/common.h" +#include "shared/basic_forwarder.h" +#include "shared/port_manager.h" #include "nfv_status.h" /* @@ -28,9 +30,7 @@ void get_sec_stats_json(char *str, int cli_id, const char *running_stat, - uint8_t lcore_id_used[RTE_MAX_LCORE], - struct port *ports_fwd_array, - struct port_map *port_map) + uint8_t lcore_id_used[RTE_MAX_LCORE]) { sprintf(str, "{\"client-id\":%d,", cli_id); @@ -40,10 +40,10 @@ get_sec_stats_json(char *str, int cli_id, append_lcore_info_json(str, lcore_id_used); sprintf(str + strlen(str), ","); - append_port_info_json(str, ports_fwd_array, port_map); + append_port_info_json(str); sprintf(str + strlen(str), ","); - append_patch_info_json(str, ports_fwd_array, port_map); + append_patch_info_json(str); sprintf(str + strlen(str), "}"); /* Make sure to be terminated with null character. */ @@ -76,53 +76,63 @@ append_lcore_info_json(char *str, * "ports": ["phy:0", "phy:1", "ring:0", "vhost:0"] */ int -append_port_info_json(char *str, - struct port *ports_fwd_array, - struct port_map *port_map) +append_port_info_json(char *str) { - unsigned int i; + unsigned int i, j; unsigned int has_port = 0; // for checking having port at last + uint16_t max_queue; sprintf(str + strlen(str), "\"ports\":["); for (i = 0; i < RTE_MAX_ETHPORTS; i++) { + max_queue = get_port_max_queues(i); - if (ports_fwd_array[i].in_port_id == PORT_RESET) - continue; + for (j = 0; j < max_queue; j++) { + if (ports_fwd_array[i][j].in_port_id == PORT_RESET) + continue; - has_port = 1; - switch (port_map[i].port_type) { - case PHY: - sprintf(str + strlen(str), "\"phy:%u\",", - port_map[i].id); - break; - case RING: - sprintf(str + strlen(str), "\"ring:%u\",", - port_map[i].id); - break; - case VHOST: - sprintf(str + strlen(str), "\"vhost:%u\",", - port_map[i].id); - break; - case PCAP: - sprintf(str + strlen(str), "\"pcap:%u\",", - port_map[i].id); - break; - case NULLPMD: - sprintf(str + strlen(str), "\"nullpmd:%u\",", - port_map[i].id); - break; - case TAP: - sprintf(str + strlen(str), "\"tap:%u\",", + has_port = 1; + switch (port_map[i].port_type) { + case PHY: + if (max_queue == 1) + sprintf(str + strlen(str), + "\"phy:%u\",", port_map[i].id); + else + sprintf(str + strlen(str), + "\"phy:%u nq %u\",", + port_map[i].id, j); + break; + case RING: + sprintf(str + strlen(str), "\"ring:%u\",", port_map[i].id); - break; - case MEMIF: - sprintf(str + strlen(str), "\"memif:%u\",", + break; + case VHOST: + sprintf(str + strlen(str), "\"vhost:%u\",", port_map[i].id); - break; - case UNDEF: - /* TODO(yasufum) Need to remove print for undefined ? */ - sprintf(str + strlen(str), "\"udf\","); - break; + break; + case PCAP: + sprintf(str + strlen(str), "\"pcap:%u\",", + port_map[i].id); + break; + case NULLPMD: + sprintf(str + strlen(str), "\"nullpmd:%u\",", + port_map[i].id); + break; + case TAP: + sprintf(str + strlen(str), "\"tap:%u\",", + port_map[i].id); + break; + case MEMIF: + sprintf(str + strlen(str), "\"memif:%u\",", + port_map[i].id); + break; + case UNDEF: + /* + * TODO(yasufum) Need to remove print for + * undefined ? + */ + sprintf(str + strlen(str), "\"udf\","); + break; + } } } @@ -136,6 +146,57 @@ append_port_info_json(char *str, return 0; } +static void +append_port_string(char *str, enum port_type port_type, + uint16_t port_id, uint16_t queue_id, int max_queue) +{ + switch (port_type) { + case PHY: + RTE_LOG(INFO, SHARED, "Type: PHY\n"); + if (max_queue > 1) + sprintf(str, "\"phy:%u nq %u\"", port_id, queue_id); + else + sprintf(str, "\"phy:%u\"", port_id); + break; + + case RING: + RTE_LOG(INFO, SHARED, "Type: RING\n"); + sprintf(str, "\"ring:%u\"", port_id); + break; + + case VHOST: + RTE_LOG(INFO, SHARED, "Type: VHOST\n"); + sprintf(str, "\"vhost:%u\"", port_id); + break; + + case PCAP: + RTE_LOG(INFO, SHARED, "Type: PCAP\n"); + sprintf(str, "\"pcap:%u\"", port_id); + break; + + case NULLPMD: + RTE_LOG(INFO, SHARED, "Type: NULLPMD\n"); + sprintf(str, "\"nullpmd:%u\"", port_id); + break; + + case TAP: + RTE_LOG(INFO, SHARED, "Type: TAP\n"); + sprintf(str, "\"tap:%u\"", port_id); + break; + + case MEMIF: + RTE_LOG(INFO, SHARED, "Type: MEMIF\n"); + sprintf(str, "\"memif:%u\"", port_id); + break; + + case UNDEF: + RTE_LOG(INFO, SHARED, "Type: UDF\n"); + /* TODO(yasufum) Need to remove print for undefined ? */ + sprintf(str, "\"udf\""); + break; + } +} + /* * Append patch info to sec status. It is called from get_sec_stats_json() * to add a JSON formatted patch info to given 'str'. Here is an example. @@ -146,152 +207,56 @@ append_port_info_json(char *str, * ] */ int -append_patch_info_json(char *str, - struct port *ports_fwd_array, - struct port_map *port_map) +append_patch_info_json(char *str) { - unsigned int i; + unsigned int i, j; unsigned int has_patch = 0; // for checking having patch at last + unsigned int out_port_id; + uint16_t out_queue_id; + uint16_t in_max_queue, out_max_queue; char patch_str[128]; sprintf(str + strlen(str), "\"patches\":["); for (i = 0; i < RTE_MAX_ETHPORTS; i++) { + in_max_queue = get_port_max_queues(i); - if (ports_fwd_array[i].in_port_id == PORT_RESET) - continue; - - RTE_LOG(INFO, SHARED, "Port ID %d\n", i); - RTE_LOG(INFO, SHARED, "Status %d\n", - ports_fwd_array[i].in_port_id); + for (j = 0; j < in_max_queue; j++) { - memset(patch_str, '\0', sizeof(patch_str)); + if (ports_fwd_array[i][j].in_port_id == PORT_RESET || + ports_fwd_array[i][j].out_port_id == PORT_RESET) + continue; - sprintf(patch_str, "{\"src\":"); - - switch (port_map[i].port_type) { - case PHY: - RTE_LOG(INFO, SHARED, "Type: PHY\n"); - sprintf(patch_str + strlen(patch_str), - "\"phy:%u\",", - port_map[i].id); - break; - case RING: - RTE_LOG(INFO, SHARED, "Type: RING\n"); - sprintf(patch_str + strlen(patch_str), - "\"ring:%u\",", - port_map[i].id); - break; - case VHOST: - RTE_LOG(INFO, SHARED, "Type: VHOST\n"); - sprintf(patch_str + strlen(patch_str), - "\"vhost:%u\",", - port_map[i].id); - break; - case PCAP: - RTE_LOG(INFO, SHARED, "Type: PCAP\n"); - sprintf(patch_str + strlen(patch_str), - "\"pcap:%u\",", - port_map[i].id); - break; - case NULLPMD: - RTE_LOG(INFO, SHARED, "Type: NULLPMD\n"); - sprintf(patch_str + strlen(patch_str), - "\"nullpmd:%u\",", - port_map[i].id); - break; - case TAP: - RTE_LOG(INFO, SHARED, "Type: TAP\n"); - sprintf(patch_str + strlen(patch_str), - "\"tap:%u\",", - port_map[i].id); - break; - case MEMIF: - RTE_LOG(INFO, SHARED, "Type: MEMIF\n"); - sprintf(patch_str + strlen(patch_str), - "\"memif:%u\",", - port_map[i].id); - break; - case UNDEF: - RTE_LOG(INFO, SHARED, "Type: UDF\n"); - /* TODO(yasufum) Need to remove print for undefined ? */ - sprintf(patch_str + strlen(patch_str), - "\"udf\","); - break; - } - - sprintf(patch_str + strlen(patch_str), "\"dst\":"); - - RTE_LOG(INFO, SHARED, "Out Port ID %d\n", - ports_fwd_array[i].out_port_id); - - if (ports_fwd_array[i].out_port_id == PORT_RESET) { - //sprintf(patch_str + strlen(patch_str), "%s", "\"\""); - continue; - } else { has_patch = 1; - unsigned int j = ports_fwd_array[i].out_port_id; - switch (port_map[j].port_type) { - case PHY: - RTE_LOG(INFO, SHARED, "Type: PHY\n"); - sprintf(patch_str + strlen(patch_str), - "\"phy:%u\"", - port_map[j].id); - break; - case RING: - RTE_LOG(INFO, SHARED, "Type: RING\n"); - sprintf(patch_str + strlen(patch_str), - "\"ring:%u\"", - port_map[j].id); - break; - case VHOST: - RTE_LOG(INFO, SHARED, "Type: VHOST\n"); - sprintf(patch_str + strlen(patch_str), - "\"vhost:%u\"", - port_map[j].id); - break; - case PCAP: - RTE_LOG(INFO, SHARED, "Type: PCAP\n"); - sprintf(patch_str + strlen(patch_str), - "\"pcap:%u\"", - port_map[j].id); - break; - case NULLPMD: - RTE_LOG(INFO, SHARED, "Type: NULLPMD\n"); - sprintf(patch_str + strlen(patch_str), - "\"nullpmd:%u\"", - port_map[j].id); - break; - case TAP: - RTE_LOG(INFO, SHARED, "Type: TAP\n"); - sprintf(patch_str + strlen(patch_str), - "\"tap:%u\"", - port_map[j].id); - break; - case MEMIF: - RTE_LOG(INFO, SHARED, "Type: MEMIF\n"); - sprintf(patch_str + strlen(patch_str), - "\"memif:%u\"", - port_map[j].id); - break; - case UNDEF: - RTE_LOG(INFO, SHARED, "Type: UDF\n"); - /* - * TODO(yasufum) Need to remove print for - * undefined ? - */ - sprintf(patch_str + strlen(patch_str), - "\"udf\""); - break; - } - } - - sprintf(patch_str + strlen(patch_str), "},"); + RTE_LOG(INFO, SHARED, "Port ID %d\n", i); + RTE_LOG(INFO, SHARED, "Queue ID %d\n", j); + RTE_LOG(INFO, SHARED, "Status %d\n", + ports_fwd_array[i][j].in_port_id); + + memset(patch_str, '\0', sizeof(patch_str)); + + sprintf(patch_str, "{\"src\":"); + append_port_string(patch_str + strlen(patch_str), + port_map[i].port_type, port_map[i].id, + j, in_max_queue); + sprintf(patch_str + strlen(patch_str), ",\"dst\":"); + + out_port_id = ports_fwd_array[i][j].out_port_id; + out_queue_id = ports_fwd_array[i][j].out_queue_id; + RTE_LOG(INFO, SHARED, "Out Port ID %d\n", out_port_id); + RTE_LOG(INFO, SHARED, "Out Queue ID %d\n", + out_queue_id); + + out_max_queue = get_port_max_queues(out_port_id); + append_port_string(patch_str + strlen(patch_str), + port_map[out_port_id].port_type, + port_map[out_port_id].id, + out_queue_id, out_max_queue); + sprintf(patch_str + strlen(patch_str), "},"); - if (has_patch != 0) sprintf(str + strlen(str), "%s", patch_str); + } } - /* Check if it has at least one patch to remove ",". */ if (has_patch == 0) { sprintf(str + strlen(str), "]"); diff --git a/src/nfv/nfv_status.h b/src/nfv/nfv_status.h index 14225cc..cf59dde 100644 --- a/src/nfv/nfv_status.h +++ b/src/nfv/nfv_status.h @@ -8,21 +8,15 @@ /* Get status of spp_nfv or spp_vm as JSON format. */ void get_sec_stats_json(char *str, int client_id, const char *running_stat, - uint8_t lcore_id_used[RTE_MAX_LCORE], - struct port *ports_fwd_array, - struct port_map *port_map); + uint8_t lcore_id_used[RTE_MAX_LCORE]); int append_lcore_info_json(char *str, uint8_t lcore_id_used[RTE_MAX_LCORE]); /* Append port info to sec status, called from get_sec_stats_json(). */ -int append_port_info_json(char *str, - struct port *ports_fwd_array, - struct port_map *port_map); +int append_port_info_json(char *str); /* Append patch info to sec status, called from get_sec_stats_json(). */ -int append_patch_info_json(char *str, - struct port *ports_fwd_array, - struct port_map *port_map); +int append_patch_info_json(char *str); #endif -- 2.17.1