diff mbox series

[net-next,5/9] nfp: flower: remove list infastructure from MAC offload

Message ID 20190116030659.27755-6-jakub.kicinski@netronome.com
State Accepted
Delegated to: David Miller
Headers show
Series nfp: flower: improve flower resilience | expand

Commit Message

Jakub Kicinski Jan. 16, 2019, 3:06 a.m. UTC
From: John Hurley <john.hurley@netronome.com>

Potential MAC destination addresses for tunnel end-points are offloaded to
firmware. This was done by building a list of such MACs and writing to
firmware as blocks of addresses.

Simplify this code by removing the list format and sending a new message
for each offloaded MAC.

This is in preparation for delete MAC messages. There will be one delete
flag per message so we cannot assume that this applies to all addresses
in a list.

Signed-off-by: John Hurley <john.hurley@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 .../net/ethernet/netronome/nfp/flower/main.h  |   7 -
 .../net/ethernet/netronome/nfp/flower/match.c |   3 -
 .../netronome/nfp/flower/tunnel_conf.c        | 159 ++++--------------
 3 files changed, 37 insertions(+), 132 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h
index 977667ae0b5a..1b9d6fd084d8 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -58,29 +58,23 @@  struct nfp_fl_stats_id {
 
 /**
  * struct nfp_fl_tunnel_offloads - priv data for tunnel offloads
- * @mac_off_list:	List of MAC addresses to offload
  * @mac_index_list:	List of unique 8-bit indexes for non NFP netdevs
  * @ipv4_off_list:	List of IPv4 addresses to offload
  * @neigh_off_list:	List of neighbour offloads
- * @mac_off_lock:	Lock for the MAC address list
  * @mac_index_lock:	Lock for the MAC index list
  * @ipv4_off_lock:	Lock for the IPv4 address list
  * @neigh_off_lock:	Lock for the neighbour address list
  * @mac_off_ids:	IDA to manage id assignment for offloaded MACs
- * @mac_off_count:	Number of MACs in address list
  * @neigh_nb:		Notifier to monitor neighbour state
  */
 struct nfp_fl_tunnel_offloads {
-	struct list_head mac_off_list;
 	struct list_head mac_index_list;
 	struct list_head ipv4_off_list;
 	struct list_head neigh_off_list;
-	struct mutex mac_off_lock;
 	struct mutex mac_index_lock;
 	struct mutex ipv4_off_lock;
 	spinlock_t neigh_off_lock;
 	struct ida mac_off_ids;
-	int mac_off_count;
 	struct notifier_block neigh_nb;
 };
 
@@ -268,7 +262,6 @@  void nfp_tunnel_config_stop(struct nfp_app *app);
 int nfp_tunnel_mac_event_handler(struct nfp_app *app,
 				 struct net_device *netdev,
 				 unsigned long event, void *ptr);
-void nfp_tunnel_write_macs(struct nfp_app *app);
 void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4);
 void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4);
 void nfp_tunnel_request_route(struct nfp_app *app, struct sk_buff *skb);
diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c
index cdf75595f627..c04a0d6b0184 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/match.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/match.c
@@ -403,9 +403,6 @@  int nfp_flower_compile_flow_match(struct nfp_app *app,
 		ext += sizeof(struct nfp_flower_ipv4_udp_tun);
 		msk += sizeof(struct nfp_flower_ipv4_udp_tun);
 
-		/* Configure tunnel end point MAC. */
-		nfp_tunnel_write_macs(app);
-
 		/* Store the tunnel destination in the rule data.
 		 * This must be present and be an exact match.
 		 */
diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
index 4e509c8c1aca..9b8c73bfcb5b 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
@@ -99,32 +99,17 @@  struct nfp_ipv4_addr_entry {
 };
 
 /**
- * struct nfp_tun_mac_addr - configure MAC address of tunnel EP on NFP
+ * struct nfp_tun_mac_addr_offload - configure MAC address of tunnel EP on NFP
  * @reserved:	reserved for future use
- * @count:	number of MAC addresses in the message
- * @addresses.index:	index of MAC address in the lookup table
- * @addresses.addr:	interface MAC address
- * @addresses:	series of MACs to offload
+ * @count:	number of MAC addresses in the message (should be 1)
+ * @index:	index of MAC address in the lookup table
+ * @addr:	interface MAC address
  */
-struct nfp_tun_mac_addr {
+struct nfp_tun_mac_addr_offload {
 	__be16 reserved;
 	__be16 count;
-	struct index_mac_addr {
-		__be16 index;
-		u8 addr[ETH_ALEN];
-	} addresses[];
-};
-
-/**
- * struct nfp_tun_mac_offload_entry - list of MACs to offload
- * @index:	index of MAC address for offloading
- * @addr:	interface MAC address
- * @list:	list pointer
- */
-struct nfp_tun_mac_offload_entry {
 	__be16 index;
 	u8 addr[ETH_ALEN];
-	struct list_head list;
 };
 
 #define NFP_MAX_MAC_INDEX       0xff
@@ -473,64 +458,6 @@  void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4)
 	nfp_tun_write_ipv4_list(app);
 }
 
