Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 09/15] mlxsw: spectrum_acl: Don't take rtnl lock during vregion_rehash_intrvl_set()
From: Ido Schimmel @ 2019-02-24  6:46 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: davem@davemloft.net, Jiri Pirko, mlxsw, Ido Schimmel
In-Reply-To: <20190224064525.14913-1-idosch@mellanox.com>

From: Jiri Pirko <jiri@mellanox.com>

Relax dependency on rtnl mutex during vregion_rehash_intrvl_set(). The
vregion list is protected with newly introduced mutex.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c   | 11 +++++++++--
 .../net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h   |  1 +
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
index cdbcf612b6fd..5c8976e471ad 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
@@ -38,6 +38,7 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
 	size_t alloc_size;
 	int err;
 
+	mutex_init(&tcam->lock);
 	tcam->vregion_rehash_intrvl =
 			MLXSW_SP_ACL_TCAM_VREGION_REHASH_INTRVL_DFLT;
 	INIT_LIST_HEAD(&tcam->vregion_list);
@@ -85,6 +86,7 @@ void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
 {
 	const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
 
+	mutex_destroy(&tcam->lock);
 	ops->fini(mlxsw_sp, tcam->priv);
 	kfree(tcam->used_groups);
 	kfree(tcam->used_regions);
@@ -784,7 +786,9 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp,
 		INIT_DELAYED_WORK(&vregion->rehash_dw,
 				  mlxsw_sp_acl_tcam_vregion_rehash_work);
 		mlxsw_sp_acl_tcam_vregion_rehash_work_schedule(vregion);
+		mutex_lock(&tcam->lock);
 		list_add_tail(&vregion->tlist, &tcam->vregion_list);
+		mutex_unlock(&tcam->lock);
 	}
 
 	return vregion;
