Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 428f1f71 authored by Matthew Vick's avatar Matthew Vick Committed by Jeff Kirsher
Browse files

igb: Add timeout for PTP Tx work item



When transmitting a packet that must return a Tx timestamp, a work item
gets scheduled to poll for the Tx timestamp being completed in hardware.
Add a timeout on this work item of 15 seconds from when the driver gets the
skb, after which it will stop polling. Report via stats and system log if
this occurs.

Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: default avatarMatthew Vick <matthew.vick@intel.com>
Acked-by: default avatarJacob Keller <Jacob.e.keller@intel.com>
Tested-by: default avatarAaron Brown <aaron.f.brown@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent b66e2397
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -414,9 +414,11 @@ struct igb_adapter {
	struct delayed_work ptp_overflow_work;
	struct work_struct ptp_tx_work;
	struct sk_buff *ptp_tx_skb;
	unsigned long ptp_tx_start;
	spinlock_t tmreg_lock;
	struct cyclecounter cc;
	struct timecounter tc;
	u32 tx_hwtstamp_timeouts;

	char fw_version[32];
#ifdef CONFIG_IGB_HWMON
+1 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ static const struct igb_stats igb_gstrings_stats[] = {
	IGB_STAT("os2bmc_tx_by_bmc", stats.b2ospc),
	IGB_STAT("os2bmc_tx_by_host", stats.o2bspc),
	IGB_STAT("os2bmc_rx_by_host", stats.b2ogprc),
	IGB_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts),
};

#define IGB_NETDEV_STAT(_net_stat) { \
+1 −0
Original line number Diff line number Diff line
@@ -4618,6 +4618,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
		tx_flags |= IGB_TX_FLAGS_TSTAMP;

		adapter->ptp_tx_skb = skb_get(skb);
		adapter->ptp_tx_start = jiffies;
		if (adapter->hw.mac.type == e1000_82576)
			schedule_work(&adapter->ptp_tx_work);
	}
+10 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@
 */

#define IGB_SYSTIM_OVERFLOW_PERIOD	(HZ * 60 * 9)
#define IGB_PTP_TX_TIMEOUT		(HZ * 15)
#define INCPERIOD_82576			(1 << E1000_TIMINCA_16NS_SHIFT)
#define INCVALUE_82576_MASK		((1 << E1000_TIMINCA_16NS_SHIFT) - 1)
#define INCVALUE_82576			(16 << IGB_82576_TSYNC_SHIFT)
@@ -396,6 +397,15 @@ void igb_ptp_tx_work(struct work_struct *work)
	if (!adapter->ptp_tx_skb)
		return;

	if (time_is_before_jiffies(adapter->ptp_tx_start +
				   IGB_PTP_TX_TIMEOUT)) {
		dev_kfree_skb_any(adapter->ptp_tx_skb);
		adapter->ptp_tx_skb = NULL;
		adapter->tx_hwtstamp_timeouts++;
		dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang");
		return;
	}

	tsynctxctl = rd32(E1000_TSYNCTXCTL);
	if (tsynctxctl & E1000_TSYNCTXCTL_VALID)
		igb_ptp_tx_hwtstamp(adapter);