Skip to content

Commit de1b23b

Browse files
committed
Merge branch 'dsa-deferred-xmit'
Vladimir Oltean says: ==================== Improvements to the DSA deferred xmit After the feedback received on v1: https://www.spinics.net/lists/netdev/msg622617.html I've decided to move the deferred xmit implementation completely within the sja1105 driver. The executive summary for this series is the same as it was for v1 (better for everybody): - For those who don't use it, thanks to one less assignment in the hotpath (and now also thanks to less code in the DSA core) - For those who do, by making its scheduling more amenable and moving it outside the generic workqueue (since it still deals with packet hotpath, after all) There are some simplification (1/3) and cosmetic (3/3) patches in the areas next to the code touched by the main patch (2/3). ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 8bd17dc + 2821d50 commit de1b23b

File tree

6 files changed

+94
-96
lines changed

6 files changed

+94
-96
lines changed

drivers/net/dsa/sja1105/sja1105_main.c

Lines changed: 75 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -426,14 +426,6 @@ static int sja1105_init_general_params(struct sja1105_private *priv)
426426
.tpid2 = ETH_P_SJA1105,
427427
};
428428
struct sja1105_table *table;
429-
int i, k = 0;
430-
431-
for (i = 0; i < SJA1105_NUM_PORTS; i++) {
432-
if (dsa_is_dsa_port(priv->ds, i))
433-
default_general_params.casc_port = i;
434-
else if (dsa_is_user_port(priv->ds, i))
435-
priv->ports[i].mgmt_slot = k++;
436-
}
437429

438430
table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS];
439431

