DPDK patches and discussions
 help / color / mirror / Atom feed
From: Ophir Munk <ophirmu@mellanox.com>
To: dev@dpdk.org, Pascal Mazon <pascal.mazon@6wind.com>
Cc: Thomas Monjalon <thomas@monjalon.net>,
	Olga Shern <olgas@mellanox.com>,
	Ophir Munk <ophirmu@mellanox.com>
Subject: [dpdk-dev] [PATCH v2 2/2] net/tap: fix eBPF RSS map key handling
Date: Tue, 30 Jan 2018 16:00:29 +0000	[thread overview]
Message-ID: <1517328029-17052-3-git-send-email-ophirmu@mellanox.com> (raw)
In-Reply-To: <1517328029-17052-1-git-send-email-ophirmu@mellanox.com>

This commit addresses a case of RSS and non RSS flows mixture.
In the corrupted code, if a non-RSS flow is destroyed, it has an eBPF map
index 0 (initialized upon flow creation). This might unintentionally remove
RSS entry 0 from eBPF map.
To fix this issue, add an offset to the real index during a KEY_CMD_GET
operation, and subtract this offset during a KEY_CMD_RELEASE operation, in
order to restore the real index.
Thus, if a non RSS flow is falsely trying to release map entry 0 - The
offset subtraction will calculate the real map index as an
out-of-range value, and the release operation will be silently ignored.

Fixes: 036d721a8229 ("net/tap: implement RSS using eBPF")

Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
 drivers/net/tap/tap_flow.c | 47 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 533879d..18cfb91 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -1797,6 +1797,7 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error)
 }
 
 #define MAX_RSS_KEYS 256
+#define KEY_IDX_OFFSET (3 * MAX_RSS_KEYS)
 #define SEC_NAME_CLS_Q "cls_q"
 
 const char *sec_name[SEC_MAX] = {
@@ -1953,38 +1954,62 @@ static int rss_enable(struct pmd_internals *pmd,
 static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
 {
 	__u32 i;
-	int err = -1;
+	int err = 0;
 	static __u32 num_used_keys;
 	static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC};
 	static __u32 rss_keys_initialized;
 
 	switch (cmd) {
 	case KEY_CMD_GET:
-		if (!rss_keys_initialized)
+		if (!rss_keys_initialized) {
+			err = -1;
 			break;
+		}
 
-		if (num_used_keys == RTE_DIM(rss_keys))
+		if (num_used_keys == RTE_DIM(rss_keys)) {
+			err = -1;
 			break;
+		}
 
 		*key_idx = num_used_keys % RTE_DIM(rss_keys);
 		while (rss_keys[*key_idx] == KEY_STAT_USED)
 			*key_idx = (*key_idx + 1) % RTE_DIM(rss_keys);
 
 		rss_keys[*key_idx] = KEY_STAT_USED;
+
+		/*
+		 * Add an offset to key_idx in order to handle a case of
+		 * RSS and non RSS flows mixture.
+		 * If a non RSS flow is destroyed it has an eBPF map
+		 * index 0 (initialized on flow creation) and might
+		 * unintentionally remove RSS entry 0 from eBPF map.
+		 * To avoid this issue, add an offset to the real index
+		 * during a KEY_CMD_GET operation and subtract this offset
+		 * during a KEY_CMD_RELEASE operation in order to restore
+		 * the real index.
+		 */
+		*key_idx += KEY_IDX_OFFSET;
 		num_used_keys++;
-		err = 0;
 	break;
 
 	case KEY_CMD_RELEASE:
-		if (!rss_keys_initialized) {
-			err = 0;
+		if (!rss_keys_initialized)
+			break;
+
+		/*
+		 * Subtract offest to restore real key index
+		 * If a non RSS flow is falsely trying to release map
+		 * entry 0 - the offset subtraction will calculate the real
+		 * map index as an out-of-range value and the release operation
+		 * will be silently ignored.
+		 */
+		__u32 key = *key_idx - KEY_IDX_OFFSET;
+		if (key >= RTE_DIM(rss_keys))
 			break;
-		}
 
-		if (rss_keys[*key_idx] == KEY_STAT_USED) {
-			rss_keys[*key_idx] = KEY_STAT_AVAILABLE;
+		if (rss_keys[key] == KEY_STAT_USED) {
+			rss_keys[key] = KEY_STAT_AVAILABLE;
 			num_used_keys--;
-			err = 0;
 		}
 	break;
 
@@ -1994,7 +2019,6 @@ static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
 
 		rss_keys_initialized = 1;
 		num_used_keys = 0;
-		err = 0;
 	break;
 
 	case KEY_CMD_DEINIT:
@@ -2003,7 +2027,6 @@ static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
 
 		rss_keys_initialized = 0;
 		num_used_keys = 0;
-		err = 0;
 	break;
 
 	default:
-- 
2.7.4

  parent reply	other threads:[~2018-01-30 16:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-29 11:18 [dpdk-dev] [PATCH v1] net/tap: fix eBPF file descriptors leakage Ophir Munk
2018-01-30 16:00 ` [dpdk-dev] [PATCH v2 0/2] fix eBPF TAP RSS leakage and map key handling Ophir Munk
2018-01-30 16:00   ` [dpdk-dev] [PATCH v2 1/2] net/tap: fix eBPF file descriptors leakage Ophir Munk
2018-01-30 16:00   ` Ophir Munk [this message]
2018-01-30 16:10   ` [dpdk-dev] [PATCH v2 0/2] fix eBPF TAP RSS leakage and map key handling Pascal Mazon
2018-01-31 18:52     ` Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1517328029-17052-3-git-send-email-ophirmu@mellanox.com \
    --to=ophirmu@mellanox.com \
    --cc=dev@dpdk.org \
    --cc=olgas@mellanox.com \
    --cc=pascal.mazon@6wind.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).