All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/5] Mellanox driver update Jul-16-2014
@ 2014-07-16  8:57 Amir Vadai
  2014-07-16  8:57 ` [PATCH net-next 1/5] net/mlx4_core: Fix leakage of SW multicast entries Amir Vadai
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Amir Vadai @ 2014-07-16  8:57 UTC (permalink / raw
  To: David S. Miller; +Cc: netdev, Or Gerlitz, Yevgeny Petrilin, Amir Vadai

Hi,

This patchset contains some bug fixes related to MCG table management (flow
steering) in Mellanox NIC.

Fixes were applied and tested over commit 0854a7f ("Merge branch
'amd811e-cleanups'").

Thanks,
Amir

Alexander Guller (1):
  net/mlx4_core: Make sure the max number of QPs per MCG isn't exceeded

Dotan Barak (1):
  net/mlx4_core: Make sure that negative array index isn't used

Eugenia Emantayev (1):
  net/mlx4_core: In SR-IOV mode host should add promisc QP to default
    entry only

Saeed Mahameed (1):
  net/mlx4_core: Remove MCG in case it is attached to promiscuous QPs
    only

Yevgeny Petrilin (1):
  net/mlx4_core: Fix leakage of SW multicast entries

 drivers/net/ethernet/mellanox/mlx4/mcg.c | 279 +++++++++++++++++++++----------
 1 file changed, 188 insertions(+), 91 deletions(-)

-- 
1.8.3.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH net-next 1/5] net/mlx4_core: Fix leakage of SW multicast entries
  2014-07-16  8:57 [PATCH net-next 0/5] Mellanox driver update Jul-16-2014 Amir Vadai
@ 2014-07-16  8:57 ` Amir Vadai
  2014-07-16  8:57 ` [PATCH net-next 2/5] net/mlx4_core: Make sure that negative array index isn't used Amir Vadai
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Amir Vadai @ 2014-07-16  8:57 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, Or Gerlitz, Yevgeny Petrilin, Amir Vadai,
	Yevgeny Petrilin, Eugenia Emantayev

From: Yevgeny Petrilin <yevgenyp@mellanox.co.il>

When removing multicast address in B0 steering mode there is
a bug in cases where there is a single QP registered for the address,
and this QP is also promiscuous. In such cases the entry wouldn't be
deleted from the SW structure representing all Ethernet MCG entries,
but would be removed in HW. This way when driver goes to remove it
from SW and HW structures the HW deletion fails.
Moreover the same index could later be used for registering
different address, which can be Infiniband.


Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/mcg.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 4c36def..14a4071 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -363,8 +363,20 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
 	ret = true;
 	list_for_each_entry_safe(entry, tmp_entry, &s_steer->steer_entries[steer], list) {
 		if (entry->index == index) {
-			if (list_empty(&entry->duplicates)) {
+			if (list_empty(&entry->duplicates) ||
+			    members_count == 1) {
+				struct mlx4_promisc_qp *pqp, *tmp_pqp;
+				/* If there is only 1 entry in duplicates then
+				 * this is the QP we want to delete, going over
+				 * the list and deleting the entry.
+				 */
 				list_del(&entry->list);
+				list_for_each_entry_safe(pqp, tmp_pqp,
+							 &entry->duplicates,
+							 list) {
+					list_del(&pqp->list);
+					kfree(pqp);
+				}
 				kfree(entry);
 			} else {
 				/* This entry contains duplicates so it shouldn't be removed */
-- 
1.8.3.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH net-next 2/5] net/mlx4_core: Make sure that negative array index isn't used
  2014-07-16  8:57 [PATCH net-next 0/5] Mellanox driver update Jul-16-2014 Amir Vadai
  2014-07-16  8:57 ` [PATCH net-next 1/5] net/mlx4_core: Fix leakage of SW multicast entries Amir Vadai
@ 2014-07-16  8:57 ` Amir Vadai
  2014-07-16  8:57 ` [PATCH net-next 3/5] net/mlx4_core: Make sure the max number of QPs per MCG isn't exceeded Amir Vadai
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Amir Vadai @ 2014-07-16  8:57 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, Or Gerlitz, Yevgeny Petrilin, Amir Vadai, Dotan Barak,
	Eugenia Emantayev

From: Dotan Barak <dotanb@dev.mellanox.co.il>

