summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-12-05 20:08:04 -0500
committerDavid S. Miller <davem@davemloft.net>2017-12-05 20:08:04 -0500
commitb9f242047f2185f762e952d8d773f6d01f3c2d20 (patch)
tree91f74e51339a36da5305ac9d82bc04061a1495e0
parent9a63b255dffd6de31fe47a80d16d26d0291d3714 (diff)
parentcc1674eeee60ad158d16129837bd91f93a2f7b26 (diff)
downloadlinux-b9f242047f2185f762e952d8d773f6d01f3c2d20.tar.gz
Merge branch 'macb-rx-filter-cleanups'
Julia Cartwright says:

====================
macb rx filter cleanups

Here's a proper patchset based on net-next.

v1 -> v2:
  - Rebased on net-next
  - Add Nicolas's Acks
  - Reorder commits, putting the list_empty() cleanups prior to the
    others.
  - Added commit reverting the GFP_ATOMIC change.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/cadence/macb_main.c47
1 files changed, 23 insertions, 24 deletions
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index ebfeab853bf4..234667eaaa92 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -2796,10 +2796,11 @@ static int gem_add_flow_filter(struct net_device *netdev,
 	struct macb *bp = netdev_priv(netdev);
 	struct ethtool_rx_flow_spec *fs = &cmd->fs;
 	struct ethtool_rx_fs_item *item, *newfs;
+	unsigned long flags;
 	int ret = -EINVAL;
 	bool added = false;
 
-	newfs = kmalloc(sizeof(*newfs), GFP_ATOMIC);
+	newfs = kmalloc(sizeof(*newfs), GFP_KERNEL);
 	if (newfs == NULL)
 		return -ENOMEM;
 	memcpy(&newfs->fs, fs, sizeof(newfs->fs));
@@ -2811,25 +2812,23 @@ static int gem_add_flow_filter(struct net_device *netdev,
 			htonl(fs->h_u.tcp_ip4_spec.ip4dst),
 			htons(fs->h_u.tcp_ip4_spec.psrc), htons(fs->h_u.tcp_ip4_spec.pdst));
 
+	spin_lock_irqsave(&bp->rx_fs_lock, flags);
+
 	/* find correct place to add in list */
-	if (list_empty(&bp->rx_fs_list.list))
-		list_add(&newfs->list, &bp->rx_fs_list.list);
-	else {
-		list_for_each_entry(item, &bp->rx_fs_list.list, list) {
-			if (item->fs.location > newfs->fs.location) {
-				list_add_tail(&newfs->list, &item->list);
-				added = true;
-				break;
-			} else if (item->fs.location == fs->location) {
-				netdev_err(netdev, "Rule not added: location %d not free!\n",
-						fs->location);
-				ret = -EBUSY;
-				goto err;
-			}
+	list_for_each_entry(item, &bp->rx_fs_list.list, list) {
+		if (item->fs.location > newfs->fs.location) {
+			list_add_tail(&newfs->list, &item->list);
+			added = true;
+			break;
+		} else if (item->fs.location == fs->location) {
+			netdev_err(netdev, "Rule not added: location %d not free!\n",
+					fs->location);
+			ret = -EBUSY;
+			goto err;
 		}
-		if (!added)
-			list_add_tail(&newfs->list, &bp->rx_fs_list.list);
 	}
+	if (!added)
+		list_add_tail(&newfs->list, &bp->rx_fs_list.list);
 
 	gem_prog_cmp_regs(bp, fs);
 	bp->rx_fs_list.count++;
@@ -2837,9 +2836,11 @@ static int gem_add_flow_filter(struct net_device *netdev,
 	if (netdev->features & NETIF_F_NTUPLE)
 		gem_enable_flow_filters(bp, 1);
 
+	spin_unlock_irqrestore(&bp->rx_fs_lock, flags);
 	return 0;
 
 err:
+	spin_unlock_irqrestore(&bp->rx_fs_lock, flags);
 	kfree(newfs);
 	return ret;
 }
@@ -2850,9 +2851,9 @@ static int gem_del_flow_filter(struct net_device *netdev,
 	struct macb *bp = netdev_priv(netdev);
 	struct ethtool_rx_fs_item *item;
 	struct ethtool_rx_flow_spec *fs;
+	unsigned long flags;
 
-	if (list_empty(&bp->rx_fs_list.list))
-		return -EINVAL;
+	spin_lock_irqsave(&bp->rx_fs_lock, flags);
 
 	list_for_each_entry(item, &bp->rx_fs_list.list, list) {
 		if (item->fs.location == cmd->fs.location) {
@@ -2869,12 +2870,14 @@ static int gem_del_flow_filter(struct net_device *netdev,
 			gem_writel_n(bp, SCRT2, fs->location, 0);
 
 			list_del(&item->list);
-			kfree(item);
 			bp->rx_fs_list.count--;
+			spin_unlock_irqrestore(&bp->rx_fs_lock, flags);
+			kfree(item);
 			return 0;
 		}
 	}
 
+	spin_unlock_irqrestore(&bp->rx_fs_lock, flags);
 	return -EINVAL;
 }
 
@@ -2943,11 +2946,8 @@ static int gem_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
 static int gem_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
 {
 	struct macb *bp = netdev_priv(netdev);
-	unsigned long flags;
 	int ret;
 
-	spin_lock_irqsave(&bp->rx_fs_lock, flags);
-
 	switch (cmd->cmd) {
 	case ETHTOOL_SRXCLSRLINS:
 		if ((cmd->fs.location >= bp->max_tuples)
@@ -2966,7 +2966,6 @@ static int gem_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
 		ret = -EOPNOTSUPP;
 	}
 
-	spin_unlock_irqrestore(&bp->rx_fs_lock, flags);
 	return ret;
 }