From patchwork Wed Sep 20 09:56:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jasvinder Singh X-Patchwork-Id: 28994 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 620E91B194; Wed, 20 Sep 2017 11:45:07 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 3DDA0199B6 for ; Wed, 20 Sep 2017 11:44:59 +0200 (CEST) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2017 02:44:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.42,420,1500966000"; d="scan'208";a="130609065" Received: from silpixa00381635.ir.intel.com (HELO silpixa00381635.ger.corp.intel.com) ([10.237.222.149]) by orsmga004.jf.intel.com with ESMTP; 20 Sep 2017 02:44:57 -0700 From: Jasvinder Singh To: dev@dpdk.org Cc: cristian.dumitrescu@intel.com, jingjing.wu@intel.com, pablo.de.lara.guarch@intel.com Date: Wed, 20 Sep 2017 10:56:53 +0100 Message-Id: <20170920095653.110750-5-jasvinder.singh@intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170920095653.110750-1-jasvinder.singh@intel.com> References: <20170914115302.33995-1-jasvinder.singh@intel.com> <20170920095653.110750-1-jasvinder.singh@intel.com> Subject: [dpdk-dev] [PATCH v3 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 | 11 ++ app/test-pmd/cmdline_tm.c | 305 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 316 insertions(+) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 70a376a..480fe4b 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -702,6 +702,13 @@ static void cmd_help_long_parsed(void *parsed_result, "port tm hierarchy commit (port_id) (clean_on_fail)\n" " Commit tm hierarchy.\n\n" + "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() ); @@ -14275,6 +14282,8 @@ extern cmdline_parse_inst_t cmd_del_port_tm_node; extern cmdline_parse_inst_t cmd_set_port_tm_node_parent; #endif extern cmdline_parse_inst_t cmd_port_tm_hierarchy_commit; +extern cmdline_parse_inst_t cmd_set_port_tm_pktfield; +extern cmdline_parse_inst_t cmd_set_port_tm_tc_table; #endif /* *********************************************************************** */ @@ -14488,6 +14497,8 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent, #endif (cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit, + (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 b36326d..829442f 100644 --- a/app/test-pmd/cmdline_tm.c +++ b/app/test-pmd/cmdline_tm.c @@ -2197,3 +2197,308 @@ cmdline_parse_inst_t cmd_port_tm_hierarchy_commit = { NULL, }, }; + +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, + }, +};