To make sure that the array index isn't used in the code with
negative value, we stop using the for loop integer iterator
outside of it.
>From now on use members count to swap the last QP with removed one.
Fix also the second occurrence of this flow in mlx4_qp_detach_common().
In mlx4_qp_detach_common() use members_count instead of
loop iterator outside of the for loop.


Signed-off-by: Dotan Barak <dotanb@dev.mellanox.co.il>
Reviewed-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/mcg.c | 38 ++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 14a4071..04a8636 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -513,7 +513,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
 	u32 members_count;
 	bool found;
 	bool back_to_list = false;
-	int loc, i;
+	int i;
 	int err;
 
 	if (port < 1 || port > dev->caps.num_ports)
@@ -565,18 +565,30 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
 			list_del(&dqp->list);
 			kfree(dqp);
 		} else {
+			int loc = -1;
 			err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
 				if (err)
 					goto out_mailbox;
 			members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
-			for (loc = -1, i = 0; i < members_count; ++i)
-				if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn)
+			for (i = 0; i < members_count; ++i)
+				if ((be32_to_cpu(mgm->qp[i]) &
+				     MGM_QPN_MASK) == qpn) {
 					loc = i;
+					break;
+				}
+
+			if (loc < 0) {
+				mlx4_err(dev, "QP %06x wasn't found in entry %d\n",
+					 qpn, entry->index);
+				err = -EINVAL;
+				goto out_mailbox;
+			}
 
+			/* copy the last QP in this MGM over removed QP */
+			mgm->qp[loc] = mgm->qp[members_count - 1];
+			mgm->qp[members_count - 1] = 0;
 			mgm->members_count = cpu_to_be32(--members_count |
 							 (MLX4_PROT_ETH << 30));
-			mgm->qp[loc] = mgm->qp[i - 1];
-			mgm->qp[i - 1] = 0;
 
 			err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
 				if (err)
@@ -1074,7 +1086,7 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
 	struct mlx4_mgm *mgm;
 	u32 members_count;
 	int prev, index;
-	int i, loc;
+	int i, loc = -1;
 	int err;
 	u8 port = gid[5];
 	bool removed_entry = false;
@@ -1103,9 +1115,11 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
 		goto out;
 
 	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
-	for (loc = -1, i = 0; i < members_count; ++i)
-		if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn)
+	for (i = 0; i < members_count; ++i)
+		if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) {
 			loc = i;
+			break;
+		}
 
 	if (loc == -1) {
 		mlx4_err(dev, "QP %06x not found in MGM\n", qp->qpn);
@@ -1113,15 +1127,15 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
 		goto out;
 	}
 
-
+	/* copy the last QP in this MGM over removed QP */
+	mgm->qp[loc] = mgm->qp[members_count - 1];
+	mgm->qp[members_count - 1] = 0;
 	mgm->members_count = cpu_to_be32(--members_count | (u32) prot << 30);
-	mgm->qp[loc]       = mgm->qp[i - 1];
-	mgm->qp[i - 1]     = 0;
 
 	if (prot == MLX4_PROT_ETH)
 		removed_entry = can_remove_steering_entry(dev, port, steer,
 								index, qp->qpn);
-	if (i != 1 && (prot != MLX4_PROT_ETH || !removed_entry)) {
+	if (members_count && (prot != MLX4_PROT_ETH || !removed_entry)) {
 		err = mlx4_WRITE_ENTRY(dev, index, mailbox);
 		goto out;
 	}
-- 
1.8.3.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH net-next 3/5] net/mlx4_core: Make sure the max number of QPs per MCG isn't exceeded
  2014-07-16  8:57 [PATCH net-next 0/5] Mellanox driver update Jul-16-2014 Amir Vadai
  2014-07-16  8:57 ` [PATCH net-next 1/5] net/mlx4_core: Fix leakage of SW multicast entries Amir Vadai
  2014-07-16  8:57 ` [PATCH net-next 2/5] net/mlx4_core: Make sure that negative array index isn't used Amir Vadai
@ 2014-07-16  8:57 ` Amir Vadai
  2014-07-16  8:57 ` [PATCH net-next 4/5] net/mlx4_core: In SR-IOV mode host should add promisc QP to default entry only Amir Vadai
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Amir Vadai @ 2014-07-16  8:57 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, Or Gerlitz, Yevgeny Petrilin, Amir Vadai,
	Alexander Guller, Eugenia Emantayev

From: Alexander Guller <alexg@mellanox.com>

In B0 steering mode when adding QPs to the default MCG entry need
to check that maximal number of QPs per MCG entry was not exceeded.