@@ -804,9 +808,12 @@ mlxsw_sp_acl_tcam_vregion_destroy(struct mlxsw_sp *mlxsw_sp,
 {
 	const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
 	struct mlxsw_sp_acl_tcam_vgroup *vgroup = vregion->vgroup;
+	struct mlxsw_sp_acl_tcam *tcam = vregion->tcam;
 
 	if (vgroup->vregion_rehash_enabled && ops->region_rehash_hints_get) {
+		mutex_lock(&tcam->lock);
 		list_del(&vregion->tlist);
+		mutex_unlock(&tcam->lock);
 		cancel_delayed_work_sync(&vregion->rehash_dw);
 	}
 	mlxsw_sp_acl_tcam_vgroup_vregion_detach(mlxsw_sp, vregion);
@@ -842,14 +849,14 @@ int mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp,
 	if (WARN_ON(!ops->region_rehash_hints_get))
 		return -EOPNOTSUPP;
 	tcam->vregion_rehash_intrvl = val;
-	rtnl_lock();
+	mutex_lock(&tcam->lock);
 	list_for_each_entry(vregion, &tcam->vregion_list, tlist) {
 		if (val)
 			mlxsw_core_schedule_dw(&vregion->rehash_dw, 0);
 		else
 			cancel_delayed_work_sync(&vregion->rehash_dw);
 	}
-	rtnl_unlock();
+	mutex_unlock(&tcam->lock);
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
index 77de76647ede..5965913565a5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
@@ -17,6 +17,7 @@ struct mlxsw_sp_acl_tcam {
 	unsigned long *used_groups;  /* bit array */
 	unsigned int max_groups;
 	unsigned int max_group_size;
+	struct mutex lock; /* guards vregion list */
 	struct list_head vregion_list;
 	u32 vregion_rehash_intrvl;   /* ms */
 	unsigned long priv[0];
-- 
2.20.1


^ permalink raw reply related

* [PATCH net-next 08/15] mlxsw: spectrum_acl: Enable vregion rehash per-profile
From: Ido Schimmel @ 2019-02-24  6:46 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: davem@davemloft.net, Jiri Pirko, mlxsw, Ido Schimmel
In-Reply-To: <20190224064525.14913-1-idosch@mellanox.com>

From: Jiri Pirko <jiri@mellanox.com>

For MR ACL profile is does not make sense to do periodical rehashes, as
there is only one mask in use during the whole vregion lifetime.
Therefore periodical work is scheduled but the rehash never happens.
So allow to enable/disable rehash for the whole group, which is added
per-profile. Disable rehashing for MR profile.

Addition to the vregion list is done only in case the rehash is enable
on the particular vregion. Also, the addition is moved after delayed
work init to avoid schedule of uninitialized work
from vregion_rehash_intrvl_set(). Symmetrically, deletion from
the list is done before canceling the delayed work so it is
not scheduled by vregion_rehash_intrvl_set() again.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../mellanox/mlxsw/spectrum_acl_tcam.c        | 23 ++++++++++++-------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
index 54c0519195b7..cdbcf612b6fd 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
@@ -175,6 +175,7 @@ struct mlxsw_sp_acl_tcam_vgroup {
 	unsigned int patterns_count;
 	bool tmplt_elusage_set;
 	struct mlxsw_afk_element_usage tmplt_elusage;
+	bool vregion_rehash_enabled;
 };
 
 struct mlxsw_sp_acl_tcam_vregion {
@@ -188,6 +189,7 @@ struct mlxsw_sp_acl_tcam_vregion {
 	struct list_head vchunk_list; /* List of vchunks under this vregion */
 	struct mlxsw_afk_key_info *key_info;
 	struct mlxsw_sp_acl_tcam *tcam;
+	struct mlxsw_sp_acl_tcam_vgroup *vgroup;
 	struct delayed_work rehash_dw;
 	struct mlxsw_sp *mlxsw_sp;
 	bool failed_rollback; /* Indicates failed rollback during migration */
@@ -290,12 +292,15 @@ mlxsw_sp_acl_tcam_vgroup_add(struct mlxsw_sp *mlxsw_sp,
 			     struct mlxsw_sp_acl_tcam_vgroup *vgroup,
 			     const struct mlxsw_sp_acl_tcam_pattern *patterns,
 			     unsigned int patterns_count,
-			     struct mlxsw_afk_element_usage *tmplt_elusage)
+			     struct mlxsw_afk_element_usage *tmplt_elusage,
+			     bool vregion_rehash_enabled)
 {
 	int err;
 
 	vgroup->patterns = patterns;
 	vgroup->patterns_count = patterns_count;
+	vgroup->vregion_rehash_enabled = vregion_rehash_enabled;
+
 	if (tmplt_elusage) {
 		vgroup->tmplt_elusage_set = true;
 		memcpy(&vgroup->tmplt_elusage, tmplt_elusage,
@@ -753,6 +758,7 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp,
 	mutex_init(&vregion->lock);
 	vregion->tcam = tcam;
 	vregion->mlxsw_sp = mlxsw_sp;
+	vregion->vgroup = vgroup;
 	vregion->ref_count = 1;
 
 	vregion->key_info = mlxsw_afk_key_info_get(afk, elusage);
@@ -773,13 +779,12 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp,
 	if (err)
 		goto err_vgroup_vregion_attach;
 
-	list_add_tail(&vregion->tlist, &tcam->vregion_list);
-
-	if (ops->region_rehash_hints_get) {
+	if (vgroup->vregion_rehash_enabled && ops->region_rehash_hints_get) {
 		/* Create the delayed work for vregion periodic rehash */
 		INIT_DELAYED_WORK(&vregion->rehash_dw,
 				  mlxsw_sp_acl_tcam_vregion_rehash_work);
 		mlxsw_sp_acl_tcam_vregion_rehash_work_schedule(vregion);
+		list_add_tail(&vregion->tlist, &tcam->vregion_list);
 	}
 
 	return vregion;
@@ -798,10 +803,12 @@ mlxsw_sp_acl_tcam_vregion_destroy(struct mlxsw_sp *mlxsw_sp,
 				  struct mlxsw_sp_acl_tcam_vregion *vregion)
 {
 	const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
+	struct mlxsw_sp_acl_tcam_vgroup *vgroup = vregion->vgroup;
 
-	if (ops->region_rehash_hints_get)
+	if (vgroup->vregion_rehash_enabled && ops->region_rehash_hints_get) {
+		list_del(&vregion->tlist);
 		cancel_delayed_work_sync(&vregion->rehash_dw);
-	list_del(&vregion->tlist);
+	}
 	mlxsw_sp_acl_tcam_vgroup_vregion_detach(mlxsw_sp, vregion);
 	if (vregion->region2)
 		mlxsw_sp_acl_tcam_region_destroy(mlxsw_sp, vregion->region2);
@@ -1410,7 +1417,7 @@ mlxsw_sp_acl_tcam_flower_ruleset_add(struct mlxsw_sp *mlxsw_sp,
 	return mlxsw_sp_acl_tcam_vgroup_add(mlxsw_sp, tcam, &ruleset->vgroup,
 					    mlxsw_sp_acl_tcam_patterns,
 					    MLXSW_SP_ACL_TCAM_PATTERNS_COUNT,
-					    tmplt_elusage);
+					    tmplt_elusage, true);
 }
 
 static void
@@ -1527,7 +1534,7 @@ mlxsw_sp_acl_tcam_mr_ruleset_add(struct mlxsw_sp *mlxsw_sp,
 	err = mlxsw_sp_acl_tcam_vgroup_add(mlxsw_sp, tcam, &ruleset->vgroup,
 					   mlxsw_sp_acl_tcam_patterns,
 					   MLXSW_SP_ACL_TCAM_PATTERNS_COUNT,
-					   tmplt_elusage);
+					   tmplt_elusage, false);
 	if (err)
 		return err;
 
-- 
2.20.1


^ permalink raw reply related

* [PATCH net-next 04/15] mlxsw: spectrum_acl: Refactor vregion association code
From: Ido Schimmel @ 2019-02-24  6:46 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: davem@davemloft.net, Jiri Pirko, mlxsw, Ido Schimmel
In-Reply-To: <20190224064525.14913-1-idosch@mellanox.com>

From: Jiri Pirko <jiri@mellanox.com>

Refactor existing _vchunk_assoc/_vchunk_deassoc() functions into
_vregion_get()/_vregion_put() to make the code simpler and prepared for
vregion locking.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../mellanox/mlxsw/spectrum_acl_tcam.c        | 133 +++++++++---------
 1 file changed, 66 insertions(+), 67 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
index 21ebda19a2ad..e100b14b4815 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
@@ -188,6 +188,7 @@ struct mlxsw_sp_acl_tcam_vregion {
 	struct delayed_work rehash_dw;
 	struct mlxsw_sp *mlxsw_sp;
 	bool failed_rollback; /* Indicates failed rollback during migration */
+	unsigned int ref_count;
 };
 
 struct mlxsw_sp_acl_tcam_vchunk;
@@ -388,6 +389,7 @@ static int
 mlxsw_sp_acl_tcam_group_region_attach(struct mlxsw_sp *mlxsw_sp,
 				      struct mlxsw_sp_acl_tcam_group *group,
 				      struct mlxsw_sp_acl_tcam_region *region,
+				      unsigned int priority,
 				      struct mlxsw_sp_acl_tcam_region *next_region)
 {
 	struct mlxsw_sp_acl_tcam_region *region2;
@@ -410,7 +412,7 @@ mlxsw_sp_acl_tcam_group_region_attach(struct mlxsw_sp *mlxsw_sp,
 		list_for_each(pos, &group->region_list) {
 			region2 = list_entry(pos, typeof(*region2), list);
 			if (mlxsw_sp_acl_tcam_vregion_prio(region2->vregion) >
-			    mlxsw_sp_acl_tcam_vregion_prio(region->vregion))
+			    priority)
 				break;
 		}
 	}
@@ -448,7 +450,8 @@ mlxsw_sp_acl_tcam_group_region_detach(struct mlxsw_sp *mlxsw_sp,
 static int
 mlxsw_sp_acl_tcam_vgroup_vregion_attach(struct mlxsw_sp *mlxsw_sp,
 					struct mlxsw_sp_acl_tcam_vgroup *vgroup,
-					struct mlxsw_sp_acl_tcam_vregion *vregion)
+					struct mlxsw_sp_acl_tcam_vregion *vregion,
+					unsigned int priority)
 {
 	struct mlxsw_sp_acl_tcam_vregion *vregion2;
 	struct list_head *pos;
@@ -457,15 +460,14 @@ mlxsw_sp_acl_tcam_vgroup_vregion_attach(struct mlxsw_sp *mlxsw_sp,
 	/* Position the vregion inside the list according to priority */
 	list_for_each(pos, &vgroup->vregion_list) {
 		vregion2 = list_entry(pos, typeof(*vregion2), list);
-		if (mlxsw_sp_acl_tcam_vregion_prio(vregion2) >
-		    mlxsw_sp_acl_tcam_vregion_prio(vregion)) {
+		if (mlxsw_sp_acl_tcam_vregion_prio(vregion2) > priority)
 			break;
-		}
 	}
 	list_add_tail(&vregion->list, pos);
 
 	err = mlxsw_sp_acl_tcam_group_region_attach(mlxsw_sp, &vgroup->group,
-						    vregion->region, NULL);
+						    vregion->region,
+						    priority, NULL);
 	if (err)
 		goto err_region_attach;
 
@@ -731,11 +733,13 @@ static void mlxsw_sp_acl_tcam_vregion_rehash_work(struct work_struct *work)
 
 static struct mlxsw_sp_acl_tcam_vregion *
 mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp,
-				 struct mlxsw_sp_acl_tcam *tcam,
+				 struct mlxsw_sp_acl_tcam_vgroup *vgroup,
+				 unsigned int priority,
 				 struct mlxsw_afk_element_usage *elusage)
 {
 	const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
 	struct mlxsw_afk *afk = mlxsw_sp_acl_afk(mlxsw_sp->acl);
+	struct mlxsw_sp_acl_tcam *tcam = vgroup->group.tcam;
 	struct mlxsw_sp_acl_tcam_vregion *vregion;
 	int err;
 
@@ -745,6 +749,7 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp,
 	INIT_LIST_HEAD(&vregion->vchunk_list);
 	vregion->tcam = tcam;
 	vregion->mlxsw_sp = mlxsw_sp;
+	vregion->ref_count = 1;
 
 	vregion->key_info = mlxsw_afk_key_info_get(afk, elusage);
 	if (IS_ERR(vregion->key_info)) {
@@ -759,6 +764,11 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp,
 		goto err_region_create;
 	}
 
+	err = mlxsw_sp_acl_tcam_vgroup_vregion_attach(mlxsw_sp, vgroup, vregion,
+						      priority);
+	if (err)
+		goto err_vgroup_vregion_attach;
+
 	list_add_tail(&vregion->tlist, &tcam->vregion_list);
 
 	if (ops->region_rehash_hints_get) {
@@ -770,6 +780,8 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp,
 
 	return vregion;
 
+err_vgroup_vregion_attach:
+	mlxsw_sp_acl_tcam_region_destroy(mlxsw_sp, vregion->region);
 err_region_create:
 	mlxsw_afk_key_info_put(vregion->key_info);
 err_key_info_get:
@@ -786,6 +798,7 @@ mlxsw_sp_acl_tcam_vregion_destroy(struct mlxsw_sp *mlxsw_sp,
 	if (ops->region_rehash_hints_get)
 		cancel_delayed_work_sync(&vregion->rehash_dw);
 	list_del(&vregion->tlist);
+	mlxsw_sp_acl_tcam_vgroup_vregion_detach(mlxsw_sp, vregion);
 	if (vregion->region2)
 		mlxsw_sp_acl_tcam_region_destroy(mlxsw_sp, vregion->region2);
 	mlxsw_sp_acl_tcam_region_destroy(mlxsw_sp, vregion->region);
@@ -828,71 +841,47 @@ int mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp,
 	return 0;
 }
 
-static int
-mlxsw_sp_acl_tcam_vchunk_assoc(struct mlxsw_sp *mlxsw_sp,
-			       struct mlxsw_sp_acl_tcam_vgroup *vgroup,
-			       unsigned int priority,
-			       struct mlxsw_afk_element_usage *elusage,
-			       struct mlxsw_sp_acl_tcam_vchunk *vchunk)
+static struct mlxsw_sp_acl_tcam_vregion *
+mlxsw_sp_acl_tcam_vregion_get(struct mlxsw_sp *mlxsw_sp,
+			      struct mlxsw_sp_acl_tcam_vgroup *vgroup,
+			      unsigned int priority,
+			      struct mlxsw_afk_element_usage *elusage)
 {
+	struct mlxsw_afk_element_usage vregion_elusage;
 	struct mlxsw_sp_acl_tcam_vregion *vregion;
-	bool vregion_created = false;
 	bool need_split;
-	int err;
 
 	vregion = mlxsw_sp_acl_tcam_vgroup_vregion_find(vgroup, priority,
 							elusage, &need_split);
-	if (vregion && need_split) {
-		/* According to priority, the vchunk should belong to an
-		 * existing vregion. However, this vchunk needs elements
-		 * that vregion does not contain. We need to split the existing
-		 * vregion into two and create a new vregion for this vchunk
-		 * in between. This is not supported now.
-		 */
-		return -EOPNOTSUPP;
-	}
-	if (!vregion) {
-		struct mlxsw_afk_element_usage vregion_elusage;
-
-		mlxsw_sp_acl_tcam_vgroup_use_patterns(vgroup, elusage,
-						      &vregion_elusage);
-		vregion = mlxsw_sp_acl_tcam_vregion_create(mlxsw_sp,
-							   vgroup->group.tcam,
-							   &vregion_elusage);
-		if (IS_ERR(vregion))
-			return PTR_ERR(vregion);
-		vregion_created = true;
+	if (vregion) {
+		if (need_split) {
+			/* According to priority, new vchunk should belong to
+			 * an existing vregion. However, this vchunk needs
+			 * elements that vregion does not contain. We need
+			 * to split the existing vregion into two and create
+			 * a new vregion for the new vchunk in between.
+			 * This is not supported now.
+			 */
+			return ERR_PTR(-EOPNOTSUPP);
+		}
+		vregion->ref_count++;
+		return vregion;
 	}
 
-	vchunk->vregion = vregion;
-	list_add_tail(&vchunk->list, &vregion->vchunk_list);
-
-	if (!vregion_created)
-		return 0;
+	mlxsw_sp_acl_tcam_vgroup_use_patterns(vgroup, elusage,
+					      &vregion_elusage);
 
-	err = mlxsw_sp_acl_tcam_vgroup_vregion_attach(mlxsw_sp, vgroup,
-						      vregion);
-	if (err)
-		goto err_vgroup_vregion_attach;
-
-	return 0;
-
-err_vgroup_vregion_attach:
-	mlxsw_sp_acl_tcam_vregion_destroy(mlxsw_sp, vregion);
-	return err;
+	return mlxsw_sp_acl_tcam_vregion_create(mlxsw_sp, vgroup, priority,
+						&vregion_elusage);
 }
 
 static void
-mlxsw_sp_acl_tcam_vchunk_deassoc(struct mlxsw_sp *mlxsw_sp,
-				 struct mlxsw_sp_acl_tcam_vchunk *vchunk)
+mlxsw_sp_acl_tcam_vregion_put(struct mlxsw_sp *mlxsw_sp,
+			      struct mlxsw_sp_acl_tcam_vregion *vregion)
 {
-	struct mlxsw_sp_acl_tcam_vregion *vregion = vchunk->vregion;
-
-	list_del(&vchunk->list);
-	if (list_empty(&vregion->vchunk_list)) {
-		mlxsw_sp_acl_tcam_vgroup_vregion_detach(mlxsw_sp, vregion);
-		mlxsw_sp_acl_tcam_vregion_destroy(mlxsw_sp, vregion);
-	}
+	if (--vregion->ref_count)
+		return;
+	mlxsw_sp_acl_tcam_vregion_destroy(mlxsw_sp, vregion);
 }
 
 static struct mlxsw_sp_acl_tcam_chunk *
@@ -929,6 +918,7 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp,
 				unsigned int priority,
 				struct mlxsw_afk_element_usage *elusage)
 {
+	struct mlxsw_sp_acl_tcam_vregion *vregion;
 	struct mlxsw_sp_acl_tcam_vchunk *vchunk;
 	int err;
 
@@ -943,10 +933,14 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp,
 	vchunk->vgroup = vgroup;
 	vchunk->ref_count = 1;
 
-	err = mlxsw_sp_acl_tcam_vchunk_assoc(mlxsw_sp, vgroup, priority,
-					     elusage, vchunk);
-	if (err)
-		goto err_vchunk_assoc;
+	vregion = mlxsw_sp_acl_tcam_vregion_get(mlxsw_sp, vgroup,
+						priority, elusage);
+	if (IS_ERR(vregion)) {
+		err = PTR_ERR(vregion);
+		goto err_vregion_get;
+	}
+
+	vchunk->vregion = vregion;
 
 	err = rhashtable_insert_fast(&vgroup->vchunk_ht, &vchunk->ht_node,
 				     mlxsw_sp_acl_tcam_vchunk_ht_params);
@@ -960,14 +954,16 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp,
 		goto err_chunk_create;
 	}
 
+	list_add_tail(&vchunk->list, &vregion->vchunk_list);
+
 	return vchunk;
 
 err_chunk_create:
 	rhashtable_remove_fast(&vgroup->vchunk_ht, &vchunk->ht_node,
 			       mlxsw_sp_acl_tcam_vchunk_ht_params);
 err_rhashtable_insert:
-	mlxsw_sp_acl_tcam_vchunk_deassoc(mlxsw_sp, vchunk);
-err_vchunk_assoc:
+	mlxsw_sp_acl_tcam_vregion_put(mlxsw_sp, vregion);
+err_vregion_get:
 	kfree(vchunk);
 	return ERR_PTR(err);
 }
@@ -978,12 +974,13 @@ mlxsw_sp_acl_tcam_vchunk_destroy(struct mlxsw_sp *mlxsw_sp,
 {
 	struct mlxsw_sp_acl_tcam_vgroup *vgroup = vchunk->vgroup;
 
+	list_del(&vchunk->list);
 	if (vchunk->chunk2)
 		mlxsw_sp_acl_tcam_chunk_destroy(mlxsw_sp, vchunk->chunk2);
 	mlxsw_sp_acl_tcam_chunk_destroy(mlxsw_sp, vchunk->chunk);
 	rhashtable_remove_fast(&vgroup->vchunk_ht, &vchunk->ht_node,
 			       mlxsw_sp_acl_tcam_vchunk_ht_params);
-	mlxsw_sp_acl_tcam_vchunk_deassoc(mlxsw_sp, vchunk);
+	mlxsw_sp_acl_tcam_vregion_put(mlxsw_sp, vchunk->vregion);
 	kfree(vchunk);
 }
 
@@ -1240,6 +1237,7 @@ mlxsw_sp_acl_tcam_vregion_migrate(struct mlxsw_sp *mlxsw_sp,
 				  struct mlxsw_sp_acl_tcam_vregion *vregion,
 				  void *hints_priv)
 {
+	unsigned int priority = mlxsw_sp_acl_tcam_vregion_prio(vregion);
 	struct mlxsw_sp_acl_tcam_region *region2, *unused_region;
 	int err;
 
@@ -1253,7 +1251,8 @@ mlxsw_sp_acl_tcam_vregion_migrate(struct mlxsw_sp *mlxsw_sp,
 	vregion->region2 = region2;
 	err = mlxsw_sp_acl_tcam_group_region_attach(mlxsw_sp,
 						    vregion->region->group,
-						    region2, vregion->region);
+						    region2, priority,
+						    vregion->region);
 	if (err)
 		goto err_group_region_attach;
 
-- 
2.20.1


^ permalink raw reply related

* [PATCH net-next 05/15] mlxsw: spectrum_acl: Introduce vregion mutex
From: Ido Schimmel @ 2019-02-24  6:46 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: davem@davemloft.net, Jiri Pirko, mlxsw, Ido Schimmel
In-Reply-To: <20190224064525.14913-1-idosch@mellanox.com>

From: Jiri Pirko <jiri@mellanox.com>

In order to remove dependency on RTNL, introduce a mutex
to guard vregion structure, list of chunks and list of entries in
chunks.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../mellanox/mlxsw/spectrum_acl_tcam.c        | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
index e100b14b4815..54c0519195b7 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
@@ -178,6 +178,9 @@ struct mlxsw_sp_acl_tcam_vgroup {
 };
 
 struct mlxsw_sp_acl_tcam_vregion {
+	struct mutex lock; /* Protects consistency of region, region2 pointers
+			    * and vchunk_list.
+			    */
 	struct mlxsw_sp_acl_tcam_region *region;
 	struct mlxsw_sp_acl_tcam_region *region2; /* Used during migration */
 	struct list_head list; /* Member of a TCAM group */
@@ -747,6 +750,7 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp,
 	if (!vregion)
 		return ERR_PTR(-ENOMEM);
 	INIT_LIST_HEAD(&vregion->vchunk_list);
+	mutex_init(&vregion->lock);
 	vregion->tcam = tcam;
 	vregion->mlxsw_sp = mlxsw_sp;
 	vregion->ref_count = 1;
@@ -803,6 +807,7 @@ mlxsw_sp_acl_tcam_vregion_destroy(struct mlxsw_sp *mlxsw_sp,
 		mlxsw_sp_acl_tcam_region_destroy(mlxsw_sp, vregion->region2);
 	mlxsw_sp_acl_tcam_region_destroy(mlxsw_sp, vregion->region);
 	mlxsw_afk_key_info_put(vregion->key_info);
+	mutex_destroy(&vregion->lock);
 	kfree(vregion);
 }
 
@@ -947,14 +952,17 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp,
 	if (err)
 		goto err_rhashtable_insert;
 
+	mutex_lock(&vregion->lock);
 	vchunk->chunk = mlxsw_sp_acl_tcam_chunk_create(mlxsw_sp, vchunk,
 						       vchunk->vregion->region);
 	if (IS_ERR(vchunk->chunk)) {
+		mutex_unlock(&vregion->lock);
 		err = PTR_ERR(vchunk->chunk);
 		goto err_chunk_create;
 	}
 
 	list_add_tail(&vchunk->list, &vregion->vchunk_list);
+	mutex_unlock(&vregion->lock);
 
 	return vchunk;
 
@@ -972,12 +980,15 @@ static void
 mlxsw_sp_acl_tcam_vchunk_destroy(struct mlxsw_sp *mlxsw_sp,
 				 struct mlxsw_sp_acl_tcam_vchunk *vchunk)
 {
+	struct mlxsw_sp_acl_tcam_vregion *vregion = vchunk->vregion;
 	struct mlxsw_sp_acl_tcam_vgroup *vgroup = vchunk->vgroup;
 
+	mutex_lock(&vregion->lock);
 	list_del(&vchunk->list);
 	if (vchunk->chunk2)
 		mlxsw_sp_acl_tcam_chunk_destroy(mlxsw_sp, vchunk->chunk2);
 	mlxsw_sp_acl_tcam_chunk_destroy(mlxsw_sp, vchunk->chunk);
+	mutex_unlock(&vregion->lock);
 	rhashtable_remove_fast(&vgroup->vchunk_ht, &vchunk->ht_node,
 			       mlxsw_sp_acl_tcam_vchunk_ht_params);
 	mlxsw_sp_acl_tcam_vregion_put(mlxsw_sp, vchunk->vregion);
@@ -1079,6 +1090,7 @@ static int mlxsw_sp_acl_tcam_ventry_add(struct mlxsw_sp *mlxsw_sp,
 					struct mlxsw_sp_acl_tcam_ventry *ventry,
 					struct mlxsw_sp_acl_rule_info *rulei)
 {
+	struct mlxsw_sp_acl_tcam_vregion *vregion;
 	struct mlxsw_sp_acl_tcam_vchunk *vchunk;
 	int err;
 
@@ -1089,14 +1101,19 @@ static int mlxsw_sp_acl_tcam_ventry_add(struct mlxsw_sp *mlxsw_sp,
 
 	ventry->vchunk = vchunk;
 	ventry->rulei = rulei;
+	vregion = vchunk->vregion;
+
+	mutex_lock(&vregion->lock);
 	ventry->entry = mlxsw_sp_acl_tcam_entry_create(mlxsw_sp, ventry,
 						       vchunk->chunk);
 	if (IS_ERR(ventry->entry)) {
+		mutex_unlock(&vregion->lock);
 		err = PTR_ERR(ventry->entry);
 		goto err_entry_create;
 	}
 
 	list_add_tail(&ventry->list, &vchunk->ventry_list);
+	mutex_unlock(&vregion->lock);
 
 	return 0;
 
@@ -1109,9 +1126,12 @@ static void mlxsw_sp_acl_tcam_ventry_del(struct mlxsw_sp *mlxsw_sp,
 					 struct mlxsw_sp_acl_tcam_ventry *ventry)
 {
 	struct mlxsw_sp_acl_tcam_vchunk *vchunk = ventry->vchunk;
+	struct mlxsw_sp_acl_tcam_vregion *vregion = vchunk->vregion;
 
+	mutex_lock(&vregion->lock);
 	list_del(&ventry->list);
 	mlxsw_sp_acl_tcam_entry_destroy(mlxsw_sp, ventry->entry);
+	mutex_unlock(&vregion->lock);
 	mlxsw_sp_acl_tcam_vchunk_put(mlxsw_sp, vchunk);
 }
 
@@ -1256,6 +1276,8 @@ mlxsw_sp_acl_tcam_vregion_migrate(struct mlxsw_sp *mlxsw_sp,
 	if (err)
 		goto err_group_region_attach;
 
+	mutex_lock(&vregion->lock);
+
 	err = mlxsw_sp_acl_tcam_vchunk_migrate_all(mlxsw_sp, vregion);
 	if (!vregion->failed_rollback) {
 		if (!err) {
@@ -1270,10 +1292,14 @@ mlxsw_sp_acl_tcam_vregion_migrate(struct mlxsw_sp *mlxsw_sp,
 			 */
 			unused_region = vregion->region2;
 		}
+		mutex_unlock(&vregion->lock);
 		vregion->region2 = NULL;
 		mlxsw_sp_acl_tcam_group_region_detach(mlxsw_sp, unused_region);
 		mlxsw_sp_acl_tcam_region_destroy(mlxsw_sp, unused_region);
+	} else {
+		mutex_unlock(&vregion->lock);
 	}
+
 	return err;
 
 err_group_region_attach:
-- 
2.20.1


^ permalink raw reply related

* [PATCH net-next 01/15] mlxsw: spectrum_acl: Remove unused ops field from group structure
From: Ido Schimmel @ 2019-02-24  6:46 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: davem@davemloft.net, Jiri Pirko, mlxsw, Ido Schimmel
In-Reply-To: <20190224064525.14913-1-idosch@mellanox.com>

From: Jiri Pirko <jiri@mellanox.com>

Never used, remove it.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
index 7e225a86e3a8..80bf0a510203 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
@@ -164,7 +164,6 @@ struct mlxsw_sp_acl_tcam_group {
 	struct list_head vregion_list;
 	unsigned int region_count;
 	struct rhashtable vchunk_ht;
-	struct mlxsw_sp_acl_tcam_group_ops *ops;
 	const struct mlxsw_sp_acl_tcam_pattern *patterns;
 	unsigned int patterns_count;
 	bool tmplt_elusage_set;
-- 
2.20.1


^ permalink raw reply related

* [PATCH net-next 02/15] mlxsw: spectrum_acl: Split TCAM group structure into two
From: Ido Schimmel @ 2019-02-24  6:46 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: davem@davemloft.net, Jiri Pirko, mlxsw, Ido Schimmel
In-Reply-To: <20190224064525.14913-1-idosch@mellanox.com>

From: Jiri Pirko <jiri@mellanox.com>

Make the existing group structure to contain fields needed for HW region
list manipulations. Move the rest of the fields into new vgroup struct.
This makes layering cleaner as the vgroup struct is on higher level than
low-level group struct. Also, this makes it possible to introduce
fine-grained locking.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../mellanox/mlxsw/spectrum_acl_tcam.c        | 260 +++++++++++-------
 .../mellanox/mlxsw/spectrum_acl_tcam.h        |   2 +
 2 files changed, 161 insertions(+), 101 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
index 80bf0a510203..922f17adcee7 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
@@ -161,8 +161,13 @@ struct mlxsw_sp_acl_tcam_pattern {
 struct mlxsw_sp_acl_tcam_group {
 	struct mlxsw_sp_acl_tcam *tcam;
 	u16 id;
-	struct list_head vregion_list;
+	struct list_head region_list;
 	unsigned int region_count;
+};
+
+struct mlxsw_sp_acl_tcam_vgroup {
+	struct mlxsw_sp_acl_tcam_group group;
+	struct list_head vregion_list;
 	struct rhashtable vchunk_ht;
 	const struct mlxsw_sp_acl_tcam_pattern *patterns;
 	unsigned int patterns_count;
@@ -176,7 +181,6 @@ struct mlxsw_sp_acl_tcam_vregion {
 	struct list_head list; /* Member of a TCAM group */
 	struct list_head tlist; /* Member of a TCAM */
 	struct list_head vchunk_list; /* List of vchunks under this vregion */
-	struct mlxsw_sp_acl_tcam_group *group;
 	struct mlxsw_afk_key_info *key_info;
 	struct mlxsw_sp_acl_tcam *tcam;
 	struct delayed_work rehash_dw;
@@ -200,7 +204,7 @@ struct mlxsw_sp_acl_tcam_vchunk {
 	struct rhash_head ht_node; /* Member of a chunk HT */
 	struct list_head ventry_list;
 	unsigned int priority; /* Priority within the vregion and group */
-	struct mlxsw_sp_acl_tcam_group *group;
+	struct mlxsw_sp_acl_tcam_vgroup *vgroup;
 	struct mlxsw_sp_acl_tcam_vregion *vregion;
 	unsigned int ref_count;
 };
@@ -229,46 +233,73 @@ static const struct rhashtable_params mlxsw_sp_acl_tcam_vchunk_ht_params = {
 static int mlxsw_sp_acl_tcam_group_update(struct mlxsw_sp *mlxsw_sp,
 					  struct mlxsw_sp_acl_tcam_group *group)
 {
-	struct mlxsw_sp_acl_tcam_vregion *vregion;
+	struct mlxsw_sp_acl_tcam_region *region;
 	char pagt_pl[MLXSW_REG_PAGT_LEN];
 	int acl_index = 0;
 
 	mlxsw_reg_pagt_pack(pagt_pl, group->id);
-	list_for_each_entry(vregion, &group->vregion_list, list) {
-		if (vregion->region2)
-			mlxsw_reg_pagt_acl_id_pack(pagt_pl, acl_index++,
-						   vregion->region2->id, true);
+	list_for_each_entry(region, &group->region_list, list) {
+		bool multi = false;
+
+		/* Check if the next entry in the list has the same vregion. */
+		if (region->list.next != &group->region_list &&
+		    list_next_entry(region, list)->vregion == region->vregion)
+			multi = true;
 		mlxsw_reg_pagt_acl_id_pack(pagt_pl, acl_index++,
-					   vregion->region->id, false);
+					   region->id, multi);
 	}
 	mlxsw_reg_pagt_size_set(pagt_pl, acl_index);
 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pagt), pagt_pl);
 }
 
 static int
-mlxsw_sp_acl_tcam_group_add(struct mlxsw_sp *mlxsw_sp,
-			    struct mlxsw_sp_acl_tcam *tcam,
-			    struct mlxsw_sp_acl_tcam_group *group,
-			    const struct mlxsw_sp_acl_tcam_pattern *patterns,
-			    unsigned int patterns_count,
-			    struct mlxsw_afk_element_usage *tmplt_elusage)
+mlxsw_sp_acl_tcam_group_add(struct mlxsw_sp_acl_tcam *tcam,
+			    struct mlxsw_sp_acl_tcam_group *group)
 {
 	int err;
 
 	group->tcam = tcam;
-	group->patterns = patterns;
-	group->patterns_count = patterns_count;
+	INIT_LIST_HEAD(&group->region_list);
+
+	err = mlxsw_sp_acl_tcam_group_id_get(tcam, &group->id);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static void mlxsw_sp_acl_tcam_group_del(struct mlxsw_sp_acl_tcam_group *group)
+{
+	struct mlxsw_sp_acl_tcam *tcam = group->tcam;
+
+	mlxsw_sp_acl_tcam_group_id_put(tcam, group->id);
+	WARN_ON(!list_empty(&group->region_list));
+}
+
+static int
+mlxsw_sp_acl_tcam_vgroup_add(struct mlxsw_sp *mlxsw_sp,
+			     struct mlxsw_sp_acl_tcam *tcam,
+			     struct mlxsw_sp_acl_tcam_vgroup *vgroup,
+			     const struct mlxsw_sp_acl_tcam_pattern *patterns,
+			     unsigned int patterns_count,
+			     struct mlxsw_afk_element_usage *tmplt_elusage)
+{
+	int err;
+
+	vgroup->patterns = patterns;
+	vgroup->patterns_count = patterns_count;
 	if (tmplt_elusage) {
-		group->tmplt_elusage_set = true;
-		memcpy(&group->tmplt_elusage, tmplt_elusage,
-		       sizeof(group->tmplt_elusage));
+		vgroup->tmplt_elusage_set = true;
+		memcpy(&vgroup->tmplt_elusage, tmplt_elusage,
+		       sizeof(vgroup->tmplt_elusage));
 	}
-	INIT_LIST_HEAD(&group->vregion_list);
-	err = mlxsw_sp_acl_tcam_group_id_get(tcam, &group->id);
+	INIT_LIST_HEAD(&vgroup->vregion_list);
+
+	err = mlxsw_sp_acl_tcam_group_add(tcam, &vgroup->group);
 	if (err)
 		return err;
 
-	err = rhashtable_init(&group->vchunk_ht,
+	err = rhashtable_init(&vgroup->vchunk_ht,
 			      &mlxsw_sp_acl_tcam_vchunk_ht_params);
 	if (err)
 		goto err_rhashtable_init;
@@ -276,18 +307,16 @@ mlxsw_sp_acl_tcam_group_add(struct mlxsw_sp *mlxsw_sp,
 	return 0;
 
 err_rhashtable_init:
-	mlxsw_sp_acl_tcam_group_id_put(tcam, group->id);
+	mlxsw_sp_acl_tcam_group_del(&vgroup->group);
 	return err;
 }
 
-static void mlxsw_sp_acl_tcam_group_del(struct mlxsw_sp *mlxsw_sp,
-					struct mlxsw_sp_acl_tcam_group *group)
+static void
+mlxsw_sp_acl_tcam_vgroup_del(struct mlxsw_sp_acl_tcam_vgroup *vgroup)
 {
-	struct mlxsw_sp_acl_tcam *tcam = group->tcam;
-
-	rhashtable_destroy(&group->vchunk_ht);
-	mlxsw_sp_acl_tcam_group_id_put(tcam, group->id);
-	WARN_ON(!list_empty(&group->vregion_list));
+	rhashtable_destroy(&vgroup->vchunk_ht);
+	mlxsw_sp_acl_tcam_group_del(&vgroup->group);
+	WARN_ON(!list_empty(&vgroup->vregion_list));
 }
 
 static int
@@ -353,52 +382,78 @@ mlxsw_sp_acl_tcam_vregion_max_prio(struct mlxsw_sp_acl_tcam_vregion *vregion)
 
 static int
 mlxsw_sp_acl_tcam_group_region_attach(struct mlxsw_sp *mlxsw_sp,
-				      struct mlxsw_sp_acl_tcam_region *region)
+				      struct mlxsw_sp_acl_tcam_group *group,
+				      struct mlxsw_sp_acl_tcam_region *region,
+				      struct mlxsw_sp_acl_tcam_region *next_region)
 {
-	struct mlxsw_sp_acl_tcam_group *group = region->vregion->group;
+	struct mlxsw_sp_acl_tcam_region *region2;
+	struct list_head *pos;
 	int err;
 
 	if (group->region_count == group->tcam->max_group_size)
 		return -ENOBUFS;
 
+	if (next_region) {
+		/* If the next region is defined, place the new one
+		 * before it. The next one is a sibling.
+		 */
+		pos = &next_region->list;
+	} else {
+		/* Position the region inside the list according to priority */
+		list_for_each(pos, &group->region_list) {
+			region2 = list_entry(pos, typeof(*region2), list);
+			if (mlxsw_sp_acl_tcam_vregion_prio(region2->vregion) >
+			    mlxsw_sp_acl_tcam_vregion_prio(region->vregion))
+				break;
+		}
+	}
+	list_add_tail(&region->list, pos);
+	region->group = group;
+
 	err = mlxsw_sp_acl_tcam_group_update(mlxsw_sp, group);
 	if (err)
-		return err;
+		goto err_group_update;
 
 	group->region_count++;
 	return 0;
+
+err_group_update:
+	list_del(&region->list);
+	return err;
 }
 
 static void
 mlxsw_sp_acl_tcam_group_region_detach(struct mlxsw_sp *mlxsw_sp,
 				      struct mlxsw_sp_acl_tcam_region *region)
 {
-	struct mlxsw_sp_acl_tcam_group *group = region->vregion->group;
+	struct mlxsw_sp_acl_tcam_group *group = region->group;
 
+	list_del(&region->list);
 	group->region_count--;
 	mlxsw_sp_acl_tcam_group_update(mlxsw_sp, group);
 }
 
 static int
-mlxsw_sp_acl_tcam_group_vregion_attach(struct mlxsw_sp *mlxsw_sp,
-				       struct mlxsw_sp_acl_tcam_group *group,
-				       struct mlxsw_sp_acl_tcam_vregion *vregion)
+mlxsw_sp_acl_tcam_vgroup_vregion_attach(struct mlxsw_sp *mlxsw_sp,
+					struct mlxsw_sp_acl_tcam_vgroup *vgroup,
+					struct mlxsw_sp_acl_tcam_vregion *vregion)
 {
 	struct mlxsw_sp_acl_tcam_vregion *vregion2;
 	struct list_head *pos;
 	int err;
 
 	/* Position the vregion inside the list according to priority */
-	list_for_each(pos, &group->vregion_list) {
+	list_for_each(pos, &vgroup->vregion_list) {
 		vregion2 = list_entry(pos, typeof(*vregion2), list);
 		if (mlxsw_sp_acl_tcam_vregion_prio(vregion2) >
-		    mlxsw_sp_acl_tcam_vregion_prio(vregion))
+		    mlxsw_sp_acl_tcam_vregion_prio(vregion)) {
 			break;
+		}
 	}
 	list_add_tail(&vregion->list, pos);
-	vregion->group = group;
 
-	err = mlxsw_sp_acl_tcam_group_region_attach(mlxsw_sp, vregion->region);
+	err = mlxsw_sp_acl_tcam_group_region_attach(mlxsw_sp, &vgroup->group,
+						    vregion->region, NULL);
 	if (err)
 		goto err_region_attach;
 
@@ -410,8 +465,8 @@ mlxsw_sp_acl_tcam_group_vregion_attach(struct mlxsw_sp *mlxsw_sp,
 }
 
 static void
-mlxsw_sp_acl_tcam_group_vregion_detach(struct mlxsw_sp *mlxsw_sp,
-				       struct mlxsw_sp_acl_tcam_vregion *vregion)
+mlxsw_sp_acl_tcam_vgroup_vregion_detach(struct mlxsw_sp *mlxsw_sp,
+					struct mlxsw_sp_acl_tcam_vregion *vregion)
 {
 	list_del(&vregion->list);
 	if (vregion->region2)
@@ -421,22 +476,22 @@ mlxsw_sp_acl_tcam_group_vregion_detach(struct mlxsw_sp *mlxsw_sp,
 }
 
 static struct mlxsw_sp_acl_tcam_vregion *
-mlxsw_sp_acl_tcam_group_vregion_find(struct mlxsw_sp_acl_tcam_group *group,
-				     unsigned int priority,
-				     struct mlxsw_afk_element_usage *elusage,
-				     bool *p_need_split)
+mlxsw_sp_acl_tcam_vgroup_vregion_find(struct mlxsw_sp_acl_tcam_vgroup *vgroup,
+				      unsigned int priority,
+				      struct mlxsw_afk_element_usage *elusage,
+				      bool *p_need_split)
 {
 	struct mlxsw_sp_acl_tcam_vregion *vregion, *vregion2;
 	struct list_head *pos;
 	bool issubset;
 
-	list_for_each(pos, &group->vregion_list) {
+	list_for_each(pos, &vgroup->vregion_list) {
 		vregion = list_entry(pos, typeof(*vregion), list);
 
 		/* First, check if the requested priority does not rather belong
 		 * under some of the next vregions.
 		 */
-		if (pos->next != &group->vregion_list) { /* not last */
+		if (pos->next != &vgroup->vregion_list) { /* not last */
 			vregion2 = list_entry(pos->next, typeof(*vregion2),
 					      list);
 			if (priority >=
@@ -477,9 +532,9 @@ mlxsw_sp_acl_tcam_group_vregion_find(struct mlxsw_sp_acl_tcam_group *group,
 }
 
 static void
-mlxsw_sp_acl_tcam_group_use_patterns(struct mlxsw_sp_acl_tcam_group *group,
-				     struct mlxsw_afk_element_usage *elusage,
-				     struct mlxsw_afk_element_usage *out)
+mlxsw_sp_acl_tcam_vgroup_use_patterns(struct mlxsw_sp_acl_tcam_vgroup *vgroup,
+				      struct mlxsw_afk_element_usage *elusage,
+				      struct mlxsw_afk_element_usage *out)
 {
 	const struct mlxsw_sp_acl_tcam_pattern *pattern;
 	int i;
@@ -487,14 +542,14 @@ mlxsw_sp_acl_tcam_group_use_patterns(struct mlxsw_sp_acl_tcam_group *group,
 	/* In case the template is set, we don't have to look up the pattern
 	 * and just use the template.
 	 */
-	if (group->tmplt_elusage_set) {
-		memcpy(out, &group->tmplt_elusage, sizeof(*out));
+	if (vgroup->tmplt_elusage_set) {
+		memcpy(out, &vgroup->tmplt_elusage, sizeof(*out));
 		WARN_ON(!mlxsw_afk_element_usage_subset(elusage, out));
 		return;
 	}
 
-	for (i = 0; i < group->patterns_count; i++) {
-		pattern = &group->patterns[i];
+	for (i = 0; i < vgroup->patterns_count; i++) {
+		pattern = &vgroup->patterns[i];
 		mlxsw_afk_element_usage_fill(out, pattern->elements,
 					     pattern->elements_count);
 		if (mlxsw_afk_element_usage_subset(elusage, out))
@@ -627,7 +682,7 @@ mlxsw_sp_acl_tcam_region_destroy(struct mlxsw_sp *mlxsw_sp,
 	ops->region_fini(mlxsw_sp, region->priv);
 	mlxsw_sp_acl_tcam_region_disable(mlxsw_sp, region);
 	mlxsw_sp_acl_tcam_region_free(mlxsw_sp, region);
-	mlxsw_sp_acl_tcam_region_id_put(region->vregion->group->tcam,
+	mlxsw_sp_acl_tcam_region_id_put(region->group->tcam,
 					region->id);
 	kfree(region);
 }
@@ -763,7 +818,7 @@ int mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp,
 
 static int
 mlxsw_sp_acl_tcam_vchunk_assoc(struct mlxsw_sp *mlxsw_sp,
-			       struct mlxsw_sp_acl_tcam_group *group,
+			       struct mlxsw_sp_acl_tcam_vgroup *vgroup,
 			       unsigned int priority,
 			       struct mlxsw_afk_element_usage *elusage,
 			       struct mlxsw_sp_acl_tcam_vchunk *vchunk)
@@ -773,8 +828,8 @@ mlxsw_sp_acl_tcam_vchunk_assoc(struct mlxsw_sp *mlxsw_sp,
 	bool need_split;
 	int err;
 
-	vregion = mlxsw_sp_acl_tcam_group_vregion_find(group, priority, elusage,
-						       &need_split);
+	vregion = mlxsw_sp_acl_tcam_vgroup_vregion_find(vgroup, priority,
+							elusage, &need_split);
 	if (vregion && need_split) {
 		/* According to priority, the vchunk should belong to an
 		 * existing vregion. However, this vchunk needs elements
@@ -787,10 +842,10 @@ mlxsw_sp_acl_tcam_vchunk_assoc(struct mlxsw_sp *mlxsw_sp,
 	if (!vregion) {
 		struct mlxsw_afk_element_usage vregion_elusage;
 
-		mlxsw_sp_acl_tcam_group_use_patterns(group, elusage,
-						     &vregion_elusage);
+		mlxsw_sp_acl_tcam_vgroup_use_patterns(vgroup, elusage,
+						      &vregion_elusage);
 		vregion = mlxsw_sp_acl_tcam_vregion_create(mlxsw_sp,
-							   group->tcam,
+							   vgroup->group.tcam,
 							   &vregion_elusage);
 		if (IS_ERR(vregion))
 			return PTR_ERR(vregion);
@@ -803,13 +858,14 @@ mlxsw_sp_acl_tcam_vchunk_assoc(struct mlxsw_sp *mlxsw_sp,
 	if (!vregion_created)
 		return 0;
 
-	err = mlxsw_sp_acl_tcam_group_vregion_attach(mlxsw_sp, group, vregion);
+	err = mlxsw_sp_acl_tcam_vgroup_vregion_attach(mlxsw_sp, vgroup,
+						      vregion);
 	if (err)
-		goto err_group_vregion_attach;
+		goto err_vgroup_vregion_attach;
 
 	return 0;
 
-err_group_vregion_attach:
+err_vgroup_vregion_attach:
 	mlxsw_sp_acl_tcam_vregion_destroy(mlxsw_sp, vregion);
 	return err;
 }
@@ -822,7 +878,7 @@ mlxsw_sp_acl_tcam_vchunk_deassoc(struct mlxsw_sp *mlxsw_sp,
 
 	list_del(&vchunk->list);
 	if (list_empty(&vregion->vchunk_list)) {
-		mlxsw_sp_acl_tcam_group_vregion_detach(mlxsw_sp, vregion);
+		mlxsw_sp_acl_tcam_vgroup_vregion_detach(mlxsw_sp, vregion);
 		mlxsw_sp_acl_tcam_vregion_destroy(mlxsw_sp, vregion);
 	}
 }
@@ -857,7 +913,7 @@ mlxsw_sp_acl_tcam_chunk_destroy(struct mlxsw_sp *mlxsw_sp,
 
 static struct mlxsw_sp_acl_tcam_vchunk *
 mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp,
-				struct mlxsw_sp_acl_tcam_group *group,
+				struct mlxsw_sp_acl_tcam_vgroup *vgroup,
 				unsigned int priority,
 				struct mlxsw_afk_element_usage *elusage)
 {
@@ -872,15 +928,15 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp,
 		return ERR_PTR(-ENOMEM);
 	INIT_LIST_HEAD(&vchunk->ventry_list);
 	vchunk->priority = priority;
-	vchunk->group = group;
+	vchunk->vgroup = vgroup;
 	vchunk->ref_count = 1;
 
-	err = mlxsw_sp_acl_tcam_vchunk_assoc(mlxsw_sp, group, priority,
+	err = mlxsw_sp_acl_tcam_vchunk_assoc(mlxsw_sp, vgroup, priority,
 					     elusage, vchunk);
 	if (err)
 		goto err_vchunk_assoc;
 
-	err = rhashtable_insert_fast(&group->vchunk_ht, &vchunk->ht_node,
+	err = rhashtable_insert_fast(&vgroup->vchunk_ht, &vchunk->ht_node,
 				     mlxsw_sp_acl_tcam_vchunk_ht_params);
 	if (err)
 		goto err_rhashtable_insert;
@@ -895,7 +951,7 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp,
 	return vchunk;
 
 err_chunk_create:
-	rhashtable_remove_fast(&group->vchunk_ht, &vchunk->ht_node,
+	rhashtable_remove_fast(&vgroup->vchunk_ht, &vchunk->ht_node,
 			       mlxsw_sp_acl_tcam_vchunk_ht_params);
 err_rhashtable_insert:
 	mlxsw_sp_acl_tcam_vchunk_deassoc(mlxsw_sp, vchunk);
@@ -908,12 +964,12 @@ static void
 mlxsw_sp_acl_tcam_vchunk_destroy(struct mlxsw_sp *mlxsw_sp,
 				 struct mlxsw_sp_acl_tcam_vchunk *vchunk)
 {
-	struct mlxsw_sp_acl_tcam_group *group = vchunk->group;
+	struct mlxsw_sp_acl_tcam_vgroup *vgroup = vchunk->vgroup;
 
 	if (vchunk->chunk2)
 		mlxsw_sp_acl_tcam_chunk_destroy(mlxsw_sp, vchunk->chunk2);
 	mlxsw_sp_acl_tcam_chunk_destroy(mlxsw_sp, vchunk->chunk);
-	rhashtable_remove_fast(&group->vchunk_ht, &vchunk->ht_node,
+	rhashtable_remove_fast(&vgroup->vchunk_ht, &vchunk->ht_node,
 			       mlxsw_sp_acl_tcam_vchunk_ht_params);
 	mlxsw_sp_acl_tcam_vchunk_deassoc(mlxsw_sp, vchunk);
 	kfree(vchunk);
@@ -921,13 +977,13 @@ mlxsw_sp_acl_tcam_vchunk_destroy(struct mlxsw_sp *mlxsw_sp,
 
 static struct mlxsw_sp_acl_tcam_vchunk *
 mlxsw_sp_acl_tcam_vchunk_get(struct mlxsw_sp *mlxsw_sp,
-			     struct mlxsw_sp_acl_tcam_group *group,
+			     struct mlxsw_sp_acl_tcam_vgroup *vgroup,
 			     unsigned int priority,
 			     struct mlxsw_afk_element_usage *elusage)
 {
 	struct mlxsw_sp_acl_tcam_vchunk *vchunk;
 
-	vchunk = rhashtable_lookup_fast(&group->vchunk_ht, &priority,
+	vchunk = rhashtable_lookup_fast(&vgroup->vchunk_ht, &priority,
 					mlxsw_sp_acl_tcam_vchunk_ht_params);
 	if (vchunk) {
 		if (WARN_ON(!mlxsw_afk_key_info_subset(vchunk->vregion->key_info,
@@ -936,7 +992,7 @@ mlxsw_sp_acl_tcam_vchunk_get(struct mlxsw_sp *mlxsw_sp,
 		vchunk->ref_count++;
 		return vchunk;
 	}
-	return mlxsw_sp_acl_tcam_vchunk_create(mlxsw_sp, group,
+	return mlxsw_sp_acl_tcam_vchunk_create(mlxsw_sp, vgroup,
 					       priority, elusage);
 }
 
@@ -1010,14 +1066,14 @@ mlxsw_sp_acl_tcam_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
 }
 
 static int mlxsw_sp_acl_tcam_ventry_add(struct mlxsw_sp *mlxsw_sp,
-					struct mlxsw_sp_acl_tcam_group *group,
+					struct mlxsw_sp_acl_tcam_vgroup *vgroup,
 					struct mlxsw_sp_acl_tcam_ventry *ventry,
 					struct mlxsw_sp_acl_rule_info *rulei)
 {
 	struct mlxsw_sp_acl_tcam_vchunk *vchunk;
 	int err;
 
-	vchunk = mlxsw_sp_acl_tcam_vchunk_get(mlxsw_sp, group, rulei->priority,
+	vchunk = mlxsw_sp_acl_tcam_vchunk_get(mlxsw_sp, vgroup, rulei->priority,
 					      &rulei->values.elusage);
 	if (IS_ERR(vchunk))
 		return PTR_ERR(vchunk);
@@ -1183,7 +1239,9 @@ mlxsw_sp_acl_tcam_vregion_migrate(struct mlxsw_sp *mlxsw_sp,
 		return PTR_ERR(region2);
 
 	vregion->region2 = region2;
-	err = mlxsw_sp_acl_tcam_group_region_attach(mlxsw_sp, region2);
+	err = mlxsw_sp_acl_tcam_group_region_attach(mlxsw_sp,
+						    vregion->region->group,
+						    region2, vregion->region);
 	if (err)
 		goto err_group_region_attach;
 
@@ -1297,7 +1355,7 @@ static const struct mlxsw_sp_acl_tcam_pattern mlxsw_sp_acl_tcam_patterns[] = {
 	ARRAY_SIZE(mlxsw_sp_acl_tcam_patterns)
 
 struct mlxsw_sp_acl_tcam_flower_ruleset {
-	struct mlxsw_sp_acl_tcam_group group;
+	struct mlxsw_sp_acl_tcam_vgroup vgroup;
 };
 
 struct mlxsw_sp_acl_tcam_flower_rule {
@@ -1312,10 +1370,10 @@ mlxsw_sp_acl_tcam_flower_ruleset_add(struct mlxsw_sp *mlxsw_sp,
 {
 	struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv;
 
-	return mlxsw_sp_acl_tcam_group_add(mlxsw_sp, tcam, &ruleset->group,
-					   mlxsw_sp_acl_tcam_patterns,
-					   MLXSW_SP_ACL_TCAM_PATTERNS_COUNT,
-					   tmplt_elusage);
+	return mlxsw_sp_acl_tcam_vgroup_add(mlxsw_sp, tcam, &ruleset->vgroup,
+					    mlxsw_sp_acl_tcam_patterns,
+					    MLXSW_SP_ACL_TCAM_PATTERNS_COUNT,
+					    tmplt_elusage);
 }
 
 static void
@@ -1324,7 +1382,7 @@ mlxsw_sp_acl_tcam_flower_ruleset_del(struct mlxsw_sp *mlxsw_sp,
 {
 	struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv;
 
-	mlxsw_sp_acl_tcam_group_del(mlxsw_sp, &ruleset->group);
+	mlxsw_sp_acl_tcam_vgroup_del(&ruleset->vgroup);
 }
 
 static int
@@ -1335,7 +1393,7 @@ mlxsw_sp_acl_tcam_flower_ruleset_bind(struct mlxsw_sp *mlxsw_sp,
 {
 	struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv;
 
-	return mlxsw_sp_acl_tcam_group_bind(mlxsw_sp, &ruleset->group,
+	return mlxsw_sp_acl_tcam_group_bind(mlxsw_sp, &ruleset->vgroup.group,
 					    mlxsw_sp_port, ingress);
 }
 
@@ -1347,7 +1405,7 @@ mlxsw_sp_acl_tcam_flower_ruleset_unbind(struct mlxsw_sp *mlxsw_sp,
 {
 	struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv;
 
-	mlxsw_sp_acl_tcam_group_unbind(mlxsw_sp, &ruleset->group,
+	mlxsw_sp_acl_tcam_group_unbind(mlxsw_sp, &ruleset->vgroup.group,
 				       mlxsw_sp_port, ingress);
 }
 
@@ -1356,7 +1414,7 @@ mlxsw_sp_acl_tcam_flower_ruleset_group_id(void *ruleset_priv)
 {
 	struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv;
 
-	return mlxsw_sp_acl_tcam_group_id(&ruleset->group);
+	return mlxsw_sp_acl_tcam_group_id(&ruleset->vgroup.group);
 }
 
 static int
@@ -1367,7 +1425,7 @@ mlxsw_sp_acl_tcam_flower_rule_add(struct mlxsw_sp *mlxsw_sp,
 	struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv;
 	struct mlxsw_sp_acl_tcam_flower_rule *rule = rule_priv;
 
-	return mlxsw_sp_acl_tcam_ventry_add(mlxsw_sp, &ruleset->group,
+	return mlxsw_sp_acl_tcam_ventry_add(mlxsw_sp, &ruleset->vgroup,
 					    &rule->ventry, rulei);
 }
 
@@ -1413,7 +1471,7 @@ static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_flower_ops = {
 
 struct mlxsw_sp_acl_tcam_mr_ruleset {
 	struct mlxsw_sp_acl_tcam_vchunk *vchunk;
-	struct mlxsw_sp_acl_tcam_group group;
+	struct mlxsw_sp_acl_tcam_vgroup vgroup;
 };
 
 struct mlxsw_sp_acl_tcam_mr_rule {
@@ -1429,10 +1487,10 @@ mlxsw_sp_acl_tcam_mr_ruleset_add(struct mlxsw_sp *mlxsw_sp,
 	struct mlxsw_sp_acl_tcam_mr_ruleset *ruleset = ruleset_priv;
 	int err;
 
-	err = mlxsw_sp_acl_tcam_group_add(mlxsw_sp, tcam, &ruleset->group,
-					  mlxsw_sp_acl_tcam_patterns,
-					  MLXSW_SP_ACL_TCAM_PATTERNS_COUNT,
-					  tmplt_elusage);
+	err = mlxsw_sp_acl_tcam_vgroup_add(mlxsw_sp, tcam, &ruleset->vgroup,
+					   mlxsw_sp_acl_tcam_patterns,
+					   MLXSW_SP_ACL_TCAM_PATTERNS_COUNT,
+					   tmplt_elusage);
 	if (err)
 		return err;
 
@@ -1443,7 +1501,7 @@ mlxsw_sp_acl_tcam_mr_ruleset_add(struct mlxsw_sp *mlxsw_sp,
 	 * is initialized.
 	 */
 	ruleset->vchunk = mlxsw_sp_acl_tcam_vchunk_get(mlxsw_sp,
-						       &ruleset->group, 1,
+						       &ruleset->vgroup, 1,
 						       tmplt_elusage);
 	if (IS_ERR(ruleset->vchunk)) {
 		err = PTR_ERR(ruleset->vchunk);
@@ -1453,7 +1511,7 @@ mlxsw_sp_acl_tcam_mr_ruleset_add(struct mlxsw_sp *mlxsw_sp,
 	return 0;
 
 err_chunk_get:
-	mlxsw_sp_acl_tcam_group_del(mlxsw_sp, &ruleset->group);
+	mlxsw_sp_acl_tcam_vgroup_del(&ruleset->vgroup);
 	return err;
 }
 
@@ -1463,7 +1521,7 @@ mlxsw_sp_acl_tcam_mr_ruleset_del(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv)
 	struct mlxsw_sp_acl_tcam_mr_ruleset *ruleset = ruleset_priv;
 
 	mlxsw_sp_acl_tcam_vchunk_put(mlxsw_sp, ruleset->vchunk);
-	mlxsw_sp_acl_tcam_group_del(mlxsw_sp, &ruleset->group);
+	mlxsw_sp_acl_tcam_vgroup_del(&ruleset->vgroup);
 }
 
 static int
@@ -1488,7 +1546,7 @@ mlxsw_sp_acl_tcam_mr_ruleset_group_id(void *ruleset_priv)
 {
 	struct mlxsw_sp_acl_tcam_mr_ruleset *ruleset = ruleset_priv;
 
-	return mlxsw_sp_acl_tcam_group_id(&ruleset->group);
+	return mlxsw_sp_acl_tcam_group_id(&ruleset->vgroup.group);
 }
 
 static int
@@ -1499,7 +1557,7 @@ mlxsw_sp_acl_tcam_mr_rule_add(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
 	struct mlxsw_sp_acl_tcam_mr_ruleset *ruleset = ruleset_priv;
 	struct mlxsw_sp_acl_tcam_mr_rule *rule = rule_priv;
 
-	return mlxsw_sp_acl_tcam_ventry_add(mlxsw_sp, &ruleset->group,
+	return mlxsw_sp_acl_tcam_ventry_add(mlxsw_sp, &ruleset->vgroup,
 					   &rule->ventry, rulei);
 }
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
index 96bd42a9fbc3..77de76647ede 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
@@ -78,6 +78,8 @@ struct mlxsw_sp_acl_tcam_vregion;
 
 struct mlxsw_sp_acl_tcam_region {
 	struct mlxsw_sp_acl_tcam_vregion *vregion;
+	struct mlxsw_sp_acl_tcam_group *group;
+	struct list_head list; /* Member of a TCAM group */
 	enum mlxsw_reg_ptar_key_type key_type;
 	u16 id; /* ACL ID and region ID - they are same */
 	char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN];
-- 
2.20.1


^ permalink raw reply related

* [PATCH net-next 03/15] mlxsw: spectrum_acl: Introduce a mutex to guard region list updates
From: Ido Schimmel @ 2019-02-24  6:46 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: davem@davemloft.net, Jiri Pirko, mlxsw, Ido Schimmel
In-Reply-To: <20190224064525.14913-1-idosch@mellanox.com>

From: Jiri Pirko <jiri@mellanox.com>

In order to remove RTNL lock dependency, it is needed to protect
the regions list in a group. Introduce a mutex to do the job.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_acl_tcam.c  | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
index 922f17adcee7..21ebda19a2ad 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
@@ -8,6 +8,7 @@
 #include <linux/list.h>
 #include <linux/rhashtable.h>
 #include <linux/netdevice.h>
+#include <linux/mutex.h>
 #include <trace/events/mlxsw.h>
 
 #include "reg.h"
@@ -161,6 +162,7 @@ struct mlxsw_sp_acl_tcam_pattern {
 struct mlxsw_sp_acl_tcam_group {
 	struct mlxsw_sp_acl_tcam *tcam;
 	u16 id;
+	struct mutex lock; /* guards region list updates */
 	struct list_head region_list;
 	unsigned int region_count;
 };
@@ -259,6 +261,7 @@ mlxsw_sp_acl_tcam_group_add(struct mlxsw_sp_acl_tcam *tcam,
 	int err;
 
 	group->tcam = tcam;
+	mutex_init(&group->lock);
 	INIT_LIST_HEAD(&group->region_list);
 
 	err = mlxsw_sp_acl_tcam_group_id_get(tcam, &group->id);
@@ -272,6 +275,7 @@ static void mlxsw_sp_acl_tcam_group_del(struct mlxsw_sp_acl_tcam_group *group)
 {
 	struct mlxsw_sp_acl_tcam *tcam = group->tcam;
 
+	mutex_destroy(&group->lock);
 	mlxsw_sp_acl_tcam_group_id_put(tcam, group->id);
 	WARN_ON(!list_empty(&group->region_list));
 }
@@ -390,8 +394,11 @@ mlxsw_sp_acl_tcam_group_region_attach(struct mlxsw_sp *mlxsw_sp,
 	struct list_head *pos;
 	int err;
 
-	if (group->region_count == group->tcam->max_group_size)
-		return -ENOBUFS;
+	mutex_lock(&group->lock);
+	if (group->region_count == group->tcam->max_group_size) {
+		err = -ENOBUFS;
+		goto err_region_count_check;
+	}
 
 	if (next_region) {
 		/* If the next region is defined, place the new one
@@ -415,10 +422,13 @@ mlxsw_sp_acl_tcam_group_region_attach(struct mlxsw_sp *mlxsw_sp,
 		goto err_group_update;
 
 	group->region_count++;
+	mutex_unlock(&group->lock);
 	return 0;
 
 err_group_update:
 	list_del(&region->list);
+err_region_count_check:
+	mutex_unlock(&group->lock);
 	return err;
 }
 
@@ -428,9 +438,11 @@ mlxsw_sp_acl_tcam_group_region_detach(struct mlxsw_sp *mlxsw_sp,
 {
 	struct mlxsw_sp_acl_tcam_group *group = region->group;
 
+	mutex_lock(&group->lock);
 	list_del(&region->list);
 	group->region_count--;
 	mlxsw_sp_acl_tcam_group_update(mlxsw_sp, group);
+	mutex_unlock(&group->lock);
 }
 
 static int
-- 
2.20.1


^ permalink raw reply related

* [PATCH net-next 00/15] mlxsw: spectrum_acl: Don't take rtnl mutex for region rehash
From: Ido Schimmel @ 2019-02-24  6:46 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: davem@davemloft.net, Jiri Pirko, mlxsw, Ido Schimmel

Jiri says:

During region rehash, a new region is created with a more optimized set
of masks (ERPs). When transitioning to the new region, all the rules
from the old region are copied one-by-one to the new region. This
transition can be time consuming and currently done under RTNL lock.

In order to remove RTNL lock dependency during region rehash, introduce
multiple smaller locks guarding dedicated structures or parts of them.
That is the vast majority of this patchset. Only patch #1 is simple
cleanup and patches 12-15 are improving or introducing new selftests.

Jiri Pirko (15):
  mlxsw: spectrum_acl: Remove unused ops field from group structure
  mlxsw: spectrum_acl: Split TCAM group structure into two
  mlxsw: spectrum_acl: Introduce a mutex to guard region list updates
  mlxsw: spectrum_acl: Refactor vregion association code
  mlxsw: spectrum_acl: Introduce vregion mutex
  mlxsw: spectrum_acl: Introduce mutex to guard Bloom Filter updates
  mlxsw: spectrum_acl: Introduce a mutex to guard objagg instance
    manipulation
  mlxsw: spectrum_acl: Enable vregion rehash per-profile
  mlxsw: spectrum_acl: Don't take rtnl lock during
    vregion_rehash_intrvl_set()
  mlxsw: spectrum_acl: Remove RTNL lock assertions from ERP code
  mlxsw: spectrum_acl: Don't take mutex in
    mlxsw_sp_acl_tcam_vregion_rehash_work()
  selftests: mlxsw: spectrum-2: Add IPv6 variant of simple delta rehash
    test
  mlxsw: spectrum_acl: Add vregion migration end tracepoint
  selftests: mlxsw: spectrum-2: Check migrate end trace
  selftests: mlxsw: spectrum-2: Add massive delta rehash test

 .../mlxsw/spectrum_acl_bloom_filter.c         |  34 +-
 .../mellanox/mlxsw/spectrum_acl_erp.c         |  31 +-
 .../mellanox/mlxsw/spectrum_acl_tcam.c        | 446 +++++++++++-------
 .../mellanox/mlxsw/spectrum_acl_tcam.h        |   3 +
 include/trace/events/mlxsw.h                  |  20 +
 .../drivers/net/mlxsw/spectrum-2/tc_flower.sh | 245 ++++++++++
 6 files changed, 592 insertions(+), 187 deletions(-)

-- 
2.20.1


^ permalink raw reply

* [Q] why do we ever try to call unix_dgram_peer_wake_disconnect() for SOCK_STREAM?
From: Al Viro @ 2019-02-24  6:28 UTC (permalink / raw)
  To: netdev; +Cc: Rainer Weikusat

	What's the point of calling unix_dgram_peer_wake_disconnect() in
unix_release_sock() of SOCK_STREAM/SOCK_SEQPACKET sockets?  AFAICS,
for those we never call unix_dgram_peer_wake_connect(), i.e. ->peer_wake.private
of any non-SOCK_DGRAM socker has to remain NULL.  Which makes that call simply
	spin_lock(&unix_sk(skpair)->peer_wait.lock);
	spin_unlock(&unix_sk(skpair)->peer_wait.lock);
and that doesn't even serve as a barrier for anything else.  Should that
have been
                if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
                        unix_state_lock(skpair);
                        /* No more writes */
                        skpair->sk_shutdown = SHUTDOWN_MASK;
                        if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
                                skpair->sk_err = ECONNRESET;
                        unix_state_unlock(skpair);
                        skpair->sk_state_change(skpair);
                        sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
                } else {
			unix_dgram_peer_wake_disconnect(sk, skpair);
		}
or am I missing something subtle here?

^ permalink raw reply

* [PATCH net-next] trace: events: neigh_update: print new state in string format
From: Roopa Prabhu @ 2019-02-24  6:25 UTC (permalink / raw)
  To: davem; +Cc: netdev

From: Roopa Prabhu <roopa@cumulusnetworks.com>

Also, extend neigh_state_str to include neigh dummy states
noarp and permanent

Fixes: 9c03b282badb ("trace: events: add a few neigh tracepoints")
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
 include/trace/events/neigh.h | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/trace/events/neigh.h b/include/trace/events/neigh.h
index ed10353..0bdb085 100644
--- a/include/trace/events/neigh.h
+++ b/include/trace/events/neigh.h
@@ -16,7 +16,9 @@
 		{ NUD_STALE, "stale" },			\
 		{ NUD_DELAY, "delay" },			\
 		{ NUD_PROBE, "probe" },			\
-		{ NUD_FAILED, "failed" })
+		{ NUD_FAILED, "failed" },		\
+		{ NUD_NOARP, "noarp" },			\
+		{ NUD_PERMANENT, "permanent"})
 
 TRACE_EVENT(neigh_update,
 
@@ -90,7 +92,7 @@ TRACE_EVENT(neigh_update,
 	TP_printk("family %d dev %s lladdr %s flags %02x nud_state %s type %02x "
 		  "dead %d refcnt %d primary_key4 %pI4 primary_key6 %pI6c "
 		  "confirmed %lu updated %lu used %lu new_lladdr %s "
-		  "new_state %02x update_flags %02x pid %d",
+		  "new_state %s update_flags %02x pid %d",
 		  __entry->family, __get_str(dev),
 		  __print_hex_str(__entry->lladdr, __entry->lladdr_len),
 		  __entry->flags, neigh_state_str(__entry->nud_state),
@@ -98,7 +100,7 @@ TRACE_EVENT(neigh_update,
 		  __entry->primary_key4, __entry->primary_key6,
 		  __entry->confirmed, __entry->updated, __entry->used,
 		  __print_hex_str(__entry->new_lladdr, __entry->lladdr_len),
-		  __entry->new_state,
+		  neigh_state_str(__entry->new_state),
 		  __entry->update_flags, __entry->pid)
 );
 
-- 
2.1.4


^ permalink raw reply related

* Re: kTLS getsockopt TLS_RX support
From: Hayakawa Yutaro @ 2019-02-24  5:59 UTC (permalink / raw)
  To: Vakul Garg; +Cc: netdev@vger.kernel.org
In-Reply-To: <DB7PR04MB4252EA89BB7958D2127366748B790@DB7PR04MB4252.eurprd04.prod.outlook.com>


> 2019/02/24 14:33、Vakul Garg <vakul.garg@nxp.com>のメール:
> 
> 
> 
>> -----Original Message-----
>> From: Hayakawa Yutaro <yhayakawa3720subscribe@gmail.com>
>> Sent: Sunday, February 24, 2019 11:01 AM
>> To: Vakul Garg <vakul.garg@nxp.com>
>> Cc: netdev@vger.kernel.org
>> Subject: Re: kTLS getsockopt TLS_RX support
>> 
>> 
>>> 2019/02/24 10:50、Vakul Garg <vakul.garg@nxp.com>のメール:
>>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: netdev-owner@vger.kernel.org <netdev-owner@vger.kernel.org>
>> On
>>>> Behalf Of Hayakawa Yutaro
>>>> Sent: Saturday, February 23, 2019 10:59 PM
>>>> To: netdev@vger.kernel.org
>>>> Subject: kTLS getsockopt TLS_RX support
>>>> 
>>>> Hello,
>>>> 
>>>> While trying the kTLS, I found out that currently, there is no
>>>> support for kTLS getsockopt TLS_RX which extracts receive side crypto
>>>> information from kTLS socket. Since setting crypto information for RX
>>>> side is supported, I felt wonder why it is not supported.
>>>> 
>>>> Is there any particular reason for it?
>>> 
>>> What use case do you have in mind?
>>> Why give back state of record layer which also contains (record sequence
>> number) to user space?
>> 
>> I’d like to checkpoint/restore the TLS session in conjunction with
>> TCP_REPAIR.
>> 
>> When we checkpoint the kTLS session, we need to pick the record sequence
>> number or any other session information from kernel. For TX side, it is
>> already supported (getsockopt TLS_TX), so I’m wondering why RX side is
>> missing.
>> 
>> Is there any technical difficulty or it will never supported in future?
> 
> Don't think so. 
> Will you submit a patch?

Since I am one of the beginner user of kTLS, I don’t have much knowledge about the
internal, but I have my own patch. I can test and submit it to here.

Yutaro

> 
>> Regards,
>> Yutaro
>> 
>>> 
>>>> 
>>>> Regards,
>>>> Yutaro


^ permalink raw reply

* RE: kTLS getsockopt TLS_RX support
From: Vakul Garg @ 2019-02-24  5:33 UTC (permalink / raw)
  To: Hayakawa Yutaro; +Cc: netdev@vger.kernel.org
In-Reply-To: <8989A671-47DB-4910-AFE8-8A6E6E30A827@gmail.com>



> -----Original Message-----
> From: Hayakawa Yutaro <yhayakawa3720subscribe@gmail.com>
> Sent: Sunday, February 24, 2019 11:01 AM
> To: Vakul Garg <vakul.garg@nxp.com>
> Cc: netdev@vger.kernel.org
> Subject: Re: kTLS getsockopt TLS_RX support
> 
> 
> > 2019/02/24 10:50、Vakul Garg <vakul.garg@nxp.com>のメール:
> >
> >
> >
> >> -----Original Message-----
> >> From: netdev-owner@vger.kernel.org <netdev-owner@vger.kernel.org>
> On
> >> Behalf Of Hayakawa Yutaro
> >> Sent: Saturday, February 23, 2019 10:59 PM
> >> To: netdev@vger.kernel.org
> >> Subject: kTLS getsockopt TLS_RX support
> >>
> >> Hello,
> >>
> >> While trying the kTLS, I found out that currently, there is no
> >> support for kTLS getsockopt TLS_RX which extracts receive side crypto
> >> information from kTLS socket. Since setting crypto information for RX
> >> side is supported, I felt wonder why it is not supported.
> >>
> >> Is there any particular reason for it?
> >
> > What use case do you have in mind?
> > Why give back state of record layer which also contains (record sequence
> number) to user space?
> 
> I’d like to checkpoint/restore the TLS session in conjunction with
> TCP_REPAIR.
> 
> When we checkpoint the kTLS session, we need to pick the record sequence
> number or any other session information from kernel. For TX side, it is
> already supported (getsockopt TLS_TX), so I’m wondering why RX side is
> missing.
> 
> Is there any technical difficulty or it will never supported in future?

Don't think so. 
Will you submit a patch?

> Regards,
> Yutaro
> 
> >
> >>
> >> Regards,
> >> Yutaro


^ permalink raw reply

* Re: kTLS getsockopt TLS_RX support
From: Hayakawa Yutaro @ 2019-02-24  5:31 UTC (permalink / raw)
  To: Vakul Garg; +Cc: netdev@vger.kernel.org
In-Reply-To: <DB7PR04MB4252AE898032DB6D4C49BB3C8B790@DB7PR04MB4252.eurprd04.prod.outlook.com>


> 2019/02/24 10:50、Vakul Garg <vakul.garg@nxp.com>のメール:
> 
> 
> 
>> -----Original Message-----
>> From: netdev-owner@vger.kernel.org <netdev-owner@vger.kernel.org> On
>> Behalf Of Hayakawa Yutaro
>> Sent: Saturday, February 23, 2019 10:59 PM
>> To: netdev@vger.kernel.org
>> Subject: kTLS getsockopt TLS_RX support
>> 
>> Hello,
>> 
>> While trying the kTLS, I found out that currently, there is no support for kTLS
>> getsockopt TLS_RX which extracts receive side crypto information from kTLS
>> socket. Since setting crypto information for RX side is supported, I felt
>> wonder why it is not supported.
>> 
>> Is there any particular reason for it?
> 
> What use case do you have in mind?
> Why give back state of record layer which also contains (record sequence number) to user space?

I’d like to checkpoint/restore the TLS session in conjunction with TCP_REPAIR.

When we checkpoint the kTLS session, we need to pick the record sequence number or
any other session information from kernel. For TX side, it is already supported (getsockopt
TLS_TX), so I’m wondering why RX side is missing.

Is there any technical difficulty or it will never supported in future?

Regards,
Yutaro

> 
>> 
>> Regards,
>> Yutaro


^ permalink raw reply

* Re: [PATCH v2 bpf-next 0/9] bpf: Network Resource Manager (NRM)
From: Alexei Starovoitov @ 2019-02-24  4:48 UTC (permalink / raw)
  To: David Ahern
  Cc: Eric Dumazet, brakmo, netdev, Martin Lau, Alexei Starovoitov,
	Daniel Borkmann, Kernel Team
In-Reply-To: <b5dc095e-198b-3b23-cebc-29c3c682d6e7@gmail.com>

On Sat, Feb 23, 2019 at 09:58:57PM -0500, David Ahern wrote:
> On 2/23/19 6:25 PM, Alexei Starovoitov wrote:
> >>> hmm. please see our NRM presentation at LPC.
> 
> Reference?
> 
> We also gave a talk about a resource manager in November 2017:
> 
> https://netdevconf.org/2.2/papers/roulin-hardwareresourcesmgmt-talk.pdf
> 
> in this case the context is hardware resources for networking which
> aligns with devlink and switchdev.
> 
> >>> It is a networking _resource_ management for cgroups.
> >>> Bandwidth enforcement is a particular example.
> >>> It's not a policer either.
> >>>
> >>
> >> Well, this definitely looks a policer to me, sorry if we disagree, this is fine.
> > 
> > this particular example certainly does look like it. we both agree.
> > It's overall direction of this work that is aiming to do
> > network resource management. For example bpf prog may choose
> > to react on SLA violations in one cgroup by throttling flows
> > in the other cgroup. Aggregated per-cgroup bandwidth doesn't
> > need to cross a threshold for bpf prog to take action.
> > It could do 'work conserving' 'policer'.
> > I think this set of patches represent a revolutionary approach and existing
> > networking nomenclature doesn't have precise words to describe it :)
> > 'NRM' describes our goals the best.
> 
> Are you doing something beyond bandwidth usage? e.g., are you limiting
> neighbor entries, fdb entries or FIB entries by cgroup? what about
> router interfaces or vlans? I cannot imagine why or how you would manage
> that but my point is the meaning of 'network resources'.

'network resources' also include back bone and TOR capacity and
this mechanism is going to help address that as well.


^ permalink raw reply

* Re: [PATCH v2 bpf-next 2/9] bpf: Add bpf helper bpf_tcp_enter_cwr
From: Alexei Starovoitov @ 2019-02-24  4:44 UTC (permalink / raw)
  To: Martin Lau
  Cc: Eric Dumazet, Lawrence Brakmo, netdev, Alexei Starovoitov,
	Daniel Borkmann, Kernel Team
In-Reply-To: <20190224030845.imwjbkoaxipuzb75@kafai-mbp.dhcp.thefacebook.com>

On Sun, Feb 24, 2019 at 03:08:48AM +0000, Martin Lau wrote:
> On Sat, Feb 23, 2019 at 05:32:14PM -0800, Eric Dumazet wrote:
> > 
> > 
> > On 02/22/2019 05:06 PM, brakmo wrote:
> > > From: Martin KaFai Lau <kafai@fb.com>
> > > 
> > > This patch adds a new bpf helper BPF_FUNC_tcp_enter_cwr
> > > "int bpf_tcp_enter_cwr(struct bpf_tcp_sock *tp)".
> > > It is added to BPF_PROG_TYPE_CGROUP_SKB which can be attached
> > > to the egress path where the bpf prog is called by
> > > ip_finish_output() or ip6_finish_output().  The verifier
> > > ensures that the parameter must be a tcp_sock.
> > > 
> > > This helper makes a tcp_sock enter CWR state.  It can be used
> > > by a bpf_prog to manage egress network bandwidth limit per
> > > cgroupv2.  A later patch will have a sample program to
> > > show how it can be used to limit bandwidth usage per cgroupv2.
> > > 
> > > To ensure it is only called from BPF_CGROUP_INET_EGRESS, the
> > > attr->expected_attach_type must be specified as BPF_CGROUP_INET_EGRESS
> > > during load time if the prog uses this new helper.
> > > The newly added prog->enforce_expected_attach_type bit will also be set
> > > if this new helper is used.  This bit is for backward compatibility reason
> > > because currently prog->expected_attach_type has been ignored in
> > > BPF_PROG_TYPE_CGROUP_SKB.  During attach time,
> > > prog->expected_attach_type is only enforced if the
> > > prog->enforce_expected_attach_type bit is set.
> > > i.e. prog->expected_attach_type is only enforced if this new helper
> > > is used by the prog.
> > > 
> > 
> > BTW, it seems to me that BPF_CGROUP_INET_EGRESS can be used while the socket lock is not held.
> Thanks for pointing it out.
> 
> ic. I just noticed the comments at ip6_xmit():
> /*
>  * xmit an sk_buff (used by TCP, SCTP and DCCP)
>  * Note : socket lock is not held for SYNACK packets, but might be modified
>  * by calls to skb_set_owner_w() and ipv6_local_error(),
>  * which are using proper atomic operations or spinlocks.
>  */
> Is there other cases other than SYNACK?

I don't think it's a problem.
the helper does:
BPF_CALL_1(bpf_tcp_enter_cwr, struct tcp_sock *, tp)
+{
+	struct sock *sk = (struct sock *)tp;
+
+	if (sk->sk_state == TCP_ESTABLISHED) {
+		tcp_enter_cwr(sk);

I believe at the time ip_finish_output is called on established socket
it's safe to call tcp_enter_cwr.
I don't see how this is different from normal __tcp_transmit_skb path.

Eric, what issue do you see?


^ permalink raw reply

* [PATCH net-next v4] route: Add multipath_hash in flowi_common to make user-define hash
From: wenxu @ 2019-02-24  3:36 UTC (permalink / raw)
  To: nikolay, davem; +Cc: netdev

From: wenxu <wenxu@ucloud.cn>

Current fib_multipath_hash_policy can make hash based on the L3 or
L4. But it only work on the outer IP. So a specific tunnel always
has the same hash value. But a specific tunnel may contain so many
inner connections.

This patch provide a generic multipath_hash in floi_common. It can
make a user-define hash which can mix with L3 or L4 hash.

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c | 2 +-
 include/net/flow.h                                  | 2 ++
 include/net/ip_tunnels.h                            | 3 ++-
 net/ipv4/ip_gre.c                                   | 2 +-
 net/ipv4/ip_tunnel.c                                | 6 +++---
 net/ipv4/route.c                                    | 4 ++++
 6 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
index ad5a9b9..536c23c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -305,7 +305,7 @@ static int mlxsw_sp_span_dmac(struct neigh_table *tbl,
 
 	parms = mlxsw_sp_ipip_netdev_parms4(to_dev);
 	ip_tunnel_init_flow(&fl4, parms.iph.protocol, *daddrp, *saddrp,
-			    0, 0, parms.link, tun->fwmark);
+			    0, 0, parms.link, tun->fwmark, 0);
 
 	rt = ip_route_output_key(tun->net, &fl4);
 	if (IS_ERR(rt))
diff --git a/include/net/flow.h b/include/net/flow.h
index 93f2c9a..a50fb77 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -40,6 +40,7 @@ struct flowi_common {
 	__u32	flowic_secid;
 	kuid_t  flowic_uid;
 	struct flowi_tunnel flowic_tun_key;
+	__u32		flowic_multipath_hash;
 };
 
 union flowi_uli {
@@ -78,6 +79,7 @@ struct flowi4 {
 #define flowi4_secid		__fl_common.flowic_secid
 #define flowi4_tun_key		__fl_common.flowic_tun_key
 #define flowi4_uid		__fl_common.flowic_uid
+#define flowi4_multipath_hash	__fl_common.flowic_multipath_hash
 
 	/* (saddr,daddr) must be grouped, same order as in IP header */
 	__be32			saddr;
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index f069f64..af64560 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -241,7 +241,7 @@ static inline void ip_tunnel_init_flow(struct flowi4 *fl4,
 				       int proto,
 				       __be32 daddr, __be32 saddr,
 				       __be32 key, __u8 tos, int oif,
-				       __u32 mark)
+				       __u32 mark, __u32 tun_inner_hash)
 {
 	memset(fl4, 0, sizeof(*fl4));
 	fl4->flowi4_oif = oif;
@@ -251,6 +251,7 @@ static inline void ip_tunnel_init_flow(struct flowi4 *fl4,
 	fl4->flowi4_proto = proto;
 	fl4->fl4_gre_key = key;
 	fl4->flowi4_mark = mark;
+	fl4->flowi4_multipath_hash = tun_inner_hash;
 }
 
 int ip_tunnel_init(struct net_device *dev);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index ccee941..88ad95e 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -578,7 +578,7 @@ static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
 	key = &info->key;
 	ip_tunnel_init_flow(&fl4, IPPROTO_GRE, key->u.ipv4.dst, key->u.ipv4.src,
 			    tunnel_id_to_key32(key->tun_id), key->tos, 0,
-			    skb->mark);
+			    skb->mark, skb_get_hash(skb));
 	rt = ip_route_output_key(dev_net(dev), &fl4);
 	if (IS_ERR(rt))
 		return PTR_ERR(rt);
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 893f013..3a03114 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -310,7 +310,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev)
 		ip_tunnel_init_flow(&fl4, iph->protocol, iph->daddr,
 				    iph->saddr, tunnel->parms.o_key,
 				    RT_TOS(iph->tos), tunnel->parms.link,
-				    tunnel->fwmark);
+				    tunnel->fwmark, 0);
 		rt = ip_route_output_key(tunnel->net, &fl4);
 
 		if (!IS_ERR(rt)) {
@@ -584,7 +584,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 	}
 	ip_tunnel_init_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src,
 			    tunnel_id_to_key32(key->tun_id), RT_TOS(tos),
-			    0, skb->mark);
+			    0, skb->mark, skb_get_hash(skb));
 	if (tunnel->encap.type != TUNNEL_ENCAP_NONE)
 		goto tx_error;
 
@@ -738,7 +738,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 
 	ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr,
 			    tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link,
-			    tunnel->fwmark);
+			    tunnel->fwmark, skb_get_hash(skb));
 
 	if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
 		goto tx_error;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ecc12a7..7cf4c83 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1820,6 +1820,7 @@ static void ip_multipath_l3_keys(const struct sk_buff *skb,
 int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
 		       const struct sk_buff *skb, struct flow_keys *flkeys)
 {
+	u32 multipath_hash = fl4->flowi4_multipath_hash;
 	struct flow_keys hash_keys;
 	u32 mhash;
 
@@ -1870,6 +1871,9 @@ int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
 	}
 	mhash = flow_hash_from_keys(&hash_keys);
 
+	if (multipath_hash)
+		mhash = jhash_2words(mhash, multipath_hash, 0);
+
 	return mhash >> 1;
 }
 #endif /* CONFIG_IP_ROUTE_MULTIPATH */
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH][net-next] ipv6: sanitize RCU usage on fib6_next
From: kbuild test robot @ 2019-02-24  3:19 UTC (permalink / raw)
  To: Li RongQing; +Cc: kbuild-all, netdev
In-Reply-To: <1550828682-10608-1-git-send-email-lirongqing@baidu.com>

[-- Attachment #1: Type: text/plain, Size: 3840 bytes --]

Hi Li,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net/master]
[also build test WARNING on v5.0-rc4 next-20190222]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Li-RongQing/ipv6-sanitize-RCU-usage-on-fib6_next/20190224-083824
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

All warnings (new ones prefixed by >>):

>> net/ipv6/ip6_fib.c:1764:14: sparse: warning: incorrect type in assignment (different address spaces)
   net/ipv6/ip6_fib.c:1764:14: sparse:    expected struct fib6_info [noderef] <asn:4> *
   net/ipv6/ip6_fib.c:1764:14: sparse:    got struct fib6_info *

sparse warnings: (new ones prefixed by >>)

   net/ipv6/ip6_fib.c:1764:14: sparse: warning: incorrect type in assignment (different address spaces)
>> net/ipv6/ip6_fib.c:1764:14: sparse:    expected struct fib6_info [noderef] <asn:4> *
>> net/ipv6/ip6_fib.c:1764:14: sparse:    got struct fib6_info *

vim +1764 net/ipv6/ip6_fib.c

  1752	
  1753	static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
  1754				   struct fib6_info __rcu **rtp, struct nl_info *info)
  1755	{
  1756		struct fib6_walker *w;
  1757		struct fib6_info *rt = rcu_dereference_protected(*rtp,
  1758					    lockdep_is_held(&table->tb6_lock));
  1759		struct net *net = info->nl_net;
  1760	
  1761		RT6_TRACE("fib6_del_route\n");
  1762	
  1763		/* Unlink it */
> 1764		*rtp = rcu_dereference_protected(rt->fib6_next,
  1765					    lockdep_is_held(&rt->fib6_table->tb6_lock));
  1766	
  1767		rt->fib6_node = NULL;
  1768		net->ipv6.rt6_stats->fib_rt_entries--;
  1769		net->ipv6.rt6_stats->fib_discarded_routes++;
  1770	
  1771		/* Flush all cached dst in exception table */
  1772		rt6_flush_exceptions(rt);
  1773	
  1774		/* Reset round-robin state, if necessary */
  1775		if (rcu_access_pointer(fn->rr_ptr) == rt)
  1776			fn->rr_ptr = NULL;
  1777	
  1778		/* Remove this entry from other siblings */
  1779		if (rt->fib6_nsiblings) {
  1780			struct fib6_info *sibling, *next_sibling;
  1781	
  1782			list_for_each_entry_safe(sibling, next_sibling,
  1783						 &rt->fib6_siblings, fib6_siblings)
  1784				sibling->fib6_nsiblings--;
  1785			rt->fib6_nsiblings = 0;
  1786			list_del_init(&rt->fib6_siblings);
  1787			rt6_multipath_rebalance(next_sibling);
  1788		}
  1789	
  1790		/* Adjust walkers */
  1791		read_lock(&net->ipv6.fib6_walker_lock);
  1792		FOR_WALKERS(net, w) {
  1793			if (w->state == FWS_C && w->leaf == rt) {
  1794				RT6_TRACE("walker %p adjusted by delroute\n", w);
  1795				w->leaf = rcu_dereference_protected(rt->fib6_next,
  1796						    lockdep_is_held(&table->tb6_lock));
  1797				if (!w->leaf)
  1798					w->state = FWS_U;
  1799			}
  1800		}
  1801		read_unlock(&net->ipv6.fib6_walker_lock);
  1802	
  1803		/* If it was last route, call fib6_repair_tree() to:
  1804		 * 1. For root node, put back null_entry as how the table was created.
  1805		 * 2. For other nodes, expunge its radix tree node.
  1806		 */
  1807		if (!rcu_access_pointer(fn->leaf)) {
  1808			if (!(fn->fn_flags & RTN_TL_ROOT)) {
  1809				fn->fn_flags &= ~RTN_RTINFO;
  1810				net->ipv6.rt6_stats->fib_route_nodes--;
  1811			}
  1812			fn = fib6_repair_tree(net, table, fn);
  1813		}
  1814	
  1815		fib6_purge_rt(rt, fn, net);
  1816	
  1817		call_fib6_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, rt, NULL);
  1818		if (!info->skip_notify)
  1819			inet6_rt_notify(RTM_DELROUTE, rt, info, 0);
  1820		fib6_info_release(rt);
  1821	}
  1822	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 67242 bytes --]

^ permalink raw reply

* Re: [PATCH v2 bpf-next 2/9] bpf: Add bpf helper bpf_tcp_enter_cwr
From: Martin Lau @ 2019-02-24  3:08 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Lawrence Brakmo, netdev, Alexei Starovoitov, Daniel Borkmann,
	Kernel Team
In-Reply-To: <2a218060-8a62-150c-c05e-5433df18aaab@gmail.com>

On Sat, Feb 23, 2019 at 05:32:14PM -0800, Eric Dumazet wrote:
> 
> 
> On 02/22/2019 05:06 PM, brakmo wrote:
> > From: Martin KaFai Lau <kafai@fb.com>
> > 
> > This patch adds a new bpf helper BPF_FUNC_tcp_enter_cwr
> > "int bpf_tcp_enter_cwr(struct bpf_tcp_sock *tp)".
> > It is added to BPF_PROG_TYPE_CGROUP_SKB which can be attached
> > to the egress path where the bpf prog is called by
> > ip_finish_output() or ip6_finish_output().  The verifier
> > ensures that the parameter must be a tcp_sock.
> > 
> > This helper makes a tcp_sock enter CWR state.  It can be used
> > by a bpf_prog to manage egress network bandwidth limit per
> > cgroupv2.  A later patch will have a sample program to
> > show how it can be used to limit bandwidth usage per cgroupv2.
> > 
> > To ensure it is only called from BPF_CGROUP_INET_EGRESS, the
> > attr->expected_attach_type must be specified as BPF_CGROUP_INET_EGRESS
> > during load time if the prog uses this new helper.
> > The newly added prog->enforce_expected_attach_type bit will also be set
> > if this new helper is used.  This bit is for backward compatibility reason
> > because currently prog->expected_attach_type has been ignored in
> > BPF_PROG_TYPE_CGROUP_SKB.  During attach time,
> > prog->expected_attach_type is only enforced if the
> > prog->enforce_expected_attach_type bit is set.
> > i.e. prog->expected_attach_type is only enforced if this new helper
> > is used by the prog.
> > 
> 
> BTW, it seems to me that BPF_CGROUP_INET_EGRESS can be used while the socket lock is not held.
Thanks for pointing it out.

ic. I just noticed the comments at ip6_xmit():
/*
 * xmit an sk_buff (used by TCP, SCTP and DCCP)
 * Note : socket lock is not held for SYNACK packets, but might be modified
 * by calls to skb_set_owner_w() and ipv6_local_error(),
 * which are using proper atomic operations or spinlocks.
 */
Is there other cases other than SYNACK?

Thanks,
Martin

^ permalink raw reply

* Re: [PATCH v2 bpf-next 0/9] bpf: Network Resource Manager (NRM)
From: David Ahern @ 2019-02-24  2:58 UTC (permalink / raw)
  To: Alexei Starovoitov, Eric Dumazet
  Cc: brakmo, netdev, Martin Lau, Alexei Starovoitov, Daniel Borkmann,
	Kernel Team
In-Reply-To: <20190223232530.qjb5z66x6amoiis4@ast-mbp.dhcp.thefacebook.com>

On 2/23/19 6:25 PM, Alexei Starovoitov wrote:
>>> hmm. please see our NRM presentation at LPC.

Reference?

We also gave a talk about a resource manager in November 2017:

https://netdevconf.org/2.2/papers/roulin-hardwareresourcesmgmt-talk.pdf

in this case the context is hardware resources for networking which
aligns with devlink and switchdev.

>>> It is a networking _resource_ management for cgroups.
>>> Bandwidth enforcement is a particular example.
>>> It's not a policer either.
>>>
>>
>> Well, this definitely looks a policer to me, sorry if we disagree, this is fine.
> 
> this particular example certainly does look like it. we both agree.
> It's overall direction of this work that is aiming to do
> network resource management. For example bpf prog may choose
> to react on SLA violations in one cgroup by throttling flows
> in the other cgroup. Aggregated per-cgroup bandwidth doesn't
> need to cross a threshold for bpf prog to take action.
> It could do 'work conserving' 'policer'.
> I think this set of patches represent a revolutionary approach and existing
> networking nomenclature doesn't have precise words to describe it :)
> 'NRM' describes our goals the best.

Are you doing something beyond bandwidth usage? e.g., are you limiting
neighbor entries, fdb entries or FIB entries by cgroup? what about
router interfaces or vlans? I cannot imagine why or how you would manage
that but my point is the meaning of 'network resources'.


> Other folks may choose to use it differently, of course.
> Note that NRM abbreviation doesn't leak anywhere in uapi.
> It's only used in examples. So not sure what we're arguing about.
> 

It was a simple request for a more specific name that better represents
the scope of the project. Everything presented so far has been about
bandwidth.

^ permalink raw reply

* Re: [PATCH net-next v3] route: Add multipath_hash in flowi_common to make user-define hash
From: kbuild test robot @ 2019-02-24  2:57 UTC (permalink / raw)
  To: wenxu; +Cc: kbuild-all, nikolay, davem, netdev
In-Reply-To: <1550933620-29738-1-git-send-email-wenxu@ucloud.cn>

[-- Attachment #1: Type: text/plain, Size: 7008 bytes --]

Hi wenxu,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/wenxu-ucloud-cn/route-Add-multipath_hash-in-flowi_common-to-make-user-define-hash/20190224-075532
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

All warnings (new ones prefixed by >>):

   net/ipv4/route.c:771:46: sparse: warning: incorrect type in argument 2 (different base types)
   net/ipv4/route.c:771:46: sparse:    expected unsigned int [usertype] key
   net/ipv4/route.c:771:46: sparse:    got restricted __be32 [usertype] new_gw
>> net/ipv4/route.c:1823:35: sparse: warning: incorrect type in initializer (different base types)
   net/ipv4/route.c:1823:35: sparse:    expected unsigned int [usertype] multipath_hash
   net/ipv4/route.c:1823:35: sparse:    got restricted __be32 const [usertype] flowic_multipath_hash
   net/ipv4/route.c:2746:27: sparse: warning: incorrect type in assignment (different base types)
   net/ipv4/route.c:2746:27: sparse:    expected restricted __be16 [usertype] len
   net/ipv4/route.c:2746:27: sparse:    got unsigned long
--
>> include/net/ip_tunnels.h:254:36: sparse: warning: incorrect type in assignment (different base types)
   include/net/ip_tunnels.h:254:36: sparse:    expected restricted __be32 [usertype] flowic_multipath_hash
   include/net/ip_tunnels.h:254:36: sparse:    got unsigned int [usertype] tun_inner_hash
>> include/net/ip_tunnels.h:254:36: sparse: warning: incorrect type in assignment (different base types)
   include/net/ip_tunnels.h:254:36: sparse:    expected restricted __be32 [usertype] flowic_multipath_hash
   include/net/ip_tunnels.h:254:36: sparse:    got unsigned int [usertype] tun_inner_hash
>> include/net/ip_tunnels.h:254:36: sparse: warning: incorrect type in assignment (different base types)
   include/net/ip_tunnels.h:254:36: sparse:    expected restricted __be32 [usertype] flowic_multipath_hash
   include/net/ip_tunnels.h:254:36: sparse:    got unsigned int [usertype] tun_inner_hash
--
>> include/net/ip_tunnels.h:254:36: sparse: warning: incorrect type in assignment (different base types)
   include/net/ip_tunnels.h:254:36: sparse:    expected restricted __be32 [usertype] flowic_multipath_hash
   include/net/ip_tunnels.h:254:36: sparse:    got unsigned int [usertype] tun_inner_hash

sparse warnings: (new ones prefixed by >>)

   net/ipv4/route.c:771:46: sparse: warning: incorrect type in argument 2 (different base types)
   net/ipv4/route.c:771:46: sparse:    expected unsigned int [usertype] key
   net/ipv4/route.c:771:46: sparse:    got restricted __be32 [usertype] new_gw
   net/ipv4/route.c:1823:35: sparse: warning: incorrect type in initializer (different base types)
>> net/ipv4/route.c:1823:35: sparse:    expected unsigned int [usertype] multipath_hash
>> net/ipv4/route.c:1823:35: sparse:    got restricted __be32 const [usertype] flowic_multipath_hash
   net/ipv4/route.c:2746:27: sparse: warning: incorrect type in assignment (different base types)
   net/ipv4/route.c:2746:27: sparse:    expected restricted __be16 [usertype] len
   net/ipv4/route.c:2746:27: sparse:    got unsigned long
--
   include/net/ip_tunnels.h:254:36: sparse: warning: incorrect type in assignment (different base types)
>> include/net/ip_tunnels.h:254:36: sparse:    expected restricted __be32 [usertype] flowic_multipath_hash
>> include/net/ip_tunnels.h:254:36: sparse:    got unsigned int [usertype] tun_inner_hash
   include/net/ip_tunnels.h:254:36: sparse: warning: incorrect type in assignment (different base types)
>> include/net/ip_tunnels.h:254:36: sparse:    expected restricted __be32 [usertype] flowic_multipath_hash
>> include/net/ip_tunnels.h:254:36: sparse:    got unsigned int [usertype] tun_inner_hash
   include/net/ip_tunnels.h:254:36: sparse: warning: incorrect type in assignment (different base types)
>> include/net/ip_tunnels.h:254:36: sparse:    expected restricted __be32 [usertype] flowic_multipath_hash
>> include/net/ip_tunnels.h:254:36: sparse:    got unsigned int [usertype] tun_inner_hash
--
   include/net/ip_tunnels.h:254:36: sparse: warning: incorrect type in assignment (different base types)
>> include/net/ip_tunnels.h:254:36: sparse:    expected restricted __be32 [usertype] flowic_multipath_hash
>> include/net/ip_tunnels.h:254:36: sparse:    got unsigned int [usertype] tun_inner_hash

vim +1823 net/ipv4/route.c

  1818	
  1819	/* if skb is set it will be used and fl4 can be NULL */
  1820	int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
  1821			       const struct sk_buff *skb, struct flow_keys *flkeys)
  1822	{
> 1823		u32 multipath_hash = fl4->flowi4_multipath_hash;
  1824		struct flow_keys hash_keys;
  1825		u32 mhash;
  1826	
  1827		switch (net->ipv4.sysctl_fib_multipath_hash_policy) {
  1828		case 0:
  1829			memset(&hash_keys, 0, sizeof(hash_keys));
  1830			hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
  1831			if (skb) {
  1832				ip_multipath_l3_keys(skb, &hash_keys);
  1833			} else {
  1834				hash_keys.addrs.v4addrs.src = fl4->saddr;
  1835				hash_keys.addrs.v4addrs.dst = fl4->daddr;
  1836			}
  1837			break;
  1838		case 1:
  1839			/* skb is currently provided only when forwarding */
  1840			if (skb) {
  1841				unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP;
  1842				struct flow_keys keys;
  1843	
  1844				/* short-circuit if we already have L4 hash present */
  1845				if (skb->l4_hash)
  1846					return skb_get_hash_raw(skb) >> 1;
  1847	
  1848				memset(&hash_keys, 0, sizeof(hash_keys));
  1849	
  1850				if (!flkeys) {
  1851					skb_flow_dissect_flow_keys(skb, &keys, flag);
  1852					flkeys = &keys;
  1853				}
  1854	
  1855				hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
  1856				hash_keys.addrs.v4addrs.src = flkeys->addrs.v4addrs.src;
  1857				hash_keys.addrs.v4addrs.dst = flkeys->addrs.v4addrs.dst;
  1858				hash_keys.ports.src = flkeys->ports.src;
  1859				hash_keys.ports.dst = flkeys->ports.dst;
  1860				hash_keys.basic.ip_proto = flkeys->basic.ip_proto;
  1861			} else {
  1862				memset(&hash_keys, 0, sizeof(hash_keys));
  1863				hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
  1864				hash_keys.addrs.v4addrs.src = fl4->saddr;
  1865				hash_keys.addrs.v4addrs.dst = fl4->daddr;
  1866				hash_keys.ports.src = fl4->fl4_sport;
  1867				hash_keys.ports.dst = fl4->fl4_dport;
  1868				hash_keys.basic.ip_proto = fl4->flowi4_proto;
  1869			}
  1870			break;
  1871		}
  1872		mhash = flow_hash_from_keys(&hash_keys);
  1873	
  1874		if (multipath_hash)
  1875			mhash = jhash_2words(mhash, multipath_hash, 0);
  1876	
  1877		return mhash >> 1;
  1878	}
  1879	#endif /* CONFIG_IP_ROUTE_MULTIPATH */
  1880	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 67279 bytes --]

^ permalink raw reply

* [GIT] Networking
From: David Miller @ 2019-02-24  2:57 UTC (permalink / raw)
  To: torvalds; +Cc: akpm, netdev, linux-kernel


Hopefully the last pull request for this release.  Fingers crossed:

1) Only refcount ESP stats on full sockets, from Martin Willi.

2) Missing barriers in AF_UNIX, from Al Viro.

3) RCU protection fixes in ipv6 route code, from Paolo Abeni.

4) Avoid false positives in untrusted GSO validation, from Willem de
   Bruijn.

5) Forwarded mesh packets in mac80211 need more tailroom allocated,
   from Felix Fietkau.

6) Use operstate consistently for linkup in team driver, from George
   Wilkie.

7) Tunderx bug fixes from Vadim Lomovtsev.  Mostly races between VF and
   PF code paths.

8) Purge ipv6 exceptions during netdevice removal, from Paolo Abeni.

9) nfp eBPF code gen fixes from Jiong Wang.

10) bnxt_en firmware timeout fix from Michael Chan.

11) Use after free in udp/udpv6 error handlers, from Paolo Abeni.

12) Fix a race in x25_bind triggerable by syzbot, from Eric Dumazet.

Please pull, thanks a lot!

The following changes since commit 40e196a906d969fd10d885c692d2674b3d657006:

  Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net (2019-02-19 16:13:19 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git 

for you to fetch changes up to 4c8e0459b585e2a7b367545be3e102737f1e489f:

  net: phy: realtek: Dummy IRQ calls for RTL8366RB (2019-02-23 18:45:28 -0800)

----------------------------------------------------------------
Al Viro (1):
      missing barriers in some of unix_sock ->addr and ->path accesses

Alban Crequy (1):
      bpf, lpm: fix lookup bug in map_delete_elem

Arnd Bergmann (1):
      phonet: fix building with clang

Björn Töpel (2):
      Revert "xsk: simplify AF_XDP socket teardown"
      i40e: fix XDP_REDIRECT/XDP xmit ring cleanup race

Cong Wang (1):
      xfrm: destroy xfrm_state synchronously on net exit path

Daniel Borkmann (3):
      ipvlan: disallow userns cap_net_admin to change global mode/flags
      Merge branch 'bpf-nfp-codegen-fixes'
      bpf, doc: add bpf list as secondary entry to maintainers file

David Chen (1):
      r8152: Fix an error on RTL8153-BD MAC Address Passthrough support

David S. Miller (10):
      Merge branch 'ipv6-route-rcu'
      Merge branch '40GbE' of git://git.kernel.org/.../jkirsher/net-queue
      Merge branch 'tipc-improvement-for-wait-and-wakeup'
      Merge branch 'report-erspan-version-field-just-for-erspan-tunnels'
      Merge branch 'master' of git://git.kernel.org/.../klassert/ipsec
      Merge branch 'nic-thunderx-fix-communication-races-between-VF-PF'
      Merge tag 'mac80211-for-davem-2019-02-22' of git://git.kernel.org/.../jberg/mac80211
      Merge branch 'bnxt_en-firmware-message-delay-fixes'
      Merge branch 'udp-a-few-fixes'
      Merge git://git.kernel.org/.../bpf/bpf

Eric Dumazet (2):
      net/x25: fix a race in x25_bind()
      tcp: repaired skbs must init their tso_segs

Felix Fietkau (1):
      mac80211: allocate tailroom for forwarded mesh packets

Florian Fainelli (1):
      Documentation: networking: switchdev: Update port parent ID section

George Wilkie (1):
      team: use operstate consistently for linkup

Hangbin Liu (2):
      net: vrf: remove MTU limits for vrf device
      Revert "bridge: do not add port to router list when receives query with source 0.0.0.0"

Hauke Mehrtens (1):
      net: dsa: Remove documentation for port_fdb_prepare

Jan Sokolowski (1):
      ixgbe: don't do any AF_XDP zero-copy transmit if netif is not OK

Jann Horn (2):
      MAINTAINERS: mark CAIF as orphan
      net: socket: add check for negative optlen in compat setsockopt

Jeff Kirsher (1):
      ixgbe: fix older devices that do not support IXGBE_MRQC_L3L4TXSWEN

Jiong Wang (2):
      nfp: bpf: fix code-gen bug on BPF_ALU | BPF_XOR | BPF_K
      nfp: bpf: fix ALU32 high bits clearance bug

Kalash Nainwal (1):
      net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255

Li RongQing (1):
      mac80211_hwsim: propagate genlmsg_reply return code

Linus Walleij (1):
      net: phy: realtek: Dummy IRQ calls for RTL8366RB

Lorenzo Bianconi (3):
      net: ip_gre: do not report erspan_ver for gre or gretap
      net: ip6_gre: do not report erspan_ver for ip6gre or ip6gretap
      net: ip6_gre: fix possible NULL pointer dereference in ip6erspan_set_version

Maciej Kwiecien (1):
      sctp: don't compare hb_timer expire date before starting it

Magnus Karlsson (2):
      i40e: fix potential RX buffer starvation for AF_XDP
      ixgbe: fix potential RX buffer starvation for AF_XDP

Mao Wenan (1):
      net: set static variable an initial value in atl2_probe()

Martin Willi (1):
      esp: Skip TX bytes accounting when sending from a request socket

Maxime Chevallier (1):
      net: phy: marvell10g: Fix Multi-G advertisement to only advertise 10G

Michael Chan (2):
      bnxt_en: Fix typo in firmware message timeout logic.
      bnxt_en: Wait longer for the firmware message response to complete.

Michal Soltys (1):
      bonding: fix PACKET_ORIGDEV regression

Paolo Abeni (7):
      ipv6: route: enforce RCU protection in rt6_update_exception_stamp_rt()
      ipv6: route: enforce RCU protection in ip6_route_check_nh_onlink()
      ipv6: route: purge exception on removal
      udpv6: add the required annotation to mib type
      fou6: fix proto error handler argument type
      udpv6: fix possible user after free in error handler
      udp: fix possible user after free in error handler

Russell King (2):
      net: dsa: fix unintended change of bridge interface STP state
      net: marvell: mvneta: fix DMA debug warning

Sean Tranchetti (1):
      af_key: unconditionally clone on broadcast

Stanislav Fomichev (1):
      bpf/test_run: fix unkillable BPF_PROG_TEST_RUN

Thadeu Lima de Souza Cascardo (1):
      selftests: fib_tests: sleep after changing carrier. again.

Tobias Brunner (1):
      xfrm: Fix inbound traffic via XFRM interfaces across network namespaces

Toke Høiland-Jørgensen (1):
      mac80211: Change default tx_sk_pacing_shift to 7

Tung Nguyen (2):
      tipc: improve function tipc_wait_for_cond()
      tipc: improve function tipc_wait_for_rcvmsg()

Ursula Braun (1):
      net/smc: fix smc_poll in SMC_INIT state

Vadim Lomovtsev (8):
      net: thunderx: correct typo in macro name
      net: thunderx: replace global nicvf_rx_mode_wq work queue for all VFs to private for each of them.
      net: thunderx: make CFG_DONE message to run through generic send-ack sequence
      net: thunderx: add nicvf_send_msg_to_pf result check for set_rx_mode_task
      net: thunderx: rework xcast message structure to make it fit into 64 bit
      net: thunderx: add mutex to protect mailbox from concurrent calls for same VF
      net: thunderx: move link state polling function to VF
      net: thunderx: remove link change polling code and info from nicpf

Willem de Bruijn (1):
      net: avoid false positives in untrusted gso validation

YueHaibing (1):
      mdio_bus: Fix use-after-free on device_register fails

 Documentation/networking/dsa/dsa.txt              |  10 ++-----
 Documentation/networking/switchdev.txt            |  10 +++----
 MAINTAINERS                                       |  17 +++++++++--
 drivers/net/bonding/bond_main.c                   |  35 +++++++++-------------
 drivers/net/ethernet/atheros/atlx/atl2.c          |   4 +--
 drivers/net/ethernet/broadcom/bnxt/bnxt.c         |   4 +--
 drivers/net/ethernet/broadcom/bnxt/bnxt.h         |   2 +-
 drivers/net/ethernet/cavium/thunder/nic.h         |  14 +++++----
 drivers/net/ethernet/cavium/thunder/nic_main.c    | 149 +++++++++++++++++++++++++++++----------------------------------------------------------------
 drivers/net/ethernet/cavium/thunder/nicvf_main.c  | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c |   2 +-
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h |   2 +-
 drivers/net/ethernet/intel/i40e/i40e_main.c       |  27 +++++++++++++++--
 drivers/net/ethernet/intel/i40e/i40e_txrx.c       |   4 ++-
 drivers/net/ethernet/intel/i40e/i40e_xsk.c        |   5 ++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c     |  19 ++++++++++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c      |  15 ++++++++--
 drivers/net/ethernet/marvell/mvneta.c             |   2 +-
 drivers/net/ethernet/netronome/nfp/bpf/jit.c      |  17 ++++-------
 drivers/net/ipvlan/ipvlan_main.c                  |   4 +++
 drivers/net/phy/marvell10g.c                      |   6 +++-
 drivers/net/phy/mdio_bus.c                        |   1 -
 drivers/net/phy/realtek.c                         |   7 +++++
 drivers/net/team/team.c                           |   4 +--
 drivers/net/usb/r8152.c                           |   2 +-
 drivers/net/vrf.c                                 |   3 ++
 drivers/net/wireless/mac80211_hwsim.c             |   2 +-
 include/linux/phy.h                               |   8 +++++
 include/linux/virtio_net.h                        |  14 +++++++--
 include/net/phonet/pep.h                          |   5 ++--
 include/net/xfrm.h                                |  12 ++++++--
 kernel/bpf/lpm_trie.c                             |   1 +
 net/bpf/test_run.c                                |  45 +++++++++++++++-------------
 net/bridge/br_multicast.c                         |   9 +-----
 net/compat.c                                      |   6 +++-
 net/dsa/port.c                                    |   7 +++--
 net/ipv4/esp4.c                                   |   2 +-
 net/ipv4/ip_gre.c                                 |  33 +++++++++++----------
 net/ipv4/tcp_output.c                             |   1 +
 net/ipv4/udp.c                                    |   6 ++--
 net/ipv6/esp6.c                                   |   2 +-
 net/ipv6/fou6.c                                   |   2 +-
 net/ipv6/ip6_gre.c                                |  39 +++++++++++++------------
 net/ipv6/route.c                                  |  32 +++++++++++++++-----
 net/ipv6/udp.c                                    |  12 ++++----
 net/ipv6/xfrm6_tunnel.c                           |   2 +-
 net/key/af_key.c                                  |  42 ++++++++++----------------
 net/mac80211/main.c                               |   4 +--
 net/mac80211/rx.c                                 |   7 ++++-
 net/phonet/pep.c                                  |  32 ++++++++++----------
 net/sctp/transport.c                              |   3 +-
 net/smc/smc.h                                     |   6 ++--
 net/tipc/socket.c                                 |  11 +++----
 net/unix/af_unix.c                                |  57 +++++++++++++++++++++---------------
 net/unix/diag.c                                   |   3 +-
 net/x25/af_x25.c                                  |  13 +++++----
 net/xdp/xsk.c                                     |  16 +++++++++-
 net/xfrm/xfrm_interface.c                         |   4 +--
 net/xfrm/xfrm_policy.c                            |   4 ++-
 net/xfrm/xfrm_state.c                             |  30 ++++++++++++-------
 net/xfrm/xfrm_user.c                              |   2 +-
 security/lsm_audit.c                              |  10 ++++---
 tools/testing/selftests/bpf/test_lpm_map.c        |  10 +++++++
 tools/testing/selftests/net/fib_tests.sh          |   1 +
 64 files changed, 568 insertions(+), 420 deletions(-)

^ permalink raw reply

* Re: [PATCH v2] net: phy: realtek: Dummy IRQ calls for RTL8366RB
From: David Miller @ 2019-02-24  2:46 UTC (permalink / raw)
  To: linus.walleij; +Cc: andrew, f.fainelli, netdev, hkallweit1
In-Reply-To: <20190224001115.17497-1-linus.walleij@linaro.org>

From: Linus Walleij <linus.walleij@linaro.org>
Date: Sun, 24 Feb 2019 01:11:15 +0100

> This fixes a regression introduced by
> commit 0d2e778e38e0ddffab4bb2b0e9ed2ad5165c4bf7
> "net: phy: replace PHY_HAS_INTERRUPT with a check for
> config_intr and ack_interrupt".
> 
> This assumes that a PHY cannot trigger interrupt unless
> it has .config_intr() or .ack_interrupt() implemented.
> A later patch makes the code assume both need to be
> implemented for interrupts to be present.
> 
> But this PHY (which is inside a DSA) will happily
> fire interrupts without either callback.
> 
> Implement dummy callbacks for .config_intr() and
> .ack_interrupt() in the phy header to fix this.
> 
> Tested on the RTL8366RB on D-Link DIR-685.
> 
> Fixes: 0d2e778e38e0 ("net: phy: replace PHY_HAS_INTERRUPT with a check for config_intr and ack_interrupt")
> Cc: Heiner Kallweit <hkallweit1@gmail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

Applied.

^ permalink raw reply

* Re: [PATCH net] tcp: repaired skbs must init their tso_segs
From: David Miller @ 2019-02-24  2:44 UTC (permalink / raw)
  To: edumazet; +Cc: netdev, eric.dumazet, soheil, ncardwell, ycheng, syzkaller,
	avagin
In-Reply-To: <20190223235151.168283-1-edumazet@google.com>

From: Eric Dumazet <edumazet@google.com>
Date: Sat, 23 Feb 2019 15:51:51 -0800

> syzbot reported a WARN_ON(!tcp_skb_pcount(skb))
> in tcp_send_loss_probe() [1]
> 
> This was caused by TCP_REPAIR sent skbs that inadvertenly
> were missing a call to tcp_init_tso_segs()
 ...
> Fixes: 79861919b889 ("tcp: fix TCP_REPAIR xmit queue setup")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: syzbot <syzkaller@googlegroups.com>

Applied and queued up for -stable.

^ permalink raw reply

* Re: [PATCH net] net/x25: fix a race in x25_bind()
From: David Miller @ 2019-02-24  2:42 UTC (permalink / raw)
  To: edumazet; +Cc: netdev, eric.dumazet, andrew.hendry
In-Reply-To: <20190223212459.238465-1-edumazet@google.com>

From: Eric Dumazet <edumazet@google.com>
Date: Sat, 23 Feb 2019 13:24:59 -0800

> syzbot was able to trigger another soft lockup [1]
> 
> I first thought it was the O(N^2) issue I mentioned in my
> prior fix (f657d22ee1f "net/x25: do not hold the cpu
> too long in x25_new_lci()"), but I eventually found
> that x25_bind() was not checking SOCK_ZAPPED state under
> socket lock protection.
> 
> This means that multiple threads can end up calling
> x25_insert_socket() for the same socket, and corrupt x25_list
 ...
> Fixes: 90c27297a9bf ("X.25 remove bkl in bind")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: andrew hendry <andrew.hendry@gmail.com>

Applied and queued up for -stable, thanks Eric.

^ permalink raw reply

* Re: [PATCH] net: dsa: Remove documentation for port_fdb_prepare
From: David Miller @ 2019-02-24  2:38 UTC (permalink / raw)
  To: hauke; +Cc: arkadis, netdev, linux-doc
In-Reply-To: <20190222190745.28020-1-hauke@hauke-m.de>

From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Fri, 22 Feb 2019 20:07:45 +0100

> This callback was removed some time ago, also remove the documentation.
> 
> Fixes: 1b6dd556c304 ("net: dsa: Remove prepare phase for FDB")
> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>

Applied.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox