Skip to content

Commit 298f70b

Browse files
jonrebmdavem330
authored andcommitted
net: dpaa: use __dev_mc_sync in dpaa_set_rx_mode()
The original driver first unregisters then re-registers all multicast addresses in the struct net_device_ops::ndo_set_rx_mode() callback. As the networking stack calls ndo_set_rx_mode() if a single multicast address change occurs, a significant amount of time may be used to first unregister and then re-register unchanged multicast addresses. This leads to performance issues when tracking large numbers of multicast addresses. Replace the unregister and register loop and the hand crafted mc_addr_list list handling with __dev_mc_sync(), to only update entries which have changed. On profiling with an fsl_dpa NIC, this patch presented a speedup of around 40 when successively setting up 2000 multicast groups using setsockopt(), without drawbacks on smaller numbers of multicast groups. Signed-off-by: Jonas Rebmann <[email protected]> Reviewed-by: Sean Anderson <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 69a3272 commit 298f70b

File tree

6 files changed

+18
-49
lines changed

6 files changed

+18
-49
lines changed

drivers/net/ethernet/freescale/dpaa/dpaa_eth.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,22 @@ static int dpaa_set_mac_address(struct net_device *net_dev, void *addr)
463463
return 0;
464464
}
465465

466+
static int dpaa_addr_sync(struct net_device *net_dev, const u8 *addr)
467+
{
468+
const struct dpaa_priv *priv = netdev_priv(net_dev);
469+
470+
return priv->mac_dev->add_hash_mac_addr(priv->mac_dev->fman_mac,
471+
(enet_addr_t *)addr);
472+
}
473+
474+
static int dpaa_addr_unsync(struct net_device *net_dev, const u8 *addr)
475+
{
476+
const struct dpaa_priv *priv = netdev_priv(net_dev);
477+
478+
return priv->mac_dev->remove_hash_mac_addr(priv->mac_dev->fman_mac,
479+
(enet_addr_t *)addr);
480+
}
481+
466482
static void dpaa_set_rx_mode(struct net_device *net_dev)
467483
{
468484
const struct dpaa_priv *priv;
@@ -490,9 +506,9 @@ static void dpaa_set_rx_mode(struct net_device *net_dev)
490506
err);
491507
}
492508

493-
err = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
509+
err = __dev_mc_sync(net_dev, dpaa_addr_sync, dpaa_addr_unsync);
494510
if (err < 0)
495-
netif_err(priv, drv, net_dev, "mac_dev->set_multi() = %d\n",
511+
netif_err(priv, drv, net_dev, "dpaa_addr_sync() = %d\n",
496512
err);
497513
}
498514

drivers/net/ethernet/freescale/fman/fman_dtsec.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1415,7 +1415,6 @@ int dtsec_initialization(struct mac_device *mac_dev,
14151415
mac_dev->set_exception = dtsec_set_exception;
14161416
mac_dev->set_allmulti = dtsec_set_allmulti;
14171417
mac_dev->set_tstamp = dtsec_set_tstamp;
1418-
mac_dev->set_multi = fman_set_multi;
14191418
mac_dev->enable = dtsec_enable;
14201419
mac_dev->disable = dtsec_disable;
14211420

drivers/net/ethernet/freescale/fman/fman_memac.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1087,7 +1087,6 @@ int memac_initialization(struct mac_device *mac_dev,
10871087
mac_dev->set_exception = memac_set_exception;
10881088
mac_dev->set_allmulti = memac_set_allmulti;
10891089
mac_dev->set_tstamp = memac_set_tstamp;
1090-
mac_dev->set_multi = fman_set_multi;
10911090
mac_dev->enable = memac_enable;
10921091
mac_dev->disable = memac_disable;
10931092

drivers/net/ethernet/freescale/fman/fman_tgec.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,6 @@ int tgec_initialization(struct mac_device *mac_dev,
771771
mac_dev->set_exception = tgec_set_exception;
772772
mac_dev->set_allmulti = tgec_set_allmulti;
773773
mac_dev->set_tstamp = tgec_set_tstamp;
774-
mac_dev->set_multi = fman_set_multi;
775774
mac_dev->enable = tgec_enable;
776775
mac_dev->disable = tgec_disable;
777776

drivers/net/ethernet/freescale/fman/mac.c

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ MODULE_DESCRIPTION("FSL FMan MAC API based driver");
3232
struct mac_priv_s {
3333
u8 cell_index;
3434
struct fman *fman;
35-
/* List of multicast addresses */
36-
struct list_head mc_addr_list;
3735
struct platform_device *eth_dev;
3836
u16 speed;
3937
};
@@ -57,44 +55,6 @@ static void mac_exception(struct mac_device *mac_dev,
5755
__func__, ex);
5856
}
5957

60-
int fman_set_multi(struct net_device *net_dev, struct mac_device *mac_dev)
61-
{
62-
struct mac_priv_s *priv;
63-
struct mac_address *old_addr, *tmp;
64-
struct netdev_hw_addr *ha;
65-
int err;
66-
enet_addr_t *addr;
67-
68-
priv = mac_dev->priv;
69-
70-
/* Clear previous address list */
71-
list_for_each_entry_safe(old_addr, tmp, &priv->mc_addr_list, list) {
72-
addr = (enet_addr_t *)old_addr->addr;
73-
err = mac_dev->remove_hash_mac_addr(mac_dev->fman_mac, addr);
74-
if (err < 0)
75-
return err;
76-
77-
list_del(&old_addr->list);
78-
kfree(old_addr);
79-
}
80-
81-
/* Add all the addresses from the new list */
82-
netdev_for_each_mc_addr(ha, net_dev) {
83-
addr = (enet_addr_t *)ha->addr;
84-
err = mac_dev->add_hash_mac_addr(mac_dev->fman_mac, addr);
85-
if (err < 0)
86-
return err;
87-
88-
tmp = kmalloc(sizeof(*tmp), GFP_ATOMIC);
89-
if (!tmp)
90-
return -ENOMEM;
91-
92-
ether_addr_copy(tmp->addr, ha->addr);
93-
list_add(&tmp->list, &priv->mc_addr_list);
94-
}
95-
return 0;
96-
}
97-
9858
static DEFINE_MUTEX(eth_lock);
9959

10060
static struct platform_device *dpaa_eth_add_device(int fman_id,
@@ -181,8 +141,6 @@ static int mac_probe(struct platform_device *_of_dev)
181141
mac_dev->priv = priv;
182142
mac_dev->dev = dev;
183143

184-
INIT_LIST_HEAD(&priv->mc_addr_list);
185-
186144
/* Get the FM node */
187145
dev_node = of_get_parent(mac_node);
188146
if (!dev_node) {

drivers/net/ethernet/freescale/fman/mac.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ struct mac_device {
3939
int (*change_addr)(struct fman_mac *mac_dev, const enet_addr_t *enet_addr);
4040
int (*set_allmulti)(struct fman_mac *mac_dev, bool enable);
4141
int (*set_tstamp)(struct fman_mac *mac_dev, bool enable);
42-
int (*set_multi)(struct net_device *net_dev,
43-
struct mac_device *mac_dev);
4442
int (*set_exception)(struct fman_mac *mac_dev,
4543
enum fman_mac_exceptions exception, bool enable);
4644
int (*add_hash_mac_addr)(struct fman_mac *mac_dev,

0 commit comments

Comments
 (0)