-void nfp_tunnel_write_macs(struct nfp_app *app)
-{
-	struct nfp_flower_priv *priv = app->priv;
-	struct nfp_tun_mac_offload_entry *entry;
-	struct nfp_tun_mac_addr *payload;
-	struct list_head *ptr, *storage;
-	int mac_count, err, pay_size;
-
-	mutex_lock(&priv->tun.mac_off_lock);
-	if (!priv->tun.mac_off_count) {
-		mutex_unlock(&priv->tun.mac_off_lock);
-		return;
-	}
-
-	pay_size = sizeof(struct nfp_tun_mac_addr) +
-		   sizeof(struct index_mac_addr) * priv->tun.mac_off_count;
-
-	payload = kzalloc(pay_size, GFP_KERNEL);
-	if (!payload) {
-		mutex_unlock(&priv->tun.mac_off_lock);
-		return;
-	}
-
-	payload->count = cpu_to_be16(priv->tun.mac_off_count);
-
-	mac_count = 0;
-	list_for_each_safe(ptr, storage, &priv->tun.mac_off_list) {
-		entry = list_entry(ptr, struct nfp_tun_mac_offload_entry,
-				   list);
-		payload->addresses[mac_count].index = entry->index;
-		ether_addr_copy(payload->addresses[mac_count].addr,
-				entry->addr);
-		mac_count++;
-	}
-
-	err = nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_MAC,
-				       pay_size, payload, GFP_KERNEL);
-
-	kfree(payload);
-
-	if (err) {
-		mutex_unlock(&priv->tun.mac_off_lock);
-		/* Write failed so retain list for future retry. */
-		return;
-	}
-
-	/* If list was successfully offloaded, flush it. */
-	list_for_each_safe(ptr, storage, &priv->tun.mac_off_list) {
-		entry = list_entry(ptr, struct nfp_tun_mac_offload_entry,
-				   list);
-		list_del(&entry->list);
-		kfree(entry);
-	}
-
-	priv->tun.mac_off_count = 0;
-	mutex_unlock(&priv->tun.mac_off_lock);
-}
-
 static int nfp_tun_get_mac_idx(struct nfp_app *app, int ifindex)
 {
 	struct nfp_flower_priv *priv = app->priv;
@@ -588,28 +515,35 @@  static void nfp_tun_del_mac_idx(struct nfp_app *app, int ifindex)
 	mutex_unlock(&priv->tun.mac_index_lock);
 }
 
