From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 08E5DA054D; Tue, 16 Feb 2021 21:22:04 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7814516079D; Tue, 16 Feb 2021 21:21:41 +0100 (CET) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mails.dpdk.org (Postfix) with ESMTP id C146D160786 for ; Tue, 16 Feb 2021 21:21:37 +0100 (CET) IronPort-SDR: u9sA7dowNbliW+PzxdL3z1GPt+5UvucrJ+Sq+1vblDAFVuD07YabhOM5FQ2koU9OfDUfYItdTZ VaqXFAwI4oaA== X-IronPort-AV: E=McAfee;i="6000,8403,9897"; a="247073870" X-IronPort-AV: E=Sophos;i="5.81,184,1610438400"; d="scan'208";a="247073870" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2021 12:21:31 -0800 IronPort-SDR: aSFknpYX/j9r46rGwnFJzb8KsXpdCyxyh1nuTVc2cZBIQLUFCujjCOow30eQEgPBKuEHfI2/Aq BZcHRlH5iBKg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,184,1610438400"; d="scan'208";a="592507246" Received: from silpixa00400573.ir.intel.com (HELO silpixa00400573.ger.corp.intel.com) ([10.237.223.107]) by fmsmga005.fm.intel.com with ESMTP; 16 Feb 2021 12:21:27 -0800 From: Cristian Dumitrescu To: dev@dpdk.org Date: Tue, 16 Feb 2021 20:21:23 +0000 Message-Id: <20210216202127.22803-1-cristian.dumitrescu@intel.com> X-Mailer: git-send-email 2.17.1 Subject: [dpdk-dev] [PATCH v2 1/5] pipeline: improve table entry helpers X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Improve the internal table entry helper routines for key comparison, entry duplication and checks. Signed-off-by: Cristian Dumitrescu --- lib/librte_pipeline/rte_swx_ctl.c | 120 ++++++++++++++++-------------- 1 file changed, 65 insertions(+), 55 deletions(-) diff --git a/lib/librte_pipeline/rte_swx_ctl.c b/lib/librte_pipeline/rte_swx_ctl.c index ee6df4544..62ce3086d 100644 --- a/lib/librte_pipeline/rte_swx_ctl.c +++ b/lib/librte_pipeline/rte_swx_ctl.c @@ -234,6 +234,26 @@ table_entry_alloc(struct table *table) return NULL; } +static int +table_entry_key_check_em(struct table *table, struct rte_swx_table_entry *entry) +{ + uint8_t *key_mask0 = table->params.key_mask0; + uint32_t key_size = table->params.key_size, i; + + if (!entry->key_mask) + return 0; + + for (i = 0; i < key_size; i++) { + uint8_t km0 = key_mask0[i]; + uint8_t km = entry->key_mask[i]; + + if ((km & km0) != km0) + return -EINVAL; + } + + return 0; +} + static int table_entry_check(struct rte_swx_ctl_pipeline *ctl, uint32_t table_id, @@ -242,6 +262,7 @@ table_entry_check(struct rte_swx_ctl_pipeline *ctl, int data_check) { struct table *table = &ctl->tables[table_id]; + int status; CHECK(entry, EINVAL); @@ -266,7 +287,9 @@ table_entry_check(struct rte_swx_ctl_pipeline *ctl, break; case RTE_SWX_TABLE_MATCH_EXACT: - CHECK(!entry->key_mask, EINVAL); + status = table_entry_key_check_em(table, entry); + if (status) + return status; break; default: @@ -327,10 +350,7 @@ table_entry_duplicate(struct rte_swx_ctl_pipeline *ctl, new_entry->key_signature = entry->key_signature; /* key_mask. */ - if (table->params.match_type != RTE_SWX_TABLE_MATCH_EXACT) { - if (!entry->key_mask) - goto error; - + if (entry->key_mask) { new_entry->key_mask = malloc(table->params.key_size); if (!new_entry->key_mask) goto error; @@ -357,18 +377,24 @@ table_entry_duplicate(struct rte_swx_ctl_pipeline *ctl, /* action_data. */ a = &ctl->actions[entry->action_id]; - if (a->data_size) { - if (!entry->action_data) - goto error; + if (a->data_size && !entry->action_data) + goto error; - new_entry->action_data = malloc(a->data_size); - if (!new_entry->action_data) - goto error; + /* The table layer provisions a constant action data size per + * entry, which should be the largest data size for all the + * actions enabled for the current table, and atempts to copy + * this many bytes each time a table entry is added, even if the + * specific action requires less data or even no data at all, + * hence we always have to allocate the max. + */ + new_entry->action_data = calloc(1, table->params.action_data_size); + if (!new_entry->action_data) + goto error; + if (a->data_size) memcpy(new_entry->action_data, entry->action_data, a->data_size); - } } return new_entry; @@ -378,58 +404,36 @@ table_entry_duplicate(struct rte_swx_ctl_pipeline *ctl, return NULL; } -static int -entry_keycmp_em(struct rte_swx_table_entry *e0, - struct rte_swx_table_entry *e1, - uint32_t key_size) -{ - if (e0->key_signature != e1->key_signature) - return 1; /* Not equal. */ - - if (memcmp(e0->key, e1->key, key_size)) - return 1; /* Not equal. */ - - return 0; /* Equal */ -} - -static int -entry_keycmp_wm(struct rte_swx_table_entry *e0 __rte_unused, - struct rte_swx_table_entry *e1 __rte_unused, - uint32_t key_size __rte_unused) -{ - /* TBD */ - - return 1; /* Not equal */ -} - -static int -entry_keycmp_lpm(struct rte_swx_table_entry *e0 __rte_unused, - struct rte_swx_table_entry *e1 __rte_unused, - uint32_t key_size __rte_unused) -{ - /* TBD */ - - return 1; /* Not equal */ -} - static int table_entry_keycmp(struct table *table, struct rte_swx_table_entry *e0, struct rte_swx_table_entry *e1) { - switch (table->params.match_type) { - case RTE_SWX_TABLE_MATCH_EXACT: - return entry_keycmp_em(e0, e1, table->params.key_size); + uint32_t key_size = table->params.key_size; + uint32_t i; + + for (i = 0; i < key_size; i++) { + uint8_t *key_mask0 = table->params.key_mask0; + uint8_t km0, km[2], k[2]; + + km0 = key_mask0 ? key_mask0[i] : 0xFF; + + km[0] = e0->key_mask ? e0->key_mask[i] : 0xFF; + km[1] = e1->key_mask ? e1->key_mask[i] : 0xFF; - case RTE_SWX_TABLE_MATCH_WILDCARD: - return entry_keycmp_wm(e0, e1, table->params.key_size); + k[0] = e0->key[i]; + k[1] = e1->key[i]; - case RTE_SWX_TABLE_MATCH_LPM: - return entry_keycmp_lpm(e0, e1, table->params.key_size); + /* Mask comparison. */ + if ((km[0] & km0) != (km[1] & km0)) + return 1; /* Not equal. */ - default: - return 1; /* Not equal. */ + /* Value comparison. */ + if ((k[0] & km[0] & km0) != (k[1] & km[1] & km0)) + return 1; /* Not equal. */ } + + return 0; /* Equal. */ } static struct rte_swx_table_entry * @@ -893,6 +897,9 @@ rte_swx_ctl_pipeline_table_entry_add(struct rte_swx_ctl_pipeline *ctl, CHECK(table, EINVAL); table_id = table - ctl->tables; + CHECK(entry, EINVAL); + CHECK(!table_entry_check(ctl, table_id, entry, 1, 1), EINVAL); + new_entry = table_entry_duplicate(ctl, table_id, entry, 1, 1); CHECK(new_entry, ENOMEM); @@ -1095,6 +1102,9 @@ rte_swx_ctl_pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *ctl, table_id = table - ctl->tables; CHECK(!table->info.default_action_is_const, EINVAL); + CHECK(entry, EINVAL); + CHECK(!table_entry_check(ctl, table_id, entry, 0, 1), EINVAL); + new_entry = table_entry_duplicate(ctl, table_id, entry, 0, 1); CHECK(new_entry, ENOMEM); -- 2.17.1