From patchwork Thu Mar 29 18:31:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jasvinder Singh X-Patchwork-Id: 36693 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 4BC2B728E; Thu, 29 Mar 2018 20:32:53 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id 581704CBD for ; Thu, 29 Mar 2018 20:32:21 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 29 Mar 2018 11:32:21 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,378,1517904000"; d="scan'208";a="216058873" Received: from silpixa00381635.ir.intel.com (HELO silpixa00381635.ger.corp.intel.com) ([10.237.222.149]) by fmsmga005.fm.intel.com with ESMTP; 29 Mar 2018 11:32:20 -0700 From: Jasvinder Singh To: dev@dpdk.org Cc: cristian.dumitrescu@intel.com Date: Thu, 29 Mar 2018 19:31:29 +0100 Message-Id: <20180329183208.103844-11-jasvinder.singh@intel.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20180329183208.103844-1-jasvinder.singh@intel.com> References: <20180316175906.159198-2-jasvinder.singh@intel.com> <20180329183208.103844-1-jasvinder.singh@intel.com> Subject: [dpdk-dev] [PATCH v4 10/49] pipeline: add load balance action 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 implementation of the load balance action. Signed-off-by: Cristian Dumitrescu --- lib/librte_pipeline/rte_table_action.c | 102 +++++++++++++++++++++++++++++++++ lib/librte_pipeline/rte_table_action.h | 52 +++++++++++++++++ 2 files changed, 154 insertions(+) diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c index 1a32c71..83ffa5d 100644 --- a/lib/librte_pipeline/rte_table_action.c +++ b/lib/librte_pipeline/rte_table_action.c @@ -45,6 +45,55 @@ fwd_apply(struct fwd_data *data, } /** + * RTE_TABLE_ACTION_LB + */ +static int +lb_cfg_check(struct rte_table_action_lb_config *cfg) +{ + if ((cfg == NULL) || + (cfg->key_size < RTE_TABLE_ACTION_LB_KEY_SIZE_MIN) || + (cfg->key_size > RTE_TABLE_ACTION_LB_KEY_SIZE_MAX) || + (!rte_is_power_of_2(cfg->key_size)) || + (cfg->f_hash == NULL)) + return -1; + + return 0; +} + +struct lb_data { + uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE]; +} __attribute__((__packed__)); + +static int +lb_apply(struct lb_data *data, + struct rte_table_action_lb_params *p) +{ + memcpy(data->out, p->out, sizeof(data->out)); + + return 0; +} + +static __rte_always_inline void +pkt_work_lb(struct rte_mbuf *mbuf, + struct lb_data *data, + struct rte_table_action_lb_config *cfg) +{ + uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->key_offset); + uint32_t *out = RTE_MBUF_METADATA_UINT32_PTR(mbuf, cfg->out_offset); + uint64_t digest, pos; + uint32_t out_val; + + digest = cfg->f_hash(pkt_key, + cfg->key_mask, + cfg->key_size, + cfg->seed); + pos = digest & (RTE_TABLE_ACTION_LB_TABLE_SIZE - 1); + out_val = data->out[pos]; + + *out = out_val; +} + +/** * RTE_TABLE_ACTION_MTR */ static int @@ -1178,6 +1227,7 @@ action_valid(enum rte_table_action_type action) { switch (action) { case RTE_TABLE_ACTION_FWD: + case RTE_TABLE_ACTION_LB: case RTE_TABLE_ACTION_MTR: case RTE_TABLE_ACTION_TM: case RTE_TABLE_ACTION_ENCAP: @@ -1197,6 +1247,7 @@ action_valid(enum rte_table_action_type action) struct ap_config { uint64_t action_mask; struct rte_table_action_common_config common; + struct rte_table_action_lb_config lb; struct rte_table_action_mtr_config mtr; struct rte_table_action_tm_config tm; struct rte_table_action_encap_config encap; @@ -1209,6 +1260,8 @@ static size_t action_cfg_size(enum rte_table_action_type action) { switch (action) { + case RTE_TABLE_ACTION_LB: + return sizeof(struct rte_table_action_lb_config); case RTE_TABLE_ACTION_MTR: return sizeof(struct rte_table_action_mtr_config); case RTE_TABLE_ACTION_TM: @@ -1231,6 +1284,9 @@ action_cfg_get(struct ap_config *ap_config, enum rte_table_action_type type) { switch (type) { + case RTE_TABLE_ACTION_LB: + return &ap_config->lb; + case RTE_TABLE_ACTION_MTR: return &ap_config->mtr; @@ -1280,6 +1336,9 @@ action_data_size(enum rte_table_action_type action, case RTE_TABLE_ACTION_FWD: return sizeof(struct fwd_data); + case RTE_TABLE_ACTION_LB: + return sizeof(struct lb_data); + case RTE_TABLE_ACTION_MTR: return mtr_data_size(&ap_config->mtr); @@ -1373,6 +1432,10 @@ rte_table_action_profile_action_register(struct rte_table_action_profile *profil return -EINVAL; switch (type) { + case RTE_TABLE_ACTION_LB: + status = lb_cfg_check(action_config); + break; + case RTE_TABLE_ACTION_MTR: status = mtr_cfg_check(action_config); break; @@ -1507,6 +1570,10 @@ rte_table_action_apply(struct rte_table_action *action, return fwd_apply(action_data, action_params); + case RTE_TABLE_ACTION_LB: + return lb_apply(action_data, + action_params); + case RTE_TABLE_ACTION_MTR: return mtr_apply(action_data, action_params, @@ -1822,6 +1889,14 @@ pkt_work(struct rte_mbuf *mbuf, rte_ntohs(hdr->payload_len) + sizeof(struct ipv6_hdr); } + if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) { + void *data = + action_data_get(table_entry, action, RTE_TABLE_ACTION_LB); + + pkt_work_lb(mbuf, + data, + &cfg->lb); + } if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) { void *data = action_data_get(table_entry, action, RTE_TABLE_ACTION_MTR); @@ -1961,6 +2036,33 @@ pkt4_work(struct rte_mbuf **mbufs, rte_ntohs(hdr3->payload_len) + sizeof(struct ipv6_hdr); } + if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) { + void *data0 = + action_data_get(table_entry0, action, RTE_TABLE_ACTION_LB); + void *data1 = + action_data_get(table_entry1, action, RTE_TABLE_ACTION_LB); + void *data2 = + action_data_get(table_entry2, action, RTE_TABLE_ACTION_LB); + void *data3 = + action_data_get(table_entry3, action, RTE_TABLE_ACTION_LB); + + pkt_work_lb(mbuf0, + data0, + &cfg->lb); + + pkt_work_lb(mbuf1, + data1, + &cfg->lb); + + pkt_work_lb(mbuf2, + data2, + &cfg->lb); + + pkt_work_lb(mbuf3, + data3, + &cfg->lb); + } + if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) { void *data0 = action_data_get(table_entry0, action, RTE_TABLE_ACTION_MTR); diff --git a/lib/librte_pipeline/rte_table_action.h b/lib/librte_pipeline/rte_table_action.h index e9b30ab..c7f751a 100644 --- a/lib/librte_pipeline/rte_table_action.h +++ b/lib/librte_pipeline/rte_table_action.h @@ -61,6 +61,7 @@ extern "C" { #include #include #include +#include #include "rte_pipeline.h" @@ -69,6 +70,9 @@ enum rte_table_action_type { /** Forward to next pipeline table, output port or drop. */ RTE_TABLE_ACTION_FWD = 0, + /** Load balance. */ + RTE_TABLE_ACTION_LB, + /** Traffic Metering and Policing. */ RTE_TABLE_ACTION_MTR, @@ -117,6 +121,54 @@ struct rte_table_action_fwd_params { }; /** + * RTE_TABLE_ACTION_LB + */ +/** Load balance key size min (number of bytes). */ +#define RTE_TABLE_ACTION_LB_KEY_SIZE_MIN 8 + +/** Load balance key size max (number of bytes). */ +#define RTE_TABLE_ACTION_LB_KEY_SIZE_MAX 64 + +/** Load balance table size. */ +#define RTE_TABLE_ACTION_LB_TABLE_SIZE 8 + +/** Load balance action configuration (per table action profile). */ +struct rte_table_action_lb_config { + /** Key size (number of bytes). */ + uint32_t key_size; + + /** Key offset within the input packet buffer. Offset 0 points to the + * first byte of the MBUF structure. + */ + uint32_t key_offset; + + /** Key mask (*key_size* bytes are valid). */ + uint8_t key_mask[RTE_TABLE_ACTION_LB_KEY_SIZE_MAX]; + + /** Hash function. */ + rte_table_hash_op_hash f_hash; + + /** Seed value for *f_hash*. */ + uint64_t seed; + + /** Output value offset within the input packet buffer. Offset 0 points + * to the first byte of the MBUF structure. + */ + uint32_t out_offset; +}; + +/** Load balance action parameters (per table rule). */ +struct rte_table_action_lb_params { + /** Table defining the output values and their weights. The weights are + * set in 1/RTE_TABLE_ACTION_LB_TABLE_SIZE increments. To assign a + * weight of N/RTE_TABLE_ACTION_LB_TABLE_SIZE to a given output value + * (0 <= N <= RTE_TABLE_ACTION_LB_TABLE_SIZE), the same output value + * needs to show up exactly N times in this table. + */ + uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE]; +}; + +/** * RTE_TABLE_ACTION_MTR */ /** Max number of traffic classes (TCs). */