From patchwork Fri Sep 22 16:35:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jasvinder Singh X-Patchwork-Id: 29127 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id BE4A11B1A4; Fri, 22 Sep 2017 18:23:17 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 4CEC61B19C for ; Fri, 22 Sep 2017 18:23:12 +0200 (CEST) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Sep 2017 09:23:12 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.42,427,1500966000"; d="scan'208";a="152276275" Received: from silpixa00381635.ir.intel.com (HELO silpixa00381635.ger.corp.intel.com) ([10.237.222.149]) by orsmga005.jf.intel.com with ESMTP; 22 Sep 2017 09:23:10 -0700 From: Jasvinder Singh To: dev@dpdk.org Cc: cristian.dumitrescu@intel.com, jingjing.wu@intel.com, pablo.de.lara.guarch@intel.com Date: Fri, 22 Sep 2017 17:35:06 +0100 Message-Id: <20170922163506.12437-5-jasvinder.singh@intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170922163506.12437-1-jasvinder.singh@intel.com> References: <20170920095653.110750-1-jasvinder.singh@intel.com> <20170922163506.12437-1-jasvinder.singh@intel.com> Subject: [dpdk-dev] [PATCH v4 5/5] app/test-pmd: add CLI for TM packet classification X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" Add following CLIs in testpmd application; - command to set the packet field mask and offset value for classification. - command to set traffic class translation table entry Signed-off-by: Jasvinder Singh --- app/test-pmd/cmdline.c | 13 ++ app/test-pmd/cmdline_tm.c | 309 +++++++++++++++++++++++++++++++++++++++++ app/test-pmd/testpmd_cmdline.h | 4 + 3 files changed, 326 insertions(+) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index de7f487..cc0a505 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -700,6 +700,15 @@ static void cmd_help_long_parsed(void *parsed_result, "port tm hierarchy commit (port_id) (clean_on_fail)\n" " Commit tm hierarchy.\n\n" +#if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED + "set port tm pktfield (subport|pipe|tc) (port_id) offset" + " (offset) mask (mask)\n" + " Set port tm packet field.\n\n" + + "set port tm tc table (port_id) index (tb_index) tc (tc_id)" + " queue (queue id)\n" + " Set port tm traffic class table entry.\n\n" +#endif , list_pkt_forwarding_modes() ); } @@ -14460,6 +14469,10 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_del_port_tm_node, (cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent, (cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit, +#if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED + (cmdline_parse_inst_t *)&cmd_set_port_tm_pktfield, + (cmdline_parse_inst_t *)&cmd_set_port_tm_tc_table, +#endif NULL, }; diff --git a/app/test-pmd/cmdline_tm.c b/app/test-pmd/cmdline_tm.c index 5fc946d..ddeb45b 100644 --- a/app/test-pmd/cmdline_tm.c +++ b/app/test-pmd/cmdline_tm.c @@ -1890,3 +1890,312 @@ cmdline_parse_inst_t cmd_port_tm_hierarchy_commit = { NULL, }, }; + +#if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED + +static int +port_tm_pktfield_validate_mask(uint64_t mask, uint64_t n) +{ + int count = __builtin_popcountll(mask); + int pos_lead = sizeof(uint64_t) * 8 - __builtin_clzll(mask); + int pos_trail = __builtin_ctzll(mask); + int count_expected = __builtin_popcount(n - 1); + + /* Handle the exceptions */ + if (n == 0) + return -1; /* Error */ + + if ((mask == 0) && (n == 1)) + return 0; /* OK */ + + if (((mask == 0) && (n != 1)) || ((mask != 0) && (n == 1))) + return -2; /* Error */ + + /* Check that mask is contiguous */ + if ((pos_lead - pos_trail) != count) + return -3; /* Error */ + + /* Check that mask contains the expected number of bits set */ + if (count != count_expected) + return -4; /* Error */ + + return 0; /* OK */ + } + +/* *** Set Port TM Packet Fields *** */ +struct cmd_set_port_tm_pktfield_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t port; + cmdline_fixed_string_t tm; + cmdline_fixed_string_t pktfield; + cmdline_fixed_string_t type; + uint8_t port_id; + cmdline_fixed_string_t offset_string; + uint32_t offset; + cmdline_fixed_string_t mask_string; + uint64_t mask; +}; + +cmdline_parse_token_string_t cmd_set_port_tm_pktfield_set = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_pktfield_result, set, "set"); +cmdline_parse_token_string_t cmd_set_port_tm_pktfield_port = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_pktfield_result, port, "port"); +cmdline_parse_token_string_t cmd_set_port_tm_pktfield_tm = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_pktfield_result, tm, "tm"); +cmdline_parse_token_string_t cmd_set_port_tm_pktfield_pktfield = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_pktfield_result, + pktfield, "pktfield"); +cmdline_parse_token_string_t cmd_set_port_tm_pktfield_type = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_pktfield_result, + type, "subport#pipe#tc"); +cmdline_parse_token_num_t cmd_set_port_tm_pktfield_port_id = + TOKEN_NUM_INITIALIZER( + struct cmd_set_port_tm_pktfield_result, + port_id, UINT8); +cmdline_parse_token_string_t cmd_set_port_tm_pktfield_offset_string = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_pktfield_result, + offset_string, "offset"); +cmdline_parse_token_num_t cmd_set_port_tm_pktfield_offset = + TOKEN_NUM_INITIALIZER( + struct cmd_set_port_tm_pktfield_result, + offset, UINT32); +cmdline_parse_token_string_t cmd_set_port_tm_pktfield_mask_string = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_pktfield_result, + mask_string, "mask"); +cmdline_parse_token_num_t cmd_set_port_tm_pktfield_mask = + TOKEN_NUM_INITIALIZER( + struct cmd_set_port_tm_pktfield_result, + mask, UINT64); + +static void cmd_set_port_tm_pktfield_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_port_tm_pktfield_result *res = parsed_result; + struct rte_port *p; + uint32_t offset = res->offset; + uint64_t mask = res->mask; + uint8_t port_id = res->port_id; + int ret; + + if (port_id_is_invalid(port_id, ENABLED_WARN)) + return; + + p = &ports[port_id]; + + /* Port tm flag */ + if (p->softport.tm_flag == 0) { + printf(" tm not enabled on port %u (error)\n", port_id); + return; + } + + /* Forward mode: tm */ + if (strcmp(cur_fwd_config.fwd_eng->fwd_mode_name, "tm")) { + printf(" tm mode not enabled(error)\n"); + return; + } + + /* Subport */ + if (strcmp(res->type, "subport") == 0) { + uint32_t n = p->softport.tm.n_subports_per_port; + + ret = port_tm_pktfield_validate_mask(mask, n); + if (ret) { + printf(" invalid subport mask(error %d)", ret); + return; + } + /* Set packet field */ + p->softport.tm.tm_pktfield0_slabpos = offset; + p->softport.tm.tm_pktfield0_slabmask = mask; + p->softport.tm.tm_pktfield0_slabshr = __builtin_ctzll(mask); + return; + } + + /* Pipe */ + if (strcmp(res->type, "pipe") == 0) { + uint32_t n = p->softport.tm.n_pipes_per_subport; + + ret = port_tm_pktfield_validate_mask(mask, n); + if (ret) { + printf(" invalid pipe mask(error %d)", ret); + return; + } + /* Set packet field */ + p->softport.tm.tm_pktfield1_slabpos = offset; + p->softport.tm.tm_pktfield1_slabmask = mask; + p->softport.tm.tm_pktfield1_slabshr = __builtin_ctzll(mask); + return; + } + + /* Traffic class */ + if (strcmp(res->type, "tc") == 0) { + uint32_t n = RTE_DIM(p->softport.tm.tm_tc_table); + + ret = port_tm_pktfield_validate_mask(mask, n); + if (ret) { + printf(" invalid tc mask(error %d)", ret); + return; + } + /* Set packet field */ + p->softport.tm.tm_pktfield1_slabpos = offset; + p->softport.tm.tm_pktfield1_slabmask = mask; + p->softport.tm.tm_pktfield1_slabshr = __builtin_ctzll(mask); + return; + } +} + +cmdline_parse_inst_t cmd_set_port_tm_pktfield = { + .f = cmd_set_port_tm_pktfield_parsed, + .data = NULL, + .help_str = "Set port tm pktfield", + .tokens = { + (void *)&cmd_set_port_tm_pktfield_set, + (void *)&cmd_set_port_tm_pktfield_port, + (void *)&cmd_set_port_tm_pktfield_tm, + (void *)&cmd_set_port_tm_pktfield_pktfield, + (void *)&cmd_set_port_tm_pktfield_type, + (void *)&cmd_set_port_tm_pktfield_port_id, + (void *)&cmd_set_port_tm_pktfield_offset_string, + (void *)&cmd_set_port_tm_pktfield_offset, + (void *)&cmd_set_port_tm_pktfield_mask_string, + (void *)&cmd_set_port_tm_pktfield_mask, + NULL, + }, +}; + +/* *** Set Port TM Traffic Class Table Entry *** */ +struct cmd_set_port_tm_tc_table_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t port; + cmdline_fixed_string_t tm; + cmdline_fixed_string_t tc_table; + uint8_t port_id; + cmdline_fixed_string_t index_string; + uint32_t index; + cmdline_fixed_string_t tc_string; + uint32_t tc; + cmdline_fixed_string_t queue_string; + uint32_t queue; +}; + +cmdline_parse_token_string_t cmd_set_port_tm_tc_table_set = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_tc_table_result, set, "set"); +cmdline_parse_token_string_t cmd_set_port_tm_tc_table_port = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_tc_table_result, port, "port"); +cmdline_parse_token_string_t cmd_set_port_tm_tc_table_tm = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_tc_table_result, tm, "tm"); +cmdline_parse_token_string_t cmd_set_port_tm_tc_table_tc_table = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_tc_table_result, + tc_table, "tc table"); +cmdline_parse_token_num_t cmd_set_port_tm_tc_table_port_id = + TOKEN_NUM_INITIALIZER( + struct cmd_set_port_tm_tc_table_result, + port_id, UINT8); +cmdline_parse_token_string_t cmd_set_port_tm_tc_table_index_string = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_tc_table_result, + index_string, "index"); +cmdline_parse_token_num_t cmd_set_port_tm_tc_table_index = + TOKEN_NUM_INITIALIZER( + struct cmd_set_port_tm_tc_table_result, + index, UINT32); +cmdline_parse_token_string_t cmd_set_port_tm_tc_table_tc_string = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_tc_table_result, + tc_string, "tc"); +cmdline_parse_token_num_t cmd_set_port_tm_tc_table_tc = + TOKEN_NUM_INITIALIZER( + struct cmd_set_port_tm_tc_table_result, + tc, UINT32); +cmdline_parse_token_string_t cmd_set_port_tm_tc_table_queue_string = + TOKEN_STRING_INITIALIZER( + struct cmd_set_port_tm_tc_table_result, + queue_string, "queue"); +cmdline_parse_token_num_t cmd_set_port_tm_tc_table_queue = + TOKEN_NUM_INITIALIZER( + struct cmd_set_port_tm_tc_table_result, + queue, UINT32); + +static void cmd_set_port_tm_tc_table_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_port_tm_tc_table_result *res = parsed_result; + struct rte_port *p; + uint32_t tc = res->tc; + uint32_t index = res->index; + uint32_t queue = res->queue; + uint32_t val; + uint8_t port_id = res->port_id; + + if (port_id_is_invalid(port_id, ENABLED_WARN)) + return; + + p = &ports[port_id]; + + /* Port tm flag */ + if (p->softport.tm_flag == 0) { + printf(" tm not enabled on port %u (error)\n", port_id); + return; + } + + /* Forward mode: tm */ + if (strcmp(cur_fwd_config.fwd_eng->fwd_mode_name, "tm")) { + printf(" tm mode not enabled(error)\n"); + return; + } + + /* Traffic class table index */ + if (tc >= RTE_DIM(p->softport.tm.tm_tc_table)) { + printf(" invalid traffic class table index(error)\n"); + return; + } + + /* Traffic class id */ + if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) { + printf(" invalid traffic class id(error)\n"); + return; + } + + /* Traffic class queue */ + if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) { + printf(" invalid traffic class queue(error)\n"); + return; + } + + val = tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue; + p->softport.tm.tm_tc_table[index] = val; +} + +cmdline_parse_inst_t cmd_set_port_tm_tc_table = { + .f = cmd_set_port_tm_tc_table_parsed, + .data = NULL, + .help_str = "Set port tm TC table entry", + .tokens = { + (void *)&cmd_set_port_tm_tc_table_set, + (void *)&cmd_set_port_tm_tc_table_port, + (void *)&cmd_set_port_tm_tc_table_tm, + (void *)&cmd_set_port_tm_tc_table_tc_table, + (void *)&cmd_set_port_tm_tc_table_port_id, + (void *)&cmd_set_port_tm_tc_table_index_string, + (void *)&cmd_set_port_tm_tc_table_index, + (void *)&cmd_set_port_tm_tc_table_tc_string, + (void *)&cmd_set_port_tm_tc_table_tc, + (void *)&cmd_set_port_tm_tc_table_queue_string, + (void *)&cmd_set_port_tm_tc_table_queue, + NULL, + }, +}; + +#endif diff --git a/app/test-pmd/testpmd_cmdline.h b/app/test-pmd/testpmd_cmdline.h index 4fa7cc4..b6ca8c4 100755 --- a/app/test-pmd/testpmd_cmdline.h +++ b/app/test-pmd/testpmd_cmdline.h @@ -52,5 +52,9 @@ extern cmdline_parse_inst_t cmd_add_port_tm_leaf_node; extern cmdline_parse_inst_t cmd_del_port_tm_node; extern cmdline_parse_inst_t cmd_set_port_tm_node_parent; extern cmdline_parse_inst_t cmd_port_tm_hierarchy_commit; +#if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED +extern cmdline_parse_inst_t cmd_set_port_tm_pktfield; +extern cmdline_parse_inst_t cmd_set_port_tm_tc_table; +#endif #endif /* _TESTPMD_CMDLINE_H_ */