Commit 5c5416f5 authored by Yangbo Lu's avatar Yangbo Lu Committed by David S. Miller
Browse files

net: dsa: no longer clone skb in core driver



It was a waste to clone skb directly in dsa_skb_tx_timestamp().
For one-step timestamping, a clone was not needed. For any failure of
port_txtstamp (this may usually happen), the skb clone had to be freed.

So this patch moves skb cloning for tx timestamp out of dsa core, and
let drivers clone skb in port_txtstamp if they really need.

Signed-off-by: default avatarYangbo Lu <yangbo.lu@nxp.com>
Tested-by: default avatarKurt Kanzenbach <kurt@linutronix.de>
Acked-by: default avatarRichard Cochran <richardcochran@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cf536ea3
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -373,31 +373,38 @@ long hellcreek_hwtstamp_work(struct ptp_clock_info *ptp)
	return restart ? 1 : -1;
}

bool hellcreek_port_txtstamp(struct dsa_switch *ds, int port,
			     struct sk_buff *clone)
void hellcreek_port_txtstamp(struct dsa_switch *ds, int port,
			     struct sk_buff *skb)
{
	struct hellcreek *hellcreek = ds->priv;
	struct hellcreek_port_hwtstamp *ps;
	struct ptp_header *hdr;
	struct sk_buff *clone;
	unsigned int type;

	ps = &hellcreek->ports[port].port_hwtstamp;

	type = ptp_classify_raw(clone);
	type = ptp_classify_raw(skb);
	if (type == PTP_CLASS_NONE)
		return false;
		return;

	/* Make sure the message is a PTP message that needs to be timestamped
	 * and the interaction with the HW timestamping is enabled. If not, stop
	 * here
	 */
	hdr = hellcreek_should_tstamp(hellcreek, port, clone, type);
	hdr = hellcreek_should_tstamp(hellcreek, port, skb, type);
	if (!hdr)
		return false;
		return;

	clone = skb_clone_sk(skb);
	if (!clone)
		return;

	if (test_and_set_bit_lock(HELLCREEK_HWTSTAMP_TX_IN_PROGRESS,
				  &ps->state))
		return false;
				  &ps->state)) {
		kfree_skb(clone);
		return;
	}

	ps->tx_skb = clone;

@@ -407,8 +414,6 @@ bool hellcreek_port_txtstamp(struct dsa_switch *ds, int port,
	ps->tx_tstamp_start = jiffies;

	ptp_schedule_worker(hellcreek->ptp_clock, 0);

	return true;
}

bool hellcreek_port_rxtstamp(struct dsa_switch *ds, int port,
+2 −2
Original line number Diff line number Diff line
@@ -44,8 +44,8 @@ int hellcreek_port_hwtstamp_get(struct dsa_switch *ds, int port,

bool hellcreek_port_rxtstamp(struct dsa_switch *ds, int port,
			     struct sk_buff *clone, unsigned int type);
bool hellcreek_port_txtstamp(struct dsa_switch *ds, int port,
			     struct sk_buff *clone);
void hellcreek_port_txtstamp(struct dsa_switch *ds, int port,
			     struct sk_buff *skb);

int hellcreek_get_ts_info(struct dsa_switch *ds, int port,
			  struct ethtool_ts_info *info);
+15 −9
Original line number Diff line number Diff line
@@ -468,32 +468,38 @@ long mv88e6xxx_hwtstamp_work(struct ptp_clock_info *ptp)
	return restart ? 1 : -1;
}

bool mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,
			     struct sk_buff *clone)
void mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,
			     struct sk_buff *skb)
{
	struct mv88e6xxx_chip *chip = ds->priv;
	struct mv88e6xxx_port_hwtstamp *ps = &chip->port_hwtstamp[port];
	struct ptp_header *hdr;
	struct sk_buff *clone;
	unsigned int type;

	type = ptp_classify_raw(clone);
	type = ptp_classify_raw(skb);
	if (type == PTP_CLASS_NONE)
		return false;
		return;

	hdr = mv88e6xxx_should_tstamp(chip, port, clone, type);
	hdr = mv88e6xxx_should_tstamp(chip, port, skb, type);
	if (!hdr)
		return false;
		return;

	clone = skb_clone_sk(skb);
	if (!clone)
		return;

	if (test_and_set_bit_lock(MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS,
				  &ps->state))
		return false;
				  &ps->state)) {
		kfree_skb(clone);
		return;
	}

	ps->tx_skb = clone;
	ps->tx_tstamp_start = jiffies;
	ps->tx_seq_id = be16_to_cpu(hdr->sequence_id);

	ptp_schedule_worker(chip->ptp_clock, 0);
	return true;
}

int mv88e6165_global_disable(struct mv88e6xxx_chip *chip)
+4 −5
Original line number Diff line number Diff line
@@ -117,8 +117,8 @@ int mv88e6xxx_port_hwtstamp_get(struct dsa_switch *ds, int port,

bool mv88e6xxx_port_rxtstamp(struct dsa_switch *ds, int port,
			     struct sk_buff *clone, unsigned int type);
bool mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,
			     struct sk_buff *clone);
void mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,
			     struct sk_buff *skb);

int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port,
			  struct ethtool_ts_info *info);
@@ -151,10 +151,9 @@ static inline bool mv88e6xxx_port_rxtstamp(struct dsa_switch *ds, int port,
	return false;
}

static inline bool mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,
					   struct sk_buff *clone)
static inline void mv88e6xxx_port_txtstamp(struct dsa_switch *ds, int port,
					   struct sk_buff *skb)
{
	return false;
}

static inline int mv88e6xxx_get_ts_info(struct dsa_switch *ds, int port,
+8 −5
Original line number Diff line number Diff line
@@ -1395,18 +1395,21 @@ static bool felix_rxtstamp(struct dsa_switch *ds, int port,
	return false;
}

static bool felix_txtstamp(struct dsa_switch *ds, int port,
			   struct sk_buff *clone)
static void felix_txtstamp(struct dsa_switch *ds, int port,
			   struct sk_buff *skb)
{
	struct ocelot *ocelot = ds->priv;
	struct ocelot_port *ocelot_port = ocelot->ports[port];
	struct sk_buff *clone;

	if (ocelot->ptp && ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
		clone = skb_clone_sk(skb);
		if (!clone)
			return;

		ocelot_port_add_txtstamp_skb(ocelot, port, clone);
		return true;
		DSA_SKB_CB(skb)->clone = clone;
	}

	return false;
}

static int felix_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
Loading