All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch net-next v3 00/10] switchdev: transaction item queue and cleanup
@ 2015-09-24  8:02 Jiri Pirko
  2015-09-24  8:02 ` [patch net-next v3 01/10] switchdev: rename "trans" to "trans_ph" Jiri Pirko
                   ` (10 more replies)
  0 siblings, 11 replies; 25+ messages in thread
From: Jiri Pirko @ 2015-09-24  8:02 UTC (permalink / raw)
  To: netdev
  Cc: davem, idosch, eladr, sfeldma, f.fainelli, linux, vivien.didelot,
	rami.rosen, roopa, pjonnala, andrew, gospo

From: Jiri Pirko <jiri@mellanox.com>

Jiri Pirko (10):
  switchdev: rename "trans" to "trans_ph".
  switchdev: introduce transaction item queue for attr_set and obj_add
  switchdev: move transaction phase enum under transaction structure
  switchdev: add switchdev_trans_ph_prepare/commit helpers
  rocker: push struct switchdev_trans down through rocker code
  rocker: use switchdev transaction queue for allocated memory
  switchdev: remove "NONE" transaction phase
  switchdev: remove "ABORT" transaction phase
  dsa: use prepare/commit switchdev transaction helpers
  switchdev: reduce transaction phase enum down to a boolean

 Documentation/networking/switchdev.txt |  19 ++
 drivers/net/ethernet/rocker/rocker.c   | 308 ++++++++++++++-------------------
 include/net/switchdev.h                |  40 +++--
 net/dsa/slave.c                        |  31 ++--
 net/switchdev/switchdev.c              | 125 ++++++++++---
 5 files changed, 296 insertions(+), 227 deletions(-)

-- 
1.9.3

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

