Skip to content

Commit 7038cdb

Browse files
Julia Cartwrightdavem330
authored andcommitted
net: macb: reduce scope of rx_fs_lock-protected regions
Commit ae8223d ("net: macb: Added support for RX filtering") introduces a lock, rx_fs_lock which is intended to protect the list of rx_flow items and synchronize access to the hardware rx filtering registers. However, the region protected by this lock is overscoped, unnecessarily including things like slab allocation. Reduce this lock scope to only include operations which must be performed atomically: list traversal, addition, and removal, and hitting the macb filtering registers. This fixes the use of kmalloc w/ GFP_KERNEL in atomic context. Fixes: ae8223d ("net: macb: Added support for RX filtering") Cc: Rafal Ozieblo <[email protected]> Cc: Julia Lawall <[email protected]> Acked-by: Nicolas Ferre <[email protected]> Signed-off-by: Julia Cartwright <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a3da8ad commit 7038cdb

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

drivers/net/ethernet/cadence/macb_main.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2796,6 +2796,7 @@ static int gem_add_flow_filter(struct net_device *netdev,
27962796
struct macb *bp = netdev_priv(netdev);
27972797
struct ethtool_rx_flow_spec *fs = &cmd->fs;
27982798
struct ethtool_rx_fs_item *item, *newfs;
2799+
unsigned long flags;
27992800
int ret = -EINVAL;
28002801
bool added = false;
28012802

@@ -2811,6 +2812,8 @@ static int gem_add_flow_filter(struct net_device *netdev,
28112812
htonl(fs->h_u.tcp_ip4_spec.ip4dst),
28122813
htons(fs->h_u.tcp_ip4_spec.psrc), htons(fs->h_u.tcp_ip4_spec.pdst));
28132814

2815+
spin_lock_irqsave(&bp->rx_fs_lock, flags);
2816+
28142817
/* find correct place to add in list */
28152818
list_for_each_entry(item, &bp->rx_fs_list.list, list) {
28162819
if (item->fs.location > newfs->fs.location) {
@@ -2833,9 +2836,11 @@ static int gem_add_flow_filter(struct net_device *netdev,
28332836
if (netdev->features & NETIF_F_NTUPLE)
28342837
gem_enable_flow_filters(bp, 1);
28352838

2839+
spin_unlock_irqrestore(&bp->rx_fs_lock, flags);
28362840
return 0;
28372841

28382842
err:
2843+
spin_unlock_irqrestore(&bp->rx_fs_lock, flags);
28392844
kfree(newfs);
28402845
return ret;
28412846
}
@@ -2846,6 +2851,9 @@ static int gem_del_flow_filter(struct net_device *netdev,
28462851
struct macb *bp = netdev_priv(netdev);
28472852
struct ethtool_rx_fs_item *item;
28482853
struct ethtool_rx_flow_spec *fs;
2854+
unsigned long flags;
2855+
2856+
spin_lock_irqsave(&bp->rx_fs_lock, flags);
28492857

28502858
list_for_each_entry(item, &bp->rx_fs_list.list, list) {
28512859
if (item->fs.location == cmd->fs.location) {
@@ -2862,12 +2870,14 @@ static int gem_del_flow_filter(struct net_device *netdev,
28622870
gem_writel_n(bp, SCRT2, fs->location, 0);
28632871

28642872
list_del(&item->list);
2865-
kfree(item);
28662873
bp->rx_fs_list.count--;
2874+
spin_unlock_irqrestore(&bp->rx_fs_lock, flags);
2875+
kfree(item);
28672876
return 0;
28682877
}
28692878
}
28702879

2880+
spin_unlock_irqrestore(&bp->rx_fs_lock, flags);
28712881
return -EINVAL;
28722882
}
28732883

@@ -2936,11 +2946,8 @@ static int gem_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
29362946
static int gem_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
29372947
{
29382948
struct macb *bp = netdev_priv(netdev);
2939-
unsigned long flags;
29402949
int ret;
29412950

2942-
spin_lock_irqsave(&bp->rx_fs_lock, flags);
2943-
29442951
switch (cmd->cmd) {
29452952
case ETHTOOL_SRXCLSRLINS:
29462953
if ((cmd->fs.location >= bp->max_tuples)
@@ -2959,7 +2966,6 @@ static int gem_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
29592966
ret = -EOPNOTSUPP;
29602967
}
29612968

2962-
spin_unlock_irqrestore(&bp->rx_fs_lock, flags);
29632969
return ret;
29642970
}
29652971

0 commit comments

Comments
 (0)