Signed-off-by: Alexander Guller <alexg@mellanox.com>
Reviewed-by: Aviad Yehezkel <aviadye@mellanox.co.il>
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/mcg.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 04a8636..39ab85a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -477,8 +477,14 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
 	/* now need to add all the promisc qps to default entry */
 	memset(mgm, 0, sizeof *mgm);
 	members_count = 0;
-	list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list)
+	list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list) {
+		if (members_count == dev->caps.num_qp_per_mgm) {
+			/* entry is full */
+			err = -ENOMEM;
+			goto out_list;
+		}
 		mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
+	}
 	mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30);
 
 	err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox);
-- 
1.8.3.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH net-next 4/5] net/mlx4_core: In SR-IOV mode host should add promisc QP to default entry only
  2014-07-16  8:57 [PATCH net-next 0/5] Mellanox driver update Jul-16-2014 Amir Vadai
                   ` (2 preceding siblings ...)
  2014-07-16  8:57 ` [PATCH net-next 3/5] net/mlx4_core: Make sure the max number of QPs per MCG isn't exceeded Amir Vadai
@ 2014-07-16  8:57 ` Amir Vadai
  2014-07-16  8:57 ` [PATCH net-next 5/5] net/mlx4_core: Remove MCG in case it is attached to promiscuous QPs only Amir Vadai
  2014-07-17  6:26 ` [PATCH net-next 0/5] Mellanox driver update Jul-16-2014 David Miller
  5 siblings, 0 replies; 7+ messages in thread
From: Amir Vadai @ 2014-07-16  8:57 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, Or Gerlitz, Yevgeny Petrilin, Amir Vadai,
	Eugenia Emantayev

From: Eugenia Emantayev <eugenia@mellanox.com>

In current situation host is adding the promiscuous QP to all steering
entries and the default entry as well. In this case when having PV
and SR-IOV on the same setup bridge will receive all traffic that is
targeted to the other VMs. This is bad.
Solution: In SR-IOV mode host can add promiscuous QP to default entry only.
The above problem and fix are relevant for B0 steering mode only.


Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/mcg.c | 169 ++++++++++++++++++-------------
 1 file changed, 99 insertions(+), 70 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 39ab85a..9d92bc2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -433,43 +433,58 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
 	}
 	mgm = mailbox->buf;
 
-	/* the promisc qp needs to be added for each one of the steering
-	 * entries, if it already exists, needs to be added as a duplicate
-	 * for this entry */
-	list_for_each_entry(entry, &s_steer->steer_entries[steer], list) {
-		err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
-		if (err)
-			goto out_mailbox;
+	if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
+		/* The promisc QP needs to be added for each one of the steering
+		 * entries. If it already exists, needs to be added as
+		 * a duplicate for this entry.
+		 */
+		list_for_each_entry(entry,
+				    &s_steer->steer_entries[steer],
+				    list) {
+			err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
+			if (err)
+				goto out_mailbox;
 
-		members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
-		prot = be32_to_cpu(mgm->members_count) >> 30;
-		found = false;
-		for (i = 0; i < members_count; i++) {
-			if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) {
-				/* Entry already exists, add to duplicates */
-				dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
-				if (!dqp) {
+			members_count = be32_to_cpu(mgm->members_count) &
+					0xffffff;
+			prot = be32_to_cpu(mgm->members_count) >> 30;
+			found = false;
+			for (i = 0; i < members_count; i++) {
+				if ((be32_to_cpu(mgm->qp[i]) &
+				     MGM_QPN_MASK) == qpn) {
+					/* Entry already exists.
+					 * Add to duplicates.
+					 */
+					dqp = kmalloc(sizeof(*dqp), GFP_KERNEL);
+					if (!dqp) {
+						err = -ENOMEM;
+						goto out_mailbox;
+					}
+					dqp->qpn = qpn;
+					list_add_tail(&dqp->list,
+						      &entry->duplicates);
+					found = true;
+				}
+			}
+			if (!found) {
+				/* Need to add the qpn to mgm */
+				if (members_count ==
+				    dev->caps.num_qp_per_mgm) {
+					/* entry is full */
 					err = -ENOMEM;
 					goto out_mailbox;
 				}
-				dqp->qpn = qpn;
-				list_add_tail(&dqp->list, &entry->duplicates);
-				found = true;
+				mgm->qp[members_count++] =
+					cpu_to_be32(qpn & MGM_QPN_MASK);
+				mgm->members_count =
+					cpu_to_be32(members_count |
+						    (prot << 30));
+				err = mlx4_WRITE_ENTRY(dev, entry->index,
+						       mailbox);
+				if (err)
+					goto out_mailbox;
 			}
 		}
-		if (!found) {
-			/* Need to add the qpn to mgm */
-			if (members_count == dev->caps.num_qp_per_mgm) {
-				/* entry is full */
-				err = -ENOMEM;
-				goto out_mailbox;
-			}
-			mgm->qp[members_count++] = cpu_to_be32(qpn & MGM_QPN_MASK);
-			mgm->members_count = cpu_to_be32(members_count | (prot << 30));
-			err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
-			if (err)
-				goto out_mailbox;
-		}
 	}
 
 	/* add the new qpn to list of promisc qps */
@@ -556,51 +571,65 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
 	if (err)
 		goto out_mailbox;
 
-	/* remove the qp from all the steering entries*/
-	list_for_each_entry(entry, &s_steer->steer_entries[steer], list) {
-		found = false;
-		list_for_each_entry(dqp, &entry->duplicates, list) {
-			if (dqp->qpn == qpn) {
-				found = true;
-				break;
+	if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
+		/* remove the qp from all the steering entries*/
+		list_for_each_entry(entry,
+				    &s_steer->steer_entries[steer],
+				    list) {
+			found = false;
+			list_for_each_entry(dqp, &entry->duplicates, list) {
+				if (dqp->qpn == qpn) {
+					found = true;
+					break;
+				}
 			}
-		}
-		if (found) {
-			/* a duplicate, no need to change the mgm,
-			 * only update the duplicates list */
-			list_del(&dqp->list);
-			kfree(dqp);
-		} else {
-			int loc = -1;
-			err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
-				if (err)
+			if (found) {
+				/* A duplicate, no need to change the MGM,
+				 * only update the duplicates list
+				 */
+				list_del(&dqp->list);
+				kfree(dqp);
+			} else {
+				int loc = -1;
+
+				err = mlx4_READ_ENTRY(dev,
+						      entry->index,
+						      mailbox);
+					if (err)
+						goto out_mailbox;
+				members_count =
+					be32_to_cpu(mgm->members_count) &
+					0xffffff;
+				for (i = 0; i < members_count; ++i)
+					if ((be32_to_cpu(mgm->qp[i]) &
+					     MGM_QPN_MASK) == qpn) {
+						loc = i;
+						break;
+					}
+
+				if (loc < 0) {
+					mlx4_err(dev, "QP %06x wasn't found in entry %d\n",
+						 qpn, entry->index);
+					err = -EINVAL;
 					goto out_mailbox;
-			members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
-			for (i = 0; i < members_count; ++i)
-				if ((be32_to_cpu(mgm->qp[i]) &
-				     MGM_QPN_MASK) == qpn) {
-					loc = i;
-					break;
 				}
 
-			if (loc < 0) {
-				mlx4_err(dev, "QP %06x wasn't found in entry %d\n",
-					 qpn, entry->index);
-				err = -EINVAL;
-				goto out_mailbox;
+				/* copy the last QP in this MGM
+				 * over removed QP
+				 */
+				mgm->qp[loc] = mgm->qp[members_count - 1];
+				mgm->qp[members_count - 1] = 0;
+				mgm->members_count =
+					cpu_to_be32(--members_count |
+						    (MLX4_PROT_ETH << 30));
+
+				err = mlx4_WRITE_ENTRY(dev,
+						       entry->index,
+						       mailbox);
+					if (err)
+						goto out_mailbox;
 			}
-
-			/* copy the last QP in this MGM over removed QP */
-			mgm->qp[loc] = mgm->qp[members_count - 1];
-			mgm->qp[members_count - 1] = 0;
-			mgm->members_count = cpu_to_be32(--members_count |
-							 (MLX4_PROT_ETH << 30));
-
-			err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
-				if (err)
-					goto out_mailbox;
 		}
-
 	}
 
 out_mailbox:
-- 
1.8.3.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH net-next 5/5] net/mlx4_core: Remove MCG in case it is attached to promiscuous QPs only
  2014-07-16  8:57 [PATCH net-next 0/5] Mellanox driver update Jul-16-2014 Amir Vadai
                   ` (3 preceding siblings ...)
  2014-07-16  8:57 ` [PATCH net-next 4/5] net/mlx4_core: In SR-IOV mode host should add promisc QP to default entry only Amir Vadai
@ 2014-07-16  8:57 ` Amir Vadai
  2014-07-17  6:26 ` [PATCH net-next 0/5] Mellanox driver update Jul-16-2014 David Miller
  5 siblings, 0 replies; 7+ messages in thread
From: Amir Vadai @ 2014-07-16  8:57 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, Or Gerlitz, Yevgeny Petrilin, Amir Vadai, Saeed Mahameed,
	Eugenia Emantayev

From: Saeed Mahameed <saeedm@mellanox.com>

In B0 steering mode if promiscuous QP asks to be detached from MCG entry,
and it is the only one in this entry then the entry will never be deleted.
This is a wrong behavior since we don't want to keep those entries after
the promiscuous QP becomes non-promiscuous. Therefore remove steering
entry containing only promiscuous QP.


Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/mcg.c | 88 ++++++++++++++++++++++----------
 1 file changed, 62 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 9d92bc2..d80e7a6 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -270,7 +270,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port,
 	 * we need to add it as a duplicate to this entry
 	 * for future references */
 	list_for_each_entry(dqp, &entry->duplicates, list) {
-		if (qpn == pqp->qpn)
+		if (qpn == dqp->qpn)
 			return 0; /* qp is already duplicated */
 	}
 
@@ -324,24 +324,22 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,
 	return true;
 }
 
-/* I a steering entry contains only promisc QPs, it can be removed. */
-static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
-				      enum mlx4_steer_type steer,
-				      unsigned int index, u32 tqpn)
+/* Returns true if all the QPs != tqpn contained in this entry
+ * are Promisc QPs. Returns false otherwise.
+ */
+static bool promisc_steering_entry(struct mlx4_dev *dev, u8 port,
+				   enum mlx4_steer_type steer,
+				   unsigned int index, u32 tqpn,
+				   u32 *members_count)
 {
-	struct mlx4_steer *s_steer;
 	struct mlx4_cmd_mailbox *mailbox;
 	struct mlx4_mgm *mgm;
-	struct mlx4_steer_index *entry = NULL, *tmp_entry;
-	u32 qpn;
-	u32 members_count;
+	u32 m_count;
 	bool ret = false;
 	int i;
 
 	if (port < 1 || port > dev->caps.num_ports)
-		return NULL;
-
-	s_steer = &mlx4_priv(dev)->steer[port - 1];
+		return false;
 
 	mailbox = mlx4_alloc_cmd_mailbox(dev);
 	if (IS_ERR(mailbox))
@@ -350,15 +348,43 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
 
 	if (mlx4_READ_ENTRY(dev, index, mailbox))
 		goto out;
-	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
-	for (i = 0;  i < members_count; i++) {
-		qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK;
+	m_count = be32_to_cpu(mgm->members_count) & 0xffffff;
+	if (members_count)
+		*members_count = m_count;
+
+	for (i = 0;  i < m_count; i++) {
+		u32 qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK;
 		if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) {
 			/* the qp is not promisc, the entry can't be removed */
 			goto out;
 		}
 	}
-	 /* All the qps currently registered for this entry are promiscuous,
+	ret = true;
+out:
+	mlx4_free_cmd_mailbox(dev, mailbox);
+	return ret;
+}
+
+/* IF a steering entry contains only promisc QPs, it can be removed. */
+static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
+				      enum mlx4_steer_type steer,
+				      unsigned int index, u32 tqpn)
+{
+	struct mlx4_steer *s_steer;
+	struct mlx4_steer_index *entry = NULL, *tmp_entry;
+	u32 members_count;
+	bool ret = false;
+
+	if (port < 1 || port > dev->caps.num_ports)
+		return NULL;
+
+	s_steer = &mlx4_priv(dev)->steer[port - 1];
+
+	if (!promisc_steering_entry(dev, port, steer, index,
+				    tqpn, &members_count))
+		goto out;
+
+	/* All the qps currently registered for this entry are promiscuous,
 	  * Checking for duplicates */
 	ret = true;
 	list_for_each_entry_safe(entry, tmp_entry, &s_steer->steer_entries[steer], list) {
@@ -387,7 +413,6 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
 	}
 
 out:
-	mlx4_free_cmd_mailbox(dev, mailbox);
 	return ret;
 }
 
@@ -528,7 +553,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
 	struct mlx4_steer *s_steer;
 	struct mlx4_cmd_mailbox *mailbox;
 	struct mlx4_mgm *mgm;
-	struct mlx4_steer_index *entry;
+	struct mlx4_steer_index *entry, *tmp_entry;
 	struct mlx4_promisc_qp *pqp;
 	struct mlx4_promisc_qp *dqp;
 	u32 members_count;
@@ -572,10 +597,10 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
 		goto out_mailbox;
 
 	if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
-		/* remove the qp from all the steering entries*/
-		list_for_each_entry(entry,
-				    &s_steer->steer_entries[steer],
-				    list) {
+		/* Remove the QP from all the steering entries */
+		list_for_each_entry_safe(entry, tmp_entry,
+					 &s_steer->steer_entries[steer],
+					 list) {
 			found = false;
 			list_for_each_entry(dqp, &entry->duplicates, list) {
 				if (dqp->qpn == qpn) {
@@ -600,6 +625,14 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
 				members_count =
 					be32_to_cpu(mgm->members_count) &
 					0xffffff;
+				if (!members_count) {
+					mlx4_warn(dev, "QP %06x wasn't found in entry %x mcount=0. deleting entry...\n",
+						  qpn, entry->index);
+					list_del(&entry->list);
+					kfree(entry);
+					continue;
+				}
+
 				for (i = 0; i < members_count; ++i)
 					if ((be32_to_cpu(mgm->qp[i]) &
 					     MGM_QPN_MASK) == qpn) {
@@ -614,7 +647,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
 					goto out_mailbox;
 				}
 
-				/* copy the last QP in this MGM
+				/* Copy the last QP in this MGM
 				 * over removed QP
 				 */
 				mgm->qp[loc] = mgm->qp[members_count - 1];
@@ -1144,10 +1177,13 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
 		goto out;
 	}
 
-	/* if this pq is also a promisc qp, it shouldn't be removed */
+	/* If this QP is also a promisc QP, it shouldn't be removed only if
+	 * at least one none promisc QP is also attached to this MCG
+	 */
 	if (prot == MLX4_PROT_ETH &&
-	    check_duplicate_entry(dev, port, steer, index, qp->qpn))
-		goto out;
+	    check_duplicate_entry(dev, port, steer, index, qp->qpn) &&
+	    !promisc_steering_entry(dev, port, steer, index, qp->qpn, NULL))
+			goto out;
 
 	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
 	for (i = 0; i < members_count; ++i)
-- 
1.8.3.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH net-next 0/5] Mellanox driver update Jul-16-2014
  2014-07-16  8:57 [PATCH net-next 0/5] Mellanox driver update Jul-16-2014 Amir Vadai
                   ` (4 preceding siblings ...)
  2014-07-16  8:57 ` [PATCH net-next 5/5] net/mlx4_core: Remove MCG in case it is attached to promiscuous QPs only Amir Vadai
@ 2014-07-17  6:26 ` David Miller
  5 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2014-07-17  6:26 UTC (permalink / raw
  To: amirv; +Cc: netdev, ogerlitz, yevgenyp

From: Amir Vadai <amirv@mellanox.com>
Date: Wed, 16 Jul 2014 11:57:46 +0300

> This patchset contains some bug fixes related to MCG table management (flow
> steering) in Mellanox NIC.
> 
> Fixes were applied and tested over commit 0854a7f ("Merge branch
> 'amd811e-cleanups'").

Series applied, thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-07-17  6:26 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-16  8:57 [PATCH net-next 0/5] Mellanox driver update Jul-16-2014 Amir Vadai
2014-07-16  8:57 ` [PATCH net-next 1/5] net/mlx4_core: Fix leakage of SW multicast entries Amir Vadai
2014-07-16  8:57 ` [PATCH net-next 2/5] net/mlx4_core: Make sure that negative array index isn't used Amir Vadai
2014-07-16  8:57 ` [PATCH net-next 3/5] net/mlx4_core: Make sure the max number of QPs per MCG isn't exceeded Amir Vadai
2014-07-16  8:57 ` [PATCH net-next 4/5] net/mlx4_core: In SR-IOV mode host should add promisc QP to default entry only Amir Vadai
2014-07-16  8:57 ` [PATCH net-next 5/5] net/mlx4_core: Remove MCG in case it is attached to promiscuous QPs only Amir Vadai
2014-07-17  6:26 ` [PATCH net-next 0/5] Mellanox driver update Jul-16-2014 David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.