-static void nfp_tun_add_to_mac_offload_list(struct net_device *netdev,
-					    struct nfp_app *app)
+static int __nfp_tunnel_offload_mac(struct nfp_app *app, u8 *mac, u16 idx)
+{
+	struct nfp_tun_mac_addr_offload payload;
+
+	memset(&payload, 0, sizeof(payload));
+
+	/* FW supports multiple MACs per cmsg but restrict to single. */
+	payload.count = cpu_to_be16(1);
+	payload.index = cpu_to_be16(idx);
+	ether_addr_copy(payload.addr, mac);
+
+	return nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_MAC,
+					sizeof(struct nfp_tun_mac_addr_offload),
+					&payload, GFP_KERNEL);
+}
+
+static int
+nfp_tunnel_offload_mac(struct nfp_app *app, struct net_device *netdev)
 {
-	struct nfp_flower_priv *priv = app->priv;
-	struct nfp_tun_mac_offload_entry *entry;
 	u16 nfp_mac_idx;
 	int port = 0;
 
-	/* Check if MAC should be offloaded. */
-	if (!is_valid_ether_addr(netdev->dev_addr))
-		return;
-
 	if (nfp_netdev_is_nfp_repr(netdev))
 		port = nfp_repr_get_port_id(netdev);
 	else if (!nfp_fl_is_netdev_to_offload(netdev))
-		return;
+		return 0;
 
-	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-	if (!entry) {
-		nfp_flower_cmsg_warn(app, "Mem fail when offloading MAC.\n");
-		return;
-	}
+	if (!is_valid_ether_addr(netdev->dev_addr))
+		return -EINVAL;
 
 	if (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port) ==
 	    NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT) {
@@ -618,40 +552,33 @@  static void nfp_tun_add_to_mac_offload_list(struct net_device *netdev,
 		/* Must assign our own unique 8-bit index. */
 		int idx = nfp_tun_get_mac_idx(app, netdev->ifindex);
 
-		if (idx < 0) {
-			nfp_flower_cmsg_warn(app, "Can't assign non-repr MAC index.\n");
-			kfree(entry);
-			return;
-		}
+		if (idx < 0)
+			return idx;
+
 		nfp_mac_idx = idx << 8 | NFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT;
 	} else {
-		kfree(entry);
-		return;
+		return 0;
 	}
 
-	entry->index = cpu_to_be16(nfp_mac_idx);
-	ether_addr_copy(entry->addr, netdev->dev_addr);
-
-	mutex_lock(&priv->tun.mac_off_lock);
-	priv->tun.mac_off_count++;
-	list_add_tail(&entry->list, &priv->tun.mac_off_list);
-	mutex_unlock(&priv->tun.mac_off_lock);
+	return __nfp_tunnel_offload_mac(app, netdev->dev_addr, nfp_mac_idx);
 }
 
 int nfp_tunnel_mac_event_handler(struct nfp_app *app,
 				 struct net_device *netdev,
 				 unsigned long event, void *ptr)
 {
+	int err;
+
 	if (event == NETDEV_DOWN || event == NETDEV_UNREGISTER) {
 		/* If non-nfp netdev then free its offload index. */
 		if (nfp_fl_is_netdev_to_offload(netdev))
 			nfp_tun_del_mac_idx(app, netdev->ifindex);
 	} else if (event == NETDEV_UP || event == NETDEV_CHANGEADDR ||
 		   event == NETDEV_REGISTER) {
-		nfp_tun_add_to_mac_offload_list(netdev, app);
-
-		/* Force a list write to keep NFP up to date. */
-		nfp_tunnel_write_macs(app);
+		err = nfp_tunnel_offload_mac(app, netdev);
+		if (err)
+			nfp_flower_cmsg_warn(app, "Failed to offload MAC on %s.\n",
+					     netdev_name(netdev));
 	}
 	return NOTIFY_OK;
 }
@@ -661,9 +588,6 @@  int nfp_tunnel_config_start(struct nfp_app *app)
 	struct nfp_flower_priv *priv = app->priv;
 
 	/* Initialise priv data for MAC offloading. */
-	priv->tun.mac_off_count = 0;
-	mutex_init(&priv->tun.mac_off_lock);
-	INIT_LIST_HEAD(&priv->tun.mac_off_list);
 	mutex_init(&priv->tun.mac_index_lock);
 	INIT_LIST_HEAD(&priv->tun.mac_index_list);
 	ida_init(&priv->tun.mac_off_ids);
@@ -682,7 +606,6 @@  int nfp_tunnel_config_start(struct nfp_app *app)
 
 void nfp_tunnel_config_stop(struct nfp_app *app)
 {
-	struct nfp_tun_mac_offload_entry *mac_entry;
 	struct nfp_flower_priv *priv = app->priv;
 	struct nfp_ipv4_route_entry *route_entry;
 	struct nfp_tun_mac_non_nfp_idx *mac_idx;
@@ -691,14 +614,6 @@  void nfp_tunnel_config_stop(struct nfp_app *app)
 
 	unregister_netevent_notifier(&priv->tun.neigh_nb);
 
-	/* Free any memory that may be occupied by MAC list. */
-	list_for_each_safe(ptr, storage, &priv->tun.mac_off_list) {
-		mac_entry = list_entry(ptr, struct nfp_tun_mac_offload_entry,
-				       list);
-		list_del(&mac_entry->list);
-		kfree(mac_entry);
-	}
-
 	/* Free any memory that may be occupied by MAC index list. */
 	list_for_each_safe(ptr, storage, &priv->tun.mac_index_list) {
 		mac_idx = list_entry(ptr, struct nfp_tun_mac_non_nfp_idx,