[dpdk-stable] patch 'net/cxgbe: fix slot allocation for IPv6 flows' has been queued to LTS release 18.11.6
Kevin Traynor
ktraynor at redhat.com
Tue Dec 3 19:26:25 CET 2019
Hi,
FYI, your patch has been queued to LTS release 18.11.6
Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 12/10/19. So please
shout if anyone has objections.
Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.
Queued patches are on a temporary branch at:
https://github.com/kevintraynor/dpdk-stable-queue
This queued commit can be viewed at:
https://github.com/kevintraynor/dpdk-stable-queue/commit/16c88049ae286623e8fb0b6cd5997b3081add248
Thanks.
Kevin.
---
>From 16c88049ae286623e8fb0b6cd5997b3081add248 Mon Sep 17 00:00:00 2001
From: Rahul Lakkireddy <rahul.lakkireddy at chelsio.com>
Date: Sat, 28 Sep 2019 02:00:03 +0530
Subject: [PATCH] net/cxgbe: fix slot allocation for IPv6 flows
[ upstream commit 31d4d2334672fe9d96a0d23cdf914c1f219f932f ]
IPv6 flows occupy only 2 slots on Chelsio T6 NICs. Fix the slot
calculation logic to return correct number of slots.
Fixes: ee61f5113b17 ("net/cxgbe: parse and validate flows")
Fixes: 9eb2c9a48072 ("net/cxgbe: implement flow create operation")
Fixes: 3f2c1e209cfc ("net/cxgbe: add Compressed Local IP region")
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy at chelsio.com>
---
drivers/net/cxgbe/cxgbe_filter.c | 197 +++++++++++--------------------
drivers/net/cxgbe/cxgbe_filter.h | 5 +-
drivers/net/cxgbe/cxgbe_flow.c | 15 ++-
3 files changed, 87 insertions(+), 130 deletions(-)
diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index 461b71ebe..8cd26212f 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -213,18 +213,30 @@ static inline void mk_set_tcb_field_ulp(struct filter_entry *f,
/**
- * Check if entry already filled.
+ * IPv6 requires 2 slots on T6 and 4 slots for cards below T6.
+ * IPv4 requires only 1 slot on all cards.
*/
-bool cxgbe_is_filter_set(struct tid_info *t, int fidx, int family)
+u8 cxgbe_filter_slots(struct adapter *adap, u8 family)
+{
+ if (family == FILTER_TYPE_IPV6) {
+ if (CHELSIO_CHIP_VERSION(adap->params.chip) < CHELSIO_T6)
+ return 4;
+
+ return 2;
+ }
+
+ return 1;
+}
+
+/**
+ * Check if entries are already filled.
+ */
+bool cxgbe_is_filter_set(struct tid_info *t, u32 fidx, u8 nentries)
{
bool result = FALSE;
- int i, max;
-
- /* IPv6 requires four slots and IPv4 requires only 1 slot.
- * Ensure, there's enough slots available.
- */
- max = family == FILTER_TYPE_IPV6 ? fidx + 3 : fidx;
+ u32 i;
+ /* Ensure there's enough slots available. */
t4_os_lock(&t->ftid_lock);
- for (i = fidx; i <= max; i++) {
+ for (i = fidx; i < fidx + nentries; i++) {
if (rte_bitmap_get(t->ftid_bmap, i)) {
result = TRUE;
@@ -237,7 +249,7 @@ bool cxgbe_is_filter_set(struct tid_info *t, int fidx, int family)
/**
- * Allocate a available free entry
+ * Allocate available free entries.
*/
-int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family)
+int cxgbe_alloc_ftid(struct adapter *adap, u8 nentries)
{
struct tid_info *t = &adap->tids;
@@ -246,6 +258,7 @@ int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family)
t4_os_lock(&t->ftid_lock);
- if (family == FILTER_TYPE_IPV6)
- pos = cxgbe_bitmap_find_free_region(t->ftid_bmap, size, 4);
+ if (nentries > 1)
+ pos = cxgbe_bitmap_find_free_region(t->ftid_bmap, size,
+ nentries);
else
pos = cxgbe_find_first_zero_bit(t->ftid_bmap, size);
@@ -565,5 +578,5 @@ static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
goto out_err;
- if (f->fs.type) {
+ if (f->fs.type == FILTER_TYPE_IPV6) {
/* IPv6 hash filter */
f->clipt = cxgbe_clip_alloc(f->dev, (u32 *)&f->fs.val.lip);
@@ -804,9 +817,10 @@ out:
/**
- * Set the corresponding entry in the bitmap. 4 slots are
- * marked for IPv6, whereas only 1 slot is marked for IPv4.
+ * Set the corresponding entries in the bitmap.
*/
-static int cxgbe_set_ftid(struct tid_info *t, int fidx, int family)
+static int cxgbe_set_ftid(struct tid_info *t, u32 fidx, u8 nentries)
{
+ u32 i;
+
t4_os_lock(&t->ftid_lock);
if (rte_bitmap_get(t->ftid_bmap, fidx)) {
@@ -815,12 +829,6 @@ static int cxgbe_set_ftid(struct tid_info *t, int fidx, int family)
}
- if (family == FILTER_TYPE_IPV4) {
- rte_bitmap_set(t->ftid_bmap, fidx);
- } else {
- rte_bitmap_set(t->ftid_bmap, fidx);
- rte_bitmap_set(t->ftid_bmap, fidx + 1);
- rte_bitmap_set(t->ftid_bmap, fidx + 2);
- rte_bitmap_set(t->ftid_bmap, fidx + 3);
- }
+ for (i = fidx; i < fidx + nentries; i++)
+ rte_bitmap_set(t->ftid_bmap, i);
t4_os_unlock(&t->ftid_lock);
return 0;
@@ -828,18 +836,13 @@ static int cxgbe_set_ftid(struct tid_info *t, int fidx, int family)
/**
- * Clear the corresponding entry in the bitmap. 4 slots are
- * cleared for IPv6, whereas only 1 slot is cleared for IPv4.
+ * Clear the corresponding entries in the bitmap.
*/
-static void cxgbe_clear_ftid(struct tid_info *t, int fidx, int family)
+static void cxgbe_clear_ftid(struct tid_info *t, u32 fidx, u8 nentries)
{
+ u32 i;
+
t4_os_lock(&t->ftid_lock);
- if (family == FILTER_TYPE_IPV4) {
- rte_bitmap_clear(t->ftid_bmap, fidx);
- } else {
- rte_bitmap_clear(t->ftid_bmap, fidx);
- rte_bitmap_clear(t->ftid_bmap, fidx + 1);
- rte_bitmap_clear(t->ftid_bmap, fidx + 2);
- rte_bitmap_clear(t->ftid_bmap, fidx + 3);
- }
+ for (i = fidx; i < fidx + nentries; i++)
+ rte_bitmap_clear(t->ftid_bmap, i);
t4_os_unlock(&t->ftid_lock);
}
@@ -859,4 +862,5 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
struct filter_entry *f;
unsigned int chip_ver;
+ u8 nentries;
int ret;
@@ -869,16 +873,9 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
- ret = cxgbe_is_filter_set(&adapter->tids, filter_id, fs->type);
- if (!ret) {
- dev_warn(adap, "%s: could not find filter entry: %u\n",
- __func__, filter_id);
- return -EINVAL;
- }
-
/*
- * Ensure filter id is aligned on the 2 slot boundary for T6,
+ * Ensure IPv6 filter id is aligned on the 2 slot boundary for T6,
* and 4 slot boundary for cards below T6.
*/
- if (fs->type) {
+ if (fs->type == FILTER_TYPE_IPV6) {
if (chip_ver < CHELSIO_T6)
filter_id &= ~(0x3);
@@ -887,4 +884,12 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
}
+ nentries = cxgbe_filter_slots(adapter, fs->type);
+ ret = cxgbe_is_filter_set(&adapter->tids, filter_id, nentries);
+ if (!ret) {
+ dev_warn(adap, "%s: could not find filter entry: %u\n",
+ __func__, filter_id);
+ return -EINVAL;
+ }
+
f = &adapter->tids.ftid_tab[filter_id];
ret = writable_filter(f);
@@ -896,6 +901,5 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
cxgbe_clear_ftid(&adapter->tids,
f->tid - adapter->tids.ftid_base,
- f->fs.type ? FILTER_TYPE_IPV6 :
- FILTER_TYPE_IPV4);
+ nentries);
return del_filter_wr(dev, filter_id);
}
@@ -927,8 +931,8 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
struct port_info *pi = ethdev2pinfo(dev);
struct adapter *adapter = pi->adapter;
- unsigned int fidx, iq, fid_bit = 0;
+ unsigned int fidx, iq;
struct filter_entry *f;
unsigned int chip_ver;
- uint8_t bitoff[16] = {0};
+ u8 nentries, bitoff[16] = {0};
int ret;
@@ -945,17 +949,4 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
return ret;
- /*
- * Ensure filter id is aligned on the 4 slot boundary for IPv6
- * maskfull filters.
- */
- if (fs->type)
- filter_id &= ~(0x3);
-
- ret = cxgbe_is_filter_set(&adapter->tids, filter_id, fs->type);
- if (ret)
- return -EBUSY;
-
- iq = get_filter_steerq(dev, fs);
-
/*
* IPv6 filters occupy four slots and must be aligned on four-slot
@@ -964,60 +955,24 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
*
* IPv4 filters only occupy a single slot and have no alignment
- * requirements but writing a new IPv4 filter into the middle
- * of an existing IPv6 filter requires clearing the old IPv6
- * filter.
+ * requirements.
*/
- if (fs->type == FILTER_TYPE_IPV4) { /* IPv4 */
- /*
- * For T6, If our IPv4 filter isn't being written to a
- * multiple of two filter index and there's an IPv6
- * filter at the multiple of 2 base slot, then we need
- * to delete that IPv6 filter ...
- * For adapters below T6, IPv6 filter occupies 4 entries.
- */
+ fidx = filter_id;
+ if (fs->type == FILTER_TYPE_IPV6) {
if (chip_ver < CHELSIO_T6)
- fidx = filter_id & ~0x3;
+ fidx &= ~(0x3);
else
- fidx = filter_id & ~0x1;
-
- if (fidx != filter_id && adapter->tids.ftid_tab[fidx].fs.type) {
- f = &adapter->tids.ftid_tab[fidx];
- if (f->valid)
- return -EBUSY;
- }
- } else { /* IPv6 */
- unsigned int max_filter_id;
-
- if (chip_ver < CHELSIO_T6) {
- /*
- * Ensure that the IPv6 filter is aligned on a
- * multiple of 4 boundary.
- */
- if (filter_id & 0x3)
- return -EINVAL;
-
- max_filter_id = filter_id + 4;
- } else {
- /*
- * For T6, CLIP being enabled, IPv6 filter would occupy
- * 2 entries.
- */
- if (filter_id & 0x1)
- return -EINVAL;
-
- max_filter_id = filter_id + 2;
- }
-
- /*
- * Check all except the base overlapping IPv4 filter
- * slots.
- */
- for (fidx = filter_id + 1; fidx < max_filter_id; fidx++) {
- f = &adapter->tids.ftid_tab[fidx];
- if (f->valid)
- return -EBUSY;
- }
+ fidx &= ~(0x1);
}
+ if (fidx != filter_id)
+ return -EINVAL;
+
+ nentries = cxgbe_filter_slots(adapter, fs->type);
+ ret = cxgbe_is_filter_set(&adapter->tids, filter_id, nentries);
+ if (ret)
+ return -EBUSY;
+
+ iq = get_filter_steerq(dev, fs);
+
/*
* Check to make sure that provided filter index is not
@@ -1029,7 +984,5 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
fidx = adapter->tids.ftid_base + filter_id;
- fid_bit = filter_id;
- ret = cxgbe_set_ftid(&adapter->tids, fid_bit,
- fs->type ? FILTER_TYPE_IPV6 : FILTER_TYPE_IPV4);
+ ret = cxgbe_set_ftid(&adapter->tids, filter_id, nentries);
if (ret)
return ret;
@@ -1041,7 +994,5 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
if (ret) {
/* Clear the bits we have set above */
- cxgbe_clear_ftid(&adapter->tids, fid_bit,
- fs->type ? FILTER_TYPE_IPV6 :
- FILTER_TYPE_IPV4);
+ cxgbe_clear_ftid(&adapter->tids, filter_id, nentries);
return ret;
}
@@ -1074,15 +1025,11 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
f->tid = fidx; /* Save the actual tid */
ret = set_filter_wr(dev, filter_id);
- if (ret) {
- fid_bit = f->tid - adapter->tids.ftid_base;
+ if (ret)
goto free_tid;
- }
return ret;
free_tid:
- cxgbe_clear_ftid(&adapter->tids, fid_bit,
- fs->type ? FILTER_TYPE_IPV6 :
- FILTER_TYPE_IPV4);
+ cxgbe_clear_ftid(&adapter->tids, filter_id, nentries);
clear_filter(f);
return ret;
diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h
index 6738ae4f1..06bac8ef0 100644
--- a/drivers/net/cxgbe/cxgbe_filter.h
+++ b/drivers/net/cxgbe/cxgbe_filter.h
@@ -249,5 +249,6 @@ cxgbe_bitmap_find_free_region(struct rte_bitmap *bmap, unsigned int size,
}
-bool cxgbe_is_filter_set(struct tid_info *, int fidx, int family);
+u8 cxgbe_filter_slots(struct adapter *adap, u8 family);
+bool cxgbe_is_filter_set(struct tid_info *t, u32 fidx, u8 nentries);
void cxgbe_filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl);
int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
@@ -257,5 +258,5 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
struct ch_filter_specification *fs,
struct filter_ctx *ctx);
-int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family);
+int cxgbe_alloc_ftid(struct adapter *adap, u8 nentries);
int cxgbe_init_hash_filter(struct adapter *adap);
void cxgbe_hash_filter_rpl(struct adapter *adap,
diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index 17d5608fa..f8f3d0a22 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -305,4 +305,5 @@ static int cxgbe_validate_fidxondel(struct filter_entry *f, unsigned int fidx)
struct adapter *adap = ethdev2adap(f->dev);
struct ch_filter_specification fs = f->fs;
+ u8 nentries;
if (fidx >= adap->tids.nftids) {
@@ -310,5 +311,7 @@ static int cxgbe_validate_fidxondel(struct filter_entry *f, unsigned int fidx)
return -EINVAL;
}
- if (!cxgbe_is_filter_set(&adap->tids, fidx, fs.type)) {
+
+ nentries = cxgbe_filter_slots(adap, fs.type);
+ if (!cxgbe_is_filter_set(&adap->tids, fidx, nentries)) {
dev_err(adap, "Already free fidx:%d f:%p\n", fidx, f);
return -EINVAL;
@@ -322,8 +325,12 @@ cxgbe_validate_fidxonadd(struct ch_filter_specification *fs,
struct adapter *adap, unsigned int fidx)
{
- if (cxgbe_is_filter_set(&adap->tids, fidx, fs->type)) {
+ u8 nentries;
+
+ nentries = cxgbe_filter_slots(adap, fs->type);
+ if (cxgbe_is_filter_set(&adap->tids, fidx, nentries)) {
dev_err(adap, "filter index: %d is busy.\n", fidx);
return -EBUSY;
}
+
if (fidx >= adap->tids.nftids) {
dev_err(adap, "filter index (%u) >= max(%u)\n",
@@ -352,7 +359,9 @@ static int cxgbe_get_fidx(struct rte_flow *flow, unsigned int *fidx)
/* For tcam get the next available slot, if default value specified */
if (flow->fidx == FILTER_ID_MAX) {
+ u8 nentries;
int idx;
- idx = cxgbe_alloc_ftid(adap, fs->type);
+ nentries = cxgbe_filter_slots(adap, fs->type);
+ idx = cxgbe_alloc_ftid(adap, nentries);
if (idx < 0) {
dev_err(adap, "unable to get a filter index in tcam\n");
--
2.21.0
---
Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- - 2019-12-03 17:29:52.751531199 +0000
+++ 0016-net-cxgbe-fix-slot-allocation-for-IPv6-flows.patch 2019-12-03 17:29:51.716750661 +0000
@@ -1 +1 @@
-From 31d4d2334672fe9d96a0d23cdf914c1f219f932f Mon Sep 17 00:00:00 2001
+From 16c88049ae286623e8fb0b6cd5997b3081add248 Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit 31d4d2334672fe9d96a0d23cdf914c1f219f932f ]
+
@@ -12 +13,0 @@
-Cc: stable at dpdk.org
@@ -22 +23 @@
-index 3b7966d04..33b95a69a 100644
+index 461b71ebe..8cd26212f 100644
@@ -25 +26 @@
-@@ -214,18 +214,30 @@ static inline void mk_set_tcb_field_ulp(struct filter_entry *f,
+@@ -213,18 +213,30 @@ static inline void mk_set_tcb_field_ulp(struct filter_entry *f,
@@ -65 +66 @@
-@@ -238,7 +250,7 @@ bool cxgbe_is_filter_set(struct tid_info *t, int fidx, int family)
+@@ -237,7 +249,7 @@ bool cxgbe_is_filter_set(struct tid_info *t, int fidx, int family)
@@ -75 +76 @@
-@@ -247,6 +259,7 @@ int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family)
+@@ -246,6 +258,7 @@ int cxgbe_alloc_ftid(struct adapter *adap, unsigned int family)
@@ -85 +86 @@
-@@ -566,5 +579,5 @@ static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
+@@ -565,5 +578,5 @@ static int cxgbe_set_hash_filter(struct rte_eth_dev *dev,
@@ -92 +93 @@
-@@ -805,9 +818,10 @@ out:
+@@ -804,9 +817,10 @@ out:
@@ -106 +107 @@
-@@ -816,12 +830,6 @@ static int cxgbe_set_ftid(struct tid_info *t, int fidx, int family)
+@@ -815,12 +829,6 @@ static int cxgbe_set_ftid(struct tid_info *t, int fidx, int family)
@@ -121 +122 @@
-@@ -829,18 +837,13 @@ static int cxgbe_set_ftid(struct tid_info *t, int fidx, int family)
+@@ -828,18 +836,13 @@ static int cxgbe_set_ftid(struct tid_info *t, int fidx, int family)
@@ -146 +147 @@
-@@ -860,4 +863,5 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
+@@ -859,4 +862,5 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
@@ -152 +153 @@
-@@ -870,16 +874,9 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
+@@ -869,16 +873,9 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
@@ -171 +172 @@
-@@ -888,4 +885,12 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
+@@ -887,4 +884,12 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
@@ -184 +185 @@
-@@ -897,6 +902,5 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
+@@ -896,6 +901,5 @@ int cxgbe_del_filter(struct rte_eth_dev *dev, unsigned int filter_id,
@@ -192 +193 @@
-@@ -928,8 +932,8 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
+@@ -927,8 +931,8 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
@@ -203 +204 @@
-@@ -946,17 +950,4 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
+@@ -945,17 +949,4 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
@@ -221 +222 @@
-@@ -965,60 +956,24 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
+@@ -964,60 +955,24 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
@@ -297 +298 @@
-@@ -1030,7 +985,5 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
+@@ -1029,7 +984,5 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
@@ -306 +307 @@
-@@ -1042,7 +995,5 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
+@@ -1041,7 +994,5 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
@@ -315 +316 @@
-@@ -1075,15 +1026,11 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
+@@ -1074,15 +1025,11 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
@@ -334 +335 @@
-index 1964730ba..06021c854 100644
+index 6738ae4f1..06bac8ef0 100644
@@ -353 +354 @@
-index 848c61f02..8a5d06ff3 100644
+index 17d5608fa..f8f3d0a22 100644
More information about the stable
mailing list