From 6a18e1af70a451f85f67b7b8c6971cf3b144520e Mon Sep 17 00:00:00 2001 From: Ouyang Changchun Date: Mon, 26 May 2014 15:45:31 +0800 Subject: [PATCH] app/testpmd: Tx rate limitation for queue and VF Signed-off-by: Ouyang Changchun Acked-by: Jijiang Liu Tested-by: Waterman Cao Acked-by: Huawei Xie --- app/test-pmd/cmdline.c | 155 +++++++++++++++++++++++++++++++++++++++++ app/test-pmd/config.c | 47 +++++++++++++ app/test-pmd/testpmd.h | 6 ++ 3 files changed, 208 insertions(+) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index f567c0c06f..4678977e5e 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -347,6 +347,13 @@ static void cmd_help_long_parsed(void *parsed_result, "MPE:accepts all multicast packets\n\n" " Enable/Disable a VF receive mode of a port\n\n" + "set port (port_id) queue (queue_id) rate (rate_num)\n" + " Set rate limit for a queue of a port\n\n" + + "set port (port_id) vf (vf_id) rate (rate_num) " + "queue_mask (queue_mask_value)\n" + " Set rate limit for queues in VF of a port\n\n" + "set port (port_id) mirror-rule (rule_id)" "(pool-mirror|vlan-mirror)\n" " (poolmask|vlanid[,vlanid]*) dst-pool (pool_id) (on|off)\n" @@ -5019,6 +5026,152 @@ cmdline_parse_inst_t cmd_vf_rxvlan_filter = { }, }; +/* *** SET RATE LIMIT FOR A QUEUE OF A PORT *** */ +struct cmd_queue_rate_limit_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t port; + uint8_t port_num; + cmdline_fixed_string_t queue; + uint8_t queue_num; + cmdline_fixed_string_t rate; + uint16_t rate_num; +}; + +static void cmd_queue_rate_limit_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_queue_rate_limit_result *res = parsed_result; + int ret = 0; + + if ((strcmp(res->set, "set") == 0) && (strcmp(res->port, "port") == 0) + && (strcmp(res->queue, "queue") == 0) + && (strcmp(res->rate, "rate") == 0)) + ret = set_queue_rate_limit(res->port_num, res->queue_num, + res->rate_num); + if (ret < 0) + printf("queue_rate_limit_cmd error: (%s)\n", strerror(-ret)); + +} + +cmdline_parse_token_string_t cmd_queue_rate_limit_set = + TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result, + set, "set"); +cmdline_parse_token_string_t cmd_queue_rate_limit_port = + TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result, + port, "port"); +cmdline_parse_token_num_t cmd_queue_rate_limit_portnum = + TOKEN_NUM_INITIALIZER(struct cmd_queue_rate_limit_result, + port_num, UINT8); +cmdline_parse_token_string_t cmd_queue_rate_limit_queue = + TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result, + queue, "queue"); +cmdline_parse_token_num_t cmd_queue_rate_limit_queuenum = + TOKEN_NUM_INITIALIZER(struct cmd_queue_rate_limit_result, + queue_num, UINT8); +cmdline_parse_token_string_t cmd_queue_rate_limit_rate = + TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result, + rate, "rate"); +cmdline_parse_token_num_t cmd_queue_rate_limit_ratenum = + TOKEN_NUM_INITIALIZER(struct cmd_queue_rate_limit_result, + rate_num, UINT16); + +cmdline_parse_inst_t cmd_queue_rate_limit = { + .f = cmd_queue_rate_limit_parsed, + .data = (void *)0, + .help_str = "set port X queue Y rate Z:(X = port number," + "Y = queue number,Z = rate number)set rate limit for a queue on port X", + .tokens = { + (void *)&cmd_queue_rate_limit_set, + (void *)&cmd_queue_rate_limit_port, + (void *)&cmd_queue_rate_limit_portnum, + (void *)&cmd_queue_rate_limit_queue, + (void *)&cmd_queue_rate_limit_queuenum, + (void *)&cmd_queue_rate_limit_rate, + (void *)&cmd_queue_rate_limit_ratenum, + NULL, + }, +}; + +/* *** SET RATE LIMIT FOR A VF OF A PORT *** */ +struct cmd_vf_rate_limit_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t port; + uint8_t port_num; + cmdline_fixed_string_t vf; + uint8_t vf_num; + cmdline_fixed_string_t rate; + uint16_t rate_num; + cmdline_fixed_string_t q_msk; + uint64_t q_msk_val; +}; + +static void cmd_vf_rate_limit_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_vf_rate_limit_result *res = parsed_result; + int ret = 0; + + if ((strcmp(res->set, "set") == 0) && (strcmp(res->port, "port") == 0) + && (strcmp(res->vf, "vf") == 0) + && (strcmp(res->rate, "rate") == 0) + && (strcmp(res->q_msk, "queue_mask") == 0)) + ret = set_vf_rate_limit(res->port_num, res->vf_num, + res->rate_num, res->q_msk_val); + if (ret < 0) + printf("vf_rate_limit_cmd error: (%s)\n", strerror(-ret)); + +} + +cmdline_parse_token_string_t cmd_vf_rate_limit_set = + TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result, + set, "set"); +cmdline_parse_token_string_t cmd_vf_rate_limit_port = + TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result, + port, "port"); +cmdline_parse_token_num_t cmd_vf_rate_limit_portnum = + TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result, + port_num, UINT8); +cmdline_parse_token_string_t cmd_vf_rate_limit_vf = + TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result, + vf, "vf"); +cmdline_parse_token_num_t cmd_vf_rate_limit_vfnum = + TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result, + vf_num, UINT8); +cmdline_parse_token_string_t cmd_vf_rate_limit_rate = + TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result, + rate, "rate"); +cmdline_parse_token_num_t cmd_vf_rate_limit_ratenum = + TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result, + rate_num, UINT16); +cmdline_parse_token_string_t cmd_vf_rate_limit_q_msk = + TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result, + q_msk, "queue_mask"); +cmdline_parse_token_num_t cmd_vf_rate_limit_q_msk_val = + TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result, + q_msk_val, UINT64); + +cmdline_parse_inst_t cmd_vf_rate_limit = { + .f = cmd_vf_rate_limit_parsed, + .data = (void *)0, + .help_str = "set port X vf Y rate Z queue_mask V:(X = port number," + "Y = VF number,Z = rate number, V = queue mask value)set rate limit " + "for queues of VF on port X", + .tokens = { + (void *)&cmd_vf_rate_limit_set, + (void *)&cmd_vf_rate_limit_port, + (void *)&cmd_vf_rate_limit_portnum, + (void *)&cmd_vf_rate_limit_vf, + (void *)&cmd_vf_rate_limit_vfnum, + (void *)&cmd_vf_rate_limit_rate, + (void *)&cmd_vf_rate_limit_ratenum, + (void *)&cmd_vf_rate_limit_q_msk, + (void *)&cmd_vf_rate_limit_q_msk_val, + NULL, + }, +}; + /* *** CONFIGURE VM MIRROR VLAN/POOL RULE *** */ struct cmd_set_mirror_mask_result { cmdline_fixed_string_t set; @@ -5461,6 +5614,8 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_vf_mac_addr_filter , (cmdline_parse_inst_t *)&cmd_set_vf_traffic, (cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter, + (cmdline_parse_inst_t *)&cmd_queue_rate_limit, + (cmdline_parse_inst_t *)&cmd_vf_rate_limit, (cmdline_parse_inst_t *)&cmd_set_mirror_mask, (cmdline_parse_inst_t *)&cmd_set_mirror_link, (cmdline_parse_inst_t *)&cmd_reset_mirror_rule, diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 584aeeea90..52ad01abc1 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1824,3 +1824,50 @@ set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id, uint64_t vf_mask, uint8_t on) "diag=%d\n", port_id, diag); } +int +set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate) +{ + int diag; + struct rte_eth_link link; + + if (port_id_is_invalid(port_id)) + return 1; + rte_eth_link_get_nowait(port_id, &link); + if (rate > link.link_speed) { + printf("Invalid rate value:%u bigger than link speed: %u\n", + rate, link.link_speed); + return 1; + } + diag = rte_eth_set_queue_rate_limit(port_id, queue_idx, rate); + if (diag == 0) + return diag; + printf("rte_eth_set_queue_rate_limit for port_id=%d failed diag=%d\n", + port_id, diag); + return diag; +} + +int +set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk) +{ + int diag; + struct rte_eth_link link; + + if (q_msk == 0) + return 0; + + if (port_id_is_invalid(port_id)) + return 1; + rte_eth_link_get_nowait(port_id, &link); + if (rate > link.link_speed) { + printf("Invalid rate value:%u bigger than link speed: %u\n", + rate, link.link_speed); + return 1; + } + diag = rte_eth_set_vf_rate_limit(port_id, vf, rate, q_msk); + if (diag == 0) + return diag; + printf("rte_eth_set_vf_rate_limit for port_id=%d failed diag=%d\n", + port_id, diag); + return diag; +} + diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 16611f00d2..4fabf1c880 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -525,11 +525,17 @@ void fdir_update_perfect_filter(portid_t port_id, uint16_t soft_id, void fdir_remove_perfect_filter(portid_t port_id, uint16_t soft_id, struct rte_fdir_filter *fdir_filter); void fdir_set_masks(portid_t port_id, struct rte_fdir_masks *fdir_masks); + void port_rss_reta_info(portid_t port_id, struct rte_eth_rss_reta *reta_conf); + void set_vf_traffic(portid_t port_id, uint8_t is_rx, uint16_t vf, uint8_t on); void set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id, uint64_t vf_mask, uint8_t on); +int set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate); +int set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, + uint64_t q_msk); + void port_rss_hash_conf_show(portid_t port_id, int show_rss_key); void port_rss_hash_key_update(portid_t port_id, uint8_t *hash_key); -- 2.20.1