* [patch net-next v3 01/10] switchdev: rename "trans" to "trans_ph".
  2015-09-24  8:02 [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Jiri Pirko
@ 2015-09-24  8:02 ` Jiri Pirko
  2015-09-24  8:02 ` [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add Jiri Pirko
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Jiri Pirko @ 2015-09-24  8:02 UTC (permalink / raw)
  To: netdev
  Cc: davem, idosch, eladr, sfeldma, f.fainelli, linux, vivien.didelot,
	rami.rosen, roopa, pjonnala, andrew, gospo, Jiri Pirko

From: Jiri Pirko <jiri@mellanox.com>

This is temporary, name "trans" will be used for something else and
"trans_ph" will eventually disappear.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
v1->v2:
- no change
v2->v3:
- rebased on top of Scott's ageing patchset
---
 drivers/net/ethernet/rocker/rocker.c | 382 +++++++++++++++++------------------
 include/net/switchdev.h              |   6 +-
 net/dsa/slave.c                      |   8 +-
 net/switchdev/switchdev.c            |  12 +-
 4 files changed, 204 insertions(+), 204 deletions(-)

diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
index 32c5429..cf03b07 100644
--- a/drivers/net/ethernet/rocker/rocker.c
+++ b/drivers/net/ethernet/rocker/rocker.c
@@ -343,7 +343,7 @@ static bool rocker_port_is_ovsed(const struct rocker_port *rocker_port)
 #define ROCKER_OP_FLAG_REFRESH		BIT(3)
 
 static void *__rocker_port_mem_alloc(struct rocker_port *rocker_port,
-				     enum switchdev_trans trans, int flags,
+				     enum switchdev_trans_ph trans_ph, int flags,
 				     size_t size)
 {
 	struct list_head *elem = NULL;
@@ -359,7 +359,7 @@ static void *__rocker_port_mem_alloc(struct rocker_port *rocker_port,
 	 * memory used in the commit phase.
 	 */
 
-	switch (trans) {
+	switch (trans_ph) {
 	case SWITCHDEV_TRANS_PREPARE:
 		elem = kzalloc(size + sizeof(*elem), gfp_flags);
 		if (!elem)
@@ -384,20 +384,20 @@ static void *__rocker_port_mem_alloc(struct rocker_port *rocker_port,
 }
 
 static void *rocker_port_kzalloc(struct rocker_port *rocker_port,
-				 enum switchdev_trans trans, int flags,
+				 enum switchdev_trans_ph trans_ph, int flags,
 				 size_t size)
 {
-	return __rocker_port_mem_alloc(rocker_port, trans, flags, size);
+	return __rocker_port_mem_alloc(rocker_port, trans_ph, flags, size);
 }
 
 static void *rocker_port_kcalloc(struct rocker_port *rocker_port,
-				 enum switchdev_trans trans, int flags,
+				 enum switchdev_trans_ph trans_ph, int flags,
 				 size_t n, size_t size)
 {
-	return __rocker_port_mem_alloc(rocker_port, trans, flags, n * size);
+	return __rocker_port_mem_alloc(rocker_port, trans_ph, flags, n * size);
 }
 
-static void rocker_port_kfree(enum switchdev_trans trans, const void *mem)
+static void rocker_port_kfree(enum switchdev_trans_ph trans_ph, const void *mem)
 {
 	struct list_head *elem;
 
@@ -406,7 +406,7 @@ static void rocker_port_kfree(enum switchdev_trans trans, const void *mem)
 	 * commit phase.
 	 */
 
-	if (trans == SWITCHDEV_TRANS_PREPARE)
+	if (trans_ph == SWITCHDEV_TRANS_PREPARE)
 		return;
 
 	elem = (struct list_head *)mem - 1;
@@ -433,22 +433,22 @@ static void rocker_wait_init(struct rocker_wait *wait)
 }
 
 static struct rocker_wait *rocker_wait_create(struct rocker_port *rocker_port,
-					      enum switchdev_trans trans,
+					      enum switchdev_trans_ph trans_ph,
 					      int flags)
 {
 	struct rocker_wait *wait;
 
-	wait = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*wait));
+	wait = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*wait));
 	if (!wait)
 		return NULL;
 	rocker_wait_init(wait);
 	return wait;
 }
 
-static void rocker_wait_destroy(enum switchdev_trans trans,
+static void rocker_wait_destroy(enum switchdev_trans_ph trans_ph,
 				struct rocker_wait *wait)
 {
-	rocker_port_kfree(trans, wait);
+	rocker_port_kfree(trans_ph, wait);
 }
 
 static bool rocker_wait_event_timeout(struct rocker_wait *wait,
@@ -1466,7 +1466,7 @@ static int rocker_event_link_change(const struct rocker *rocker,
 }
 
 static int rocker_port_fdb(struct rocker_port *rocker_port,
-			   enum switchdev_trans trans,
+			   enum switchdev_trans_ph trans_ph,
 			   const unsigned char *addr,
 			   __be16 vlan_id, int flags);
 
@@ -1585,7 +1585,7 @@ typedef int (*rocker_cmd_proc_cb_t)(const struct rocker_port *rocker_port,
 				    void *priv);
 
 static int rocker_cmd_exec(struct rocker_port *rocker_port,
-			   enum switchdev_trans trans, int flags,
+			   enum switchdev_trans_ph trans_ph, int flags,
 			   rocker_cmd_prep_cb_t prepare, void *prepare_priv,
 			   rocker_cmd_proc_cb_t process, void *process_priv)
 {
@@ -1596,7 +1596,7 @@ static int rocker_cmd_exec(struct rocker_port *rocker_port,
 	unsigned long lock_flags;
 	int err;
 
-	wait = rocker_wait_create(rocker_port, trans, flags);
+	wait = rocker_wait_create(rocker_port, trans_ph, flags);
 	if (!wait)
 		return -ENOMEM;
 	wait->nowait = nowait;
@@ -1618,7 +1618,7 @@ static int rocker_cmd_exec(struct rocker_port *rocker_port,
 
 	rocker_desc_cookie_ptr_set(desc_info, wait);
 
-	if (trans != SWITCHDEV_TRANS_PREPARE)
+	if (trans_ph != SWITCHDEV_TRANS_PREPARE)
 		rocker_desc_head_set(rocker, &rocker->cmd_ring, desc_info);
 
 	spin_unlock_irqrestore(&rocker->cmd_ring_lock, lock_flags);
@@ -1626,7 +1626,7 @@ static int rocker_cmd_exec(struct rocker_port *rocker_port,
 	if (nowait)
 		return 0;
 
-	if (trans != SWITCHDEV_TRANS_PREPARE)
+	if (trans_ph != SWITCHDEV_TRANS_PREPARE)
 		if (!rocker_wait_event_timeout(wait, HZ / 10))
 			return -EIO;
 
@@ -1639,7 +1639,7 @@ static int rocker_cmd_exec(struct rocker_port *rocker_port,
 
 	rocker_desc_gen_clear(desc_info);
 out:
-	rocker_wait_destroy(trans, wait);
+	rocker_wait_destroy(trans_ph, wait);
 	return err;
 }
 
@@ -1918,9 +1918,9 @@ static int rocker_cmd_set_port_settings_mtu(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_set_learning(struct rocker_port *rocker_port,
-				    enum switchdev_trans trans)
+				    enum switchdev_trans_ph trans_ph)
 {
-	return rocker_cmd_exec(rocker_port, trans, 0,
+	return rocker_cmd_exec(rocker_port, trans_ph, 0,
 			       rocker_cmd_set_port_learning_prep,
 			       NULL, NULL, NULL);
 }
@@ -2436,7 +2436,7 @@ rocker_flow_tbl_find(const struct rocker *rocker,
 }
 
 static int rocker_flow_tbl_add(struct rocker_port *rocker_port,
-			       enum switchdev_trans trans, int flags,
+			       enum switchdev_trans_ph trans_ph, int flags,
 			       struct rocker_flow_tbl_entry *match)
 {
 	struct rocker *rocker = rocker_port->rocker;
@@ -2452,9 +2452,9 @@ static int rocker_flow_tbl_add(struct rocker_port *rocker_port,
 
 	if (found) {
 		match->cookie = found->cookie;
-		if (trans != SWITCHDEV_TRANS_PREPARE)
+		if (trans_ph != SWITCHDEV_TRANS_PREPARE)
 			hash_del(&found->entry);
-		rocker_port_kfree(trans, found);
+		rocker_port_kfree(trans_ph, found);
 		found = match;
 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_MOD;
 	} else {
@@ -2463,17 +2463,17 @@ static int rocker_flow_tbl_add(struct rocker_port *rocker_port,
 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_ADD;
 	}
 
-	if (trans != SWITCHDEV_TRANS_PREPARE)
+	if (trans_ph != SWITCHDEV_TRANS_PREPARE)
 		hash_add(rocker->flow_tbl, &found->entry, found->key_crc32);
 
 	spin_unlock_irqrestore(&rocker->flow_tbl_lock, lock_flags);
 
-	return rocker_cmd_exec(rocker_port, trans, flags,
+	return rocker_cmd_exec(rocker_port, trans_ph, flags,
 			       rocker_cmd_flow_tbl_add, found, NULL, NULL);
 }
 
 static int rocker_flow_tbl_del(struct rocker_port *rocker_port,
-			       enum switchdev_trans trans, int flags,
+			       enum switchdev_trans_ph trans_ph, int flags,
 			       struct rocker_flow_tbl_entry *match)
 {
 	struct rocker *rocker = rocker_port->rocker;
@@ -2489,43 +2489,43 @@ static int rocker_flow_tbl_del(struct rocker_port *rocker_port,
 	found = rocker_flow_tbl_find(rocker, match);
 
 	if (found) {
-		if (trans != SWITCHDEV_TRANS_PREPARE)
+		if (trans_ph != SWITCHDEV_TRANS_PREPARE)
 			hash_del(&found->entry);
 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_DEL;
 	}
 
 	spin_unlock_irqrestore(&rocker->flow_tbl_lock, lock_flags);
 
-	rocker_port_kfree(trans, match);
+	rocker_port_kfree(trans_ph, match);
 
 	if (found) {
-		err = rocker_cmd_exec(rocker_port, trans, flags,
+		err = rocker_cmd_exec(rocker_port, trans_ph, flags,
 				      rocker_cmd_flow_tbl_del,
 				      found, NULL, NULL);
-		rocker_port_kfree(trans, found);
+		rocker_port_kfree(trans_ph, found);
 	}
 
 	return err;
 }
 
 static int rocker_flow_tbl_do(struct rocker_port *rocker_port,
-			      enum switchdev_trans trans, int flags,
+			      enum switchdev_trans_ph trans_ph, int flags,
 			      struct rocker_flow_tbl_entry *entry)
 {
 	if (flags & ROCKER_OP_FLAG_REMOVE)
-		return rocker_flow_tbl_del(rocker_port, trans, flags, entry);
+		return rocker_flow_tbl_del(rocker_port, trans_ph, flags, entry);
 	else
-		return rocker_flow_tbl_add(rocker_port, trans, flags, entry);
+		return rocker_flow_tbl_add(rocker_port, trans_ph, flags, entry);
 }
 
 static int rocker_flow_tbl_ig_port(struct rocker_port *rocker_port,
-				   enum switchdev_trans trans, int flags,
+				   enum switchdev_trans_ph trans_ph, int flags,
 				   u32 in_pport, u32 in_pport_mask,
 				   enum rocker_of_dpa_table_id goto_tbl)
 {
 	struct rocker_flow_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2535,11 +2535,11 @@ static int rocker_flow_tbl_ig_port(struct rocker_port *rocker_port,
 	entry->key.ig_port.in_pport_mask = in_pport_mask;
 	entry->key.ig_port.goto_tbl = goto_tbl;
 
-	return rocker_flow_tbl_do(rocker_port, trans, flags, entry);
+	return rocker_flow_tbl_do(rocker_port, trans_ph, flags, entry);
 }
 
 static int rocker_flow_tbl_vlan(struct rocker_port *rocker_port,
-				enum switchdev_trans trans, int flags,
+				enum switchdev_trans_ph trans_ph, int flags,
 				u32 in_pport, __be16 vlan_id,
 				__be16 vlan_id_mask,
 				enum rocker_of_dpa_table_id goto_tbl,
@@ -2547,7 +2547,7 @@ static int rocker_flow_tbl_vlan(struct rocker_port *rocker_port,
 {
 	struct rocker_flow_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2561,11 +2561,11 @@ static int rocker_flow_tbl_vlan(struct rocker_port *rocker_port,
 	entry->key.vlan.untagged = untagged;
 	entry->key.vlan.new_vlan_id = new_vlan_id;
 
-	return rocker_flow_tbl_do(rocker_port, trans, flags, entry);
+	return rocker_flow_tbl_do(rocker_port, trans_ph, flags, entry);
 }
 
 static int rocker_flow_tbl_term_mac(struct rocker_port *rocker_port,
-				    enum switchdev_trans trans,
+				    enum switchdev_trans_ph trans_ph,
 				    u32 in_pport, u32 in_pport_mask,
 				    __be16 eth_type, const u8 *eth_dst,
 				    const u8 *eth_dst_mask, __be16 vlan_id,
@@ -2574,7 +2574,7 @@ static int rocker_flow_tbl_term_mac(struct rocker_port *rocker_port,
 {
 	struct rocker_flow_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2598,11 +2598,11 @@ static int rocker_flow_tbl_term_mac(struct rocker_port *rocker_port,
 	entry->key.term_mac.vlan_id_mask = vlan_id_mask;
 	entry->key.term_mac.copy_to_cpu = copy_to_cpu;
 
-	return rocker_flow_tbl_do(rocker_port, trans, flags, entry);
+	return rocker_flow_tbl_do(rocker_port, trans_ph, flags, entry);
 }
 
 static int rocker_flow_tbl_bridge(struct rocker_port *rocker_port,
-				  enum switchdev_trans trans, int flags,
+				  enum switchdev_trans_ph trans_ph, int flags,
 				  const u8 *eth_dst, const u8 *eth_dst_mask,
 				  __be16 vlan_id, u32 tunnel_id,
 				  enum rocker_of_dpa_table_id goto_tbl,
@@ -2614,7 +2614,7 @@ static int rocker_flow_tbl_bridge(struct rocker_port *rocker_port,
 	bool dflt = !eth_dst || (eth_dst && eth_dst_mask);
 	bool wild = false;
 
-	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2652,11 +2652,11 @@ static int rocker_flow_tbl_bridge(struct rocker_port *rocker_port,
 	entry->key.bridge.group_id = group_id;
 	entry->key.bridge.copy_to_cpu = copy_to_cpu;
 
-	return rocker_flow_tbl_do(rocker_port, trans, flags, entry);
+	return rocker_flow_tbl_do(rocker_port, trans_ph, flags, entry);
 }
 
 static int rocker_flow_tbl_ucast4_routing(struct rocker_port *rocker_port,
-					  enum switchdev_trans trans,
+					  enum switchdev_trans_ph trans_ph,
 					  __be16 eth_type, __be32 dst,
 					  __be32 dst_mask, u32 priority,
 					  enum rocker_of_dpa_table_id goto_tbl,
@@ -2664,7 +2664,7 @@ static int rocker_flow_tbl_ucast4_routing(struct rocker_port *rocker_port,
 {
 	struct rocker_flow_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2678,11 +2678,11 @@ static int rocker_flow_tbl_ucast4_routing(struct rocker_port *rocker_port,
 	entry->key_len = offsetof(struct rocker_flow_tbl_key,
 				  ucast_routing.group_id);
 
-	return rocker_flow_tbl_do(rocker_port, trans, flags, entry);
+	return rocker_flow_tbl_do(rocker_port, trans_ph, flags, entry);
 }
 
 static int rocker_flow_tbl_acl(struct rocker_port *rocker_port,
-			       enum switchdev_trans trans, int flags,
+			       enum switchdev_trans_ph trans_ph, int flags,
 			       u32 in_pport, u32 in_pport_mask,
 			       const u8 *eth_src, const u8 *eth_src_mask,
 			       const u8 *eth_dst, const u8 *eth_dst_mask,
@@ -2694,7 +2694,7 @@ static int rocker_flow_tbl_acl(struct rocker_port *rocker_port,
 	u32 priority;
 	struct rocker_flow_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2729,7 +2729,7 @@ static int rocker_flow_tbl_acl(struct rocker_port *rocker_port,
 	entry->key.acl.ip_tos_mask = ip_tos_mask;
 	entry->key.acl.group_id = group_id;
 
-	return rocker_flow_tbl_do(rocker_port, trans, flags, entry);
+	return rocker_flow_tbl_do(rocker_port, trans_ph, flags, entry);
 }
 
 static struct rocker_group_tbl_entry *
@@ -2747,22 +2747,22 @@ rocker_group_tbl_find(const struct rocker *rocker,
 	return NULL;
 }
 
-static void rocker_group_tbl_entry_free(enum switchdev_trans trans,
+static void rocker_group_tbl_entry_free(enum switchdev_trans_ph trans_ph,
 					struct rocker_group_tbl_entry *entry)
 {
 	switch (ROCKER_GROUP_TYPE_GET(entry->group_id)) {
 	case ROCKER_OF_DPA_GROUP_TYPE_L2_FLOOD:
 	case ROCKER_OF_DPA_GROUP_TYPE_L2_MCAST:
-		rocker_port_kfree(trans, entry->group_ids);
+		rocker_port_kfree(trans_ph, entry->group_ids);
 		break;
 	default:
 		break;
 	}
-	rocker_port_kfree(trans, entry);
+	rocker_port_kfree(trans_ph, entry);
 }
 
 static int rocker_group_tbl_add(struct rocker_port *rocker_port,
-				enum switchdev_trans trans, int flags,
+				enum switchdev_trans_ph trans_ph, int flags,
 				struct rocker_group_tbl_entry *match)
 {
 	struct rocker *rocker = rocker_port->rocker;
@@ -2774,9 +2774,9 @@ static int rocker_group_tbl_add(struct rocker_port *rocker_port,
 	found = rocker_group_tbl_find(rocker, match);
 
 	if (found) {
-		if (trans != SWITCHDEV_TRANS_PREPARE)
+		if (trans_ph != SWITCHDEV_TRANS_PREPARE)
 			hash_del(&found->entry);
-		rocker_group_tbl_entry_free(trans, found);
+		rocker_group_tbl_entry_free(trans_ph, found);
 		found = match;
 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_MOD;
 	} else {
@@ -2784,17 +2784,17 @@ static int rocker_group_tbl_add(struct rocker_port *rocker_port,
 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_ADD;
 	}
 
-	if (trans != SWITCHDEV_TRANS_PREPARE)
+	if (trans_ph != SWITCHDEV_TRANS_PREPARE)
 		hash_add(rocker->group_tbl, &found->entry, found->group_id);
 
 	spin_unlock_irqrestore(&rocker->group_tbl_lock, lock_flags);
 
-	return rocker_cmd_exec(rocker_port, trans, flags,
+	return rocker_cmd_exec(rocker_port, trans_ph, flags,
 			       rocker_cmd_group_tbl_add, found, NULL, NULL);
 }
 
 static int rocker_group_tbl_del(struct rocker_port *rocker_port,
-				enum switchdev_trans trans, int flags,
+				enum switchdev_trans_ph trans_ph, int flags,
 				struct rocker_group_tbl_entry *match)
 {
 	struct rocker *rocker = rocker_port->rocker;
@@ -2807,95 +2807,95 @@ static int rocker_group_tbl_del(struct rocker_port *rocker_port,
 	found = rocker_group_tbl_find(rocker, match);
 
 	if (found) {
-		if (trans != SWITCHDEV_TRANS_PREPARE)
+		if (trans_ph != SWITCHDEV_TRANS_PREPARE)
 			hash_del(&found->entry);
 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_DEL;
 	}
 
 	spin_unlock_irqrestore(&rocker->group_tbl_lock, lock_flags);
 
-	rocker_group_tbl_entry_free(trans, match);
+	rocker_group_tbl_entry_free(trans_ph, match);
 
 	if (found) {
-		err = rocker_cmd_exec(rocker_port, trans, flags,
+		err = rocker_cmd_exec(rocker_port, trans_ph, flags,
 				      rocker_cmd_group_tbl_del,
 				      found, NULL, NULL);
-		rocker_group_tbl_entry_free(trans, found);
+		rocker_group_tbl_entry_free(trans_ph, found);
 	}
 
 	return err;
 }
 
 static int rocker_group_tbl_do(struct rocker_port *rocker_port,
-			       enum switchdev_trans trans, int flags,
+			       enum switchdev_trans_ph trans_ph, int flags,
 			       struct rocker_group_tbl_entry *entry)
 {
 	if (flags & ROCKER_OP_FLAG_REMOVE)
-		return rocker_group_tbl_del(rocker_port, trans, flags, entry);
+		return rocker_group_tbl_del(rocker_port, trans_ph, flags, entry);
 	else
-		return rocker_group_tbl_add(rocker_port, trans, flags, entry);
+		return rocker_group_tbl_add(rocker_port, trans_ph, flags, entry);
 }
 
 static int rocker_group_l2_interface(struct rocker_port *rocker_port,
-				     enum switchdev_trans trans, int flags,
+				     enum switchdev_trans_ph trans_ph, int flags,
 				     __be16 vlan_id, u32 out_pport,
 				     int pop_vlan)
 {
 	struct rocker_group_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
 	entry->group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, out_pport);
 	entry->l2_interface.pop_vlan = pop_vlan;
 
-	return rocker_group_tbl_do(rocker_port, trans, flags, entry);
+	return rocker_group_tbl_do(rocker_port, trans_ph, flags, entry);
 }
 
 static int rocker_group_l2_fan_out(struct rocker_port *rocker_port,
-				   enum switchdev_trans trans,
+				   enum switchdev_trans_ph trans_ph,
 				   int flags, u8 group_count,
 				   const u32 *group_ids, u32 group_id)
 {
 	struct rocker_group_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
 	entry->group_id = group_id;
 	entry->group_count = group_count;
 
-	entry->group_ids = rocker_port_kcalloc(rocker_port, trans, flags,
+	entry->group_ids = rocker_port_kcalloc(rocker_port, trans_ph, flags,
 					       group_count, sizeof(u32));
 	if (!entry->group_ids) {
-		rocker_port_kfree(trans, entry);
+		rocker_port_kfree(trans_ph, entry);
 		return -ENOMEM;
 	}
 	memcpy(entry->group_ids, group_ids, group_count * sizeof(u32));
 
-	return rocker_group_tbl_do(rocker_port, trans, flags, entry);
+	return rocker_group_tbl_do(rocker_port, trans_ph, flags, entry);
 }
 
 static int rocker_group_l2_flood(struct rocker_port *rocker_port,
-				 enum switchdev_trans trans, int flags,
+				 enum switchdev_trans_ph trans_ph, int flags,
 				 __be16 vlan_id, u8 group_count,
 				 const u32 *group_ids, u32 group_id)
 {
-	return rocker_group_l2_fan_out(rocker_port, trans, flags,
+	return rocker_group_l2_fan_out(rocker_port, trans_ph, flags,
 				       group_count, group_ids,
 				       group_id);
 }
 
 static int rocker_group_l3_unicast(struct rocker_port *rocker_port,
-				   enum switchdev_trans trans, int flags,
+				   enum switchdev_trans_ph trans_ph, int flags,
 				   u32 index, const u8 *src_mac, const u8 *dst_mac,
 				   __be16 vlan_id, bool ttl_check, u32 pport)
 {
 	struct rocker_group_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2908,7 +2908,7 @@ static int rocker_group_l3_unicast(struct rocker_port *rocker_port,
 	entry->l3_unicast.ttl_check = ttl_check;
 	entry->l3_unicast.group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, pport);
 
-	return rocker_group_tbl_do(rocker_port, trans, flags, entry);
+	return rocker_group_tbl_do(rocker_port, trans_ph, flags, entry);
 }
 
 static struct rocker_neigh_tbl_entry *
@@ -2925,43 +2925,43 @@ rocker_neigh_tbl_find(const struct rocker *rocker, __be32 ip_addr)
 }
 
 static void _rocker_neigh_add(struct rocker *rocker,
-			      enum switchdev_trans trans,
+			      enum switchdev_trans_ph trans_ph,
 			      struct rocker_neigh_tbl_entry *entry)
 {
-	if (trans != SWITCHDEV_TRANS_COMMIT)
+	if (trans_ph != SWITCHDEV_TRANS_COMMIT)
 		entry->index = rocker->neigh_tbl_next_index++;
-	if (trans == SWITCHDEV_TRANS_PREPARE)
+	if (trans_ph == SWITCHDEV_TRANS_PREPARE)
 		return;
 	entry->ref_count++;
 	hash_add(rocker->neigh_tbl, &entry->entry,
 		 be32_to_cpu(entry->ip_addr));
 }
 
-static void _rocker_neigh_del(enum switchdev_trans trans,
+static void _rocker_neigh_del(enum switchdev_trans_ph trans_ph,
 			      struct rocker_neigh_tbl_entry *entry)
 {
-	if (trans == SWITCHDEV_TRANS_PREPARE)
+	if (trans_ph == SWITCHDEV_TRANS_PREPARE)
 		return;
 	if (--entry->ref_count == 0) {
 		hash_del(&entry->entry);
-		rocker_port_kfree(trans, entry);
+		rocker_port_kfree(trans_ph, entry);
 	}
 }
 
 static void _rocker_neigh_update(struct rocker_neigh_tbl_entry *entry,
-				 enum switchdev_trans trans,
+				 enum switchdev_trans_ph trans_ph,
 				 const u8 *eth_dst, bool ttl_check)
 {
 	if (eth_dst) {
 		ether_addr_copy(entry->eth_dst, eth_dst);
 		entry->ttl_check = ttl_check;
-	} else if (trans != SWITCHDEV_TRANS_PREPARE) {
+	} else if (trans_ph != SWITCHDEV_TRANS_PREPARE) {
 		entry->ref_count++;
 	}
 }
 
 static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
-				  enum switchdev_trans trans,
+				  enum switchdev_trans_ph trans_ph,
 				  int flags, __be32 ip_addr, const u8 *eth_dst)
 {
 	struct rocker *rocker = rocker_port->rocker;
@@ -2978,7 +2978,7 @@ static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
 	bool removing;
 	int err = 0;
 
-	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2995,12 +2995,12 @@ static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
 		entry->dev = rocker_port->dev;
 		ether_addr_copy(entry->eth_dst, eth_dst);
 		entry->ttl_check = true;
-		_rocker_neigh_add(rocker, trans, entry);
+		_rocker_neigh_add(rocker, trans_ph, entry);
 	} else if (removing) {
 		memcpy(entry, found, sizeof(*entry));
-		_rocker_neigh_del(trans, found);
+		_rocker_neigh_del(trans_ph, found);
 	} else if (updating) {
-		_rocker_neigh_update(found, trans, eth_dst, true);
+		_rocker_neigh_update(found, trans_ph, eth_dst, true);
 		memcpy(entry, found, sizeof(*entry));
 	} else {
 		err = -ENOENT;
@@ -3017,7 +3017,7 @@ static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
 	 * other routes' nexthops.
 	 */
 
-	err = rocker_group_l3_unicast(rocker_port, trans, flags,
+	err = rocker_group_l3_unicast(rocker_port, trans_ph, flags,
 				      entry->index,
 				      rocker_port->dev->dev_addr,
 				      entry->eth_dst,
@@ -3033,7 +3033,7 @@ static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
 
 	if (adding || removing) {
 		group_id = ROCKER_GROUP_L3_UNICAST(entry->index);
-		err = rocker_flow_tbl_ucast4_routing(rocker_port, trans,
+		err = rocker_flow_tbl_ucast4_routing(rocker_port, trans_ph,
 						     eth_type, ip_addr,
 						     inet_make_mask(32),
 						     priority, goto_tbl,
@@ -3047,13 +3047,13 @@ static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
 
 err_out:
 	if (!adding)
-		rocker_port_kfree(trans, entry);
+		rocker_port_kfree(trans_ph, entry);
 
 	return err;
 }
 
 static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port,
-				    enum switchdev_trans trans, __be32 ip_addr)
+				    enum switchdev_trans_ph trans_ph, __be32 ip_addr)
 {
 	struct net_device *dev = rocker_port->dev;
 	struct neighbour *n = __ipv4_neigh_lookup(dev, (__force u32)ip_addr);
@@ -3071,7 +3071,7 @@ static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port,
 	 */
 
 	if (n->nud_state & NUD_VALID)
-		err = rocker_port_ipv4_neigh(rocker_port, trans, 0,
+		err = rocker_port_ipv4_neigh(rocker_port, trans_ph, 0,
 					     ip_addr, n->ha);
 	else
 		neigh_event_send(n, NULL);
@@ -3081,7 +3081,7 @@ static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_ipv4_nh(struct rocker_port *rocker_port,
-			       enum switchdev_trans trans, int flags,
+			       enum switchdev_trans_ph trans_ph, int flags,
 			       __be32 ip_addr, u32 *index)
 {
 	struct rocker *rocker = rocker_port->rocker;
@@ -3094,7 +3094,7 @@ static int rocker_port_ipv4_nh(struct rocker_port *rocker_port,
 	bool resolved = true;
 	int err = 0;
 
-	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -3111,13 +3111,13 @@ static int rocker_port_ipv4_nh(struct rocker_port *rocker_port,
 	if (adding) {
 		entry->ip_addr = ip_addr;
 		entry->dev = rocker_port->dev;
-		_rocker_neigh_add(rocker, trans, entry);
+		_rocker_neigh_add(rocker, trans_ph, entry);
 		*index = entry->index;
 		resolved = false;
 	} else if (removing) {
-		_rocker_neigh_del(trans, found);
+		_rocker_neigh_del(trans_ph, found);
 	} else if (updating) {
-		_rocker_neigh_update(found, trans, NULL, false);
+		_rocker_neigh_update(found, trans_ph, NULL, false);
 		resolved = !is_zero_ether_addr(found->eth_dst);
 	} else {
 		err = -ENOENT;
@@ -3126,7 +3126,7 @@ static int rocker_port_ipv4_nh(struct rocker_port *rocker_port,
 	spin_unlock_irqrestore(&rocker->neigh_tbl_lock, lock_flags);
 
 	if (!adding)
-		rocker_port_kfree(trans, entry);
+		rocker_port_kfree(trans_ph, entry);
 
 	if (err)
 		return err;
@@ -3134,13 +3134,13 @@ static int rocker_port_ipv4_nh(struct rocker_port *rocker_port,
 	/* Resolved means neigh ip_addr is resolved to neigh mac. */
 
 	if (!resolved)
-		err = rocker_port_ipv4_resolve(rocker_port, trans, ip_addr);
+		err = rocker_port_ipv4_resolve(rocker_port, trans_ph, ip_addr);
 
 	return err;
 }
 
 static int rocker_port_vlan_flood_group(struct rocker_port *rocker_port,
-					enum switchdev_trans trans,
+					enum switchdev_trans_ph trans_ph,
 					int flags, __be16 vlan_id)
 {
 	struct rocker_port *p;
@@ -3151,7 +3151,7 @@ static int rocker_port_vlan_flood_group(struct rocker_port *rocker_port,
 	int err = 0;
 	int i;
 
-	group_ids = rocker_port_kcalloc(rocker_port, trans, flags,
+	group_ids = rocker_port_kcalloc(rocker_port, trans_ph, flags,
 					rocker->port_count, sizeof(u32));
 	if (!group_ids)
 		return -ENOMEM;
@@ -3177,19 +3177,19 @@ static int rocker_port_vlan_flood_group(struct rocker_port *rocker_port,
 	if (group_count == 0)
 		goto no_ports_in_vlan;
 
-	err = rocker_group_l2_flood(rocker_port, trans, flags, vlan_id,
+	err = rocker_group_l2_flood(rocker_port, trans_ph, flags, vlan_id,
 				    group_count, group_ids, group_id);
 	if (err)
 		netdev_err(rocker_port->dev,
 			   "Error (%d) port VLAN l2 flood group\n", err);
 
 no_ports_in_vlan:
-	rocker_port_kfree(trans, group_ids);
+	rocker_port_kfree(trans_ph, group_ids);
 	return err;
 }
 
 static int rocker_port_vlan_l2_groups(struct rocker_port *rocker_port,
-				      enum switchdev_trans trans, int flags,
+				      enum switchdev_trans_ph trans_ph, int flags,
 				      __be16 vlan_id, bool pop_vlan)
 {
 	const struct rocker *rocker = rocker_port->rocker;
@@ -3207,7 +3207,7 @@ static int rocker_port_vlan_l2_groups(struct rocker_port *rocker_port,
 	if (rocker_port->stp_state == BR_STATE_LEARNING ||
 	    rocker_port->stp_state == BR_STATE_FORWARDING) {
 		out_pport = rocker_port->pport;
-		err = rocker_group_l2_interface(rocker_port, trans, flags,
+		err = rocker_group_l2_interface(rocker_port, trans_ph, flags,
 						vlan_id, out_pport, pop_vlan);
 		if (err) {
 			netdev_err(rocker_port->dev,
@@ -3232,7 +3232,7 @@ static int rocker_port_vlan_l2_groups(struct rocker_port *rocker_port,
 		return 0;
 
 	out_pport = 0;
-	err = rocker_group_l2_interface(rocker_port, trans, flags,
+	err = rocker_group_l2_interface(rocker_port, trans_ph, flags,
 					vlan_id, out_pport, pop_vlan);
 	if (err) {
 		netdev_err(rocker_port->dev,
@@ -3295,7 +3295,7 @@ static struct rocker_ctrl {
 };
 
 static int rocker_port_ctrl_vlan_acl(struct rocker_port *rocker_port,
-				     enum switchdev_trans trans, int flags,
+				     enum switchdev_trans_ph trans_ph, int flags,
 				     const struct rocker_ctrl *ctrl, __be16 vlan_id)
 {
 	u32 in_pport = rocker_port->pport;
@@ -3311,7 +3311,7 @@ static int rocker_port_ctrl_vlan_acl(struct rocker_port *rocker_port,
 	u32 group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, out_pport);
 	int err;
 
-	err = rocker_flow_tbl_acl(rocker_port, trans, flags,
+	err = rocker_flow_tbl_acl(rocker_port, trans_ph, flags,
 				  in_pport, in_pport_mask,
 				  eth_src, eth_src_mask,
 				  ctrl->eth_dst, ctrl->eth_dst_mask,
@@ -3328,7 +3328,7 @@ static int rocker_port_ctrl_vlan_acl(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_ctrl_vlan_bridge(struct rocker_port *rocker_port,
-					enum switchdev_trans trans, int flags,
+					enum switchdev_trans_ph trans_ph, int flags,
 					const struct rocker_ctrl *ctrl,
 					__be16 vlan_id)
 {
@@ -3341,7 +3341,7 @@ static int rocker_port_ctrl_vlan_bridge(struct rocker_port *rocker_port,
 	if (!rocker_port_is_bridged(rocker_port))
 		return 0;
 
-	err = rocker_flow_tbl_bridge(rocker_port, trans, flags,
+	err = rocker_flow_tbl_bridge(rocker_port, trans_ph, flags,
 				     ctrl->eth_dst, ctrl->eth_dst_mask,
 				     vlan_id, tunnel_id,
 				     goto_tbl, group_id, ctrl->copy_to_cpu);
@@ -3353,7 +3353,7 @@ static int rocker_port_ctrl_vlan_bridge(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_ctrl_vlan_term(struct rocker_port *rocker_port,
-				      enum switchdev_trans trans, int flags,
+				      enum switchdev_trans_ph trans_ph, int flags,
 				      const struct rocker_ctrl *ctrl, __be16 vlan_id)
 {
 	u32 in_pport_mask = 0xffffffff;
@@ -3363,7 +3363,7 @@ static int rocker_port_ctrl_vlan_term(struct rocker_port *rocker_port,
 	if (ntohs(vlan_id) == 0)
 		vlan_id = rocker_port->internal_vlan_id;
 
-	err = rocker_flow_tbl_term_mac(rocker_port, trans,
+	err = rocker_flow_tbl_term_mac(rocker_port, trans_ph,
 				       rocker_port->pport, in_pport_mask,
 				       ctrl->eth_type, ctrl->eth_dst,
 				       ctrl->eth_dst_mask, vlan_id,
@@ -3377,25 +3377,25 @@ static int rocker_port_ctrl_vlan_term(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_ctrl_vlan(struct rocker_port *rocker_port,
-				 enum switchdev_trans trans, int flags,
+				 enum switchdev_trans_ph trans_ph, int flags,
 				 const struct rocker_ctrl *ctrl, __be16 vlan_id)
 {
 	if (ctrl->acl)
-		return rocker_port_ctrl_vlan_acl(rocker_port, trans, flags,
+		return rocker_port_ctrl_vlan_acl(rocker_port, trans_ph, flags,
 						 ctrl, vlan_id);
 	if (ctrl->bridge)
-		return rocker_port_ctrl_vlan_bridge(rocker_port, trans, flags,
+		return rocker_port_ctrl_vlan_bridge(rocker_port, trans_ph, flags,
 						    ctrl, vlan_id);
 
 	if (ctrl->term)
-		return rocker_port_ctrl_vlan_term(rocker_port, trans, flags,
+		return rocker_port_ctrl_vlan_term(rocker_port, trans_ph, flags,
 						  ctrl, vlan_id);
 
 	return -EOPNOTSUPP;
 }
 
 static int rocker_port_ctrl_vlan_add(struct rocker_port *rocker_port,
-				     enum switchdev_trans trans, int flags,
+				     enum switchdev_trans_ph trans_ph, int flags,
 				     __be16 vlan_id)
 {
 	int err = 0;
@@ -3403,7 +3403,7 @@ static int rocker_port_ctrl_vlan_add(struct rocker_port *rocker_port,
 
 	for (i = 0; i < ROCKER_CTRL_MAX; i++) {
 		if (rocker_port->ctrls[i]) {
-			err = rocker_port_ctrl_vlan(rocker_port, trans, flags,
+			err = rocker_port_ctrl_vlan(rocker_port, trans_ph, flags,
 						    &rocker_ctrls[i], vlan_id);
 			if (err)
 				return err;
@@ -3414,7 +3414,7 @@ static int rocker_port_ctrl_vlan_add(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_ctrl(struct rocker_port *rocker_port,
-			    enum switchdev_trans trans, int flags,
+			    enum switchdev_trans_ph trans_ph, int flags,
 			    const struct rocker_ctrl *ctrl)
 {
 	u16 vid;
@@ -3423,7 +3423,7 @@ static int rocker_port_ctrl(struct rocker_port *rocker_port,
 	for (vid = 1; vid < VLAN_N_VID; vid++) {
 		if (!test_bit(vid, rocker_port->vlan_bitmap))
 			continue;
-		err = rocker_port_ctrl_vlan(rocker_port, trans, flags,
+		err = rocker_port_ctrl_vlan(rocker_port, trans_ph, flags,
 					    ctrl, htons(vid));
 		if (err)
 			break;
@@ -3433,7 +3433,7 @@ static int rocker_port_ctrl(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_vlan(struct rocker_port *rocker_port,
-			    enum switchdev_trans trans, int flags, u16 vid)
+			    enum switchdev_trans_ph trans_ph, int flags, u16 vid)
 {
 	enum rocker_of_dpa_table_id goto_tbl =
 		ROCKER_OF_DPA_TABLE_ID_TERMINATION_MAC;
@@ -3457,7 +3457,7 @@ static int rocker_port_vlan(struct rocker_port *rocker_port,
 	change_bit(ntohs(internal_vlan_id), rocker_port->vlan_bitmap);
 
 	if (adding) {
-		err = rocker_port_ctrl_vlan_add(rocker_port, trans, flags,
+		err = rocker_port_ctrl_vlan_add(rocker_port, trans_ph, flags,
 						internal_vlan_id);
 		if (err) {
 			netdev_err(rocker_port->dev,
@@ -3466,7 +3466,7 @@ static int rocker_port_vlan(struct rocker_port *rocker_port,
 		}
 	}
 
-	err = rocker_port_vlan_l2_groups(rocker_port, trans, flags,
+	err = rocker_port_vlan_l2_groups(rocker_port, trans_ph, flags,
 					 internal_vlan_id, untagged);
 	if (err) {
 		netdev_err(rocker_port->dev,
@@ -3474,7 +3474,7 @@ static int rocker_port_vlan(struct rocker_port *rocker_port,
 		goto err_out;
 	}
 
-	err = rocker_port_vlan_flood_group(rocker_port, trans, flags,
+	err = rocker_port_vlan_flood_group(rocker_port, trans_ph, flags,
 					   internal_vlan_id);
 	if (err) {
 		netdev_err(rocker_port->dev,
@@ -3482,7 +3482,7 @@ static int rocker_port_vlan(struct rocker_port *rocker_port,
 		goto err_out;
 	}
 
-	err = rocker_flow_tbl_vlan(rocker_port, trans, flags,
+	err = rocker_flow_tbl_vlan(rocker_port, trans_ph, flags,
 				   in_pport, vlan_id, vlan_id_mask,
 				   goto_tbl, untagged, internal_vlan_id);
 	if (err)
@@ -3490,14 +3490,14 @@ static int rocker_port_vlan(struct rocker_port *rocker_port,
 			   "Error (%d) port VLAN table\n", err);
 
 err_out:
-	if (trans == SWITCHDEV_TRANS_PREPARE)
+	if (trans_ph == SWITCHDEV_TRANS_PREPARE)
 		change_bit(ntohs(internal_vlan_id), rocker_port->vlan_bitmap);
 
 	return err;
 }
 
 static int rocker_port_ig_tbl(struct rocker_port *rocker_port,
-			      enum switchdev_trans trans, int flags)
+			      enum switchdev_trans_ph trans_ph, int flags)
 {
 	enum rocker_of_dpa_table_id goto_tbl;
 	u32 in_pport;
@@ -3512,7 +3512,7 @@ static int rocker_port_ig_tbl(struct rocker_port *rocker_port,
 	in_pport_mask = 0xffff0000;
 	goto_tbl = ROCKER_OF_DPA_TABLE_ID_VLAN;
 
-	err = rocker_flow_tbl_ig_port(rocker_port, trans, flags,
+	err = rocker_flow_tbl_ig_port(rocker_port, trans_ph, flags,
 				      in_pport, in_pport_mask,
 				      goto_tbl);
 	if (err)
@@ -3525,7 +3525,7 @@ static int rocker_port_ig_tbl(struct rocker_port *rocker_port,
 struct rocker_fdb_learn_work {
 	struct work_struct work;
 	struct rocker_port *rocker_port;
-	enum switchdev_trans trans;
+	enum switchdev_trans_ph trans_ph;
 	int flags;
 	u8 addr[ETH_ALEN];
 	u16 vid;
@@ -3549,11 +3549,11 @@ static void rocker_port_fdb_learn_work(struct work_struct *work)
 		call_switchdev_notifiers(SWITCHDEV_FDB_ADD,
 					 lw->rocker_port->dev, &info.info);
 
-	rocker_port_kfree(lw->trans, work);
+	rocker_port_kfree(lw->trans_ph, work);
 }
 
 static int rocker_port_fdb_learn(struct rocker_port *rocker_port,
-				 enum switchdev_trans trans, int flags,
+				 enum switchdev_trans_ph trans_ph, int flags,
 				 const u8 *addr, __be16 vlan_id)
 {
 	struct rocker_fdb_learn_work *lw;
@@ -3570,7 +3570,7 @@ static int rocker_port_fdb_learn(struct rocker_port *rocker_port,
 		group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, out_pport);
 
 	if (!(flags & ROCKER_OP_FLAG_REFRESH)) {
-		err = rocker_flow_tbl_bridge(rocker_port, trans, flags, addr,
+		err = rocker_flow_tbl_bridge(rocker_port, trans_ph, flags, addr,
 					     NULL, vlan_id, tunnel_id, goto_tbl,
 					     group_id, copy_to_cpu);
 		if (err)
@@ -3583,20 +3583,20 @@ static int rocker_port_fdb_learn(struct rocker_port *rocker_port,
 	if (!rocker_port_is_bridged(rocker_port))
 		return 0;
 
-	lw = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*lw));
+	lw = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*lw));
 	if (!lw)
 		return -ENOMEM;
 
 	INIT_WORK(&lw->work, rocker_port_fdb_learn_work);
 
 	lw->rocker_port = rocker_port;
-	lw->trans = trans;
+	lw->trans_ph = trans_ph;
 	lw->flags = flags;
 	ether_addr_copy(lw->addr, addr);
 	lw->vid = rocker_port_vlan_to_vid(rocker_port, vlan_id);
 
-	if (trans == SWITCHDEV_TRANS_PREPARE)
-		rocker_port_kfree(trans, lw);
+	if (trans_ph == SWITCHDEV_TRANS_PREPARE)
+		rocker_port_kfree(trans_ph, lw);
 	else
 		schedule_work(&lw->work);
 
@@ -3617,7 +3617,7 @@ rocker_fdb_tbl_find(const struct rocker *rocker,
 }
 
 static int rocker_port_fdb(struct rocker_port *rocker_port,
-			   enum switchdev_trans trans,
+			   enum switchdev_trans_ph trans_ph,
 			   const unsigned char *addr,
 			   __be16 vlan_id, int flags)
 {
@@ -3627,7 +3627,7 @@ static int rocker_port_fdb(struct rocker_port *rocker_port,
 	bool removing = (flags & ROCKER_OP_FLAG_REMOVE);
 	unsigned long lock_flags;
 
-	fdb = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*fdb));
+	fdb = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*fdb));
 	if (!fdb)
 		return -ENOMEM;
 
@@ -3645,12 +3645,12 @@ static int rocker_port_fdb(struct rocker_port *rocker_port,
 	if (found) {
 		found->touched = jiffies;
 		if (removing) {
-			rocker_port_kfree(trans, fdb);
-			if (trans != SWITCHDEV_TRANS_PREPARE)
+			rocker_port_kfree(trans_ph, fdb);
+			if (trans_ph != SWITCHDEV_TRANS_PREPARE)
 				hash_del(&found->entry);
 		}
 	} else if (!removing) {
-		if (trans != SWITCHDEV_TRANS_PREPARE)
+		if (trans_ph != SWITCHDEV_TRANS_PREPARE)
 			hash_add(rocker->fdb_tbl, &fdb->entry,
 				 fdb->key_crc32);
 	}
@@ -3659,18 +3659,18 @@ static int rocker_port_fdb(struct rocker_port *rocker_port,
 
 	/* Check if adding and already exists, or removing and can't find */
 	if (!found != !removing) {
-		rocker_port_kfree(trans, fdb);
+		rocker_port_kfree(trans_ph, fdb);
 		if (!found && removing)
 			return 0;
 		/* Refreshing existing to update aging timers */
 		flags |= ROCKER_OP_FLAG_REFRESH;
 	}
 
-	return rocker_port_fdb_learn(rocker_port, trans, flags, addr, vlan_id);
+	return rocker_port_fdb_learn(rocker_port, trans_ph, flags, addr, vlan_id);
 }
 
 static int rocker_port_fdb_flush(struct rocker_port *rocker_port,
-				 enum switchdev_trans trans, int flags)
+				 enum switchdev_trans_ph trans_ph, int flags)
 {
 	struct rocker *rocker = rocker_port->rocker;
 	struct rocker_fdb_tbl_entry *found;
@@ -3692,12 +3692,12 @@ static int rocker_port_fdb_flush(struct rocker_port *rocker_port,
 			continue;
 		if (!found->learned)
 			continue;
-		err = rocker_port_fdb_learn(rocker_port, trans, flags,
+		err = rocker_port_fdb_learn(rocker_port, trans_ph, flags,
 					    found->key.addr,
 					    found->key.vlan_id);
 		if (err)
 			goto err_out;
-		if (trans != SWITCHDEV_TRANS_PREPARE)
+		if (trans_ph != SWITCHDEV_TRANS_PREPARE)
 			hash_del(&found->entry);
 	}
 
@@ -3743,7 +3743,7 @@ static void rocker_fdb_cleanup(unsigned long data)
 }
 
 static int rocker_port_router_mac(struct rocker_port *rocker_port,
-				  enum switchdev_trans trans, int flags,
+				  enum switchdev_trans_ph trans_ph, int flags,
 				  __be16 vlan_id)
 {
 	u32 in_pport_mask = 0xffffffff;
@@ -3757,7 +3757,7 @@ static int rocker_port_router_mac(struct rocker_port *rocker_port,
 		vlan_id = rocker_port->internal_vlan_id;
 
 	eth_type = htons(ETH_P_IP);
-	err = rocker_flow_tbl_term_mac(rocker_port, trans,
+	err = rocker_flow_tbl_term_mac(rocker_port, trans_ph,
 				       rocker_port->pport, in_pport_mask,
 				       eth_type, rocker_port->dev->dev_addr,
 				       dst_mac_mask, vlan_id, vlan_id_mask,
@@ -3766,7 +3766,7 @@ static int rocker_port_router_mac(struct rocker_port *rocker_port,
 		return err;
 
 	eth_type = htons(ETH_P_IPV6);
-	err = rocker_flow_tbl_term_mac(rocker_port, trans,
+	err = rocker_flow_tbl_term_mac(rocker_port, trans_ph,
 				       rocker_port->pport, in_pport_mask,
 				       eth_type, rocker_port->dev->dev_addr,
 				       dst_mac_mask, vlan_id, vlan_id_mask,
@@ -3776,7 +3776,7 @@ static int rocker_port_router_mac(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_fwding(struct rocker_port *rocker_port,
-			      enum switchdev_trans trans, int flags)
+			      enum switchdev_trans_ph trans_ph, int flags)
 {
 	bool pop_vlan;
 	u32 out_pport;
@@ -3801,7 +3801,7 @@ static int rocker_port_fwding(struct rocker_port *rocker_port,
 			continue;
 		vlan_id = htons(vid);
 		pop_vlan = rocker_vlan_id_is_internal(vlan_id);
-		err = rocker_group_l2_interface(rocker_port, trans, flags,
+		err = rocker_group_l2_interface(rocker_port, trans_ph, flags,
 						vlan_id, out_pport, pop_vlan);
 		if (err) {
 			netdev_err(rocker_port->dev,
@@ -3815,7 +3815,7 @@ static int rocker_port_fwding(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_stp_update(struct rocker_port *rocker_port,
-				  enum switchdev_trans trans, int flags,
+				  enum switchdev_trans_ph trans_ph, int flags,
 				  u8 state)
 {
 	bool want[ROCKER_CTRL_MAX] = { 0, };
@@ -3824,7 +3824,7 @@ static int rocker_port_stp_update(struct rocker_port *rocker_port,
 	int err;
 	int i;
 
-	if (trans == SWITCHDEV_TRANS_PREPARE) {
+	if (trans_ph == SWITCHDEV_TRANS_PREPARE) {
 		memcpy(prev_ctrls, rocker_port->ctrls, sizeof(prev_ctrls));
 		prev_state = rocker_port->stp_state;
 	}
@@ -3861,7 +3861,7 @@ static int rocker_port_stp_update(struct rocker_port *rocker_port,
 		if (want[i] != rocker_port->ctrls[i]) {
 			int ctrl_flags = flags |
 					 (want[i] ? 0 : ROCKER_OP_FLAG_REMOVE);
-			err = rocker_port_ctrl(rocker_port, trans, ctrl_flags,
+			err = rocker_port_ctrl(rocker_port, trans_ph, ctrl_flags,
 					       &rocker_ctrls[i]);
 			if (err)
 				goto err_out;
@@ -3869,14 +3869,14 @@ static int rocker_port_stp_update(struct rocker_port *rocker_port,
 		}
 	}
 
-	err = rocker_port_fdb_flush(rocker_port, trans, flags);
+	err = rocker_port_fdb_flush(rocker_port, trans_ph, flags);
 	if (err)
 		goto err_out;
 
-	err = rocker_port_fwding(rocker_port, trans, flags);
+	err = rocker_port_fwding(rocker_port, trans_ph, flags);
 
 err_out:
-	if (trans == SWITCHDEV_TRANS_PREPARE) {
+	if (trans_ph == SWITCHDEV_TRANS_PREPARE) {
 		memcpy(rocker_port->ctrls, prev_ctrls, sizeof(prev_ctrls));
 		rocker_port->stp_state = prev_state;
 	}
@@ -3885,26 +3885,26 @@ err_out:
 }
 
 static int rocker_port_fwd_enable(struct rocker_port *rocker_port,
-				  enum switchdev_trans trans, int flags)
+				  enum switchdev_trans_ph trans_ph, int flags)
 {
 	if (rocker_port_is_bridged(rocker_port))
 		/* bridge STP will enable port */
 		return 0;
 
 	/* port is not bridged, so simulate going to FORWARDING state */
-	return rocker_port_stp_update(rocker_port, trans, flags,
+	return rocker_port_stp_update(rocker_port, trans_ph, flags,
 				      BR_STATE_FORWARDING);
 }
 
 static int rocker_port_fwd_disable(struct rocker_port *rocker_port,
-				   enum switchdev_trans trans, int flags)
+				   enum switchdev_trans_ph trans_ph, int flags)
 {
 	if (rocker_port_is_bridged(rocker_port))
 		/* bridge STP will disable port */
 		return 0;
 
 	/* port is not bridged, so simulate going to DISABLED state */
-	return rocker_port_stp_update(rocker_port, trans, flags,
+	return rocker_port_stp_update(rocker_port, trans_ph, flags,
 				      BR_STATE_DISABLED);
 }
 
@@ -3995,7 +3995,7 @@ not_found:
 }
 
 static int rocker_port_fib_ipv4(struct rocker_port *rocker_port,
-				enum switchdev_trans trans, __be32 dst,
+				enum switchdev_trans_ph trans_ph, __be32 dst,
 				int dst_len, const struct fib_info *fi,
 				u32 tb_id, int flags)
 {
@@ -4019,7 +4019,7 @@ static int rocker_port_fib_ipv4(struct rocker_port *rocker_port,
 	has_gw = !!nh->nh_gw;
 
 	if (has_gw && nh_on_port) {
-		err = rocker_port_ipv4_nh(rocker_port, trans, flags,
+		err = rocker_port_ipv4_nh(rocker_port, trans_ph, flags,
 					  nh->nh_gw, &index);
 		if (err)
 			return err;
@@ -4030,7 +4030,7 @@ static int rocker_port_fib_ipv4(struct rocker_port *rocker_port,
 		group_id = ROCKER_GROUP_L2_INTERFACE(internal_vlan_id, 0);
 	}
 
-	err = rocker_flow_tbl_ucast4_routing(rocker_port, trans, eth_type, dst,
+	err = rocker_flow_tbl_ucast4_routing(rocker_port, trans_ph, eth_type, dst,
 					     dst_mask, priority, goto_tbl,
 					     group_id, flags);
 	if (err)
@@ -4365,7 +4365,7 @@ static void rocker_port_trans_abort(const struct rocker_port *rocker_port)
 }
 
 static int rocker_port_brport_flags_set(struct rocker_port *rocker_port,
-					enum switchdev_trans trans,
+					enum switchdev_trans_ph trans_ph,
 					unsigned long brport_flags)
 {
 	unsigned long orig_flags;
@@ -4374,9 +4374,9 @@ static int rocker_port_brport_flags_set(struct rocker_port *rocker_port,
 	orig_flags = rocker_port->brport_flags;
 	rocker_port->brport_flags = brport_flags;
 	if ((orig_flags ^ rocker_port->brport_flags) & BR_LEARNING)
-		err = rocker_port_set_learning(rocker_port, trans);
+		err = rocker_port_set_learning(rocker_port, trans_ph);
 
-	if (trans == SWITCHDEV_TRANS_PREPARE)
+	if (trans_ph == SWITCHDEV_TRANS_PREPARE)
 		rocker_port->brport_flags = orig_flags;
 
 	return err;
@@ -4388,7 +4388,7 @@ static int rocker_port_attr_set(struct net_device *dev,
 	struct rocker_port *rocker_port = netdev_priv(dev);
 	int err = 0;
 
-	switch (attr->trans) {
+	switch (attr->trans_ph) {
 	case SWITCHDEV_TRANS_PREPARE:
 		BUG_ON(!list_empty(&rocker_port->trans_mem));
 		break;
@@ -4401,12 +4401,12 @@ static int rocker_port_attr_set(struct net_device *dev,
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_PORT_STP_STATE:
-		err = rocker_port_stp_update(rocker_port, attr->trans,
+		err = rocker_port_stp_update(rocker_port, attr->trans_ph,
 					     ROCKER_OP_FLAG_NOWAIT,
 					     attr->u.stp_state);
 		break;
 	case SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS:
-		err = rocker_port_brport_flags_set(rocker_port, attr->trans,
+		err = rocker_port_brport_flags_set(rocker_port, attr->trans_ph,
 						   attr->u.brport_flags);
 		break;
 	default:
@@ -4418,33 +4418,33 @@ static int rocker_port_attr_set(struct net_device *dev,
 }
 
 static int rocker_port_vlan_add(struct rocker_port *rocker_port,
-				enum switchdev_trans trans, u16 vid, u16 flags)
+				enum switchdev_trans_ph trans_ph, u16 vid, u16 flags)
 {
 	int err;
 
 	/* XXX deal with flags for PVID and untagged */
 
-	err = rocker_port_vlan(rocker_port, trans, 0, vid);
+	err = rocker_port_vlan(rocker_port, trans_ph, 0, vid);
 	if (err)
 		return err;
 
-	err = rocker_port_router_mac(rocker_port, trans, 0, htons(vid));
+	err = rocker_port_router_mac(rocker_port, trans_ph, 0, htons(vid));
 	if (err)
-		rocker_port_vlan(rocker_port, trans,
+		rocker_port_vlan(rocker_port, trans_ph,
 				 ROCKER_OP_FLAG_REMOVE, vid);
 
 	return err;
 }
 
 static int rocker_port_vlans_add(struct rocker_port *rocker_port,
-				 enum switchdev_trans trans,
+				 enum switchdev_trans_ph trans_ph,
 				 const struct switchdev_obj_vlan *vlan)
 {
 	u16 vid;
 	int err;
 
 	for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
-		err = rocker_port_vlan_add(rocker_port, trans,
+		err = rocker_port_vlan_add(rocker_port, trans_ph,
 					   vid, vlan->flags);
 		if (err)
 			return err;
@@ -4454,7 +4454,7 @@ static int rocker_port_vlans_add(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_fdb_add(struct rocker_port *rocker_port,
-			       enum switchdev_trans trans,
+			       enum switchdev_trans_ph trans_ph,
 			       const struct switchdev_obj_fdb *fdb)
 {
 	__be16 vlan_id = rocker_port_vid_to_vlan(rocker_port, fdb->vid, NULL);
@@ -4463,7 +4463,7 @@ static int rocker_port_fdb_add(struct rocker_port *rocker_port,
 	if (!rocker_port_is_bridged(rocker_port))
 		return -EINVAL;
 
-	return rocker_port_fdb(rocker_port, trans, fdb->addr, vlan_id, flags);
+	return rocker_port_fdb(rocker_port, trans_ph, fdb->addr, vlan_id, flags);
 }
 
 static int rocker_port_obj_add(struct net_device *dev,
@@ -4473,7 +4473,7 @@ static int rocker_port_obj_add(struct net_device *dev,
 	const struct switchdev_obj_ipv4_fib *fib4;
 	int err = 0;
 
-	switch (obj->trans) {
+	switch (obj->trans_ph) {
 	case SWITCHDEV_TRANS_PREPARE:
 		BUG_ON(!list_empty(&rocker_port->trans_mem));
 		break;
@@ -4486,17 +4486,17 @@ static int rocker_port_obj_add(struct net_device *dev,
 
 	switch (obj->id) {
 	case SWITCHDEV_OBJ_PORT_VLAN:
-		err = rocker_port_vlans_add(rocker_port, obj->trans,
+		err = rocker_port_vlans_add(rocker_port, obj->trans_ph,
 					    &obj->u.vlan);
 		break;
 	case SWITCHDEV_OBJ_IPV4_FIB:
 		fib4 = &obj->u.ipv4_fib;
-		err = rocker_port_fib_ipv4(rocker_port, obj->trans,
+		err = rocker_port_fib_ipv4(rocker_port, obj->trans_ph,
 					   htonl(fib4->dst), fib4->dst_len,
 					   fib4->fi, fib4->tb_id, 0);
 		break;
 	case SWITCHDEV_OBJ_PORT_FDB:
-		err = rocker_port_fdb_add(rocker_port, obj->trans, &obj->u.fdb);
+		err = rocker_port_fdb_add(rocker_port, obj->trans_ph, &obj->u.fdb);
 		break;
 	default:
 		err = -EOPNOTSUPP;
@@ -4536,7 +4536,7 @@ static int rocker_port_vlans_del(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_fdb_del(struct rocker_port *rocker_port,
-			       enum switchdev_trans trans,
+			       enum switchdev_trans_ph trans_ph,
 			       const struct switchdev_obj_fdb *fdb)
 {
 	__be16 vlan_id = rocker_port_vid_to_vlan(rocker_port, fdb->vid, NULL);
@@ -4545,7 +4545,7 @@ static int rocker_port_fdb_del(struct rocker_port *rocker_port,
 	if (!rocker_port_is_bridged(rocker_port))
 		return -EINVAL;
 
-	return rocker_port_fdb(rocker_port, trans, fdb->addr, vlan_id, flags);
+	return rocker_port_fdb(rocker_port, trans_ph, fdb->addr, vlan_id, flags);
 }
 
 static int rocker_port_obj_del(struct net_device *dev,
@@ -4567,7 +4567,7 @@ static int rocker_port_obj_del(struct net_device *dev,
 					   ROCKER_OP_FLAG_REMOVE);
 		break;
 	case SWITCHDEV_OBJ_PORT_FDB:
-		err = rocker_port_fdb_del(rocker_port, obj->trans, &obj->u.fdb);
+		err = rocker_port_fdb_del(rocker_port, obj->trans_ph, &obj->u.fdb);
 		break;
 	default:
 		err = -EOPNOTSUPP;
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 319baab..494f510 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -16,7 +16,7 @@
 
 #define SWITCHDEV_F_NO_RECURSE		BIT(0)
 
-enum switchdev_trans {
+enum switchdev_trans_ph {
 	SWITCHDEV_TRANS_NONE,
 	SWITCHDEV_TRANS_PREPARE,
 	SWITCHDEV_TRANS_ABORT,
@@ -32,7 +32,7 @@ enum switchdev_attr_id {
 
 struct switchdev_attr {
 	enum switchdev_attr_id id;
-	enum switchdev_trans trans;
+	enum switchdev_trans_ph trans_ph;
 	u32 flags;
 	union {
 		struct netdev_phys_item_id ppid;	/* PORT_PARENT_ID */
@@ -52,7 +52,7 @@ enum switchdev_obj_id {
 
 struct switchdev_obj {
 	enum switchdev_obj_id id;
-	enum switchdev_trans trans;
+	enum switchdev_trans_ph trans_ph;
 	int (*cb)(struct net_device *dev, struct switchdev_obj *obj);
 	union {
 		struct switchdev_obj_vlan {		/* PORT_VLAN */
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index cce9738..7f50b74 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -250,7 +250,7 @@ static int dsa_slave_port_vlan_add(struct net_device *dev,
 	u16 vid;
 	int err;
 
-	switch (obj->trans) {
+	switch (obj->trans_ph) {
 	case SWITCHDEV_TRANS_PREPARE:
 		if (!ds->drv->port_vlan_add || !ds->drv->port_pvid_set)
 			return -EOPNOTSUPP;
@@ -354,9 +354,9 @@ static int dsa_slave_port_fdb_add(struct net_device *dev,
 	struct dsa_switch *ds = p->parent;
 	int ret = -EOPNOTSUPP;
 
-	if (obj->trans == SWITCHDEV_TRANS_PREPARE)
+	if (obj->trans_ph == SWITCHDEV_TRANS_PREPARE)
 		ret = ds->drv->port_fdb_add ? 0 : -EOPNOTSUPP;
-	else if (obj->trans == SWITCHDEV_TRANS_COMMIT)
+	else if (obj->trans_ph == SWITCHDEV_TRANS_COMMIT)
 		ret = ds->drv->port_fdb_add(ds, p->port, fdb->addr, fdb->vid);
 
 	return ret;
@@ -462,7 +462,7 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_PORT_STP_STATE:
-		if (attr->trans == SWITCHDEV_TRANS_COMMIT)
+		if (attr->trans_ph == SWITCHDEV_TRANS_COMMIT)
 			ret = dsa_slave_stp_update(dev, attr->u.stp_state);
 		break;
 	default:
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index fda38f8..df5a544 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -163,7 +163,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 	 * but should not commit the attr.
 	 */
 
-	attr->trans = SWITCHDEV_TRANS_PREPARE;
+	attr->trans_ph = SWITCHDEV_TRANS_PREPARE;
 	err = __switchdev_port_attr_set(dev, attr);
 	if (err) {
 		/* Prepare phase failed: abort the transaction.  Any
@@ -172,7 +172,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 		 */
 
 		if (err != -EOPNOTSUPP) {
-			attr->trans = SWITCHDEV_TRANS_ABORT;
+			attr->trans_ph = SWITCHDEV_TRANS_ABORT;
 			__switchdev_port_attr_set(dev, attr);
 		}
 
@@ -184,7 +184,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 	 * because the driver said everythings was OK in phase I.
 	 */
 
-	attr->trans = SWITCHDEV_TRANS_COMMIT;
+	attr->trans_ph = SWITCHDEV_TRANS_COMMIT;
 	err = __switchdev_port_attr_set(dev, attr);
 	WARN(err, "%s: Commit of attribute (id=%d) failed.\n",
 	     dev->name, attr->id);
@@ -243,7 +243,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 	 * but should not commit the obj.
 	 */
 
-	obj->trans = SWITCHDEV_TRANS_PREPARE;
+	obj->trans_ph = SWITCHDEV_TRANS_PREPARE;
 	err = __switchdev_port_obj_add(dev, obj);
 	if (err) {
 		/* Prepare phase failed: abort the transaction.  Any
@@ -252,7 +252,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 		 */
 
 		if (err != -EOPNOTSUPP) {
-			obj->trans = SWITCHDEV_TRANS_ABORT;
+			obj->trans_ph = SWITCHDEV_TRANS_ABORT;
 			__switchdev_port_obj_add(dev, obj);
 		}
 
@@ -264,7 +264,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 	 * because the driver said everythings was OK in phase I.
 	 */
 
-	obj->trans = SWITCHDEV_TRANS_COMMIT;
+	obj->trans_ph = SWITCHDEV_TRANS_COMMIT;
 	err = __switchdev_port_obj_add(dev, obj);
 	WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id);
 
-- 
1.9.3

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

* [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add
  2015-09-24  8:02 [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Jiri Pirko
  2015-09-24  8:02 ` [patch net-next v3 01/10] switchdev: rename "trans" to "trans_ph" Jiri Pirko
@ 2015-09-24  8:02 ` Jiri Pirko
  2015-09-25  4:36   ` Vivien Didelot
  2015-09-24  8:02 ` [patch net-next v3 03/10] switchdev: move transaction phase enum under transaction structure Jiri Pirko
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 25+ messages in thread
From: Jiri Pirko @ 2015-09-24  8:02 UTC (permalink / raw)
  To: netdev
  Cc: davem, idosch, eladr, sfeldma, f.fainelli, linux, vivien.didelot,
	rami.rosen, roopa, pjonnala, andrew, gospo, Jiri Pirko

From: Jiri Pirko <jiri@mellanox.com>

Now, the memory allocation in prepare/commit state is done separatelly
in each driver (rocker). Introduce the similar mechanism in generic
switchdev code, in form of queue. That can be used not only for memory
allocations, but also for different items. Abort item destruction
is handled as well.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
v1->v2:
- added comment blocks to exported functions as suggested by Scott
- made switchdev_trans_init and switchdev_trans_items_destroy static
- added documentation for this to switchdev.txt as suggested by Scott
v2->v3:
- warn in case of transaction item queue is not empty after commit phase
  as suggested by Scott
---
 Documentation/networking/switchdev.txt |  19 ++++++
 drivers/net/ethernet/rocker/rocker.c   |   6 +-
 include/net/switchdev.h                |  24 ++++++-
 net/dsa/slave.c                        |   6 +-
 net/switchdev/switchdev.c              | 111 +++++++++++++++++++++++++++++----
 5 files changed, 146 insertions(+), 20 deletions(-)

diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt
index 67e43ee..9f9e258 100644
--- a/Documentation/networking/switchdev.txt
+++ b/Documentation/networking/switchdev.txt
@@ -369,3 +369,22 @@ The driver can monitor for updates to arp_tbl using the netevent notifier
 NETEVENT_NEIGH_UPDATE.  The device can be programmed with resolved nexthops
 for the routes as arp_tbl updates.  The driver implements ndo_neigh_destroy
 to know when arp_tbl neighbor entries are purged from the port.
+
+Transaction item queue
+^^^^^^^^^^^^^^^^^^^^^^
+
+For switchdev ops attr_set and obj_add, there is a 2 phase transaction model
+used. First phase is to "prepare" anything needed, including various checks,
+memory allocation, etc. The goal is to handle the stuff that is not unlikely
+to fail here. The second phase is to "commit" the actual changes.
+
+Switchdev provides an inftrastructure for sharing items (for example memory
+allocations) between the two phases.
+
+The object created by a driver in "prepare" phase and it is queued up by:
+switchdev_trans_item_enqueue()
+During the "commit" phase, the driver gets the object by:
+switchdev_trans_item_dequeue()
+
+If a transaction is aborted during "prepare" phase, switchdev code will handle
+cleanup of the queued-up objects.
diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
index cf03b07..dcc6f3f 100644
--- a/drivers/net/ethernet/rocker/rocker.c
+++ b/drivers/net/ethernet/rocker/rocker.c
@@ -4383,7 +4383,8 @@ static int rocker_port_brport_flags_set(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_attr_set(struct net_device *dev,
-				struct switchdev_attr *attr)
+				struct switchdev_attr *attr,
+				struct switchdev_trans *trans)
 {
 	struct rocker_port *rocker_port = netdev_priv(dev);
 	int err = 0;
@@ -4467,7 +4468,8 @@ static int rocker_port_fdb_add(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_obj_add(struct net_device *dev,
-			       struct switchdev_obj *obj)
+			       struct switchdev_obj *obj,
+			       struct switchdev_trans *trans)
 {
 	struct rocker_port *rocker_port = netdev_priv(dev);
 	const struct switchdev_obj_ipv4_fib *fib4;
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 494f510..1e394f1 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -1,6 +1,6 @@
 /*
  * include/net/switchdev.h - Switch device API
- * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us>
+ * Copyright (c) 2014-2015 Jiri Pirko <jiri@resnulli.us>
  * Copyright (c) 2014-2015 Scott Feldman <sfeldma@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -13,6 +13,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/notifier.h>
+#include <linux/list.h>
 
 #define SWITCHDEV_F_NO_RECURSE		BIT(0)
 
@@ -23,6 +24,16 @@ enum switchdev_trans_ph {
 	SWITCHDEV_TRANS_COMMIT,
 };
 
+struct switchdev_trans_item {
+	struct list_head list;
+	void *data;
+	void (*destructor)(const void *data);
+};
+
+struct switchdev_trans {
+	struct list_head item_list;
+};
+
 enum switchdev_attr_id {
 	SWITCHDEV_ATTR_UNDEFINED,
 	SWITCHDEV_ATTR_PORT_PARENT_ID,
@@ -77,6 +88,11 @@ struct switchdev_obj {
 	} u;
 };
 
+void switchdev_trans_item_enqueue(struct switchdev_trans *trans,
+				  void *data, void (*destructor)(void const *),
+				  struct switchdev_trans_item *tritem);
+void *switchdev_trans_item_dequeue(struct switchdev_trans *trans);
+
 /**
  * struct switchdev_ops - switchdev operations
  *
@@ -94,9 +110,11 @@ struct switchdev_ops {
 	int	(*switchdev_port_attr_get)(struct net_device *dev,
 					   struct switchdev_attr *attr);
 	int	(*switchdev_port_attr_set)(struct net_device *dev,
-					   struct switchdev_attr *attr);
+					   struct switchdev_attr *attr,
+					   struct switchdev_trans *trans);
 	int	(*switchdev_port_obj_add)(struct net_device *dev,
-					  struct switchdev_obj *obj);
+					  struct switchdev_obj *obj,
+					  struct switchdev_trans *trans);
 	int	(*switchdev_port_obj_del)(struct net_device *dev,
 					  struct switchdev_obj *obj);
 	int	(*switchdev_port_obj_dump)(struct net_device *dev,
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 7f50b74..ac76fd1 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -456,7 +456,8 @@ static int dsa_slave_stp_update(struct net_device *dev, u8 state)
 }
 
 static int dsa_slave_port_attr_set(struct net_device *dev,
-				   struct switchdev_attr *attr)
+				   struct switchdev_attr *attr,
+				   struct switchdev_trans *trans)
 {
 	int ret = 0;
 
@@ -474,7 +475,8 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
 }
 
 static int dsa_slave_port_obj_add(struct net_device *dev,
-				  struct switchdev_obj *obj)
+				  struct switchdev_obj *obj,
+				  struct switchdev_trans *trans)
 {
 	int err;
 
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index df5a544..35e2967 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -1,6 +1,6 @@
 /*
  * net/switchdev/switchdev.c - Switch device API
- * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us>
+ * Copyright (c) 2014-2015 Jiri Pirko <jiri@resnulli.us>
  * Copyright (c) 2014-2015 Scott Feldman <sfeldma@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -16,10 +16,83 @@
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
 #include <linux/if_bridge.h>
+#include <linux/list.h>
 #include <net/ip_fib.h>
 #include <net/switchdev.h>
 
 /**
+ *	switchdev_trans_item_enqueue - Enqueue data item to transaction queue
+ *
+ *	@trans: transaction
+ *	@data: pointer to data being queued
+ *	@destructor: data destructor
+ *	@tritem: transaction item being queued
+ *
+ *	Enqeueue data item to transaction queue. tritem is typically placed in
+ *	cointainter pointed at by data pointer. Destructor is called on
+ *	transaction abort and after successful commit phase in case
+ *	the caller did not dequeue the item before.
+ */
+void switchdev_trans_item_enqueue(struct switchdev_trans *trans,
+				  void *data, void (*destructor)(void const *),
+				  struct switchdev_trans_item *tritem)
+{
+	tritem->data = data;
+	tritem->destructor = destructor;
+	list_add_tail(&tritem->list, &trans->item_list);
+}
+EXPORT_SYMBOL_GPL(switchdev_trans_item_enqueue);
+
+static struct switchdev_trans_item *
+__switchdev_trans_item_dequeue(struct switchdev_trans *trans)
+{
+	struct switchdev_trans_item *tritem;
+
+	if (list_empty(&trans->item_list))
+		return NULL;
+	tritem = list_first_entry(&trans->item_list,
+				  struct switchdev_trans_item, list);
+	list_del(&tritem->list);
+	return tritem;
+}
+
+/**
+ *	switchdev_trans_item_dequeue - Dequeue data item from transaction queue
+ *
+ *	@trans: transaction
+ */
+void *switchdev_trans_item_dequeue(struct switchdev_trans *trans)
+{
+	struct switchdev_trans_item *tritem;
+
+	tritem = __switchdev_trans_item_dequeue(trans);
+	BUG_ON(!tritem);
+	return tritem->data;
+}
+EXPORT_SYMBOL_GPL(switchdev_trans_item_dequeue);
+
+static void switchdev_trans_init(struct switchdev_trans *trans)
+{
+	INIT_LIST_HEAD(&trans->item_list);
+}
+
+static void switchdev_trans_items_destroy(struct switchdev_trans *trans)
+{
+	struct switchdev_trans_item *tritem;
+
+	while ((tritem = __switchdev_trans_item_dequeue(trans)))
+		tritem->destructor(tritem->data);
+}
+
+static void switchdev_trans_items_warn_destroy(struct net_device *dev,
+					       struct switchdev_trans *trans)
+{
+	WARN(!list_empty(&trans->item_list), "%s: transaction item queue is not empty.\n",
+	     dev->name);
+	switchdev_trans_items_destroy(trans);
+}
+
+/**
  *	switchdev_port_attr_get - Get port attribute
  *
  *	@dev: port device
@@ -62,7 +135,8 @@ int switchdev_port_attr_get(struct net_device *dev, struct switchdev_attr *attr)
 EXPORT_SYMBOL_GPL(switchdev_port_attr_get);
 
 static int __switchdev_port_attr_set(struct net_device *dev,
-				     struct switchdev_attr *attr)
+				     struct switchdev_attr *attr,
+				     struct switchdev_trans *trans)
 {
 	const struct switchdev_ops *ops = dev->switchdev_ops;
 	struct net_device *lower_dev;
@@ -70,7 +144,7 @@ static int __switchdev_port_attr_set(struct net_device *dev,
 	int err = -EOPNOTSUPP;
 
 	if (ops && ops->switchdev_port_attr_set)
-		return ops->switchdev_port_attr_set(dev, attr);
+		return ops->switchdev_port_attr_set(dev, attr, trans);
 
 	if (attr->flags & SWITCHDEV_F_NO_RECURSE)
 		return err;
@@ -81,7 +155,7 @@ static int __switchdev_port_attr_set(struct net_device *dev,
 	 */
 
 	netdev_for_each_lower_dev(dev, lower_dev, iter) {
-		err = __switchdev_port_attr_set(lower_dev, attr);
+		err = __switchdev_port_attr_set(lower_dev, attr, trans);
 		if (err)
 			break;
 	}
@@ -144,6 +218,7 @@ static int switchdev_port_attr_set_defer(struct net_device *dev,
  */
 int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 {
+	struct switchdev_trans trans;
 	int err;
 
 	if (!rtnl_is_locked()) {
@@ -156,6 +231,8 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 		return switchdev_port_attr_set_defer(dev, attr);
 	}
 
+	switchdev_trans_init(&trans);
+
 	/* Phase I: prepare for attr set. Driver/device should fail
 	 * here if there are going to be issues in the commit phase,
 	 * such as lack of resources or support.  The driver/device
@@ -164,7 +241,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 	 */
 
 	attr->trans_ph = SWITCHDEV_TRANS_PREPARE;
-	err = __switchdev_port_attr_set(dev, attr);
+	err = __switchdev_port_attr_set(dev, attr, &trans);
 	if (err) {
 		/* Prepare phase failed: abort the transaction.  Any
 		 * resources reserved in the prepare phase are
@@ -173,7 +250,8 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 
 		if (err != -EOPNOTSUPP) {
 			attr->trans_ph = SWITCHDEV_TRANS_ABORT;
-			__switchdev_port_attr_set(dev, attr);
+			__switchdev_port_attr_set(dev, attr, &trans);
+			switchdev_trans_items_destroy(&trans);
 		}
 
 		return err;
@@ -185,16 +263,18 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 	 */
 
 	attr->trans_ph = SWITCHDEV_TRANS_COMMIT;
-	err = __switchdev_port_attr_set(dev, attr);
+	err = __switchdev_port_attr_set(dev, attr, &trans);
 	WARN(err, "%s: Commit of attribute (id=%d) failed.\n",
 	     dev->name, attr->id);
+	switchdev_trans_items_warn_destroy(dev, &trans);
 
 	return err;
 }
 EXPORT_SYMBOL_GPL(switchdev_port_attr_set);
 
 static int __switchdev_port_obj_add(struct net_device *dev,
-				    struct switchdev_obj *obj)
+				    struct switchdev_obj *obj,
+				    struct switchdev_trans *trans)
 {
 	const struct switchdev_ops *ops = dev->switchdev_ops;
 	struct net_device *lower_dev;
@@ -202,7 +282,7 @@ static int __switchdev_port_obj_add(struct net_device *dev,
 	int err = -EOPNOTSUPP;
 
 	if (ops && ops->switchdev_port_obj_add)
-		return ops->switchdev_port_obj_add(dev, obj);
+		return ops->switchdev_port_obj_add(dev, obj, trans);
 
 	/* Switch device port(s) may be stacked under
 	 * bond/team/vlan dev, so recurse down to add object on
@@ -210,7 +290,7 @@ static int __switchdev_port_obj_add(struct net_device *dev,
 	 */
 
 	netdev_for_each_lower_dev(dev, lower_dev, iter) {
-		err = __switchdev_port_obj_add(lower_dev, obj);
+		err = __switchdev_port_obj_add(lower_dev, obj, trans);
 		if (err)
 			break;
 	}
@@ -232,10 +312,13 @@ static int __switchdev_port_obj_add(struct net_device *dev,
  */
 int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 {
+	struct switchdev_trans trans;
 	int err;
 
 	ASSERT_RTNL();
 
+	switchdev_trans_init(&trans);
+
 	/* Phase I: prepare for obj add. Driver/device should fail
 	 * here if there are going to be issues in the commit phase,
 	 * such as lack of resources or support.  The driver/device
@@ -244,7 +327,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 	 */
 
 	obj->trans_ph = SWITCHDEV_TRANS_PREPARE;
-	err = __switchdev_port_obj_add(dev, obj);
+	err = __switchdev_port_obj_add(dev, obj, &trans);
 	if (err) {
 		/* Prepare phase failed: abort the transaction.  Any
 		 * resources reserved in the prepare phase are
@@ -253,7 +336,8 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 
 		if (err != -EOPNOTSUPP) {
 			obj->trans_ph = SWITCHDEV_TRANS_ABORT;
-			__switchdev_port_obj_add(dev, obj);
+			__switchdev_port_obj_add(dev, obj, &trans);
+			switchdev_trans_items_destroy(&trans);
 		}
 
 		return err;
@@ -265,8 +349,9 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 	 */
 
 	obj->trans_ph = SWITCHDEV_TRANS_COMMIT;
-	err = __switchdev_port_obj_add(dev, obj);
+	err = __switchdev_port_obj_add(dev, obj, &trans);
 	WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id);
+	switchdev_trans_items_warn_destroy(dev, &trans);
 
 	return err;
 }
-- 
1.9.3

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

* [patch net-next v3 03/10] switchdev: move transaction phase enum under transaction structure
  2015-09-24  8:02 [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Jiri Pirko
  2015-09-24  8:02 ` [patch net-next v3 01/10] switchdev: rename "trans" to "trans_ph" Jiri Pirko
  2015-09-24  8:02 ` [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add Jiri Pirko
@ 2015-09-24  8:02 ` Jiri Pirko
  2015-09-24  8:02 ` [patch net-next v3 04/10] switchdev: add switchdev_trans_ph_prepare/commit helpers Jiri Pirko
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Jiri Pirko @ 2015-09-24  8:02 UTC (permalink / raw)
  To: netdev
  Cc: davem, idosch, eladr, sfeldma, f.fainelli, linux, vivien.didelot,
	rami.rosen, roopa, pjonnala, andrew, gospo, Jiri Pirko

From: Jiri Pirko <jiri@mellanox.com>

Before it disappears completely, move transaction phase enum under
transaction structure and make attr/obj structures a bit cleaner.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/rocker/rocker.c | 17 +++++++++--------
 include/net/switchdev.h              |  3 +--
 net/dsa/slave.c                      | 18 ++++++++++--------
 net/switchdev/switchdev.c            | 12 ++++++------
 4 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
index dcc6f3f..c348f86 100644
--- a/drivers/net/ethernet/rocker/rocker.c
+++ b/drivers/net/ethernet/rocker/rocker.c
@@ -4389,7 +4389,7 @@ static int rocker_port_attr_set(struct net_device *dev,
 	struct rocker_port *rocker_port = netdev_priv(dev);
 	int err = 0;
 
-	switch (attr->trans_ph) {
+	switch (trans->ph) {
 	case SWITCHDEV_TRANS_PREPARE:
 		BUG_ON(!list_empty(&rocker_port->trans_mem));
 		break;
@@ -4402,12 +4402,12 @@ static int rocker_port_attr_set(struct net_device *dev,
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_PORT_STP_STATE:
-		err = rocker_port_stp_update(rocker_port, attr->trans_ph,
+		err = rocker_port_stp_update(rocker_port, trans->ph,
 					     ROCKER_OP_FLAG_NOWAIT,
 					     attr->u.stp_state);
 		break;
 	case SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS:
-		err = rocker_port_brport_flags_set(rocker_port, attr->trans_ph,
+		err = rocker_port_brport_flags_set(rocker_port, trans->ph,
 						   attr->u.brport_flags);
 		break;
 	default:
@@ -4475,7 +4475,7 @@ static int rocker_port_obj_add(struct net_device *dev,
 	const struct switchdev_obj_ipv4_fib *fib4;
 	int err = 0;
 
-	switch (obj->trans_ph) {
+	switch (trans->ph) {
 	case SWITCHDEV_TRANS_PREPARE:
 		BUG_ON(!list_empty(&rocker_port->trans_mem));
 		break;
@@ -4488,17 +4488,17 @@ static int rocker_port_obj_add(struct net_device *dev,
 
 	switch (obj->id) {
 	case SWITCHDEV_OBJ_PORT_VLAN:
-		err = rocker_port_vlans_add(rocker_port, obj->trans_ph,
+		err = rocker_port_vlans_add(rocker_port, trans->ph,
 					    &obj->u.vlan);
 		break;
 	case SWITCHDEV_OBJ_IPV4_FIB:
 		fib4 = &obj->u.ipv4_fib;
-		err = rocker_port_fib_ipv4(rocker_port, obj->trans_ph,
+		err = rocker_port_fib_ipv4(rocker_port, trans->ph,
 					   htonl(fib4->dst), fib4->dst_len,
 					   fib4->fi, fib4->tb_id, 0);
 		break;
 	case SWITCHDEV_OBJ_PORT_FDB:
-		err = rocker_port_fdb_add(rocker_port, obj->trans_ph, &obj->u.fdb);
+		err = rocker_port_fdb_add(rocker_port, trans->ph, &obj->u.fdb);
 		break;
 	default:
 		err = -EOPNOTSUPP;
@@ -4569,7 +4569,8 @@ static int rocker_port_obj_del(struct net_device *dev,
 					   ROCKER_OP_FLAG_REMOVE);
 		break;
 	case SWITCHDEV_OBJ_PORT_FDB:
-		err = rocker_port_fdb_del(rocker_port, obj->trans_ph, &obj->u.fdb);
+		err = rocker_port_fdb_del(rocker_port, SWITCHDEV_TRANS_NONE,
+					  &obj->u.fdb);
 		break;
 	default:
 		err = -EOPNOTSUPP;
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 1e394f1..368a642 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -32,6 +32,7 @@ struct switchdev_trans_item {
 
 struct switchdev_trans {
 	struct list_head item_list;
+	enum switchdev_trans_ph ph;
 };
 
 enum switchdev_attr_id {
@@ -43,7 +44,6 @@ enum switchdev_attr_id {
 
 struct switchdev_attr {
 	enum switchdev_attr_id id;
-	enum switchdev_trans_ph trans_ph;
 	u32 flags;
 	union {
 		struct netdev_phys_item_id ppid;	/* PORT_PARENT_ID */
@@ -63,7 +63,6 @@ enum switchdev_obj_id {
 
 struct switchdev_obj {
 	enum switchdev_obj_id id;
-	enum switchdev_trans_ph trans_ph;
 	int (*cb)(struct net_device *dev, struct switchdev_obj *obj);
 	union {
 		struct switchdev_obj_vlan {		/* PORT_VLAN */
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index ac76fd1..748cc63 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -242,7 +242,8 @@ static int dsa_bridge_check_vlan_range(struct dsa_switch *ds,
 }
 
 static int dsa_slave_port_vlan_add(struct net_device *dev,
-				   struct switchdev_obj *obj)
+				   struct switchdev_obj *obj,
+				   struct switchdev_trans *trans)
 {
 	struct switchdev_obj_vlan *vlan = &obj->u.vlan;
 	struct dsa_slave_priv *p = netdev_priv(dev);
@@ -250,7 +251,7 @@ static int dsa_slave_port_vlan_add(struct net_device *dev,
 	u16 vid;
 	int err;
 
-	switch (obj->trans_ph) {
+	switch (trans->ph) {
 	case SWITCHDEV_TRANS_PREPARE:
 		if (!ds->drv->port_vlan_add || !ds->drv->port_pvid_set)
 			return -EOPNOTSUPP;
@@ -347,16 +348,17 @@ static int dsa_slave_port_vlan_dump(struct net_device *dev,
 }
 
 static int dsa_slave_port_fdb_add(struct net_device *dev,
-				  struct switchdev_obj *obj)
+				  struct switchdev_obj *obj,
+				  struct switchdev_trans *trans)
 {
 	struct switchdev_obj_fdb *fdb = &obj->u.fdb;
 	struct dsa_slave_priv *p = netdev_priv(dev);
 	struct dsa_switch *ds = p->parent;
 	int ret = -EOPNOTSUPP;
 
-	if (obj->trans_ph == SWITCHDEV_TRANS_PREPARE)
+	if (trans->ph == SWITCHDEV_TRANS_PREPARE)
 		ret = ds->drv->port_fdb_add ? 0 : -EOPNOTSUPP;
-	else if (obj->trans_ph == SWITCHDEV_TRANS_COMMIT)
+	else if (trans->ph == SWITCHDEV_TRANS_COMMIT)
 		ret = ds->drv->port_fdb_add(ds, p->port, fdb->addr, fdb->vid);
 
 	return ret;
@@ -463,7 +465,7 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_PORT_STP_STATE:
-		if (attr->trans_ph == SWITCHDEV_TRANS_COMMIT)
+		if (trans->ph == SWITCHDEV_TRANS_COMMIT)
 			ret = dsa_slave_stp_update(dev, attr->u.stp_state);
 		break;
 	default:
@@ -487,10 +489,10 @@ static int dsa_slave_port_obj_add(struct net_device *dev,
 
 	switch (obj->id) {
 	case SWITCHDEV_OBJ_PORT_FDB:
-		err = dsa_slave_port_fdb_add(dev, obj);
+		err = dsa_slave_port_fdb_add(dev, obj, trans);
 		break;
 	case SWITCHDEV_OBJ_PORT_VLAN:
-		err = dsa_slave_port_vlan_add(dev, obj);
+		err = dsa_slave_port_vlan_add(dev, obj, trans);
 		break;
 	default:
 		err = -EOPNOTSUPP;
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 35e2967..d1c7d51 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -240,7 +240,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 	 * but should not commit the attr.
 	 */
 
-	attr->trans_ph = SWITCHDEV_TRANS_PREPARE;
+	trans.ph = SWITCHDEV_TRANS_PREPARE;
 	err = __switchdev_port_attr_set(dev, attr, &trans);
 	if (err) {
 		/* Prepare phase failed: abort the transaction.  Any
@@ -249,7 +249,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 		 */
 
 		if (err != -EOPNOTSUPP) {
-			attr->trans_ph = SWITCHDEV_TRANS_ABORT;
+			trans.ph = SWITCHDEV_TRANS_ABORT;
 			__switchdev_port_attr_set(dev, attr, &trans);
 			switchdev_trans_items_destroy(&trans);
 		}
@@ -262,7 +262,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 	 * because the driver said everythings was OK in phase I.
 	 */
 
-	attr->trans_ph = SWITCHDEV_TRANS_COMMIT;
+	trans.ph = SWITCHDEV_TRANS_COMMIT;
 	err = __switchdev_port_attr_set(dev, attr, &trans);
 	WARN(err, "%s: Commit of attribute (id=%d) failed.\n",
 	     dev->name, attr->id);
@@ -326,7 +326,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 	 * but should not commit the obj.
 	 */
 
-	obj->trans_ph = SWITCHDEV_TRANS_PREPARE;
+	trans.ph = SWITCHDEV_TRANS_PREPARE;
 	err = __switchdev_port_obj_add(dev, obj, &trans);
 	if (err) {
 		/* Prepare phase failed: abort the transaction.  Any
@@ -335,7 +335,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 		 */
 
 		if (err != -EOPNOTSUPP) {
-			obj->trans_ph = SWITCHDEV_TRANS_ABORT;
+			trans.ph = SWITCHDEV_TRANS_ABORT;
 			__switchdev_port_obj_add(dev, obj, &trans);
 			switchdev_trans_items_destroy(&trans);
 		}
@@ -348,7 +348,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 	 * because the driver said everythings was OK in phase I.
 	 */
 
-	obj->trans_ph = SWITCHDEV_TRANS_COMMIT;
+	trans.ph = SWITCHDEV_TRANS_COMMIT;
 	err = __switchdev_port_obj_add(dev, obj, &trans);
 	WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id);
 	switchdev_trans_items_warn_destroy(dev, &trans);
-- 
1.9.3

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

* [patch net-next v3 04/10] switchdev: add switchdev_trans_ph_prepare/commit helpers
  2015-09-24  8:02 [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Jiri Pirko
                   ` (2 preceding siblings ...)
  2015-09-24  8:02 ` [patch net-next v3 03/10] switchdev: move transaction phase enum under transaction structure Jiri Pirko
@ 2015-09-24  8:02 ` Jiri Pirko
  2015-09-24  8:02 ` [patch net-next v3 05/10] rocker: push struct switchdev_trans down through rocker code Jiri Pirko
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Jiri Pirko @ 2015-09-24  8:02 UTC (permalink / raw)
  To: netdev
  Cc: davem, idosch, eladr, sfeldma, f.fainelli, linux, vivien.didelot,
	rami.rosen, roopa, pjonnala, andrew, gospo, Jiri Pirko

From: Jiri Pirko <jiri@mellanox.com>

Add helpers which should be used int attr_set/obj_add switchdev ops to
check the phase of transaction.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/switchdev.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 368a642..f84ecf4 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -35,6 +35,16 @@ struct switchdev_trans {
 	enum switchdev_trans_ph ph;
 };
 
+static inline bool switchdev_trans_ph_prepare(struct switchdev_trans *trans)
+{
+	return trans && trans->ph == SWITCHDEV_TRANS_PREPARE;
+}
+
+static inline bool switchdev_trans_ph_commit(struct switchdev_trans *trans)
+{
+	return trans && trans->ph == SWITCHDEV_TRANS_COMMIT;
+}
+
 enum switchdev_attr_id {
 	SWITCHDEV_ATTR_UNDEFINED,
 	SWITCHDEV_ATTR_PORT_PARENT_ID,
-- 
1.9.3

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

* [patch net-next v3 05/10] rocker: push struct switchdev_trans down through rocker code
  2015-09-24  8:02 [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Jiri Pirko
                   ` (3 preceding siblings ...)
  2015-09-24  8:02 ` [patch net-next v3 04/10] switchdev: add switchdev_trans_ph_prepare/commit helpers Jiri Pirko
@ 2015-09-24  8:02 ` Jiri Pirko
  2015-09-24  8:02 ` [patch net-next v3 06/10] rocker: use switchdev transaction queue for allocated memory Jiri Pirko
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Jiri Pirko @ 2015-09-24  8:02 UTC (permalink / raw)
  To: netdev
  Cc: davem, idosch, eladr, sfeldma, f.fainelli, linux, vivien.didelot,
	rami.rosen, roopa, pjonnala, andrew, gospo, Jiri Pirko

From: Jiri Pirko <jiri@mellanox.com>

There will be needed to have switchdev_trans available down in the call
chain, so propagate it instead of trans phase enum. This enum will be
removed anyway. Also, use prepare/commit phase check helpers to get
information about current phase of transaction.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
v1->v2:
- no change
v2->v3:
- rebased on top of Scott's ageing patchset
---
 drivers/net/ethernet/rocker/rocker.c | 462 +++++++++++++++++------------------
 1 file changed, 225 insertions(+), 237 deletions(-)

diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
index c348f86..102b37d 100644
--- a/drivers/net/ethernet/rocker/rocker.c
+++ b/drivers/net/ethernet/rocker/rocker.c
@@ -343,7 +343,7 @@ static bool rocker_port_is_ovsed(const struct rocker_port *rocker_port)
 #define ROCKER_OP_FLAG_REFRESH		BIT(3)
 
 static void *__rocker_port_mem_alloc(struct rocker_port *rocker_port,
-				     enum switchdev_trans_ph trans_ph, int flags,
+				     struct switchdev_trans *trans, int flags,
 				     size_t size)
 {
 	struct list_head *elem = NULL;
@@ -359,45 +359,39 @@ static void *__rocker_port_mem_alloc(struct rocker_port *rocker_port,
 	 * memory used in the commit phase.
 	 */
 
-	switch (trans_ph) {
-	case SWITCHDEV_TRANS_PREPARE:
+	if (!trans) {
+		elem = kzalloc(size + sizeof(*elem), gfp_flags);
+		if (elem)
+			INIT_LIST_HEAD(elem);
+	} else if (switchdev_trans_ph_prepare(trans)) {
 		elem = kzalloc(size + sizeof(*elem), gfp_flags);
 		if (!elem)
 			return NULL;
 		list_add_tail(elem, &rocker_port->trans_mem);
-		break;
-	case SWITCHDEV_TRANS_COMMIT:
+	} else {
 		BUG_ON(list_empty(&rocker_port->trans_mem));
 		elem = rocker_port->trans_mem.next;
 		list_del_init(elem);
-		break;
-	case SWITCHDEV_TRANS_NONE:
-		elem = kzalloc(size + sizeof(*elem), gfp_flags);
-		if (elem)
-			INIT_LIST_HEAD(elem);
-		break;
-	default:
-		break;
 	}
 
 	return elem ? elem + 1 : NULL;
 }
 
 static void *rocker_port_kzalloc(struct rocker_port *rocker_port,
-				 enum switchdev_trans_ph trans_ph, int flags,
+				 struct switchdev_trans *trans, int flags,
 				 size_t size)
 {
-	return __rocker_port_mem_alloc(rocker_port, trans_ph, flags, size);
+	return __rocker_port_mem_alloc(rocker_port, trans, flags, size);
 }
 
 static void *rocker_port_kcalloc(struct rocker_port *rocker_port,
-				 enum switchdev_trans_ph trans_ph, int flags,
+				 struct switchdev_trans *trans, int flags,
 				 size_t n, size_t size)
 {
-	return __rocker_port_mem_alloc(rocker_port, trans_ph, flags, n * size);
+	return __rocker_port_mem_alloc(rocker_port, trans, flags, n * size);
 }
 
-static void rocker_port_kfree(enum switchdev_trans_ph trans_ph, const void *mem)
+static void rocker_port_kfree(struct switchdev_trans *trans, const void *mem)
 {
 	struct list_head *elem;
 
@@ -406,7 +400,7 @@ static void rocker_port_kfree(enum switchdev_trans_ph trans_ph, const void *mem)
 	 * commit phase.
 	 */
 
-	if (trans_ph == SWITCHDEV_TRANS_PREPARE)
+	if (switchdev_trans_ph_prepare(trans))
 		return;
 
 	elem = (struct list_head *)mem - 1;
@@ -433,22 +427,22 @@ static void rocker_wait_init(struct rocker_wait *wait)
 }
 
 static struct rocker_wait *rocker_wait_create(struct rocker_port *rocker_port,
-					      enum switchdev_trans_ph trans_ph,
+					      struct switchdev_trans *trans,
 					      int flags)
 {
 	struct rocker_wait *wait;
 
-	wait = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*wait));
+	wait = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*wait));
 	if (!wait)
 		return NULL;
 	rocker_wait_init(wait);
 	return wait;
 }
 
-static void rocker_wait_destroy(enum switchdev_trans_ph trans_ph,
+static void rocker_wait_destroy(struct switchdev_trans *trans,
 				struct rocker_wait *wait)
 {
-	rocker_port_kfree(trans_ph, wait);
+	rocker_port_kfree(trans, wait);
 }
 
 static bool rocker_wait_event_timeout(struct rocker_wait *wait,
@@ -1411,7 +1405,7 @@ static irqreturn_t rocker_cmd_irq_handler(int irq, void *dev_id)
 		wait = rocker_desc_cookie_ptr_get(desc_info);
 		if (wait->nowait) {
 			rocker_desc_gen_clear(desc_info);
-			rocker_wait_destroy(SWITCHDEV_TRANS_NONE, wait);
+			rocker_wait_destroy(NULL, wait);
 		} else {
 			rocker_wait_wake_up(wait);
 		}
@@ -1466,7 +1460,7 @@ static int rocker_event_link_change(const struct rocker *rocker,
 }
 
 static int rocker_port_fdb(struct rocker_port *rocker_port,
-			   enum switchdev_trans_ph trans_ph,
+			   struct switchdev_trans *trans,
 			   const unsigned char *addr,
 			   __be16 vlan_id, int flags);
 
@@ -1499,8 +1493,7 @@ static int rocker_event_mac_vlan_seen(const struct rocker *rocker,
 	    rocker_port->stp_state != BR_STATE_FORWARDING)
 		return 0;
 
-	return rocker_port_fdb(rocker_port, SWITCHDEV_TRANS_NONE,
-			       addr, vlan_id, flags);
+	return rocker_port_fdb(rocker_port, NULL, addr, vlan_id, flags);
 }
 
 static int rocker_event_process(const struct rocker *rocker,
@@ -1585,7 +1578,7 @@ typedef int (*rocker_cmd_proc_cb_t)(const struct rocker_port *rocker_port,
 				    void *priv);
 
 static int rocker_cmd_exec(struct rocker_port *rocker_port,
-			   enum switchdev_trans_ph trans_ph, int flags,
+			   struct switchdev_trans *trans, int flags,
 			   rocker_cmd_prep_cb_t prepare, void *prepare_priv,
 			   rocker_cmd_proc_cb_t process, void *process_priv)
 {
@@ -1596,7 +1589,7 @@ static int rocker_cmd_exec(struct rocker_port *rocker_port,
 	unsigned long lock_flags;
 	int err;
 
-	wait = rocker_wait_create(rocker_port, trans_ph, flags);
+	wait = rocker_wait_create(rocker_port, trans, flags);
 	if (!wait)
 		return -ENOMEM;
 	wait->nowait = nowait;
@@ -1618,7 +1611,7 @@ static int rocker_cmd_exec(struct rocker_port *rocker_port,
 
 	rocker_desc_cookie_ptr_set(desc_info, wait);
 
-	if (trans_ph != SWITCHDEV_TRANS_PREPARE)
+	if (!switchdev_trans_ph_prepare(trans))
 		rocker_desc_head_set(rocker, &rocker->cmd_ring, desc_info);
 
 	spin_unlock_irqrestore(&rocker->cmd_ring_lock, lock_flags);
@@ -1626,7 +1619,7 @@ static int rocker_cmd_exec(struct rocker_port *rocker_port,
 	if (nowait)
 		return 0;
 
-	if (trans_ph != SWITCHDEV_TRANS_PREPARE)
+	if (!switchdev_trans_ph_prepare(trans))
 		if (!rocker_wait_event_timeout(wait, HZ / 10))
 			return -EIO;
 
@@ -1639,7 +1632,7 @@ static int rocker_cmd_exec(struct rocker_port *rocker_port,
 
 	rocker_desc_gen_clear(desc_info);
 out:
-	rocker_wait_destroy(trans_ph, wait);
+	rocker_wait_destroy(trans, wait);
 	return err;
 }
 
@@ -1878,7 +1871,7 @@ rocker_cmd_set_port_learning_prep(const struct rocker_port *rocker_port,
 static int rocker_cmd_get_port_settings_ethtool(struct rocker_port *rocker_port,
 						struct ethtool_cmd *ecmd)
 {
-	return rocker_cmd_exec(rocker_port, SWITCHDEV_TRANS_NONE, 0,
+	return rocker_cmd_exec(rocker_port, NULL, 0,
 			       rocker_cmd_get_port_settings_prep, NULL,
 			       rocker_cmd_get_port_settings_ethtool_proc,
 			       ecmd);
@@ -1887,7 +1880,7 @@ static int rocker_cmd_get_port_settings_ethtool(struct rocker_port *rocker_port,
 static int rocker_cmd_get_port_settings_macaddr(struct rocker_port *rocker_port,
 						unsigned char *macaddr)
 {
-	return rocker_cmd_exec(rocker_port, SWITCHDEV_TRANS_NONE, 0,
+	return rocker_cmd_exec(rocker_port, NULL, 0,
 			       rocker_cmd_get_port_settings_prep, NULL,
 			       rocker_cmd_get_port_settings_macaddr_proc,
 			       macaddr);
@@ -1896,7 +1889,7 @@ static int rocker_cmd_get_port_settings_macaddr(struct rocker_port *rocker_port,
 static int rocker_cmd_set_port_settings_ethtool(struct rocker_port *rocker_port,
 						struct ethtool_cmd *ecmd)
 {
-	return rocker_cmd_exec(rocker_port, SWITCHDEV_TRANS_NONE, 0,
+	return rocker_cmd_exec(rocker_port, NULL, 0,
 			       rocker_cmd_set_port_settings_ethtool_prep,
 			       ecmd, NULL, NULL);
 }
@@ -1904,7 +1897,7 @@ static int rocker_cmd_set_port_settings_ethtool(struct rocker_port *rocker_port,
 static int rocker_cmd_set_port_settings_macaddr(struct rocker_port *rocker_port,
 						unsigned char *macaddr)
 {
-	return rocker_cmd_exec(rocker_port, SWITCHDEV_TRANS_NONE, 0,
+	return rocker_cmd_exec(rocker_port, NULL, 0,
 			       rocker_cmd_set_port_settings_macaddr_prep,
 			       macaddr, NULL, NULL);
 }
@@ -1912,15 +1905,15 @@ static int rocker_cmd_set_port_settings_macaddr(struct rocker_port *rocker_port,
 static int rocker_cmd_set_port_settings_mtu(struct rocker_port *rocker_port,
 					    int mtu)
 {
-	return rocker_cmd_exec(rocker_port, SWITCHDEV_TRANS_NONE, 0,
+	return rocker_cmd_exec(rocker_port, NULL, 0,
 			       rocker_cmd_set_port_settings_mtu_prep,
 			       &mtu, NULL, NULL);
 }
 
 static int rocker_port_set_learning(struct rocker_port *rocker_port,
-				    enum switchdev_trans_ph trans_ph)
+				    struct switchdev_trans *trans)
 {
-	return rocker_cmd_exec(rocker_port, trans_ph, 0,
+	return rocker_cmd_exec(rocker_port, trans, 0,
 			       rocker_cmd_set_port_learning_prep,
 			       NULL, NULL, NULL);
 }
@@ -2436,7 +2429,7 @@ rocker_flow_tbl_find(const struct rocker *rocker,
 }
 
 static int rocker_flow_tbl_add(struct rocker_port *rocker_port,
-			       enum switchdev_trans_ph trans_ph, int flags,
+			       struct switchdev_trans *trans, int flags,
 			       struct rocker_flow_tbl_entry *match)
 {
 	struct rocker *rocker = rocker_port->rocker;
@@ -2452,9 +2445,9 @@ static int rocker_flow_tbl_add(struct rocker_port *rocker_port,
 
 	if (found) {
 		match->cookie = found->cookie;
-		if (trans_ph != SWITCHDEV_TRANS_PREPARE)
+		if (!switchdev_trans_ph_prepare(trans))
 			hash_del(&found->entry);
-		rocker_port_kfree(trans_ph, found);
+		rocker_port_kfree(trans, found);
 		found = match;
 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_MOD;
 	} else {
@@ -2463,17 +2456,17 @@ static int rocker_flow_tbl_add(struct rocker_port *rocker_port,
 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_ADD;
 	}
 
-	if (trans_ph != SWITCHDEV_TRANS_PREPARE)
+	if (!switchdev_trans_ph_prepare(trans))
 		hash_add(rocker->flow_tbl, &found->entry, found->key_crc32);
 
 	spin_unlock_irqrestore(&rocker->flow_tbl_lock, lock_flags);
 
-	return rocker_cmd_exec(rocker_port, trans_ph, flags,
+	return rocker_cmd_exec(rocker_port, trans, flags,
 			       rocker_cmd_flow_tbl_add, found, NULL, NULL);
 }
 
 static int rocker_flow_tbl_del(struct rocker_port *rocker_port,
-			       enum switchdev_trans_ph trans_ph, int flags,
+			       struct switchdev_trans *trans, int flags,
 			       struct rocker_flow_tbl_entry *match)
 {
 	struct rocker *rocker = rocker_port->rocker;
@@ -2489,43 +2482,43 @@ static int rocker_flow_tbl_del(struct rocker_port *rocker_port,
 	found = rocker_flow_tbl_find(rocker, match);
 
 	if (found) {
-		if (trans_ph != SWITCHDEV_TRANS_PREPARE)
+		if (!switchdev_trans_ph_prepare(trans))
 			hash_del(&found->entry);
 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_FLOW_DEL;
 	}
 
 	spin_unlock_irqrestore(&rocker->flow_tbl_lock, lock_flags);
 
-	rocker_port_kfree(trans_ph, match);
+	rocker_port_kfree(trans, match);
 
 	if (found) {
-		err = rocker_cmd_exec(rocker_port, trans_ph, flags,
+		err = rocker_cmd_exec(rocker_port, trans, flags,
 				      rocker_cmd_flow_tbl_del,
 				      found, NULL, NULL);
-		rocker_port_kfree(trans_ph, found);
+		rocker_port_kfree(trans, found);
 	}
 
 	return err;
 }
 
 static int rocker_flow_tbl_do(struct rocker_port *rocker_port,
-			      enum switchdev_trans_ph trans_ph, int flags,
+			      struct switchdev_trans *trans, int flags,
 			      struct rocker_flow_tbl_entry *entry)
 {
 	if (flags & ROCKER_OP_FLAG_REMOVE)
-		return rocker_flow_tbl_del(rocker_port, trans_ph, flags, entry);
+		return rocker_flow_tbl_del(rocker_port, trans, flags, entry);
 	else
-		return rocker_flow_tbl_add(rocker_port, trans_ph, flags, entry);
+		return rocker_flow_tbl_add(rocker_port, trans, flags, entry);
 }
 
 static int rocker_flow_tbl_ig_port(struct rocker_port *rocker_port,
-				   enum switchdev_trans_ph trans_ph, int flags,
+				   struct switchdev_trans *trans, int flags,
 				   u32 in_pport, u32 in_pport_mask,
 				   enum rocker_of_dpa_table_id goto_tbl)
 {
 	struct rocker_flow_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2535,11 +2528,11 @@ static int rocker_flow_tbl_ig_port(struct rocker_port *rocker_port,
 	entry->key.ig_port.in_pport_mask = in_pport_mask;
 	entry->key.ig_port.goto_tbl = goto_tbl;
 
-	return rocker_flow_tbl_do(rocker_port, trans_ph, flags, entry);
+	return rocker_flow_tbl_do(rocker_port, trans, flags, entry);
 }
 
 static int rocker_flow_tbl_vlan(struct rocker_port *rocker_port,
-				enum switchdev_trans_ph trans_ph, int flags,
+				struct switchdev_trans *trans, int flags,
 				u32 in_pport, __be16 vlan_id,
 				__be16 vlan_id_mask,
 				enum rocker_of_dpa_table_id goto_tbl,
@@ -2547,7 +2540,7 @@ static int rocker_flow_tbl_vlan(struct rocker_port *rocker_port,
 {
 	struct rocker_flow_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2561,11 +2554,11 @@ static int rocker_flow_tbl_vlan(struct rocker_port *rocker_port,
 	entry->key.vlan.untagged = untagged;
 	entry->key.vlan.new_vlan_id = new_vlan_id;
 
-	return rocker_flow_tbl_do(rocker_port, trans_ph, flags, entry);
+	return rocker_flow_tbl_do(rocker_port, trans, flags, entry);
 }
 
 static int rocker_flow_tbl_term_mac(struct rocker_port *rocker_port,
-				    enum switchdev_trans_ph trans_ph,
+				    struct switchdev_trans *trans,
 				    u32 in_pport, u32 in_pport_mask,
 				    __be16 eth_type, const u8 *eth_dst,
 				    const u8 *eth_dst_mask, __be16 vlan_id,
@@ -2574,7 +2567,7 @@ static int rocker_flow_tbl_term_mac(struct rocker_port *rocker_port,
 {
 	struct rocker_flow_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2598,11 +2591,11 @@ static int rocker_flow_tbl_term_mac(struct rocker_port *rocker_port,
 	entry->key.term_mac.vlan_id_mask = vlan_id_mask;
 	entry->key.term_mac.copy_to_cpu = copy_to_cpu;
 
-	return rocker_flow_tbl_do(rocker_port, trans_ph, flags, entry);
+	return rocker_flow_tbl_do(rocker_port, trans, flags, entry);
 }
 
 static int rocker_flow_tbl_bridge(struct rocker_port *rocker_port,
-				  enum switchdev_trans_ph trans_ph, int flags,
+				  struct switchdev_trans *trans, int flags,
 				  const u8 *eth_dst, const u8 *eth_dst_mask,
 				  __be16 vlan_id, u32 tunnel_id,
 				  enum rocker_of_dpa_table_id goto_tbl,
@@ -2614,7 +2607,7 @@ static int rocker_flow_tbl_bridge(struct rocker_port *rocker_port,
 	bool dflt = !eth_dst || (eth_dst && eth_dst_mask);
 	bool wild = false;
 
-	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2652,11 +2645,11 @@ static int rocker_flow_tbl_bridge(struct rocker_port *rocker_port,
 	entry->key.bridge.group_id = group_id;
 	entry->key.bridge.copy_to_cpu = copy_to_cpu;
 
-	return rocker_flow_tbl_do(rocker_port, trans_ph, flags, entry);
+	return rocker_flow_tbl_do(rocker_port, trans, flags, entry);
 }
 
 static int rocker_flow_tbl_ucast4_routing(struct rocker_port *rocker_port,
-					  enum switchdev_trans_ph trans_ph,
+					  struct switchdev_trans *trans,
 					  __be16 eth_type, __be32 dst,
 					  __be32 dst_mask, u32 priority,
 					  enum rocker_of_dpa_table_id goto_tbl,
@@ -2664,7 +2657,7 @@ static int rocker_flow_tbl_ucast4_routing(struct rocker_port *rocker_port,
 {
 	struct rocker_flow_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2678,11 +2671,11 @@ static int rocker_flow_tbl_ucast4_routing(struct rocker_port *rocker_port,
 	entry->key_len = offsetof(struct rocker_flow_tbl_key,
 				  ucast_routing.group_id);
 
-	return rocker_flow_tbl_do(rocker_port, trans_ph, flags, entry);
+	return rocker_flow_tbl_do(rocker_port, trans, flags, entry);
 }
 
 static int rocker_flow_tbl_acl(struct rocker_port *rocker_port,
-			       enum switchdev_trans_ph trans_ph, int flags,
+			       struct switchdev_trans *trans, int flags,
 			       u32 in_pport, u32 in_pport_mask,
 			       const u8 *eth_src, const u8 *eth_src_mask,
 			       const u8 *eth_dst, const u8 *eth_dst_mask,
@@ -2694,7 +2687,7 @@ static int rocker_flow_tbl_acl(struct rocker_port *rocker_port,
 	u32 priority;
 	struct rocker_flow_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2729,7 +2722,7 @@ static int rocker_flow_tbl_acl(struct rocker_port *rocker_port,
 	entry->key.acl.ip_tos_mask = ip_tos_mask;
 	entry->key.acl.group_id = group_id;
 
-	return rocker_flow_tbl_do(rocker_port, trans_ph, flags, entry);
+	return rocker_flow_tbl_do(rocker_port, trans, flags, entry);
 }
 
 static struct rocker_group_tbl_entry *
@@ -2747,22 +2740,22 @@ rocker_group_tbl_find(const struct rocker *rocker,
 	return NULL;
 }
 
-static void rocker_group_tbl_entry_free(enum switchdev_trans_ph trans_ph,
+static void rocker_group_tbl_entry_free(struct switchdev_trans *trans,
 					struct rocker_group_tbl_entry *entry)
 {
 	switch (ROCKER_GROUP_TYPE_GET(entry->group_id)) {
 	case ROCKER_OF_DPA_GROUP_TYPE_L2_FLOOD:
 	case ROCKER_OF_DPA_GROUP_TYPE_L2_MCAST:
-		rocker_port_kfree(trans_ph, entry->group_ids);
+		rocker_port_kfree(trans, entry->group_ids);
 		break;
 	default:
 		break;
 	}
-	rocker_port_kfree(trans_ph, entry);
+	rocker_port_kfree(trans, entry);
 }
 
 static int rocker_group_tbl_add(struct rocker_port *rocker_port,
-				enum switchdev_trans_ph trans_ph, int flags,
+				struct switchdev_trans *trans, int flags,
 				struct rocker_group_tbl_entry *match)
 {
 	struct rocker *rocker = rocker_port->rocker;
@@ -2774,9 +2767,9 @@ static int rocker_group_tbl_add(struct rocker_port *rocker_port,
 	found = rocker_group_tbl_find(rocker, match);
 
 	if (found) {
-		if (trans_ph != SWITCHDEV_TRANS_PREPARE)
+		if (!switchdev_trans_ph_prepare(trans))
 			hash_del(&found->entry);
-		rocker_group_tbl_entry_free(trans_ph, found);
+		rocker_group_tbl_entry_free(trans, found);
 		found = match;
 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_MOD;
 	} else {
@@ -2784,17 +2777,17 @@ static int rocker_group_tbl_add(struct rocker_port *rocker_port,
 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_ADD;
 	}
 
-	if (trans_ph != SWITCHDEV_TRANS_PREPARE)
+	if (!switchdev_trans_ph_prepare(trans))
 		hash_add(rocker->group_tbl, &found->entry, found->group_id);
 
 	spin_unlock_irqrestore(&rocker->group_tbl_lock, lock_flags);
 
-	return rocker_cmd_exec(rocker_port, trans_ph, flags,
+	return rocker_cmd_exec(rocker_port, trans, flags,
 			       rocker_cmd_group_tbl_add, found, NULL, NULL);
 }
 
 static int rocker_group_tbl_del(struct rocker_port *rocker_port,
-				enum switchdev_trans_ph trans_ph, int flags,
+				struct switchdev_trans *trans, int flags,
 				struct rocker_group_tbl_entry *match)
 {
 	struct rocker *rocker = rocker_port->rocker;
@@ -2807,95 +2800,95 @@ static int rocker_group_tbl_del(struct rocker_port *rocker_port,
 	found = rocker_group_tbl_find(rocker, match);
 
 	if (found) {
-		if (trans_ph != SWITCHDEV_TRANS_PREPARE)
+		if (!switchdev_trans_ph_prepare(trans))
 			hash_del(&found->entry);
 		found->cmd = ROCKER_TLV_CMD_TYPE_OF_DPA_GROUP_DEL;
 	}
 
 	spin_unlock_irqrestore(&rocker->group_tbl_lock, lock_flags);
 
-	rocker_group_tbl_entry_free(trans_ph, match);
+	rocker_group_tbl_entry_free(trans, match);
 
 	if (found) {
-		err = rocker_cmd_exec(rocker_port, trans_ph, flags,
+		err = rocker_cmd_exec(rocker_port, trans, flags,
 				      rocker_cmd_group_tbl_del,
 				      found, NULL, NULL);
-		rocker_group_tbl_entry_free(trans_ph, found);
+		rocker_group_tbl_entry_free(trans, found);
 	}
 
 	return err;
 }
 
 static int rocker_group_tbl_do(struct rocker_port *rocker_port,
-			       enum switchdev_trans_ph trans_ph, int flags,
+			       struct switchdev_trans *trans, int flags,
 			       struct rocker_group_tbl_entry *entry)
 {
 	if (flags & ROCKER_OP_FLAG_REMOVE)
-		return rocker_group_tbl_del(rocker_port, trans_ph, flags, entry);
+		return rocker_group_tbl_del(rocker_port, trans, flags, entry);
 	else
-		return rocker_group_tbl_add(rocker_port, trans_ph, flags, entry);
+		return rocker_group_tbl_add(rocker_port, trans, flags, entry);
 }
 
 static int rocker_group_l2_interface(struct rocker_port *rocker_port,
-				     enum switchdev_trans_ph trans_ph, int flags,
+				     struct switchdev_trans *trans, int flags,
 				     __be16 vlan_id, u32 out_pport,
 				     int pop_vlan)
 {
 	struct rocker_group_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
 	entry->group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, out_pport);
 	entry->l2_interface.pop_vlan = pop_vlan;
 
-	return rocker_group_tbl_do(rocker_port, trans_ph, flags, entry);
+	return rocker_group_tbl_do(rocker_port, trans, flags, entry);
 }
 
 static int rocker_group_l2_fan_out(struct rocker_port *rocker_port,
-				   enum switchdev_trans_ph trans_ph,
+				   struct switchdev_trans *trans,
 				   int flags, u8 group_count,
 				   const u32 *group_ids, u32 group_id)
 {
 	struct rocker_group_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
 	entry->group_id = group_id;
 	entry->group_count = group_count;
 
-	entry->group_ids = rocker_port_kcalloc(rocker_port, trans_ph, flags,
+	entry->group_ids = rocker_port_kcalloc(rocker_port, trans, flags,
 					       group_count, sizeof(u32));
 	if (!entry->group_ids) {
-		rocker_port_kfree(trans_ph, entry);
+		rocker_port_kfree(trans, entry);
 		return -ENOMEM;
 	}
 	memcpy(entry->group_ids, group_ids, group_count * sizeof(u32));
 
-	return rocker_group_tbl_do(rocker_port, trans_ph, flags, entry);
+	return rocker_group_tbl_do(rocker_port, trans, flags, entry);
 }
 
 static int rocker_group_l2_flood(struct rocker_port *rocker_port,
-				 enum switchdev_trans_ph trans_ph, int flags,
+				 struct switchdev_trans *trans, int flags,
 				 __be16 vlan_id, u8 group_count,
 				 const u32 *group_ids, u32 group_id)
 {
-	return rocker_group_l2_fan_out(rocker_port, trans_ph, flags,
+	return rocker_group_l2_fan_out(rocker_port, trans, flags,
 				       group_count, group_ids,
 				       group_id);
 }
 
 static int rocker_group_l3_unicast(struct rocker_port *rocker_port,
-				   enum switchdev_trans_ph trans_ph, int flags,
+				   struct switchdev_trans *trans, int flags,
 				   u32 index, const u8 *src_mac, const u8 *dst_mac,
 				   __be16 vlan_id, bool ttl_check, u32 pport)
 {
 	struct rocker_group_tbl_entry *entry;
 
-	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2908,7 +2901,7 @@ static int rocker_group_l3_unicast(struct rocker_port *rocker_port,
 	entry->l3_unicast.ttl_check = ttl_check;
 	entry->l3_unicast.group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, pport);
 
-	return rocker_group_tbl_do(rocker_port, trans_ph, flags, entry);
+	return rocker_group_tbl_do(rocker_port, trans, flags, entry);
 }
 
 static struct rocker_neigh_tbl_entry *
@@ -2925,43 +2918,43 @@ rocker_neigh_tbl_find(const struct rocker *rocker, __be32 ip_addr)
 }
 
 static void _rocker_neigh_add(struct rocker *rocker,
-			      enum switchdev_trans_ph trans_ph,
+			      struct switchdev_trans *trans,
 			      struct rocker_neigh_tbl_entry *entry)
 {
-	if (trans_ph != SWITCHDEV_TRANS_COMMIT)
+	if (!switchdev_trans_ph_commit(trans))
 		entry->index = rocker->neigh_tbl_next_index++;
-	if (trans_ph == SWITCHDEV_TRANS_PREPARE)
+	if (switchdev_trans_ph_prepare(trans))
 		return;
 	entry->ref_count++;
 	hash_add(rocker->neigh_tbl, &entry->entry,
 		 be32_to_cpu(entry->ip_addr));
 }
 
-static void _rocker_neigh_del(enum switchdev_trans_ph trans_ph,
+static void _rocker_neigh_del(struct switchdev_trans *trans,
 			      struct rocker_neigh_tbl_entry *entry)
 {
-	if (trans_ph == SWITCHDEV_TRANS_PREPARE)
+	if (switchdev_trans_ph_prepare(trans))
 		return;
 	if (--entry->ref_count == 0) {
 		hash_del(&entry->entry);
-		rocker_port_kfree(trans_ph, entry);
+		rocker_port_kfree(trans, entry);
 	}
 }
 
 static void _rocker_neigh_update(struct rocker_neigh_tbl_entry *entry,
-				 enum switchdev_trans_ph trans_ph,
+				 struct switchdev_trans *trans,
 				 const u8 *eth_dst, bool ttl_check)
 {
 	if (eth_dst) {
 		ether_addr_copy(entry->eth_dst, eth_dst);
 		entry->ttl_check = ttl_check;
-	} else if (trans_ph != SWITCHDEV_TRANS_PREPARE) {
+	} else if (!switchdev_trans_ph_prepare(trans)) {
 		entry->ref_count++;
 	}
 }
 
 static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
-				  enum switchdev_trans_ph trans_ph,
+				  struct switchdev_trans *trans,
 				  int flags, __be32 ip_addr, const u8 *eth_dst)
 {
 	struct rocker *rocker = rocker_port->rocker;
@@ -2978,7 +2971,7 @@ static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
 	bool removing;
 	int err = 0;
 
-	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -2995,12 +2988,12 @@ static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
 		entry->dev = rocker_port->dev;
 		ether_addr_copy(entry->eth_dst, eth_dst);
 		entry->ttl_check = true;
-		_rocker_neigh_add(rocker, trans_ph, entry);
+		_rocker_neigh_add(rocker, trans, entry);
 	} else if (removing) {
 		memcpy(entry, found, sizeof(*entry));
-		_rocker_neigh_del(trans_ph, found);
+		_rocker_neigh_del(trans, found);
 	} else if (updating) {
-		_rocker_neigh_update(found, trans_ph, eth_dst, true);
+		_rocker_neigh_update(found, trans, eth_dst, true);
 		memcpy(entry, found, sizeof(*entry));
 	} else {
 		err = -ENOENT;
@@ -3017,7 +3010,7 @@ static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
 	 * other routes' nexthops.
 	 */
 
-	err = rocker_group_l3_unicast(rocker_port, trans_ph, flags,
+	err = rocker_group_l3_unicast(rocker_port, trans, flags,
 				      entry->index,
 				      rocker_port->dev->dev_addr,
 				      entry->eth_dst,
@@ -3033,7 +3026,7 @@ static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
 
 	if (adding || removing) {
 		group_id = ROCKER_GROUP_L3_UNICAST(entry->index);
-		err = rocker_flow_tbl_ucast4_routing(rocker_port, trans_ph,
+		err = rocker_flow_tbl_ucast4_routing(rocker_port, trans,
 						     eth_type, ip_addr,
 						     inet_make_mask(32),
 						     priority, goto_tbl,
@@ -3047,13 +3040,14 @@ static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
 
 err_out:
 	if (!adding)
-		rocker_port_kfree(trans_ph, entry);
+		rocker_port_kfree(trans, entry);
 
 	return err;
 }
 
 static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port,
-				    enum switchdev_trans_ph trans_ph, __be32 ip_addr)
+				    struct switchdev_trans *trans,
+				    __be32 ip_addr)
 {
 	struct net_device *dev = rocker_port->dev;
 	struct neighbour *n = __ipv4_neigh_lookup(dev, (__force u32)ip_addr);
@@ -3071,7 +3065,7 @@ static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port,
 	 */
 
 	if (n->nud_state & NUD_VALID)
-		err = rocker_port_ipv4_neigh(rocker_port, trans_ph, 0,
+		err = rocker_port_ipv4_neigh(rocker_port, trans, 0,
 					     ip_addr, n->ha);
 	else
 		neigh_event_send(n, NULL);
@@ -3081,7 +3075,7 @@ static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_ipv4_nh(struct rocker_port *rocker_port,
-			       enum switchdev_trans_ph trans_ph, int flags,
+			       struct switchdev_trans *trans, int flags,
 			       __be32 ip_addr, u32 *index)
 {
 	struct rocker *rocker = rocker_port->rocker;
@@ -3094,7 +3088,7 @@ static int rocker_port_ipv4_nh(struct rocker_port *rocker_port,
 	bool resolved = true;
 	int err = 0;
 
-	entry = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*entry));
+	entry = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*entry));
 	if (!entry)
 		return -ENOMEM;
 
@@ -3111,13 +3105,13 @@ static int rocker_port_ipv4_nh(struct rocker_port *rocker_port,
 	if (adding) {
 		entry->ip_addr = ip_addr;
 		entry->dev = rocker_port->dev;
-		_rocker_neigh_add(rocker, trans_ph, entry);
+		_rocker_neigh_add(rocker, trans, entry);
 		*index = entry->index;
 		resolved = false;
 	} else if (removing) {
-		_rocker_neigh_del(trans_ph, found);
+		_rocker_neigh_del(trans, found);
 	} else if (updating) {
-		_rocker_neigh_update(found, trans_ph, NULL, false);
+		_rocker_neigh_update(found, trans, NULL, false);
 		resolved = !is_zero_ether_addr(found->eth_dst);
 	} else {
 		err = -ENOENT;
@@ -3126,7 +3120,7 @@ static int rocker_port_ipv4_nh(struct rocker_port *rocker_port,
 	spin_unlock_irqrestore(&rocker->neigh_tbl_lock, lock_flags);
 
 	if (!adding)
-		rocker_port_kfree(trans_ph, entry);
+		rocker_port_kfree(trans, entry);
 
 	if (err)
 		return err;
@@ -3134,13 +3128,13 @@ static int rocker_port_ipv4_nh(struct rocker_port *rocker_port,
 	/* Resolved means neigh ip_addr is resolved to neigh mac. */
 
 	if (!resolved)
-		err = rocker_port_ipv4_resolve(rocker_port, trans_ph, ip_addr);
+		err = rocker_port_ipv4_resolve(rocker_port, trans, ip_addr);
 
 	return err;
 }
 
 static int rocker_port_vlan_flood_group(struct rocker_port *rocker_port,
-					enum switchdev_trans_ph trans_ph,
+					struct switchdev_trans *trans,
 					int flags, __be16 vlan_id)
 {
 	struct rocker_port *p;
@@ -3151,7 +3145,7 @@ static int rocker_port_vlan_flood_group(struct rocker_port *rocker_port,
 	int err = 0;
 	int i;
 
-	group_ids = rocker_port_kcalloc(rocker_port, trans_ph, flags,
+	group_ids = rocker_port_kcalloc(rocker_port, trans, flags,
 					rocker->port_count, sizeof(u32));
 	if (!group_ids)
 		return -ENOMEM;
@@ -3177,19 +3171,19 @@ static int rocker_port_vlan_flood_group(struct rocker_port *rocker_port,
 	if (group_count == 0)
 		goto no_ports_in_vlan;
 
-	err = rocker_group_l2_flood(rocker_port, trans_ph, flags, vlan_id,
+	err = rocker_group_l2_flood(rocker_port, trans, flags, vlan_id,
 				    group_count, group_ids, group_id);
 	if (err)
 		netdev_err(rocker_port->dev,
 			   "Error (%d) port VLAN l2 flood group\n", err);
 
 no_ports_in_vlan:
-	rocker_port_kfree(trans_ph, group_ids);
+	rocker_port_kfree(trans, group_ids);
 	return err;
 }
 
 static int rocker_port_vlan_l2_groups(struct rocker_port *rocker_port,
-				      enum switchdev_trans_ph trans_ph, int flags,
+				      struct switchdev_trans *trans, int flags,
 				      __be16 vlan_id, bool pop_vlan)
 {
 	const struct rocker *rocker = rocker_port->rocker;
@@ -3207,7 +3201,7 @@ static int rocker_port_vlan_l2_groups(struct rocker_port *rocker_port,
 	if (rocker_port->stp_state == BR_STATE_LEARNING ||
 	    rocker_port->stp_state == BR_STATE_FORWARDING) {
 		out_pport = rocker_port->pport;
-		err = rocker_group_l2_interface(rocker_port, trans_ph, flags,
+		err = rocker_group_l2_interface(rocker_port, trans, flags,
 						vlan_id, out_pport, pop_vlan);
 		if (err) {
 			netdev_err(rocker_port->dev,
@@ -3232,7 +3226,7 @@ static int rocker_port_vlan_l2_groups(struct rocker_port *rocker_port,
 		return 0;
 
 	out_pport = 0;
-	err = rocker_group_l2_interface(rocker_port, trans_ph, flags,
+	err = rocker_group_l2_interface(rocker_port, trans, flags,
 					vlan_id, out_pport, pop_vlan);
 	if (err) {
 		netdev_err(rocker_port->dev,
@@ -3295,7 +3289,7 @@ static struct rocker_ctrl {
 };
 
 static int rocker_port_ctrl_vlan_acl(struct rocker_port *rocker_port,
-				     enum switchdev_trans_ph trans_ph, int flags,
+				     struct switchdev_trans *trans, int flags,
 				     const struct rocker_ctrl *ctrl, __be16 vlan_id)
 {
 	u32 in_pport = rocker_port->pport;
@@ -3311,7 +3305,7 @@ static int rocker_port_ctrl_vlan_acl(struct rocker_port *rocker_port,
 	u32 group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, out_pport);
 	int err;
 
-	err = rocker_flow_tbl_acl(rocker_port, trans_ph, flags,
+	err = rocker_flow_tbl_acl(rocker_port, trans, flags,
 				  in_pport, in_pport_mask,
 				  eth_src, eth_src_mask,
 				  ctrl->eth_dst, ctrl->eth_dst_mask,
@@ -3328,7 +3322,8 @@ static int rocker_port_ctrl_vlan_acl(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_ctrl_vlan_bridge(struct rocker_port *rocker_port,
-					enum switchdev_trans_ph trans_ph, int flags,
+					struct switchdev_trans *trans,
+					int flags,
 					const struct rocker_ctrl *ctrl,
 					__be16 vlan_id)
 {
@@ -3341,7 +3336,7 @@ static int rocker_port_ctrl_vlan_bridge(struct rocker_port *rocker_port,
 	if (!rocker_port_is_bridged(rocker_port))
 		return 0;
 
-	err = rocker_flow_tbl_bridge(rocker_port, trans_ph, flags,
+	err = rocker_flow_tbl_bridge(rocker_port, trans, flags,
 				     ctrl->eth_dst, ctrl->eth_dst_mask,
 				     vlan_id, tunnel_id,
 				     goto_tbl, group_id, ctrl->copy_to_cpu);
@@ -3353,7 +3348,7 @@ static int rocker_port_ctrl_vlan_bridge(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_ctrl_vlan_term(struct rocker_port *rocker_port,
-				      enum switchdev_trans_ph trans_ph, int flags,
+				      struct switchdev_trans *trans, int flags,
 				      const struct rocker_ctrl *ctrl, __be16 vlan_id)
 {
 	u32 in_pport_mask = 0xffffffff;
@@ -3363,7 +3358,7 @@ static int rocker_port_ctrl_vlan_term(struct rocker_port *rocker_port,
 	if (ntohs(vlan_id) == 0)
 		vlan_id = rocker_port->internal_vlan_id;
 
-	err = rocker_flow_tbl_term_mac(rocker_port, trans_ph,
+	err = rocker_flow_tbl_term_mac(rocker_port, trans,
 				       rocker_port->pport, in_pport_mask,
 				       ctrl->eth_type, ctrl->eth_dst,
 				       ctrl->eth_dst_mask, vlan_id,
@@ -3377,25 +3372,25 @@ static int rocker_port_ctrl_vlan_term(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_ctrl_vlan(struct rocker_port *rocker_port,
-				 enum switchdev_trans_ph trans_ph, int flags,
+				 struct switchdev_trans *trans, int flags,
 				 const struct rocker_ctrl *ctrl, __be16 vlan_id)
 {
 	if (ctrl->acl)
-		return rocker_port_ctrl_vlan_acl(rocker_port, trans_ph, flags,
+		return rocker_port_ctrl_vlan_acl(rocker_port, trans, flags,
 						 ctrl, vlan_id);
 	if (ctrl->bridge)
-		return rocker_port_ctrl_vlan_bridge(rocker_port, trans_ph, flags,
+		return rocker_port_ctrl_vlan_bridge(rocker_port, trans, flags,
 						    ctrl, vlan_id);
 
 	if (ctrl->term)
-		return rocker_port_ctrl_vlan_term(rocker_port, trans_ph, flags,
+		return rocker_port_ctrl_vlan_term(rocker_port, trans, flags,
 						  ctrl, vlan_id);
 
 	return -EOPNOTSUPP;
 }
 
 static int rocker_port_ctrl_vlan_add(struct rocker_port *rocker_port,
-				     enum switchdev_trans_ph trans_ph, int flags,
+				     struct switchdev_trans *trans, int flags,
 				     __be16 vlan_id)
 {
 	int err = 0;
@@ -3403,7 +3398,7 @@ static int rocker_port_ctrl_vlan_add(struct rocker_port *rocker_port,
 
 	for (i = 0; i < ROCKER_CTRL_MAX; i++) {
 		if (rocker_port->ctrls[i]) {
-			err = rocker_port_ctrl_vlan(rocker_port, trans_ph, flags,
+			err = rocker_port_ctrl_vlan(rocker_port, trans, flags,
 						    &rocker_ctrls[i], vlan_id);
 			if (err)
 				return err;
@@ -3414,7 +3409,7 @@ static int rocker_port_ctrl_vlan_add(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_ctrl(struct rocker_port *rocker_port,
-			    enum switchdev_trans_ph trans_ph, int flags,
+			    struct switchdev_trans *trans, int flags,
 			    const struct rocker_ctrl *ctrl)
 {
 	u16 vid;
@@ -3423,7 +3418,7 @@ static int rocker_port_ctrl(struct rocker_port *rocker_port,
 	for (vid = 1; vid < VLAN_N_VID; vid++) {
 		if (!test_bit(vid, rocker_port->vlan_bitmap))
 			continue;
-		err = rocker_port_ctrl_vlan(rocker_port, trans_ph, flags,
+		err = rocker_port_ctrl_vlan(rocker_port, trans, flags,
 					    ctrl, htons(vid));
 		if (err)
 			break;
@@ -3433,7 +3428,7 @@ static int rocker_port_ctrl(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_vlan(struct rocker_port *rocker_port,
-			    enum switchdev_trans_ph trans_ph, int flags, u16 vid)
+			    struct switchdev_trans *trans, int flags, u16 vid)
 {
 	enum rocker_of_dpa_table_id goto_tbl =
 		ROCKER_OF_DPA_TABLE_ID_TERMINATION_MAC;
@@ -3457,7 +3452,7 @@ static int rocker_port_vlan(struct rocker_port *rocker_port,
 	change_bit(ntohs(internal_vlan_id), rocker_port->vlan_bitmap);
 
 	if (adding) {
-		err = rocker_port_ctrl_vlan_add(rocker_port, trans_ph, flags,
+		err = rocker_port_ctrl_vlan_add(rocker_port, trans, flags,
 						internal_vlan_id);
 		if (err) {
 			netdev_err(rocker_port->dev,
@@ -3466,7 +3461,7 @@ static int rocker_port_vlan(struct rocker_port *rocker_port,
 		}
 	}
 
-	err = rocker_port_vlan_l2_groups(rocker_port, trans_ph, flags,
+	err = rocker_port_vlan_l2_groups(rocker_port, trans, flags,
 					 internal_vlan_id, untagged);
 	if (err) {
 		netdev_err(rocker_port->dev,
@@ -3474,7 +3469,7 @@ static int rocker_port_vlan(struct rocker_port *rocker_port,
 		goto err_out;
 	}
 
-	err = rocker_port_vlan_flood_group(rocker_port, trans_ph, flags,
+	err = rocker_port_vlan_flood_group(rocker_port, trans, flags,
 					   internal_vlan_id);
 	if (err) {
 		netdev_err(rocker_port->dev,
@@ -3482,7 +3477,7 @@ static int rocker_port_vlan(struct rocker_port *rocker_port,
 		goto err_out;
 	}
 
-	err = rocker_flow_tbl_vlan(rocker_port, trans_ph, flags,
+	err = rocker_flow_tbl_vlan(rocker_port, trans, flags,
 				   in_pport, vlan_id, vlan_id_mask,
 				   goto_tbl, untagged, internal_vlan_id);
 	if (err)
@@ -3490,14 +3485,14 @@ static int rocker_port_vlan(struct rocker_port *rocker_port,
 			   "Error (%d) port VLAN table\n", err);
 
 err_out:
-	if (trans_ph == SWITCHDEV_TRANS_PREPARE)
+	if (switchdev_trans_ph_prepare(trans))
 		change_bit(ntohs(internal_vlan_id), rocker_port->vlan_bitmap);
 
 	return err;
 }
 
 static int rocker_port_ig_tbl(struct rocker_port *rocker_port,
-			      enum switchdev_trans_ph trans_ph, int flags)
+			      struct switchdev_trans *trans, int flags)
 {
 	enum rocker_of_dpa_table_id goto_tbl;
 	u32 in_pport;
@@ -3512,7 +3507,7 @@ static int rocker_port_ig_tbl(struct rocker_port *rocker_port,
 	in_pport_mask = 0xffff0000;
 	goto_tbl = ROCKER_OF_DPA_TABLE_ID_VLAN;
 
-	err = rocker_flow_tbl_ig_port(rocker_port, trans_ph, flags,
+	err = rocker_flow_tbl_ig_port(rocker_port, trans, flags,
 				      in_pport, in_pport_mask,
 				      goto_tbl);
 	if (err)
@@ -3525,7 +3520,7 @@ static int rocker_port_ig_tbl(struct rocker_port *rocker_port,
 struct rocker_fdb_learn_work {
 	struct work_struct work;
 	struct rocker_port *rocker_port;
-	enum switchdev_trans_ph trans_ph;
+	struct switchdev_trans *trans;
 	int flags;
 	u8 addr[ETH_ALEN];
 	u16 vid;
@@ -3549,11 +3544,11 @@ static void rocker_port_fdb_learn_work(struct work_struct *work)
 		call_switchdev_notifiers(SWITCHDEV_FDB_ADD,
 					 lw->rocker_port->dev, &info.info);
 
-	rocker_port_kfree(lw->trans_ph, work);
+	rocker_port_kfree(lw->trans, work);
 }
 
 static int rocker_port_fdb_learn(struct rocker_port *rocker_port,
-				 enum switchdev_trans_ph trans_ph, int flags,
+				 struct switchdev_trans *trans, int flags,
 				 const u8 *addr, __be16 vlan_id)
 {
 	struct rocker_fdb_learn_work *lw;
@@ -3570,7 +3565,7 @@ static int rocker_port_fdb_learn(struct rocker_port *rocker_port,
 		group_id = ROCKER_GROUP_L2_INTERFACE(vlan_id, out_pport);
 
 	if (!(flags & ROCKER_OP_FLAG_REFRESH)) {
-		err = rocker_flow_tbl_bridge(rocker_port, trans_ph, flags, addr,
+		err = rocker_flow_tbl_bridge(rocker_port, trans, flags, addr,
 					     NULL, vlan_id, tunnel_id, goto_tbl,
 					     group_id, copy_to_cpu);
 		if (err)
@@ -3583,20 +3578,20 @@ static int rocker_port_fdb_learn(struct rocker_port *rocker_port,
 	if (!rocker_port_is_bridged(rocker_port))
 		return 0;
 
-	lw = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*lw));
+	lw = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*lw));
 	if (!lw)
 		return -ENOMEM;
 
 	INIT_WORK(&lw->work, rocker_port_fdb_learn_work);
 
 	lw->rocker_port = rocker_port;
-	lw->trans_ph = trans_ph;
+	lw->trans = trans;
 	lw->flags = flags;
 	ether_addr_copy(lw->addr, addr);
 	lw->vid = rocker_port_vlan_to_vid(rocker_port, vlan_id);
 
-	if (trans_ph == SWITCHDEV_TRANS_PREPARE)
-		rocker_port_kfree(trans_ph, lw);
+	if (switchdev_trans_ph_prepare(trans))
+		rocker_port_kfree(trans, lw);
 	else
 		schedule_work(&lw->work);
 
@@ -3617,7 +3612,7 @@ rocker_fdb_tbl_find(const struct rocker *rocker,
 }
 
 static int rocker_port_fdb(struct rocker_port *rocker_port,
-			   enum switchdev_trans_ph trans_ph,
+			   struct switchdev_trans *trans,
 			   const unsigned char *addr,
 			   __be16 vlan_id, int flags)
 {
@@ -3627,7 +3622,7 @@ static int rocker_port_fdb(struct rocker_port *rocker_port,
 	bool removing = (flags & ROCKER_OP_FLAG_REMOVE);
 	unsigned long lock_flags;
 
-	fdb = rocker_port_kzalloc(rocker_port, trans_ph, flags, sizeof(*fdb));
+	fdb = rocker_port_kzalloc(rocker_port, trans, flags, sizeof(*fdb));
 	if (!fdb)
 		return -ENOMEM;
 
@@ -3645,12 +3640,12 @@ static int rocker_port_fdb(struct rocker_port *rocker_port,
 	if (found) {
 		found->touched = jiffies;
 		if (removing) {
-			rocker_port_kfree(trans_ph, fdb);
-			if (trans_ph != SWITCHDEV_TRANS_PREPARE)
+			rocker_port_kfree(trans, fdb);
+			if (!switchdev_trans_ph_prepare(trans))
 				hash_del(&found->entry);
 		}
 	} else if (!removing) {
-		if (trans_ph != SWITCHDEV_TRANS_PREPARE)
+		if (!switchdev_trans_ph_prepare(trans))
 			hash_add(rocker->fdb_tbl, &fdb->entry,
 				 fdb->key_crc32);
 	}
@@ -3659,18 +3654,18 @@ static int rocker_port_fdb(struct rocker_port *rocker_port,
 
 	/* Check if adding and already exists, or removing and can't find */
 	if (!found != !removing) {
-		rocker_port_kfree(trans_ph, fdb);
+		rocker_port_kfree(trans, fdb);
 		if (!found && removing)
 			return 0;
 		/* Refreshing existing to update aging timers */
 		flags |= ROCKER_OP_FLAG_REFRESH;
 	}
 
-	return rocker_port_fdb_learn(rocker_port, trans_ph, flags, addr, vlan_id);
+	return rocker_port_fdb_learn(rocker_port, trans, flags, addr, vlan_id);
 }
 
 static int rocker_port_fdb_flush(struct rocker_port *rocker_port,
-				 enum switchdev_trans_ph trans_ph, int flags)
+				 struct switchdev_trans *trans, int flags)
 {
 	struct rocker *rocker = rocker_port->rocker;
 	struct rocker_fdb_tbl_entry *found;
@@ -3692,12 +3687,12 @@ static int rocker_port_fdb_flush(struct rocker_port *rocker_port,
 			continue;
 		if (!found->learned)
 			continue;
-		err = rocker_port_fdb_learn(rocker_port, trans_ph, flags,
+		err = rocker_port_fdb_learn(rocker_port, trans, flags,
 					    found->key.addr,
 					    found->key.vlan_id);
 		if (err)
 			goto err_out;
-		if (trans_ph != SWITCHDEV_TRANS_PREPARE)
+		if (!switchdev_trans_ph_prepare(trans))
 			hash_del(&found->entry);
 	}
 
@@ -3728,7 +3723,7 @@ static void rocker_fdb_cleanup(unsigned long data)
 		rocker_port = entry->key.rocker_port;
 		expires = entry->touched + rocker_port->ageing_time;
 		if (time_before_eq(expires, jiffies)) {
-			rocker_port_fdb_learn(rocker_port, SWITCHDEV_TRANS_NONE,
+			rocker_port_fdb_learn(rocker_port, NULL,
 					      flags, entry->key.addr,
 					      entry->key.vlan_id);
 			hash_del(&entry->entry);
@@ -3743,7 +3738,7 @@ static void rocker_fdb_cleanup(unsigned long data)
 }
 
 static int rocker_port_router_mac(struct rocker_port *rocker_port,
-				  enum switchdev_trans_ph trans_ph, int flags,
+				  struct switchdev_trans *trans, int flags,
 				  __be16 vlan_id)
 {
 	u32 in_pport_mask = 0xffffffff;
@@ -3757,7 +3752,7 @@ static int rocker_port_router_mac(struct rocker_port *rocker_port,
 		vlan_id = rocker_port->internal_vlan_id;
 
 	eth_type = htons(ETH_P_IP);
-	err = rocker_flow_tbl_term_mac(rocker_port, trans_ph,
+	err = rocker_flow_tbl_term_mac(rocker_port, trans,
 				       rocker_port->pport, in_pport_mask,
 				       eth_type, rocker_port->dev->dev_addr,
 				       dst_mac_mask, vlan_id, vlan_id_mask,
@@ -3766,7 +3761,7 @@ static int rocker_port_router_mac(struct rocker_port *rocker_port,
 		return err;
 
 	eth_type = htons(ETH_P_IPV6);
-	err = rocker_flow_tbl_term_mac(rocker_port, trans_ph,
+	err = rocker_flow_tbl_term_mac(rocker_port, trans,
 				       rocker_port->pport, in_pport_mask,
 				       eth_type, rocker_port->dev->dev_addr,
 				       dst_mac_mask, vlan_id, vlan_id_mask,
@@ -3776,7 +3771,7 @@ static int rocker_port_router_mac(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_fwding(struct rocker_port *rocker_port,
-			      enum switchdev_trans_ph trans_ph, int flags)
+			      struct switchdev_trans *trans, int flags)
 {
 	bool pop_vlan;
 	u32 out_pport;
@@ -3801,7 +3796,7 @@ static int rocker_port_fwding(struct rocker_port *rocker_port,
 			continue;
 		vlan_id = htons(vid);
 		pop_vlan = rocker_vlan_id_is_internal(vlan_id);
-		err = rocker_group_l2_interface(rocker_port, trans_ph, flags,
+		err = rocker_group_l2_interface(rocker_port, trans, flags,
 						vlan_id, out_pport, pop_vlan);
 		if (err) {
 			netdev_err(rocker_port->dev,
@@ -3815,16 +3810,16 @@ static int rocker_port_fwding(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_stp_update(struct rocker_port *rocker_port,
-				  enum switchdev_trans_ph trans_ph, int flags,
+				  struct switchdev_trans *trans, int flags,
 				  u8 state)
 {
 	bool want[ROCKER_CTRL_MAX] = { 0, };
 	bool prev_ctrls[ROCKER_CTRL_MAX];
-	u8 prev_state;
+	u8 uninitialized_var(prev_state);
 	int err;
 	int i;
 
-	if (trans_ph == SWITCHDEV_TRANS_PREPARE) {
+	if (switchdev_trans_ph_prepare(trans)) {
 		memcpy(prev_ctrls, rocker_port->ctrls, sizeof(prev_ctrls));
 		prev_state = rocker_port->stp_state;
 	}
@@ -3861,7 +3856,7 @@ static int rocker_port_stp_update(struct rocker_port *rocker_port,
 		if (want[i] != rocker_port->ctrls[i]) {
 			int ctrl_flags = flags |
 					 (want[i] ? 0 : ROCKER_OP_FLAG_REMOVE);
-			err = rocker_port_ctrl(rocker_port, trans_ph, ctrl_flags,
+			err = rocker_port_ctrl(rocker_port, trans, ctrl_flags,
 					       &rocker_ctrls[i]);
 			if (err)
 				goto err_out;
@@ -3869,14 +3864,14 @@ static int rocker_port_stp_update(struct rocker_port *rocker_port,
 		}
 	}
 
-	err = rocker_port_fdb_flush(rocker_port, trans_ph, flags);
+	err = rocker_port_fdb_flush(rocker_port, trans, flags);
 	if (err)
 		goto err_out;
 
-	err = rocker_port_fwding(rocker_port, trans_ph, flags);
+	err = rocker_port_fwding(rocker_port, trans, flags);
 
 err_out:
-	if (trans_ph == SWITCHDEV_TRANS_PREPARE) {
+	if (switchdev_trans_ph_prepare(trans)) {
 		memcpy(rocker_port->ctrls, prev_ctrls, sizeof(prev_ctrls));
 		rocker_port->stp_state = prev_state;
 	}
@@ -3885,26 +3880,26 @@ err_out:
 }
 
 static int rocker_port_fwd_enable(struct rocker_port *rocker_port,
-				  enum switchdev_trans_ph trans_ph, int flags)
+				  struct switchdev_trans *trans, int flags)
 {
 	if (rocker_port_is_bridged(rocker_port))
 		/* bridge STP will enable port */
 		return 0;
 
 	/* port is not bridged, so simulate going to FORWARDING state */
-	return rocker_port_stp_update(rocker_port, trans_ph, flags,
+	return rocker_port_stp_update(rocker_port, trans, flags,
 				      BR_STATE_FORWARDING);
 }
 
 static int rocker_port_fwd_disable(struct rocker_port *rocker_port,
-				   enum switchdev_trans_ph trans_ph, int flags)
+				   struct switchdev_trans *trans, int flags)
 {
 	if (rocker_port_is_bridged(rocker_port))
 		/* bridge STP will disable port */
 		return 0;
 
 	/* port is not bridged, so simulate going to DISABLED state */
-	return rocker_port_stp_update(rocker_port, trans_ph, flags,
+	return rocker_port_stp_update(rocker_port, trans, flags,
 				      BR_STATE_DISABLED);
 }
 
@@ -3995,7 +3990,7 @@ not_found:
 }
 
 static int rocker_port_fib_ipv4(struct rocker_port *rocker_port,
-				enum switchdev_trans_ph trans_ph, __be32 dst,
+				struct switchdev_trans *trans, __be32 dst,
 				int dst_len, const struct fib_info *fi,
 				u32 tb_id, int flags)
 {
@@ -4019,7 +4014,7 @@ static int rocker_port_fib_ipv4(struct rocker_port *rocker_port,
 	has_gw = !!nh->nh_gw;
 
 	if (has_gw && nh_on_port) {
-		err = rocker_port_ipv4_nh(rocker_port, trans_ph, flags,
+		err = rocker_port_ipv4_nh(rocker_port, trans, flags,
 					  nh->nh_gw, &index);
 		if (err)
 			return err;
@@ -4030,7 +4025,7 @@ static int rocker_port_fib_ipv4(struct rocker_port *rocker_port,
 		group_id = ROCKER_GROUP_L2_INTERFACE(internal_vlan_id, 0);
 	}
 
-	err = rocker_flow_tbl_ucast4_routing(rocker_port, trans_ph, eth_type, dst,
+	err = rocker_flow_tbl_ucast4_routing(rocker_port, trans, eth_type, dst,
 					     dst_mask, priority, goto_tbl,
 					     group_id, flags);
 	if (err)
@@ -4069,7 +4064,7 @@ static int rocker_port_open(struct net_device *dev)
 		goto err_request_rx_irq;
 	}
 
-	err = rocker_port_fwd_enable(rocker_port, SWITCHDEV_TRANS_NONE, 0);
+	err = rocker_port_fwd_enable(rocker_port, NULL, 0);
 	if (err)
 		goto err_fwd_enable;
 
@@ -4097,7 +4092,7 @@ static int rocker_port_stop(struct net_device *dev)
 	rocker_port_set_enable(rocker_port, false);
 	napi_disable(&rocker_port->napi_rx);
 	napi_disable(&rocker_port->napi_tx);
-	rocker_port_fwd_disable(rocker_port, SWITCHDEV_TRANS_NONE,
+	rocker_port_fwd_disable(rocker_port, NULL,
 				ROCKER_OP_FLAG_NOWAIT);
 	free_irq(rocker_msix_rx_vector(rocker_port), rocker_port);
 	free_irq(rocker_msix_tx_vector(rocker_port), rocker_port);
@@ -4283,7 +4278,7 @@ static int rocker_port_get_phys_port_name(struct net_device *dev,
 	struct port_name name = { .buf = buf, .len = len };
 	int err;
 
-	err = rocker_cmd_exec(rocker_port, SWITCHDEV_TRANS_NONE, 0,
+	err = rocker_cmd_exec(rocker_port, NULL, 0,
 			      rocker_cmd_get_port_settings_prep, NULL,
 			      rocker_cmd_get_port_settings_phys_name_proc,
 			      &name);
@@ -4308,7 +4303,7 @@ static void rocker_port_neigh_destroy(struct neighbour *n)
 	int flags = ROCKER_OP_FLAG_REMOVE | ROCKER_OP_FLAG_NOWAIT;
 	__be32 ip_addr = *(__be32 *)n->primary_key;
 
-	rocker_port_ipv4_neigh(rocker_port, SWITCHDEV_TRANS_NONE,
+	rocker_port_ipv4_neigh(rocker_port, NULL,
 			       flags, ip_addr, n->ha);
 }
 
@@ -4365,7 +4360,7 @@ static void rocker_port_trans_abort(const struct rocker_port *rocker_port)
 }
 
 static int rocker_port_brport_flags_set(struct rocker_port *rocker_port,
-					enum switchdev_trans_ph trans_ph,
+					struct switchdev_trans *trans,
 					unsigned long brport_flags)
 {
 	unsigned long orig_flags;
@@ -4374,9 +4369,9 @@ static int rocker_port_brport_flags_set(struct rocker_port *rocker_port,
 	orig_flags = rocker_port->brport_flags;
 	rocker_port->brport_flags = brport_flags;
 	if ((orig_flags ^ rocker_port->brport_flags) & BR_LEARNING)
-		err = rocker_port_set_learning(rocker_port, trans_ph);
+		err = rocker_port_set_learning(rocker_port, trans);
 
-	if (trans_ph == SWITCHDEV_TRANS_PREPARE)
+	if (switchdev_trans_ph_prepare(trans))
 		rocker_port->brport_flags = orig_flags;
 
 	return err;
@@ -4402,12 +4397,12 @@ static int rocker_port_attr_set(struct net_device *dev,
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_PORT_STP_STATE:
-		err = rocker_port_stp_update(rocker_port, trans->ph,
+		err = rocker_port_stp_update(rocker_port, trans,
 					     ROCKER_OP_FLAG_NOWAIT,
 					     attr->u.stp_state);
 		break;
 	case SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS:
-		err = rocker_port_brport_flags_set(rocker_port, trans->ph,
+		err = rocker_port_brport_flags_set(rocker_port, trans,
 						   attr->u.brport_flags);
 		break;
 	default:
@@ -4419,33 +4414,34 @@ static int rocker_port_attr_set(struct net_device *dev,
 }
 
 static int rocker_port_vlan_add(struct rocker_port *rocker_port,
-				enum switchdev_trans_ph trans_ph, u16 vid, u16 flags)
+				struct switchdev_trans *trans,
+				u16 vid, u16 flags)
 {
 	int err;
 
 	/* XXX deal with flags for PVID and untagged */
 
-	err = rocker_port_vlan(rocker_port, trans_ph, 0, vid);
+	err = rocker_port_vlan(rocker_port, trans, 0, vid);
 	if (err)
 		return err;
 
-	err = rocker_port_router_mac(rocker_port, trans_ph, 0, htons(vid));
+	err = rocker_port_router_mac(rocker_port, trans, 0, htons(vid));
 	if (err)
-		rocker_port_vlan(rocker_port, trans_ph,
+		rocker_port_vlan(rocker_port, trans,
 				 ROCKER_OP_FLAG_REMOVE, vid);
 
 	return err;
 }
 
 static int rocker_port_vlans_add(struct rocker_port *rocker_port,
-				 enum switchdev_trans_ph trans_ph,
+				 struct switchdev_trans *trans,
 				 const struct switchdev_obj_vlan *vlan)
 {
 	u16 vid;
 	int err;
 
 	for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
-		err = rocker_port_vlan_add(rocker_port, trans_ph,
+		err = rocker_port_vlan_add(rocker_port, trans,
 					   vid, vlan->flags);
 		if (err)
 			return err;
@@ -4455,7 +4451,7 @@ static int rocker_port_vlans_add(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_fdb_add(struct rocker_port *rocker_port,
-			       enum switchdev_trans_ph trans_ph,
+			       struct switchdev_trans *trans,
 			       const struct switchdev_obj_fdb *fdb)
 {
 	__be16 vlan_id = rocker_port_vid_to_vlan(rocker_port, fdb->vid, NULL);
@@ -4464,7 +4460,7 @@ static int rocker_port_fdb_add(struct rocker_port *rocker_port,
 	if (!rocker_port_is_bridged(rocker_port))
 		return -EINVAL;
 
-	return rocker_port_fdb(rocker_port, trans_ph, fdb->addr, vlan_id, flags);
+	return rocker_port_fdb(rocker_port, trans, fdb->addr, vlan_id, flags);
 }
 
 static int rocker_port_obj_add(struct net_device *dev,
@@ -4488,17 +4484,17 @@ static int rocker_port_obj_add(struct net_device *dev,
 
 	switch (obj->id) {
 	case SWITCHDEV_OBJ_PORT_VLAN:
-		err = rocker_port_vlans_add(rocker_port, trans->ph,
+		err = rocker_port_vlans_add(rocker_port, trans,
 					    &obj->u.vlan);
 		break;
 	case SWITCHDEV_OBJ_IPV4_FIB:
 		fib4 = &obj->u.ipv4_fib;
-		err = rocker_port_fib_ipv4(rocker_port, trans->ph,
+		err = rocker_port_fib_ipv4(rocker_port, trans,
 					   htonl(fib4->dst), fib4->dst_len,
 					   fib4->fi, fib4->tb_id, 0);
 		break;
 	case SWITCHDEV_OBJ_PORT_FDB:
-		err = rocker_port_fdb_add(rocker_port, trans->ph, &obj->u.fdb);
+		err = rocker_port_fdb_add(rocker_port, trans, &obj->u.fdb);
 		break;
 	default:
 		err = -EOPNOTSUPP;
@@ -4513,12 +4509,12 @@ static int rocker_port_vlan_del(struct rocker_port *rocker_port,
 {
 	int err;
 
-	err = rocker_port_router_mac(rocker_port, SWITCHDEV_TRANS_NONE,
+	err = rocker_port_router_mac(rocker_port, NULL,
 				     ROCKER_OP_FLAG_REMOVE, htons(vid));
 	if (err)
 		return err;
 
-	return rocker_port_vlan(rocker_port, SWITCHDEV_TRANS_NONE,
+	return rocker_port_vlan(rocker_port, NULL,
 				ROCKER_OP_FLAG_REMOVE, vid);
 }
 
@@ -4538,7 +4534,7 @@ static int rocker_port_vlans_del(struct rocker_port *rocker_port,
 }
 
 static int rocker_port_fdb_del(struct rocker_port *rocker_port,
-			       enum switchdev_trans_ph trans_ph,
+			       struct switchdev_trans *trans,
 			       const struct switchdev_obj_fdb *fdb)
 {
 	__be16 vlan_id = rocker_port_vid_to_vlan(rocker_port, fdb->vid, NULL);
@@ -4547,7 +4543,7 @@ static int rocker_port_fdb_del(struct rocker_port *rocker_port,
 	if (!rocker_port_is_bridged(rocker_port))
 		return -EINVAL;
 
-	return rocker_port_fdb(rocker_port, trans_ph, fdb->addr, vlan_id, flags);
+	return rocker_port_fdb(rocker_port, trans, fdb->addr, vlan_id, flags);
 }
 
 static int rocker_port_obj_del(struct net_device *dev,
@@ -4563,14 +4559,13 @@ static int rocker_port_obj_del(struct net_device *dev,
 		break;
 	case SWITCHDEV_OBJ_IPV4_FIB:
 		fib4 = &obj->u.ipv4_fib;
-		err = rocker_port_fib_ipv4(rocker_port, SWITCHDEV_TRANS_NONE,
+		err = rocker_port_fib_ipv4(rocker_port, NULL,
 					   htonl(fib4->dst), fib4->dst_len,
 					   fib4->fi, fib4->tb_id,
 					   ROCKER_OP_FLAG_REMOVE);
 		break;
 	case SWITCHDEV_OBJ_PORT_FDB:
-		err = rocker_port_fdb_del(rocker_port, SWITCHDEV_TRANS_NONE,
-					  &obj->u.fdb);
+		err = rocker_port_fdb_del(rocker_port, NULL, &obj->u.fdb);
 		break;
 	default:
 		err = -EOPNOTSUPP;
@@ -4784,7 +4779,7 @@ rocker_cmd_get_port_stats_ethtool_proc(const struct rocker_port *rocker_port,
 static int rocker_cmd_get_port_stats_ethtool(struct rocker_port *rocker_port,
 					     void *priv)
 {
-	return rocker_cmd_exec(rocker_port, SWITCHDEV_TRANS_NONE, 0,
+	return rocker_cmd_exec(rocker_port, NULL, 0,
 			       rocker_cmd_get_port_stats_prep, NULL,
 			       rocker_cmd_get_port_stats_ethtool_proc,
 			       priv);
@@ -4976,8 +4971,7 @@ static void rocker_remove_ports(const struct rocker *rocker)
 		rocker_port = rocker->ports[i];
 		if (!rocker_port)
 			continue;
-		rocker_port_ig_tbl(rocker_port, SWITCHDEV_TRANS_NONE,
-				   ROCKER_OP_FLAG_REMOVE);
+		rocker_port_ig_tbl(rocker_port, NULL, ROCKER_OP_FLAG_REMOVE);
 		unregister_netdev(rocker_port->dev);
 		free_netdev(rocker_port->dev);
 	}
@@ -5039,9 +5033,9 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
 
 	switchdev_port_fwd_mark_set(rocker_port->dev, NULL, false);
 
-	rocker_port_set_learning(rocker_port, SWITCHDEV_TRANS_NONE);
+	rocker_port_set_learning(rocker_port, NULL);
 
-	err = rocker_port_ig_tbl(rocker_port, SWITCHDEV_TRANS_NONE, 0);
+	err = rocker_port_ig_tbl(rocker_port, NULL, 0);
 	if (err) {
 		netdev_err(rocker_port->dev, "install ig port table failed\n");
 		goto err_port_ig_tbl;
@@ -5050,8 +5044,7 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
 	rocker_port->internal_vlan_id =
 		rocker_port_internal_vlan_id_get(rocker_port, dev->ifindex);
 
-	err = rocker_port_vlan_add(rocker_port, SWITCHDEV_TRANS_NONE,
-				   untagged_vid, 0);
+	err = rocker_port_vlan_add(rocker_port, NULL, untagged_vid, 0);
 	if (err) {
 		netdev_err(rocker_port->dev, "install untagged VLAN failed\n");
 		goto err_untagged_vlan;
@@ -5060,8 +5053,7 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
 	return 0;
 
 err_untagged_vlan:
-	rocker_port_ig_tbl(rocker_port, SWITCHDEV_TRANS_NONE,
-			   ROCKER_OP_FLAG_REMOVE);
+	rocker_port_ig_tbl(rocker_port, NULL, ROCKER_OP_FLAG_REMOVE);
 err_port_ig_tbl:
 	rocker->ports[port_number] = NULL;
 	unregister_netdev(dev);
@@ -5328,8 +5320,7 @@ static int rocker_port_bridge_join(struct rocker_port *rocker_port,
 	rocker_port->bridge_dev = bridge;
 	switchdev_port_fwd_mark_set(rocker_port->dev, bridge, true);
 
-	return rocker_port_vlan_add(rocker_port, SWITCHDEV_TRANS_NONE,
-				    untagged_vid, 0);
+	return rocker_port_vlan_add(rocker_port, NULL, untagged_vid, 0);
 }
 
 static int rocker_port_bridge_leave(struct rocker_port *rocker_port)
@@ -5351,14 +5342,12 @@ static int rocker_port_bridge_leave(struct rocker_port *rocker_port)
 				    false);
 	rocker_port->bridge_dev = NULL;
 
-	err = rocker_port_vlan_add(rocker_port, SWITCHDEV_TRANS_NONE,
-				   untagged_vid, 0);
+	err = rocker_port_vlan_add(rocker_port, NULL, untagged_vid, 0);
 	if (err)
 		return err;
 
 	if (rocker_port->dev->flags & IFF_UP)
-		err = rocker_port_fwd_enable(rocker_port,
-					     SWITCHDEV_TRANS_NONE, 0);
+		err = rocker_port_fwd_enable(rocker_port, NULL, 0);
 
 	return err;
 }
@@ -5371,10 +5360,10 @@ static int rocker_port_ovs_changed(struct rocker_port *rocker_port,
 
 	rocker_port->bridge_dev = master;
 
-	err = rocker_port_fwd_disable(rocker_port, SWITCHDEV_TRANS_NONE, 0);
+	err = rocker_port_fwd_disable(rocker_port, NULL, 0);
 	if (err)
 		return err;
-	err = rocker_port_fwd_enable(rocker_port, SWITCHDEV_TRANS_NONE, 0);
+	err = rocker_port_fwd_enable(rocker_port, NULL, 0);
 
 	return err;
 }
@@ -5452,8 +5441,7 @@ static int rocker_neigh_update(struct net_device *dev, struct neighbour *n)
 		    ROCKER_OP_FLAG_NOWAIT;
 	__be32 ip_addr = *(__be32 *)n->primary_key;
 
-	return rocker_port_ipv4_neigh(rocker_port, SWITCHDEV_TRANS_NONE,
-				      flags, ip_addr, n->ha);
+	return rocker_port_ipv4_neigh(rocker_port, NULL, flags, ip_addr, n->ha);
 }
 
 static int rocker_netevent_event(struct notifier_block *unused,
-- 
1.9.3

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

* [patch net-next v3 06/10] rocker: use switchdev transaction queue for allocated memory
  2015-09-24  8:02 [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Jiri Pirko
                   ` (4 preceding siblings ...)
  2015-09-24  8:02 ` [patch net-next v3 05/10] rocker: push struct switchdev_trans down through rocker code Jiri Pirko
@ 2015-09-24  8:02 ` Jiri Pirko
  2015-09-24  8:02 ` [patch net-next v3 07/10] switchdev: remove "NONE" transaction phase Jiri Pirko
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Jiri Pirko @ 2015-09-24  8:02 UTC (permalink / raw)
  To: netdev
  Cc: davem, idosch, eladr, sfeldma, f.fainelli, linux, vivien.didelot,
	rami.rosen, roopa, pjonnala, andrew, gospo, Jiri Pirko

From: Jiri Pirko <jiri@mellanox.com>

Benefit from previously introduced transaction item queue infrastructure
and remove rocker specific transaction memory management.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
v1->v2:
- free mem in case of none and commit transaction
---
 drivers/net/ethernet/rocker/rocker.c | 53 +++++-------------------------------
 1 file changed, 7 insertions(+), 46 deletions(-)

diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
index 102b37d..d3f6632 100644
--- a/drivers/net/ethernet/rocker/rocker.c
+++ b/drivers/net/ethernet/rocker/rocker.c
@@ -228,7 +228,6 @@ struct rocker_port {
 	struct napi_struct napi_rx;
 	struct rocker_dma_ring_info tx_ring;
 	struct rocker_dma_ring_info rx_ring;
-	struct list_head trans_mem;
 };
 
 struct rocker {
@@ -346,13 +345,13 @@ static void *__rocker_port_mem_alloc(struct rocker_port *rocker_port,
 				     struct switchdev_trans *trans, int flags,
 				     size_t size)
 {
-	struct list_head *elem = NULL;
+	struct switchdev_trans_item *elem = NULL;
 	gfp_t gfp_flags = (flags & ROCKER_OP_FLAG_NOWAIT) ?
 			  GFP_ATOMIC : GFP_KERNEL;
 
 	/* If in transaction prepare phase, allocate the memory
-	 * and enqueue it on a per-port list.  If in transaction
-	 * commit phase, dequeue the memory from the per-port list
+	 * and enqueue it on a transaction.  If in transaction
+	 * commit phase, dequeue the memory from the transaction
 	 * rather than re-allocating the memory.  The idea is the
 	 * driver code paths for prepare and commit are identical
 	 * so the memory allocated in the prepare phase is the
@@ -361,17 +360,13 @@ static void *__rocker_port_mem_alloc(struct rocker_port *rocker_port,
 
 	if (!trans) {
 		elem = kzalloc(size + sizeof(*elem), gfp_flags);
-		if (elem)
-			INIT_LIST_HEAD(elem);
 	} else if (switchdev_trans_ph_prepare(trans)) {
 		elem = kzalloc(size + sizeof(*elem), gfp_flags);
 		if (!elem)
 			return NULL;
-		list_add_tail(elem, &rocker_port->trans_mem);
+		switchdev_trans_item_enqueue(trans, elem, kfree, elem);
 	} else {
-		BUG_ON(list_empty(&rocker_port->trans_mem));
-		elem = rocker_port->trans_mem.next;
-		list_del_init(elem);
+		elem = switchdev_trans_item_dequeue(trans);
 	}
 
 	return elem ? elem + 1 : NULL;
@@ -393,7 +388,7 @@ static void *rocker_port_kcalloc(struct rocker_port *rocker_port,
 
 static void rocker_port_kfree(struct switchdev_trans *trans, const void *mem)
 {
-	struct list_head *elem;
+	struct switchdev_trans_item *elem;
 
 	/* Frees are ignored if in transaction prepare phase.  The
 	 * memory remains on the per-port list until freed in the
@@ -403,8 +398,7 @@ static void rocker_port_kfree(struct switchdev_trans *trans, const void *mem)
 	if (switchdev_trans_ph_prepare(trans))
 		return;
 
-	elem = (struct list_head *)mem - 1;
-	BUG_ON(!list_empty(elem));
+	elem = (struct switchdev_trans_item *) mem - 1;
 	kfree(elem);
 }
 
@@ -4349,16 +4343,6 @@ static int rocker_port_attr_get(struct net_device *dev,
 	return 0;
 }
 
-static void rocker_port_trans_abort(const struct rocker_port *rocker_port)
-{
-	struct list_head *mem, *tmp;
-
-	list_for_each_safe(mem, tmp, &rocker_port->trans_mem) {
-		list_del(mem);
-		kfree(mem);
-	}
-}
-
 static int rocker_port_brport_flags_set(struct rocker_port *rocker_port,
 					struct switchdev_trans *trans,
 					unsigned long brport_flags)
@@ -4384,17 +4368,6 @@ static int rocker_port_attr_set(struct net_device *dev,
 	struct rocker_port *rocker_port = netdev_priv(dev);
 	int err = 0;
 
-	switch (trans->ph) {
-	case SWITCHDEV_TRANS_PREPARE:
-		BUG_ON(!list_empty(&rocker_port->trans_mem));
-		break;
-	case SWITCHDEV_TRANS_ABORT:
-		rocker_port_trans_abort(rocker_port);
-		return 0;
-	default:
-		break;
-	}
-
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_PORT_STP_STATE:
 		err = rocker_port_stp_update(rocker_port, trans,
@@ -4471,17 +4444,6 @@ static int rocker_port_obj_add(struct net_device *dev,
 	const struct switchdev_obj_ipv4_fib *fib4;
 	int err = 0;
 
-	switch (trans->ph) {
-	case SWITCHDEV_TRANS_PREPARE:
-		BUG_ON(!list_empty(&rocker_port->trans_mem));
-		break;
-	case SWITCHDEV_TRANS_ABORT:
-		rocker_port_trans_abort(rocker_port);
-		return 0;
-	default:
-		break;
-	}
-
 	switch (obj->id) {
 	case SWITCHDEV_OBJ_PORT_VLAN:
 		err = rocker_port_vlans_add(rocker_port, trans,
@@ -5010,7 +4972,6 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
 	rocker_port->pport = port_number + 1;
 	rocker_port->brport_flags = BR_LEARNING | BR_LEARNING_SYNC;
 	rocker_port->ageing_time = BR_DEFAULT_AGEING_TIME;
-	INIT_LIST_HEAD(&rocker_port->trans_mem);
 
 	rocker_port_dev_addr_init(rocker_port);
 	dev->netdev_ops = &rocker_port_netdev_ops;
-- 
1.9.3

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

* [patch net-next v3 07/10] switchdev: remove "NONE" transaction phase
  2015-09-24  8:02 [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Jiri Pirko
                   ` (5 preceding siblings ...)
  2015-09-24  8:02 ` [patch net-next v3 06/10] rocker: use switchdev transaction queue for allocated memory Jiri Pirko
@ 2015-09-24  8:02 ` Jiri Pirko
  2015-09-24  8:02 ` [patch net-next v3 08/10] switchdev: remove "ABORT" " Jiri Pirko
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Jiri Pirko @ 2015-09-24  8:02 UTC (permalink / raw)
  To: netdev
  Cc: davem, idosch, eladr, sfeldma, f.fainelli, linux, vivien.didelot,
	rami.rosen, roopa, pjonnala, andrew, gospo, Jiri Pirko

From: Jiri Pirko <jiri@mellanox.com>

Shouldn't have been there in the first place. Now it is unused, kill it.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/switchdev.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index f84ecf4..f61ee38 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -18,7 +18,6 @@
 #define SWITCHDEV_F_NO_RECURSE		BIT(0)
 
 enum switchdev_trans_ph {
-	SWITCHDEV_TRANS_NONE,
 	SWITCHDEV_TRANS_PREPARE,
 	SWITCHDEV_TRANS_ABORT,
 	SWITCHDEV_TRANS_COMMIT,
-- 
1.9.3

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

* [patch net-next v3 08/10] switchdev: remove "ABORT" transaction phase
  2015-09-24  8:02 [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Jiri Pirko
                   ` (6 preceding siblings ...)
  2015-09-24  8:02 ` [patch net-next v3 07/10] switchdev: remove "NONE" transaction phase Jiri Pirko
@ 2015-09-24  8:02 ` Jiri Pirko
  2015-09-24  8:02 ` [patch net-next v3 09/10] dsa: use prepare/commit switchdev transaction helpers Jiri Pirko
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 25+ messages in thread
From: Jiri Pirko @ 2015-09-24  8:02 UTC (permalink / raw)
  To: netdev
  Cc: davem, idosch, eladr, sfeldma, f.fainelli, linux, vivien.didelot,
	rami.rosen, roopa, pjonnala, andrew, gospo, Jiri Pirko

From: Jiri Pirko <jiri@mellanox.com>

No longer used by drivers, as transaction queue with item destructors
takes care of abort phase internally in switchdev code. So kill it.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/switchdev.h   |  1 -
 net/switchdev/switchdev.c | 10 ++--------
 2 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index f61ee38..9cf372f 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -19,7 +19,6 @@
 
 enum switchdev_trans_ph {
 	SWITCHDEV_TRANS_PREPARE,
-	SWITCHDEV_TRANS_ABORT,
 	SWITCHDEV_TRANS_COMMIT,
 };
 
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index d1c7d51..1adeeda 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -248,11 +248,8 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 		 * released.
 		 */
 
-		if (err != -EOPNOTSUPP) {
-			trans.ph = SWITCHDEV_TRANS_ABORT;
-			__switchdev_port_attr_set(dev, attr, &trans);
+		if (err != -EOPNOTSUPP)
 			switchdev_trans_items_destroy(&trans);
-		}
 
 		return err;
 	}
@@ -334,11 +331,8 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 		 * released.
 		 */
 
-		if (err != -EOPNOTSUPP) {
-			trans.ph = SWITCHDEV_TRANS_ABORT;
-			__switchdev_port_obj_add(dev, obj, &trans);
+		if (err != -EOPNOTSUPP)
 			switchdev_trans_items_destroy(&trans);
-		}
 
 		return err;
 	}
-- 
1.9.3

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

* [patch net-next v3 09/10] dsa: use prepare/commit switchdev transaction helpers
  2015-09-24  8:02 [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Jiri Pirko
                   ` (7 preceding siblings ...)
  2015-09-24  8:02 ` [patch net-next v3 08/10] switchdev: remove "ABORT" " Jiri Pirko
@ 2015-09-24  8:02 ` Jiri Pirko
  2015-09-24  8:02 ` [patch net-next v3 10/10] switchdev: reduce transaction phase enum down to a boolean Jiri Pirko
  2015-09-25  3:05 ` [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Scott Feldman
  10 siblings, 0 replies; 25+ messages in thread
From: Jiri Pirko @ 2015-09-24  8:02 UTC (permalink / raw)
  To: netdev
  Cc: davem, idosch, eladr, sfeldma, f.fainelli, linux, vivien.didelot,
	rami.rosen, roopa, pjonnala, andrew, gospo, Jiri Pirko

From: Jiri Pirko <jiri@mellanox.com>

The enum is going to disappear, use the helpers instead.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/dsa/slave.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 748cc63..71a1155 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -251,8 +251,7 @@ static int dsa_slave_port_vlan_add(struct net_device *dev,
 	u16 vid;
 	int err;
 
-	switch (trans->ph) {
-	case SWITCHDEV_TRANS_PREPARE:
+	if (switchdev_trans_ph_prepare(trans)) {
 		if (!ds->drv->port_vlan_add || !ds->drv->port_pvid_set)
 			return -EOPNOTSUPP;
 
@@ -264,8 +263,7 @@ static int dsa_slave_port_vlan_add(struct net_device *dev,
 						  vlan->vid_end);
 		if (err)
 			return err;
-		break;
-	case SWITCHDEV_TRANS_COMMIT:
+	} else {
 		for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
 			err = ds->drv->port_vlan_add(ds, p->port, vid,
 						     vlan->flags &
@@ -275,9 +273,6 @@ static int dsa_slave_port_vlan_add(struct net_device *dev,
 			if (err)
 				return err;
 		}
-		break;
-	default:
-		return -EOPNOTSUPP;
 	}
 
 	return 0;
@@ -356,9 +351,9 @@ static int dsa_slave_port_fdb_add(struct net_device *dev,
 	struct dsa_switch *ds = p->parent;
 	int ret = -EOPNOTSUPP;
 
-	if (trans->ph == SWITCHDEV_TRANS_PREPARE)
+	if (switchdev_trans_ph_prepare(trans))
 		ret = ds->drv->port_fdb_add ? 0 : -EOPNOTSUPP;
-	else if (trans->ph == SWITCHDEV_TRANS_COMMIT)
+	else
 		ret = ds->drv->port_fdb_add(ds, p->port, fdb->addr, fdb->vid);
 
 	return ret;
@@ -465,7 +460,7 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_PORT_STP_STATE:
-		if (trans->ph == SWITCHDEV_TRANS_COMMIT)
+		if (switchdev_trans_ph_commit(trans))
 			ret = dsa_slave_stp_update(dev, attr->u.stp_state);
 		break;
 	default:
-- 
1.9.3

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

* [patch net-next v3 10/10] switchdev: reduce transaction phase enum down to a boolean
  2015-09-24  8:02 [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Jiri Pirko
                   ` (8 preceding siblings ...)
  2015-09-24  8:02 ` [patch net-next v3 09/10] dsa: use prepare/commit switchdev transaction helpers Jiri Pirko
@ 2015-09-24  8:02 ` Jiri Pirko
  2015-09-25  3:05 ` [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Scott Feldman
  10 siblings, 0 replies; 25+ messages in thread
From: Jiri Pirko @ 2015-09-24  8:02 UTC (permalink / raw)
  To: netdev
  Cc: davem, idosch, eladr, sfeldma, f.fainelli, linux, vivien.didelot,
	rami.rosen, roopa, pjonnala, andrew, gospo, Jiri Pirko

From: Jiri Pirko <jiri@mellanox.com>

Now, since we have only 2 values for transaction phase, just use bool.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/switchdev.h   | 11 +++--------
 net/switchdev/switchdev.c |  8 ++++----
 2 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 9cf372f..1820787 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -17,11 +17,6 @@
 
 #define SWITCHDEV_F_NO_RECURSE		BIT(0)
 
-enum switchdev_trans_ph {
-	SWITCHDEV_TRANS_PREPARE,
-	SWITCHDEV_TRANS_COMMIT,
-};
-
 struct switchdev_trans_item {
 	struct list_head list;
 	void *data;
@@ -30,17 +25,17 @@ struct switchdev_trans_item {
 
 struct switchdev_trans {
 	struct list_head item_list;
-	enum switchdev_trans_ph ph;
+	bool ph_prepare;
 };
 
 static inline bool switchdev_trans_ph_prepare(struct switchdev_trans *trans)
 {
-	return trans && trans->ph == SWITCHDEV_TRANS_PREPARE;
+	return trans && trans->ph_prepare;
 }
 
 static inline bool switchdev_trans_ph_commit(struct switchdev_trans *trans)
 {
-	return trans && trans->ph == SWITCHDEV_TRANS_COMMIT;
+	return trans && !trans->ph_prepare;
 }
 
 enum switchdev_attr_id {
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 1adeeda..00ee547 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -240,7 +240,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 	 * but should not commit the attr.
 	 */
 
-	trans.ph = SWITCHDEV_TRANS_PREPARE;
+	trans.ph_prepare = true;
 	err = __switchdev_port_attr_set(dev, attr, &trans);
 	if (err) {
 		/* Prepare phase failed: abort the transaction.  Any
@@ -259,7 +259,7 @@ int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
 	 * because the driver said everythings was OK in phase I.
 	 */
 
-	trans.ph = SWITCHDEV_TRANS_COMMIT;
+	trans.ph_prepare = false;
 	err = __switchdev_port_attr_set(dev, attr, &trans);
 	WARN(err, "%s: Commit of attribute (id=%d) failed.\n",
 	     dev->name, attr->id);
@@ -323,7 +323,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 	 * but should not commit the obj.
 	 */
 
-	trans.ph = SWITCHDEV_TRANS_PREPARE;
+	trans.ph_prepare = true;
 	err = __switchdev_port_obj_add(dev, obj, &trans);
 	if (err) {
 		/* Prepare phase failed: abort the transaction.  Any
@@ -342,7 +342,7 @@ int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
 	 * because the driver said everythings was OK in phase I.
 	 */
 
-	trans.ph = SWITCHDEV_TRANS_COMMIT;
+	trans.ph_prepare = false;
 	err = __switchdev_port_obj_add(dev, obj, &trans);
 	WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id);
 	switchdev_trans_items_warn_destroy(dev, &trans);
-- 
1.9.3

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

* Re: [patch net-next v3 00/10] switchdev: transaction item queue and cleanup
  2015-09-24  8:02 [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Jiri Pirko
                   ` (9 preceding siblings ...)
  2015-09-24  8:02 ` [patch net-next v3 10/10] switchdev: reduce transaction phase enum down to a boolean Jiri Pirko
@ 2015-09-25  3:05 ` Scott Feldman
  2015-09-25  6:00   ` David Miller
  10 siblings, 1 reply; 25+ messages in thread
From: Scott Feldman @ 2015-09-25  3:05 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Netdev, David S. Miller, Ido Schimmel, eladr, Florian Fainelli,
	Guenter Roeck, Vivien Didelot, Rosen, Rami, Roopa Prabhu,
	Premkumar Jonnala, andrew, Andy Gospodarek

On Thu, Sep 24, 2015 at 1:02 AM, Jiri Pirko <jiri@resnulli.us> wrote:
> From: Jiri Pirko <jiri@mellanox.com>
>
> Jiri Pirko (10):
>   switchdev: rename "trans" to "trans_ph".
>   switchdev: introduce transaction item queue for attr_set and obj_add
>   switchdev: move transaction phase enum under transaction structure
>   switchdev: add switchdev_trans_ph_prepare/commit helpers
>   rocker: push struct switchdev_trans down through rocker code
>   rocker: use switchdev transaction queue for allocated memory
>   switchdev: remove "NONE" transaction phase
>   switchdev: remove "ABORT" transaction phase
>   dsa: use prepare/commit switchdev transaction helpers
>   switchdev: reduce transaction phase enum down to a boolean
>
>  Documentation/networking/switchdev.txt |  19 ++
>  drivers/net/ethernet/rocker/rocker.c   | 308 ++++++++++++++-------------------
>  include/net/switchdev.h                |  40 +++--
>  net/dsa/slave.c                        |  31 ++--
>  net/switchdev/switchdev.c              | 125 ++++++++++---
>  5 files changed, 296 insertions(+), 227 deletions(-)

Tests pass.  ACK on all.

Acked-by: Scott Feldman <sfeldma@gmail.com>

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

* Re: [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add
  2015-09-24  8:02 ` [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add Jiri Pirko
@ 2015-09-25  4:36   ` Vivien Didelot
  2015-09-25  5:29     ` Scott Feldman
  0 siblings, 1 reply; 25+ messages in thread
From: Vivien Didelot @ 2015-09-25  4:36 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, idosch, eladr, sfeldma, f.fainelli, linux,
	rami.rosen, roopa, pjonnala, andrew, gospo, Jiri Pirko

Hi Jiri,

On Sep. Thursday 24 (39) 10:02 AM, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
> 
> Now, the memory allocation in prepare/commit state is done separatelly
> in each driver (rocker). Introduce the similar mechanism in generic
> switchdev code, in form of queue. That can be used not only for memory
> allocations, but also for different items. Abort item destruction
> is handled as well.
> 
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>

[...]

>  /**
>   * struct switchdev_ops - switchdev operations
>   *
> @@ -94,9 +110,11 @@ struct switchdev_ops {
>  	int	(*switchdev_port_attr_get)(struct net_device *dev,
>  					   struct switchdev_attr *attr);
>  	int	(*switchdev_port_attr_set)(struct net_device *dev,
> -					   struct switchdev_attr *attr);
> +					   struct switchdev_attr *attr,
> +					   struct switchdev_trans *trans);
>  	int	(*switchdev_port_obj_add)(struct net_device *dev,
> -					  struct switchdev_obj *obj);
> +					  struct switchdev_obj *obj,
> +					  struct switchdev_trans *trans);
>  	int	(*switchdev_port_obj_del)(struct net_device *dev,
>  					  struct switchdev_obj *obj);
>  	int	(*switchdev_port_obj_dump)(struct net_device *dev,

This version is better than the current state, but it's too bad we
didn't get feedback yet on the real purpose of this 2-phase model...

Anyway, if we do need that, my wish would be to at least make it
optional. What do you think about having an optional prepare op?

    int (*switchdev_port_obj_prepare)(struct net_device *dev,
                                      struct switchdev_obj *obj,
                                      struct switchdev_prepare *prep);

So that the switchdev_port_obj_add function may look like this:

    int switchdev_port_obj_add(struct net_device *dev,
                               struct switchdev_obj *obj)
    {
        struct switchdev_prepare prep;
        int err;

        ASSERT_RTNL();

        switchdev_trans_init(&prep);

        err = __switchdev_port_obj_prepare(dev, obj, &prep);
        if (!err)
            err = __switchdev_port_obj_add(dev, obj, &prep);

        switchdev_prepare_items_destroy(dev, &prep);

        return err;
    }

So drivers can implement the prepare operation if they want to setup a
transaction. You won't have to carry a boolean around, no need for extra
switchdev_trans_ph_{prepare,commit} helpers, and drivers add operation
become simpler.

Same goes for attr_set for sure. Note that I suggest "switchdev_prepare"
instead of "switchdev_trans" to avoid renaming commits and being more
explicit, but it doesn't really matter.

Thanks,
-v

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

* Re: [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add
  2015-09-25  4:36   ` Vivien Didelot
@ 2015-09-25  5:29     ` Scott Feldman
  2015-09-25  5:55       ` David Miller
  0 siblings, 1 reply; 25+ messages in thread
From: Scott Feldman @ 2015-09-25  5:29 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: Jiri Pirko, Netdev, David S. Miller, Ido Schimmel, eladr,
	Florian Fainelli, Guenter Roeck, Rosen, Rami, Roopa Prabhu,
	Premkumar Jonnala, andrew, Andy Gospodarek, Jiri Pirko

On Thu, Sep 24, 2015 at 9:36 PM, Vivien Didelot
<vivien.didelot@savoirfairelinux.com> wrote:
> Hi Jiri,
>
> On Sep. Thursday 24 (39) 10:02 AM, Jiri Pirko wrote:
>> From: Jiri Pirko <jiri@mellanox.com>
>>
>> Now, the memory allocation in prepare/commit state is done separatelly
>> in each driver (rocker). Introduce the similar mechanism in generic
>> switchdev code, in form of queue. That can be used not only for memory
>> allocations, but also for different items. Abort item destruction
>> is handled as well.
>>
>> Signed-off-by: Jiri Pirko <jiri@mellanox.com>
>
> [...]
>
>>  /**
>>   * struct switchdev_ops - switchdev operations
>>   *
>> @@ -94,9 +110,11 @@ struct switchdev_ops {
>>       int     (*switchdev_port_attr_get)(struct net_device *dev,
>>                                          struct switchdev_attr *attr);
>>       int     (*switchdev_port_attr_set)(struct net_device *dev,
>> -                                        struct switchdev_attr *attr);
>> +                                        struct switchdev_attr *attr,
>> +                                        struct switchdev_trans *trans);
>>       int     (*switchdev_port_obj_add)(struct net_device *dev,
>> -                                       struct switchdev_obj *obj);
>> +                                       struct switchdev_obj *obj,
>> +                                       struct switchdev_trans *trans);
>>       int     (*switchdev_port_obj_del)(struct net_device *dev,
>>                                         struct switchdev_obj *obj);
>>       int     (*switchdev_port_obj_dump)(struct net_device *dev,
>
> This version is better than the current state, but it's too bad we
> didn't get feedback yet on the real purpose of this 2-phase model...

Hmmm...I think I missed the question about the 2-phase model.  Let me
see if I can answer it here.

We got here first when working with stacked drivers and we wanted to
propagate an change (attr set or obj add) down the stack in a safe way
as to not leave hardware or software in an inconsistent state when
unexpected things happen.  The simple stacked driver example was two
switch ports bonded.  Setting an attr on the bond would propagate down
to each switch port.  If the setting stuck on the first port, but
didn't on the second port, we didn't want to have to go back and undo
the setting on the first port.  It gets messy real fast trying to
handle the undo operation.  So 2-phase model was suggested by davem to
solve the problem in a generic way.  First phase was to check with
each device in the stack if the operation is OK, and second phase
would commit operation.  The second phase cannot fail; the first phase
already said everything was OK to proceed.  That means no running out
of hardware resources in phase 2.  Phase 1 should have check/reserved
the resources.  And no OOM situations in phase 2.  And so on for other
detectable failures.

Stacked driver case is one case where the 2-phase model strives to
maintain hw/sw consistency.  I could see it working for batch
operations also, although we don't have any examples of batch
processing yet (in switchdev).

I'd rather keep 2-phase not optional, or at least make it some what of
a pain for drivers to opt-out of 2-phase.  Forcing the driver to see
both phases means the driver needs to put some code to skip phase 1
(and hopefully has some persistent comment explaining why its being
skipped).  Something like:

/* I'm skipping phase 1 prepare for this operation.  I have infinite hardware
 * resources and I'm not setting any persistent state in the driver or device
 * and I don't need any dynamic resources from the kernel, so its impossible
 * for me to fail phase 2 commit.  Nothing to prepare, sorry.
 */

-scott

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

* Re: [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add
  2015-09-25  5:29     ` Scott Feldman
@ 2015-09-25  5:55       ` David Miller
  2015-09-25 15:03         ` Vivien Didelot
  0 siblings, 1 reply; 25+ messages in thread
From: David Miller @ 2015-09-25  5:55 UTC (permalink / raw)
  To: sfeldma
  Cc: vivien.didelot, jiri, netdev, idosch, eladr, f.fainelli, linux,
	rami.rosen, roopa, pjonnala, andrew, gospo, jiri

From: Scott Feldman <sfeldma@gmail.com>
Date: Thu, 24 Sep 2015 22:29:43 -0700

> I'd rather keep 2-phase not optional, or at least make it some what of
> a pain for drivers to opt-out of 2-phase.  Forcing the driver to see
> both phases means the driver needs to put some code to skip phase 1
> (and hopefully has some persistent comment explaining why its being
> skipped).  Something like:
> 
> /* I'm skipping phase 1 prepare for this operation.  I have infinite hardware
>  * resources and I'm not setting any persistent state in the driver or device
>  * and I don't need any dynamic resources from the kernel, so its impossible
>  * for me to fail phase 2 commit.  Nothing to prepare, sorry.
>  */

I agree with Scott here.

If you can opt out of something, you can not think about it and thus
more likely get it wrong.

I can just see a driver not implementing prepare at all and then doing
stupid things in commit when they hit some resource limit or whatever,
rather than taking care of such issues in prepare.

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

* Re: [patch net-next v3 00/10] switchdev: transaction item queue and cleanup
  2015-09-25  3:05 ` [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Scott Feldman
@ 2015-09-25  6:00   ` David Miller
  2015-09-25  6:04     ` Jiri Pirko
  0 siblings, 1 reply; 25+ messages in thread
From: David Miller @ 2015-09-25  6:00 UTC (permalink / raw)
  To: sfeldma
  Cc: jiri, netdev, idosch, eladr, f.fainelli, linux, vivien.didelot,
	rami.rosen, roopa, pjonnala, andrew, gospo

From: Scott Feldman <sfeldma@gmail.com>
Date: Thu, 24 Sep 2015 20:05:39 -0700

> On Thu, Sep 24, 2015 at 1:02 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>> From: Jiri Pirko <jiri@mellanox.com>
>>
>> Jiri Pirko (10):
>>   switchdev: rename "trans" to "trans_ph".
>>   switchdev: introduce transaction item queue for attr_set and obj_add
>>   switchdev: move transaction phase enum under transaction structure
>>   switchdev: add switchdev_trans_ph_prepare/commit helpers
>>   rocker: push struct switchdev_trans down through rocker code
>>   rocker: use switchdev transaction queue for allocated memory
>>   switchdev: remove "NONE" transaction phase
>>   switchdev: remove "ABORT" transaction phase
>>   dsa: use prepare/commit switchdev transaction helpers
>>   switchdev: reduce transaction phase enum down to a boolean
>>
>>  Documentation/networking/switchdev.txt |  19 ++
>>  drivers/net/ethernet/rocker/rocker.c   | 308 ++++++++++++++-------------------
>>  include/net/switchdev.h                |  40 +++--
>>  net/dsa/slave.c                        |  31 ++--
>>  net/switchdev/switchdev.c              | 125 ++++++++++---
>>  5 files changed, 296 insertions(+), 227 deletions(-)
> 
> Tests pass.  ACK on all.
> 
> Acked-by: Scott Feldman <sfeldma@gmail.com>

Series applied, thanks everyone.

But Jiri, in the future you really have to give me more "meat" in this
00/10 posting.  You have to provide some description of what your
changes are doing at a high level and why.

Thanks.

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

* Re: [patch net-next v3 00/10] switchdev: transaction item queue and cleanup
  2015-09-25  6:00   ` David Miller
@ 2015-09-25  6:04     ` Jiri Pirko
  0 siblings, 0 replies; 25+ messages in thread
From: Jiri Pirko @ 2015-09-25  6:04 UTC (permalink / raw)
  To: David Miller
  Cc: sfeldma, netdev, idosch, eladr, f.fainelli, linux,
	vivien.didelot, rami.rosen, roopa, pjonnala, andrew, gospo

Fri, Sep 25, 2015 at 08:00:13AM CEST, davem@davemloft.net wrote:
>From: Scott Feldman <sfeldma@gmail.com>
>Date: Thu, 24 Sep 2015 20:05:39 -0700
>
>> On Thu, Sep 24, 2015 at 1:02 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>>> From: Jiri Pirko <jiri@mellanox.com>
>>>
>>> Jiri Pirko (10):
>>>   switchdev: rename "trans" to "trans_ph".
>>>   switchdev: introduce transaction item queue for attr_set and obj_add
>>>   switchdev: move transaction phase enum under transaction structure
>>>   switchdev: add switchdev_trans_ph_prepare/commit helpers
>>>   rocker: push struct switchdev_trans down through rocker code
>>>   rocker: use switchdev transaction queue for allocated memory
>>>   switchdev: remove "NONE" transaction phase
>>>   switchdev: remove "ABORT" transaction phase
>>>   dsa: use prepare/commit switchdev transaction helpers
>>>   switchdev: reduce transaction phase enum down to a boolean
>>>
>>>  Documentation/networking/switchdev.txt |  19 ++
>>>  drivers/net/ethernet/rocker/rocker.c   | 308 ++++++++++++++-------------------
>>>  include/net/switchdev.h                |  40 +++--
>>>  net/dsa/slave.c                        |  31 ++--
>>>  net/switchdev/switchdev.c              | 125 ++++++++++---
>>>  5 files changed, 296 insertions(+), 227 deletions(-)
>> 
>> Tests pass.  ACK on all.
>> 
>> Acked-by: Scott Feldman <sfeldma@gmail.com>
>
>Series applied, thanks everyone.
>
>But Jiri, in the future you really have to give me more "meat" in this
>00/10 posting.  You have to provide some description of what your
>changes are doing at a high level and why.

I thought that in this case it is enough to have descriptions in
separate patches. Anyway, will try to write some story to the cover
letter next time.

Thanks.

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

* Re: [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add
  2015-09-25  5:55       ` David Miller
@ 2015-09-25 15:03         ` Vivien Didelot
  2015-09-30 18:56           ` Vivien Didelot
  0 siblings, 1 reply; 25+ messages in thread
From: Vivien Didelot @ 2015-09-25 15:03 UTC (permalink / raw)
  To: David Miller
  Cc: sfeldma, jiri, netdev, idosch, eladr, f.fainelli, linux,
	rami.rosen, roopa, pjonnala, andrew, gospo, jiri, vivien.didelot

On Sep. Thursday 24 (39) 10:55 PM, David Miller wrote:
> From: Scott Feldman <sfeldma@gmail.com>
> Date: Thu, 24 Sep 2015 22:29:43 -0700
> 
> > I'd rather keep 2-phase not optional, or at least make it some what of
> > a pain for drivers to opt-out of 2-phase.  Forcing the driver to see
> > both phases means the driver needs to put some code to skip phase 1
> > (and hopefully has some persistent comment explaining why its being
> > skipped).  Something like:
> > 
> > /* I'm skipping phase 1 prepare for this operation.  I have infinite hardware
> >  * resources and I'm not setting any persistent state in the driver or device
> >  * and I don't need any dynamic resources from the kernel, so its impossible
> >  * for me to fail phase 2 commit.  Nothing to prepare, sorry.
> >  */
> 
> I agree with Scott here.
> 
> If you can opt out of something, you can not think about it and thus
> more likely get it wrong.
> 
> I can just see a driver not implementing prepare at all and then doing
> stupid things in commit when they hit some resource limit or whatever,
> rather than taking care of such issues in prepare.

OK, I have no experience with stacked devices nor what it actually looks
like, but I understand that it is a redundant setup where it makes sense
to ensure that an operation is feasible before programming the hardware.

I agree with both of you on imposing switchdev drivers such notion.

I was confused with the rtnl lock (from bridge netlink requests) which
seemed to limit a lot the usage of this prepare phase.

I don't know the batch mode neither, but I can think about a potentially
powerful usage of the prepare phase in Marvell switches (or any basic
home router switches), please tell me if the following is feasible:

Every hardware VLANs I know of are programmed with all port membership
in one shot. This is not feasible today with the bridge command. If I
could bundle in one request the equivalent of ("VID 100: 0u 1u 5t"):

    bridge vlan add master dev swp0 vid 100 pvid untagged
    bridge vlan add master dev swp1 vid 100 pvid untagged
    bridge vlan add master dev swp5 vid 100 # cpu

In such case the prepare phase could be great to allocate and populate a
VLAN entry structure (i.e. struct mv88e6xxx_vtu_stu_entry) before
programming the hardware *just once*. Is that doable?

Also, I insist on removing the assumption that no error can occure
during the commit phase, for 2 reasons:

 - errors can actually occure (e.g. MDIO calls).
 - it makes no difference to the caller of switchdev_port_attr_set() and
   switchdev_port_obj_add() whether the call failed during the prepare
   or commit phase.

So I will propose a patch to get rid of the WARN(), if you don't mind.

Finally, what do you think about the snippet I proposed in my mail you
are replying to?

Implementing (now mandatory!) port_obj_prepare and port_attr_prepare
switchdev ops will explicit the prepare phase in drivers, simplify their
code and get rid of the prepare boolean and phase helper functions.

Thanks,
-v

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

* Re: [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add
  2015-09-25 15:03         ` Vivien Didelot
@ 2015-09-30 18:56           ` Vivien Didelot
  2015-10-01  4:27             ` Scott Feldman
  0 siblings, 1 reply; 25+ messages in thread
From: Vivien Didelot @ 2015-09-30 18:56 UTC (permalink / raw)
  To: Jiri Pirko, sfeldma
  Cc: sfeldma, jiri, netdev, idosch, eladr, f.fainelli, linux,
	rami.rosen, roopa, pjonnala, andrew, gospo, jiri

Hi all,

On Sep. Friday 25 (39) 11:03 AM, Vivien Didelot wrote:
> On Sep. Thursday 24 (39) 10:55 PM, David Miller wrote:
> > From: Scott Feldman <sfeldma@gmail.com>
> > Date: Thu, 24 Sep 2015 22:29:43 -0700
> > 
> > > I'd rather keep 2-phase not optional, or at least make it some what of
> > > a pain for drivers to opt-out of 2-phase.  Forcing the driver to see
> > > both phases means the driver needs to put some code to skip phase 1
> > > (and hopefully has some persistent comment explaining why its being
> > > skipped).  Something like:
> > > 
> > > /* I'm skipping phase 1 prepare for this operation.  I have infinite hardware
> > >  * resources and I'm not setting any persistent state in the driver or device
> > >  * and I don't need any dynamic resources from the kernel, so its impossible
> > >  * for me to fail phase 2 commit.  Nothing to prepare, sorry.
> > >  */
> > 
> > I agree with Scott here.
> > 
> > If you can opt out of something, you can not think about it and thus
> > more likely get it wrong.
> > 
> > I can just see a driver not implementing prepare at all and then doing
> > stupid things in commit when they hit some resource limit or whatever,
> > rather than taking care of such issues in prepare.
> 
> OK, I have no experience with stacked devices nor what it actually looks
> like, but I understand that it is a redundant setup where it makes sense
> to ensure that an operation is feasible before programming the hardware.
> 
> I agree with both of you on imposing switchdev drivers such notion.
> 
> I was confused with the rtnl lock (from bridge netlink requests) which
> seemed to limit a lot the usage of this prepare phase.
> 
> I don't know the batch mode neither, but I can think about a potentially
> powerful usage of the prepare phase in Marvell switches (or any basic
> home router switches), please tell me if the following is feasible:
> 
> Every hardware VLANs I know of are programmed with all port membership
> in one shot. This is not feasible today with the bridge command. If I
> could bundle in one request the equivalent of ("VID 100: 0u 1u 5t"):
> 
>     bridge vlan add master dev swp0 vid 100 pvid untagged
>     bridge vlan add master dev swp1 vid 100 pvid untagged
>     bridge vlan add master dev swp5 vid 100 # cpu
> 
> In such case the prepare phase could be great to allocate and populate a
> VLAN entry structure (i.e. struct mv88e6xxx_vtu_stu_entry) before
> programming the hardware *just once*. Is that doable?

May I get answers for this? I'd need that in order to suggest a next
step for the prepare phase in DSA drivers.

Thanks,
-v

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

* Re: [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add
  2015-09-30 18:56           ` Vivien Didelot
@ 2015-10-01  4:27             ` Scott Feldman
  2015-10-01 15:15               ` Vivien Didelot
  0 siblings, 1 reply; 25+ messages in thread
From: Scott Feldman @ 2015-10-01  4:27 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: Jiri Pirko, Netdev, Ido Schimmel, eladr, Florian Fainelli,
	Guenter Roeck, Rosen, Rami, Roopa Prabhu, Premkumar Jonnala,
	andrew, Andy Gospodarek, Jiri Pirko

On Wed, Sep 30, 2015 at 11:56 AM, Vivien Didelot
<vivien.didelot@savoirfairelinux.com> wrote:
> Hi all,
>
> On Sep. Friday 25 (39) 11:03 AM, Vivien Didelot wrote:
>> On Sep. Thursday 24 (39) 10:55 PM, David Miller wrote:
>> > From: Scott Feldman <sfeldma@gmail.com>
>> > Date: Thu, 24 Sep 2015 22:29:43 -0700
>> >
>> > > I'd rather keep 2-phase not optional, or at least make it some what of
>> > > a pain for drivers to opt-out of 2-phase.  Forcing the driver to see
>> > > both phases means the driver needs to put some code to skip phase 1
>> > > (and hopefully has some persistent comment explaining why its being
>> > > skipped).  Something like:
>> > >
>> > > /* I'm skipping phase 1 prepare for this operation.  I have infinite hardware
>> > >  * resources and I'm not setting any persistent state in the driver or device
>> > >  * and I don't need any dynamic resources from the kernel, so its impossible
>> > >  * for me to fail phase 2 commit.  Nothing to prepare, sorry.
>> > >  */
>> >
>> > I agree with Scott here.
>> >
>> > If you can opt out of something, you can not think about it and thus
>> > more likely get it wrong.
>> >
>> > I can just see a driver not implementing prepare at all and then doing
>> > stupid things in commit when they hit some resource limit or whatever,
>> > rather than taking care of such issues in prepare.
>>
>> OK, I have no experience with stacked devices nor what it actually looks
>> like, but I understand that it is a redundant setup where it makes sense
>> to ensure that an operation is feasible before programming the hardware.
>>
>> I agree with both of you on imposing switchdev drivers such notion.
>>
>> I was confused with the rtnl lock (from bridge netlink requests) which
>> seemed to limit a lot the usage of this prepare phase.
>>
>> I don't know the batch mode neither, but I can think about a potentially
>> powerful usage of the prepare phase in Marvell switches (or any basic
>> home router switches), please tell me if the following is feasible:
>>
>> Every hardware VLANs I know of are programmed with all port membership
>> in one shot. This is not feasible today with the bridge command. If I
>> could bundle in one request the equivalent of ("VID 100: 0u 1u 5t"):
>>
>>     bridge vlan add master dev swp0 vid 100 pvid untagged
>>     bridge vlan add master dev swp1 vid 100 pvid untagged
>>     bridge vlan add master dev swp5 vid 100 # cpu
>>
>> In such case the prepare phase could be great to allocate and populate a
>> VLAN entry structure (i.e. struct mv88e6xxx_vtu_stu_entry) before
>> programming the hardware *just once*. Is that doable?
>
> May I get answers for this? I'd need that in order to suggest a next
> step for the prepare phase in DSA drivers.

You know we're just making this all up as we go, right?  ;)

Actually, bringing real-world examples us think about solutions, so thank you.

A partial answer to your question, I guess, is to consider
switchdev_port_obj_add(dev, obj), which is basically:

   switchdev_port_obj_add(dev, obj)
       dev->ops->switchdev_port_obj_add(dev, obj, PREPARE)
       if no err
           dev->ops->switchdev_port_obj_add(dev, obj, COMMIT)
       else
           // abort transaction

Seems you could make a batch version that iterates over list of devs
to add the same obj:

   switchdev_port_obj_add_batch(devs, obj)
       for dev in devs:
           dev->ops->switchdev_port_obj_add(dev, obj, PREPARE)
       if no errs:
           for dev in devs:
               dev->ops->switchdev_port_obj_add(dev, obj, COMMIT)
       else
           // abort transaction (on all devs)

Who calls this _batch version with a list of devs is TBD.   Not sure
if you can get the -batch and -force options in iproute2 ip cmd to get
you here.

And as I look back at your example, you really have two diff objs in
your cmd list.  First obj is vlan 100 pvid untagged, second obj is
vlan 100.  Would this be two batches?  Oh, hmmm, maybe the batch
version iterates over list of {dev, obj} tuples.  Something like
(sorry, my pseudo code is turning into python):

   switchdev_port_obj_add_batch(dev_objs)
       for dev, obj in dev_objs.items:
           dev->ops->switchdev_port_obj_add(dev, obj, PREPARE)
       if no errs:
           for dev, obj in dev_objs.items:
               dev->ops->switchdev_port_obj_add(dev, obj, COMMIT)
       else
           // abort transaction (on all devs)

Does this help?  Maybe we should walk before running and focus on
getting non-batch ops working and then revisit?

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

* Re: [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add
  2015-10-01  4:27             ` Scott Feldman
@ 2015-10-01 15:15               ` Vivien Didelot
  2015-10-01 15:28                 ` Andrew Lunn
  0 siblings, 1 reply; 25+ messages in thread
From: Vivien Didelot @ 2015-10-01 15:15 UTC (permalink / raw)
  To: Scott Feldman
  Cc: Jiri Pirko, Netdev, Ido Schimmel, eladr, Florian Fainelli,
	Guenter Roeck, Rosen, Rami, Roopa Prabhu, Premkumar Jonnala,
	andrew, Andy Gospodarek, Jiri Pirko

Hi,

On Sep. Wednesday 30 (40) 09:27 PM, Scott Feldman wrote:
> On Wed, Sep 30, 2015 at 11:56 AM, Vivien Didelot
> <vivien.didelot@savoirfairelinux.com> wrote:
> > Hi all,
> >
> > On Sep. Friday 25 (39) 11:03 AM, Vivien Didelot wrote:
> >> On Sep. Thursday 24 (39) 10:55 PM, David Miller wrote:
> >> > From: Scott Feldman <sfeldma@gmail.com>
> >> > Date: Thu, 24 Sep 2015 22:29:43 -0700
> >> >
> >> > > I'd rather keep 2-phase not optional, or at least make it some what of
> >> > > a pain for drivers to opt-out of 2-phase.  Forcing the driver to see
> >> > > both phases means the driver needs to put some code to skip phase 1
> >> > > (and hopefully has some persistent comment explaining why its being
> >> > > skipped).  Something like:
> >> > >
> >> > > /* I'm skipping phase 1 prepare for this operation.  I have infinite hardware
> >> > >  * resources and I'm not setting any persistent state in the driver or device
> >> > >  * and I don't need any dynamic resources from the kernel, so its impossible
> >> > >  * for me to fail phase 2 commit.  Nothing to prepare, sorry.
> >> > >  */
> >> >
> >> > I agree with Scott here.
> >> >
> >> > If you can opt out of something, you can not think about it and thus
> >> > more likely get it wrong.
> >> >
> >> > I can just see a driver not implementing prepare at all and then doing
> >> > stupid things in commit when they hit some resource limit or whatever,
> >> > rather than taking care of such issues in prepare.
> >>
> >> OK, I have no experience with stacked devices nor what it actually looks
> >> like, but I understand that it is a redundant setup where it makes sense
> >> to ensure that an operation is feasible before programming the hardware.
> >>
> >> I agree with both of you on imposing switchdev drivers such notion.
> >>
> >> I was confused with the rtnl lock (from bridge netlink requests) which
> >> seemed to limit a lot the usage of this prepare phase.
> >>
> >> I don't know the batch mode neither, but I can think about a potentially
> >> powerful usage of the prepare phase in Marvell switches (or any basic
> >> home router switches), please tell me if the following is feasible:
> >>
> >> Every hardware VLANs I know of are programmed with all port membership
> >> in one shot. This is not feasible today with the bridge command. If I
> >> could bundle in one request the equivalent of ("VID 100: 0u 1u 5t"):
> >>
> >>     bridge vlan add master dev swp0 vid 100 pvid untagged
> >>     bridge vlan add master dev swp1 vid 100 pvid untagged
> >>     bridge vlan add master dev swp5 vid 100 # cpu
> >>
> >> In such case the prepare phase could be great to allocate and populate a
> >> VLAN entry structure (i.e. struct mv88e6xxx_vtu_stu_entry) before
> >> programming the hardware *just once*. Is that doable?
> >
> > May I get answers for this? I'd need that in order to suggest a next
> > step for the prepare phase in DSA drivers.
> 
> You know we're just making this all up as we go, right?  ;)
> 
> Actually, bringing real-world examples us think about solutions, so thank you.

Sorry for the pushing, I'm a little too enthusiast with the ongoing
support for Ethernet switch chips :)

> 
> A partial answer to your question, I guess, is to consider
> switchdev_port_obj_add(dev, obj), which is basically:
> 
>    switchdev_port_obj_add(dev, obj)
>        dev->ops->switchdev_port_obj_add(dev, obj, PREPARE)
>        if no err
>            dev->ops->switchdev_port_obj_add(dev, obj, COMMIT)
>        else
>            // abort transaction
> 
> Seems you could make a batch version that iterates over list of devs
> to add the same obj:
> 
>    switchdev_port_obj_add_batch(devs, obj)
>        for dev in devs:
>            dev->ops->switchdev_port_obj_add(dev, obj, PREPARE)
>        if no errs:
>            for dev in devs:
>                dev->ops->switchdev_port_obj_add(dev, obj, COMMIT)
>        else
>            // abort transaction (on all devs)
> 
> Who calls this _batch version with a list of devs is TBD.   Not sure
> if you can get the -batch and -force options in iproute2 ip cmd to get
> you here.
> 
> And as I look back at your example, you really have two diff objs in
> your cmd list.  First obj is vlan 100 pvid untagged, second obj is
> vlan 100.  Would this be two batches?  Oh, hmmm, maybe the batch
> version iterates over list of {dev, obj} tuples.

Exactly. A list a {dev, obj} tuples would indeed be the key to bring
efficient hardware access, when a user wants to program a switch through
a Linux bridge.

> Something like (sorry, my pseudo code is turning into python):
> 
>    switchdev_port_obj_add_batch(dev_objs)
>        for dev, obj in dev_objs.items:
>            dev->ops->switchdev_port_obj_add(dev, obj, PREPARE)
>        if no errs:
>            for dev, obj in dev_objs.items:
>                dev->ops->switchdev_port_obj_add(dev, obj, COMMIT)
>        else
>            // abort transaction (on all devs)
> 
> Does this help?  Maybe we should walk before running and focus on
> getting non-batch ops working and then revisit?

I agree. I understand the need for a prepare phase, but it looks like it
exists for specific combinations, i.e. stacked and bonded devices.

For basic Ethernet switch chips (even DSA), it is *for the moment* a bit
too unnecessarily complex.

What I will suggest next, is to explicitly skip the prepare phase in DSA
(with a good comment as you already suggested), and fix switchdev to
allow drivers to return -EOPNOTSUPP from its commit phase.

I hope we can agree that asking the hardware "do you support this
object?", and offering the driver a nice preparation framework, are two
different things that switchdev_port_{obj_add,attr_set} accomplish.

Thanks for feeding this thread!
-v

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

* Re: [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add
  2015-10-01 15:15               ` Vivien Didelot
@ 2015-10-01 15:28                 ` Andrew Lunn
  2015-10-01 16:17                   ` Vivien Didelot
  0 siblings, 1 reply; 25+ messages in thread
From: Andrew Lunn @ 2015-10-01 15:28 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: Scott Feldman, Jiri Pirko, Netdev, Ido Schimmel, eladr,
	Florian Fainelli, Guenter Roeck, Rosen, Rami, Roopa Prabhu,
	Premkumar Jonnala, Andy Gospodarek, Jiri Pirko

> > Does this help?  Maybe we should walk before running and focus on
> > getting non-batch ops working and then revisit?
> 
> I agree. I understand the need for a prepare phase, but it looks like it
> exists for specific combinations, i.e. stacked and bonded devices.
> 
> For basic Ethernet switch chips (even DSA), it is *for the moment* a bit
> too unnecessarily complex.

I think we are going to need it though. I have bonding on my TODO
list. That will put DSA into a stacked system.
 
> What I will suggest next, is to explicitly skip the prepare phase in DSA
> (with a good comment as you already suggested), and fix switchdev to
> allow drivers to return -EOPNOTSUPP from its commit phase.

The switches have a limited number of bonds, called trunks in Marvells
terminology. So we will need the prepare phase to say: Sorry, im out
of trunks, do it in software. And different chips have different
numbers of trunks, so it will need to go down into the chip driver,
the DSA layer probably cannot decide.

    Andrew

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

* Re: [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add
  2015-10-01 15:28                 ` Andrew Lunn
@ 2015-10-01 16:17                   ` Vivien Didelot
  2015-10-01 16:26                     ` Andrew Lunn
  0 siblings, 1 reply; 25+ messages in thread
From: Vivien Didelot @ 2015-10-01 16:17 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Scott Feldman, Jiri Pirko, Netdev, Ido Schimmel, eladr,
	Florian Fainelli, Guenter Roeck, Rosen, Rami, Roopa Prabhu,
	Premkumar Jonnala, Andy Gospodarek, Jiri Pirko

Hi Andrew,

On Oct. Thursday 01 (40) 05:28 PM, Andrew Lunn wrote:
> > > Does this help?  Maybe we should walk before running and focus on
> > > getting non-batch ops working and then revisit?
> > 
> > I agree. I understand the need for a prepare phase, but it looks like it
> > exists for specific combinations, i.e. stacked and bonded devices.
> > 
> > For basic Ethernet switch chips (even DSA), it is *for the moment* a bit
> > too unnecessarily complex.
> 
> I think we are going to need it though. I have bonding on my TODO
> list. That will put DSA into a stacked system.
>  
> > What I will suggest next, is to explicitly skip the prepare phase in DSA
> > (with a good comment as you already suggested), and fix switchdev to
> > allow drivers to return -EOPNOTSUPP from its commit phase.
> 
> The switches have a limited number of bonds, called trunks in Marvells
> terminology. So we will need the prepare phase to say: Sorry, im out
> of trunks, do it in software. And different chips have different
> numbers of trunks, so it will need to go down into the chip driver,
> the DSA layer probably cannot decide.

I understand. Please consider my last comment, which is not invalidated
here: asking the hardware for a support, and the prepare transaction
framework are 2 differents things here.

In other words: struct switchdev_trans != -EOPNOTSUPP.

Even with Marvell switches, bonding 2 ports may not be supported, but if
it does, it won't need the switchdev_trans framework for this operation.

If we take a look at how dsa_slave_stp_update works today in
net/dsa/slave.c, it is quite complicated:

    dsa_slave_stp_update(dev, state)
        if (ds->drv->port_stp_update)
	    return ds->drv->port_stp_update(port, state);
        else
	    return -EOPNOTSUPP;

This checks that the driver implemented this operation. And:

    dsa_slave_port_attr_set(dev, attr, trans)
        ...
	case SWITCHDEV_ATTR_PORT_STP_STATE:
	    if (switchdev_trans_ph_prepare(trans))
	        return ds->drv->port_stp_update ? 0 : -EOPNOTSUPP;
	    else
	        return ds->drv->port_stp_update(port, state);

DSA drivers don't need dynamic resources from the kernel. But they may
not support an object. I would like to make the distinction, by skipping
the prepare phase in the DSA framework and allowing DSA drivers to
eventually return -EOPNOTSUPP from their feature implementation. It
makes no difference for the caller of switchdev_port_{obj_add,attr_set}
anyway.

Thanks,
-v

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

* Re: [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add
  2015-10-01 16:17                   ` Vivien Didelot
@ 2015-10-01 16:26                     ` Andrew Lunn
  2015-10-01 17:11                       ` Vivien Didelot
  0 siblings, 1 reply; 25+ messages in thread
From: Andrew Lunn @ 2015-10-01 16:26 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: Scott Feldman, Jiri Pirko, Netdev, Ido Schimmel, eladr,
	Florian Fainelli, Guenter Roeck, Rosen, Rami, Roopa Prabhu,
	Premkumar Jonnala, Andy Gospodarek, Jiri Pirko

> DSA drivers don't need dynamic resources from the kernel.

It is hard to say if that is going to remain true. I think when we
start doing more D in DSA, we might need to keep more state
information.

What we need to avoid is making changes now that we later need to undo
because we need dynamic resources. So i'm happy for a simple
interface, so long as i can still use the complex interface, when i
need it.

     Andrew

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

* Re: [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add
  2015-10-01 16:26                     ` Andrew Lunn
@ 2015-10-01 17:11                       ` Vivien Didelot
  0 siblings, 0 replies; 25+ messages in thread
From: Vivien Didelot @ 2015-10-01 17:11 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Scott Feldman, Jiri Pirko, Netdev, Ido Schimmel, eladr,
	Florian Fainelli, Guenter Roeck, Rosen, Rami, Roopa Prabhu,
	Premkumar Jonnala, Andy Gospodarek, Jiri Pirko

Hi Andrew,

On Oct. Thursday 01 (40) 06:26 PM, Andrew Lunn wrote:
> > DSA drivers don't need dynamic resources from the kernel.
> 
> It is hard to say if that is going to remain true. I think when we
> start doing more D in DSA, we might need to keep more state
> information.

Maybe, but we should keep things simple and do not use complex
structures until we need them.

> What we need to avoid is making changes now that we later need to undo
> because we need dynamic resources. So i'm happy for a simple
> interface, so long as i can still use the complex interface, when i
> need it.

Yes, note that I don't want to get rid of switchdev_trans here.

I want to explicitly skip it in the DSA framework (net/dev/slave.c)
while allowing DSA drivers (e.g. mv88e6xxx.c) to tell us if a feature
object is supported or not.

Thanks,
-v

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

end of thread, other threads:[~2015-10-01 17:11 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-24  8:02 [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Jiri Pirko
2015-09-24  8:02 ` [patch net-next v3 01/10] switchdev: rename "trans" to "trans_ph" Jiri Pirko
2015-09-24  8:02 ` [patch net-next v3 02/10] switchdev: introduce transaction item queue for attr_set and obj_add Jiri Pirko
2015-09-25  4:36   ` Vivien Didelot
2015-09-25  5:29     ` Scott Feldman
2015-09-25  5:55       ` David Miller
2015-09-25 15:03         ` Vivien Didelot
2015-09-30 18:56           ` Vivien Didelot
2015-10-01  4:27             ` Scott Feldman
2015-10-01 15:15               ` Vivien Didelot
2015-10-01 15:28                 ` Andrew Lunn
2015-10-01 16:17                   ` Vivien Didelot
2015-10-01 16:26                     ` Andrew Lunn
2015-10-01 17:11                       ` Vivien Didelot
2015-09-24  8:02 ` [patch net-next v3 03/10] switchdev: move transaction phase enum under transaction structure Jiri Pirko
2015-09-24  8:02 ` [patch net-next v3 04/10] switchdev: add switchdev_trans_ph_prepare/commit helpers Jiri Pirko
2015-09-24  8:02 ` [patch net-next v3 05/10] rocker: push struct switchdev_trans down through rocker code Jiri Pirko
2015-09-24  8:02 ` [patch net-next v3 06/10] rocker: use switchdev transaction queue for allocated memory Jiri Pirko
2015-09-24  8:02 ` [patch net-next v3 07/10] switchdev: remove "NONE" transaction phase Jiri Pirko
2015-09-24  8:02 ` [patch net-next v3 08/10] switchdev: remove "ABORT" " Jiri Pirko
2015-09-24  8:02 ` [patch net-next v3 09/10] dsa: use prepare/commit switchdev transaction helpers Jiri Pirko
2015-09-24  8:02 ` [patch net-next v3 10/10] switchdev: reduce transaction phase enum down to a boolean Jiri Pirko
2015-09-25  3:05 ` [patch net-next v3 00/10] switchdev: transaction item queue and cleanup Scott Feldman
2015-09-25  6:00   ` David Miller
2015-09-25  6:04     ` Jiri Pirko

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