Skip to content

Commit e2f9a8f

Browse files
vladimirolteandavem330
authored andcommitted
net: mscc: ocelot: always pass skb clone to ocelot_port_add_txtstamp_skb
Currently, ocelot switchdev passes the skb directly to the function that enqueues it to the list of skb's awaiting a TX timestamp. Whereas the felix DSA driver first clones the skb, then passes the clone to this queue. This matters because in the case of felix, the common IRQ handler, which is ocelot_get_txtstamp(), currently clones the clone, and frees the original clone. This is useless and can be simplified by using skb_complete_tx_timestamp() instead of skb_tstamp_tx(). Signed-off-by: Vladimir Oltean <[email protected]> Acked-by: Richard Cochran <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e4a85c5 commit e2f9a8f

File tree

5 files changed

+38
-29
lines changed

5 files changed

+38
-29
lines changed

drivers/net/dsa/ocelot/felix.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,8 +669,11 @@ static bool felix_txtstamp(struct dsa_switch *ds, int port,
669669
struct ocelot *ocelot = ds->priv;
670670
struct ocelot_port *ocelot_port = ocelot->ports[port];
671671

672-
if (!ocelot_port_add_txtstamp_skb(ocelot_port, clone))
672+
if (ocelot->ptp && (skb_shinfo(clone)->tx_flags & SKBTX_HW_TSTAMP) &&
673+
ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
674+
ocelot_port_add_txtstamp_skb(ocelot, port, clone);
673675
return true;
676+
}
674677

675678
return false;
676679
}

drivers/net/ethernet/mscc/ocelot.c

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -413,26 +413,20 @@ void ocelot_port_disable(struct ocelot *ocelot, int port)
413413
}
414414
EXPORT_SYMBOL(ocelot_port_disable);
415415

416-
int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port,
417-
struct sk_buff *skb)
416+
void ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port,
417+
struct sk_buff *clone)
418418
{
419-
struct skb_shared_info *shinfo = skb_shinfo(skb);
420-
struct ocelot *ocelot = ocelot_port->ocelot;
419+
struct ocelot_port *ocelot_port = ocelot->ports[port];
421420

422-
if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP &&
423-
ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
424-
spin_lock(&ocelot_port->ts_id_lock);
421+
spin_lock(&ocelot_port->ts_id_lock);
425422

426-
shinfo->tx_flags |= SKBTX_IN_PROGRESS;
427-
/* Store timestamp ID in cb[0] of sk_buff */
428-
skb->cb[0] = ocelot_port->ts_id;
429-
ocelot_port->ts_id = (ocelot_port->ts_id + 1) % 4;
430-
skb_queue_tail(&ocelot_port->tx_skbs, skb);
423+
skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS;
424+
/* Store timestamp ID in cb[0] of sk_buff */
425+
clone->cb[0] = ocelot_port->ts_id;
426+
ocelot_port->ts_id = (ocelot_port->ts_id + 1) % 4;
427+
skb_queue_tail(&ocelot_port->tx_skbs, clone);
431428

432-
spin_unlock(&ocelot_port->ts_id_lock);
433-
return 0;
434-
}
435-
return -ENODATA;
429+
spin_unlock(&ocelot_port->ts_id_lock);
436430
}
437431
EXPORT_SYMBOL(ocelot_port_add_txtstamp_skb);
438432

@@ -511,9 +505,7 @@ void ocelot_get_txtstamp(struct ocelot *ocelot)
511505
/* Set the timestamp into the skb */
512506
memset(&shhwtstamps, 0, sizeof(shhwtstamps));
513507
shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
514-
skb_tstamp_tx(skb_match, &shhwtstamps);
515-
516-
dev_kfree_skb_any(skb_match);
508+
skb_complete_tx_timestamp(skb_match, &shhwtstamps);
517509

518510
/* Next ts */
519511
ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);

drivers/net/ethernet/mscc/ocelot_net.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,6 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
330330
u8 grp = 0; /* Send everything on CPU group 0 */
331331
unsigned int i, count, last;
332332
int port = priv->chip_port;
333-
bool do_tstamp;
334333

335334
val = ocelot_read(ocelot, QS_INJ_STATUS);
336335
if (!(val & QS_INJ_STATUS_FIFO_RDY(BIT(grp))) ||
@@ -345,7 +344,23 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
345344
info.vid = skb_vlan_tag_get(skb);
346345

347346
/* Check if timestamping is needed */
348-
do_tstamp = (ocelot_port_add_txtstamp_skb(ocelot_port, skb) == 0);
347+
if (ocelot->ptp && (shinfo->tx_flags & SKBTX_HW_TSTAMP)) {
348+
info.rew_op = ocelot_port->ptp_cmd;
349+
350+
if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
351+
struct sk_buff *clone;
352+
353+
clone = skb_clone_sk(skb);
354+
if (!clone) {
355+
kfree_skb(skb);
356+
return NETDEV_TX_OK;
357+
}
358+
359+
ocelot_port_add_txtstamp_skb(ocelot, port, clone);
360+
361+
info.rew_op |= clone->cb[0] << 3;
362+
}
363+
}
349364

350365
if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP) {
351366
info.rew_op = ocelot_port->ptp_cmd;
@@ -383,8 +398,7 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
383398
dev->stats.tx_packets++;
384399
dev->stats.tx_bytes += skb->len;
385400

386-
if (!do_tstamp)
387-
dev_kfree_skb_any(skb);
401+
kfree_skb(skb);
388402

389403
return NETDEV_TX_OK;
390404
}

include/soc/mscc/ocelot.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,8 +710,8 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
710710
int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid);
711711
int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr);
712712
int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr);
713-
int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port,
714-
struct sk_buff *skb);
713+
void ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port,
714+
struct sk_buff *clone);
715715
void ocelot_get_txtstamp(struct ocelot *ocelot);
716716
void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu);
717717
int ocelot_get_max_mtu(struct ocelot *ocelot, int port);

net/dsa/tag_ocelot.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
137137
struct net_device *netdev)
138138
{
139139
struct dsa_port *dp = dsa_slave_to_port(netdev);
140+
struct sk_buff *clone = DSA_SKB_CB(skb)->clone;
140141
struct dsa_switch *ds = dp->ds;
141142
struct ocelot *ocelot = ds->priv;
142143
struct ocelot_port *ocelot_port;
@@ -159,9 +160,8 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
159160
qos_class = skb->priority;
160161
packing(injection, &qos_class, 19, 17, OCELOT_TAG_LEN, PACK, 0);
161162

162-
if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
163-
struct sk_buff *clone = DSA_SKB_CB(skb)->clone;
164-
163+
/* TX timestamping was requested */
164+
if (clone) {
165165
rew_op = ocelot_port->ptp_cmd;
166166
/* Retrieve timestamp ID populated inside skb->cb[0] of the
167167
* clone by ocelot_port_add_txtstamp_skb

0 commit comments

Comments
 (0)