]> git.baikalelectronics.ru Git - kernel.git/commitdiff
igb: Add timeout for PTP Tx work item
authorMatthew Vick <matthew.vick@intel.com>
Thu, 13 Dec 2012 07:20:34 +0000 (07:20 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 18 Jan 2013 12:56:11 +0000 (04:56 -0800)
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: Matthew Vick <matthew.vick@intel.com>
Acked-by: Jacob Keller <Jacob.e.keller@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/igb/igb.h
drivers/net/ethernet/intel/igb/igb_ethtool.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igb/igb_ptp.c

index 8372c002102cf972176131f4b324f03bfb1ca619..8c6f59d95b20d3c4303b9c72a9ce7174a999c495 100644 (file)
@@ -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
index 61803032fdd346cf34a4d757d509bd516bb50798..6f2579c50d8e5e9fdae17c0cfd5091d77d9f2e5b 100644 (file)
@@ -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) { \
index 9dd3da540cd0ca92005611184fb6a47fa9aba98f..9540a814a22594d63a1eda702a765ed8a390d339 100644 (file)
@@ -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);
        }
index ab3429729bde4134a0310a6199cf9eb1737369b6..086af4683544d70ac9f674c545da163e75f09f45 100644 (file)
@@ -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);