@@ -1740,6 +1732,16 @@ static int sja1105_setup(struct dsa_switch *ds)
17401732
static void sja1105_teardown(struct dsa_switch *ds)
17411733
{
17421734
struct sja1105_private *priv = ds->priv;
1735+
int port;
1736+
1737+
for (port = 0; port < SJA1105_NUM_PORTS; port++) {
1738+
struct sja1105_port *sp = &priv->ports[port];
1739+
1740+
if (!dsa_is_user_port(ds, port))
1741+
continue;
1742+
1743+
kthread_destroy_worker(sp->xmit_worker);
1744+
}
17431745

17441746
sja1105_tas_teardown(ds);
17451747
sja1105_ptp_clock_unregister(ds);
@@ -1761,6 +1763,18 @@ static int sja1105_port_enable(struct dsa_switch *ds, int port,
17611763
return 0;
17621764
}
17631765

1766+
static void sja1105_port_disable(struct dsa_switch *ds, int port)
1767+
{
1768+
struct sja1105_private *priv = ds->priv;
1769+
struct sja1105_port *sp = &priv->ports[port];
1770+
1771+
if (!dsa_is_user_port(ds, port))
1772+
return;
1773+
1774+
kthread_cancel_work_sync(&sp->xmit_work);
1775+
skb_queue_purge(&sp->xmit_queue);
1776+
}
1777+
17641778
static int sja1105_mgmt_xmit(struct dsa_switch *ds, int port, int slot,
17651779
struct sk_buff *skb, bool takets)
17661780
{
@@ -1819,47 +1833,36 @@ static int sja1105_mgmt_xmit(struct dsa_switch *ds, int port, int slot,
18191833
return NETDEV_TX_OK;
18201834
}
18211835

1836+
#define work_to_port(work) \
1837+
container_of((work), struct sja1105_port, xmit_work)
1838+
#define tagger_to_sja1105(t) \
1839+
container_of((t), struct sja1105_private, tagger_data)
1840+
18221841
/* Deferred work is unfortunately necessary because setting up the management
18231842
* route cannot be done from atomit context (SPI transfer takes a sleepable
18241843
* lock on the bus)
18251844
*/
1826-
static netdev_tx_t sja1105_port_deferred_xmit(struct dsa_switch *ds, int port,
1827-
struct sk_buff *skb)
1845+
static void sja1105_port_deferred_xmit(struct kthread_work *work)
18281846
{
1829-
struct sja1105_private *priv = ds->priv;
1830-
struct sja1105_port *sp = &priv->ports[port];
1831-
int slot = sp->mgmt_slot;
1832-
struct sk_buff *clone;
1833-
1834-
/* The tragic fact about the switch having 4x2 slots for installing
1835-
* management routes is that all of them except one are actually
1836-
* useless.
1837-
* If 2 slots are simultaneously configured for two BPDUs sent to the
1838-
* same (multicast) DMAC but on different egress ports, the switch
1839-
* would confuse them and redirect first frame it receives on the CPU
1840-
* port towards the port configured on the numerically first slot
1841-
* (therefore wrong port), then second received frame on second slot
1842-
* (also wrong port).
1843-
* So for all practical purposes, there needs to be a lock that
1844-
* prevents that from happening. The slot used here is utterly useless
1845-
* (could have simply been 0 just as fine), but we are doing it
1846-
* nonetheless, in case a smarter idea ever comes up in the future.
1847-
*/
1848-
mutex_lock(&priv->mgmt_lock);
1847+
struct sja1105_port *sp = work_to_port(work);
1848+
struct sja1105_tagger_data *tagger_data = sp->data;
1849+
struct sja1105_private *priv = tagger_to_sja1105(tagger_data);
1850+
int port = sp - priv->ports;
1851+
struct sk_buff *skb;
18491852

1850-
/* The clone, if there, was made by dsa_skb_tx_timestamp */
1851-
clone = DSA_SKB_CB(skb)->clone;
1853+
while ((skb = skb_dequeue(&sp->xmit_queue)) != NULL) {
1854+
struct sk_buff *clone = DSA_SKB_CB(skb)->clone;
18521855

1853-
sja1105_mgmt_xmit(ds, port, slot, skb, !!clone);
1856+
mutex_lock(&priv->mgmt_lock);
18541857

1855-
if (!clone)
1856-
goto out;
1858+
sja1105_mgmt_xmit(priv->ds, port, 0, skb, !!clone);
18571859

1858-
sja1105_ptp_txtstamp_skb(ds, port, clone);
1860+
/* The clone, if there, was made by dsa_skb_tx_timestamp */
1861+
if (clone)
1862+
sja1105_ptp_txtstamp_skb(priv->ds, port, clone);
18591863

1860-
out:
1861-
mutex_unlock(&priv->mgmt_lock);
1862-
return NETDEV_TX_OK;
1864+
mutex_unlock(&priv->mgmt_lock);
1865+
}
18631866
}
18641867

18651868
/* The MAXAGE setting belongs to the L2 Forwarding Parameters table,
@@ -1990,6 +1993,7 @@ static const struct dsa_switch_ops sja1105_switch_ops = {
19901993
.get_sset_count = sja1105_get_sset_count,
19911994
.get_ts_info = sja1105_get_ts_info,
19921995
.port_enable = sja1105_port_enable,
1996+
.port_disable = sja1105_port_disable,
19931997
.port_fdb_dump = sja1105_fdb_dump,
19941998
.port_fdb_add = sja1105_fdb_add,
19951999
.port_fdb_del = sja1105_fdb_del,
@@ -2003,7 +2007,6 @@ static const struct dsa_switch_ops sja1105_switch_ops = {
20032007
.port_mdb_prepare = sja1105_mdb_prepare,
20042008
.port_mdb_add = sja1105_mdb_add,
20052009
.port_mdb_del = sja1105_mdb_del,
2006-
.port_deferred_xmit = sja1105_port_deferred_xmit,
20072010
.port_hwtstamp_get = sja1105_hwtstamp_get,
20082011
.port_hwtstamp_set = sja1105_hwtstamp_set,
20092012
.port_rxtstamp = sja1105_port_rxtstamp,
@@ -2055,7 +2058,7 @@ static int sja1105_probe(struct spi_device *spi)
20552058
struct device *dev = &spi->dev;
20562059
struct sja1105_private *priv;
20572060
struct dsa_switch *ds;
2058-
int rc, i;
2061+
int rc, port;
20592062

20602063
if (!dev->of_node) {
20612064
dev_err(dev, "No DTS bindings for SJA1105 driver\n");
@@ -2120,15 +2123,42 @@ static int sja1105_probe(struct spi_device *spi)
21202123
return rc;
21212124

21222125
/* Connections between dsa_port and sja1105_port */
2123-
for (i = 0; i < SJA1105_NUM_PORTS; i++) {
2124-
struct sja1105_port *sp = &priv->ports[i];
2126+
for (port = 0; port < SJA1105_NUM_PORTS; port++) {
2127+
struct sja1105_port *sp = &priv->ports[port];
2128+
struct dsa_port *dp = dsa_to_port(ds, port);
2129+
struct net_device *slave;
21252130

2126-
dsa_to_port(ds, i)->priv = sp;
2127-
sp->dp = dsa_to_port(ds, i);
2131+
if (!dsa_is_user_port(ds, port))
2132+
continue;
2133+
2134+
dp->priv = sp;
2135+
sp->dp = dp;
21282136
sp->data = tagger_data;
2137+
slave = dp->slave;
2138+
kthread_init_work(&sp->xmit_work, sja1105_port_deferred_xmit);
2139+
sp->xmit_worker = kthread_create_worker(0, "%s_xmit",
2140+
slave->name);
2141+
if (IS_ERR(sp->xmit_worker)) {
2142+
rc = PTR_ERR(sp->xmit_worker);
2143+
dev_err(ds->dev,
2144+
"failed to create deferred xmit thread: %d\n",
2145+
rc);
2146+
goto out;
2147+
}
2148+
skb_queue_head_init(&sp->xmit_queue);
21292149
}
21302150

21312151
return 0;
2152+
out:
2153+
while (port-- > 0) {
2154+
struct sja1105_port *sp = &priv->ports[port];
2155+
2156+
if (!dsa_is_user_port(ds, port))
2157+
continue;
2158+
2159+
kthread_destroy_worker(sp->xmit_worker);
2160+
}
2161+
return rc;
21322162
}
21332163

21342164
static int sja1105_remove(struct spi_device *spi)

include/linux/dsa/sja1105.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,12 @@ struct sja1105_skb_cb {
5353
((struct sja1105_skb_cb *)DSA_SKB_CB_PRIV(skb))
5454

5555
struct sja1105_port {
56+
struct kthread_worker *xmit_worker;
57+
struct kthread_work xmit_work;
58+
struct sk_buff_head xmit_queue;
5659
struct sja1105_tagger_data *data;
5760
struct dsa_port *dp;
5861
bool hwts_tx_en;
59-
int mgmt_slot;
6062
};
6163

6264
#endif /* _NET_DSA_SJA1105_H */

include/net/dsa.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ struct dsa_device_ops {
9090

9191
struct dsa_skb_cb {
9292
struct sk_buff *clone;
93-
bool deferred_xmit;
9493
};
9594

9695
struct __dsa_skb_cb {
@@ -192,9 +191,6 @@ struct dsa_port {
192191
struct phylink *pl;
193192
struct phylink_config pl_config;
194193

195-
struct work_struct xmit_work;
196-
struct sk_buff_head xmit_queue;
197-
198194
struct list_head list;
199195

200196
/*
@@ -564,11 +560,6 @@ struct dsa_switch_ops {
564560
bool (*port_rxtstamp)(struct dsa_switch *ds, int port,
565561
struct sk_buff *skb, unsigned int type);
566562

567-
/*
568-
* Deferred frame Tx
569-
*/
570-
netdev_tx_t (*port_deferred_xmit)(struct dsa_switch *ds, int port,
571-
struct sk_buff *skb);
572563
/* Devlink parameters */
573564
int (*devlink_param_get)(struct dsa_switch *ds, u32 id,
574565
struct devlink_param_gset_ctx *ctx);

net/dsa/dsa_priv.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,6 @@ int dsa_slave_resume(struct net_device *slave_dev);
162162
int dsa_slave_register_notifier(void);
163163
void dsa_slave_unregister_notifier(void);
164164

165-
void *dsa_defer_xmit(struct sk_buff *skb, struct net_device *dev);
166-
167165
static inline struct dsa_port *dsa_slave_to_port(const struct net_device *dev)
168166
{
169167
struct dsa_slave_priv *p = netdev_priv(dev);

net/dsa/slave.c

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,6 @@ static int dsa_slave_close(struct net_device *dev)
116116
struct net_device *master = dsa_slave_to_master(dev);
117117
struct dsa_port *dp = dsa_slave_to_port(dev);
118118

119-
cancel_work_sync(&dp->xmit_work);
120-
skb_queue_purge(&dp->xmit_queue);
121-
122119
phylink_stop(dp->pl);
123120

124121
dsa_port_disable(dp);
@@ -518,7 +515,6 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
518515
s->tx_bytes += skb->len;
519516
u64_stats_update_end(&s->syncp);
520517

521-
DSA_SKB_CB(skb)->deferred_xmit = false;
522518
DSA_SKB_CB(skb)->clone = NULL;
523519

524520
/* Identify PTP protocol packets, clone them, and pass them to the
@@ -531,39 +527,13 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
531527
*/
532528
nskb = p->xmit(skb, dev);
533529
if (!nskb) {
534-
if (!DSA_SKB_CB(skb)->deferred_xmit)
535-
kfree_skb(skb);
530+
kfree_skb(skb);
536531
return NETDEV_TX_OK;
537532
}
538533

539534
return dsa_enqueue_skb(nskb, dev);
540535
}
541536

542-
void *dsa_defer_xmit(struct sk_buff *skb, struct net_device *dev)
543-
{
544-
struct dsa_port *dp = dsa_slave_to_port(dev);
545-
546-
DSA_SKB_CB(skb)->deferred_xmit = true;
547-
548-
skb_queue_tail(&dp->xmit_queue, skb);
549-
schedule_work(&dp->xmit_work);
550-
return NULL;
551-
}
552-
EXPORT_SYMBOL_GPL(dsa_defer_xmit);
553-
554-
static void dsa_port_xmit_work(struct work_struct *work)
555-
{
556-
struct dsa_port *dp = container_of(work, struct dsa_port, xmit_work);
557-
struct dsa_switch *ds = dp->ds;
558-
struct sk_buff *skb;
559-
560-
if (unlikely(!ds->ops->port_deferred_xmit))
561-
return;
562-
563-
while ((skb = skb_dequeue(&dp->xmit_queue)) != NULL)
564-
ds->ops->port_deferred_xmit(ds, dp->index, skb);
565-
}
566-
567537
/* ethtool operations *******************************************************/
568538

569539
static void dsa_slave_get_drvinfo(struct net_device *dev,
@@ -1367,9 +1337,6 @@ int dsa_slave_suspend(struct net_device *slave_dev)
13671337
if (!netif_running(slave_dev))
13681338
return 0;
13691339

1370-
cancel_work_sync(&dp->xmit_work);
1371-
skb_queue_purge(&dp->xmit_queue);
1372-
13731340
netif_device_detach(slave_dev);
13741341

13751342
rtnl_lock();
@@ -1455,8 +1422,6 @@ int dsa_slave_create(struct dsa_port *port)
14551422
}
14561423
p->dp = port;
14571424
INIT_LIST_HEAD(&p->mall_tc_list);
1458-
INIT_WORK(&port->xmit_work, dsa_port_xmit_work);
1459-
skb_queue_head_init(&port->xmit_queue);
14601425
p->xmit = cpu_dp->tag_ops->xmit;
14611426
port->slave = slave_dev;
14621427

net/dsa/tag_sja1105.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,24 @@ static bool sja1105_filter(const struct sk_buff *skb, struct net_device *dev)
8383
return false;
8484
}
8585

86+
/* Calls sja1105_port_deferred_xmit in sja1105_main.c */
87+
static struct sk_buff *sja1105_defer_xmit(struct sja1105_port *sp,
88+
struct sk_buff *skb)
89+
{
90+
/* Increase refcount so the kfree_skb in dsa_slave_xmit
91+
* won't really free the packet.
92+
*/
93+
skb_queue_tail(&sp->xmit_queue, skb_get(skb));
94+
kthread_queue_work(sp->xmit_worker, &sp->xmit_work);
95+
96+
return NULL;
97+
}
98+
8699
static struct sk_buff *sja1105_xmit(struct sk_buff *skb,
87100
struct net_device *netdev)
88101
{
89102
struct dsa_port *dp = dsa_slave_to_port(netdev);
90-
struct dsa_switch *ds = dp->ds;
91-
u16 tx_vid = dsa_8021q_tx_vid(ds, dp->index);
103+
u16 tx_vid = dsa_8021q_tx_vid(dp->ds, dp->index);
92104
u16 queue_mapping = skb_get_queue_mapping(skb);
93105
u8 pcp = netdev_txq_to_tc(netdev, queue_mapping);
94106

@@ -97,7 +109,7 @@ static struct sk_buff *sja1105_xmit(struct sk_buff *skb,
97109
* is the .port_deferred_xmit driver callback.
98110
*/
99111
if (unlikely(sja1105_is_link_local(skb)))
100-
return dsa_defer_xmit(skb, netdev);
112+
return sja1105_defer_xmit(dp->priv, skb);
101113

102114
/* If we are under a vlan_filtering bridge, IP termination on
103115
* switch ports based on 802.1Q tags is simply too brittle to

0 commit comments

Comments
 (0)