diff options
author | Jakub Kicinski <kubakici@wp.pl> | 2014-03-15 10:55:21 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2014-03-31 18:48:00 -0400 |
commit | 151b260c624d47b2c78b2f887e4f791c09c73c17 (patch) | |
tree | 6cb1fcce48b87be0e4fcf8f7d5ffb592587f79bc /drivers/net | |
parent | ff29a86ec9143ff1aa1901ae60f06f4980981df4 (diff) |
ixgbe: fix race conditions on queuing skb for HW time stamp
ixgbe has a single set of TX time stamping resources per NIC.
Use a simple bit lock to avoid race conditions and leaking skbs
when multiple TX rings try to claim time stamping.
Signed-off-by: Jakub Kicinski <kubakici@wp.pl>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 3 |
3 files changed, 7 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 2fff0fc4e6e8..26d27aae9793 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h | |||
@@ -812,6 +812,7 @@ enum ixgbe_state_t { | |||
812 | __IXGBE_SERVICE_SCHED, | 812 | __IXGBE_SERVICE_SCHED, |
813 | __IXGBE_IN_SFP_INIT, | 813 | __IXGBE_IN_SFP_INIT, |
814 | __IXGBE_PTP_RUNNING, | 814 | __IXGBE_PTP_RUNNING, |
815 | __IXGBE_PTP_TX_IN_PROGRESS, | ||
815 | }; | 816 | }; |
816 | 817 | ||
817 | struct ixgbe_cb { | 818 | struct ixgbe_cb { |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 24538cb0f856..c4b930c0ce7f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -7042,7 +7042,9 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, | |||
7042 | tx_flags |= IXGBE_TX_FLAGS_SW_VLAN; | 7042 | tx_flags |= IXGBE_TX_FLAGS_SW_VLAN; |
7043 | } | 7043 | } |
7044 | 7044 | ||
7045 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { | 7045 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && |
7046 | !test_and_set_bit_lock(__IXGBE_PTP_TX_IN_PROGRESS, | ||
7047 | &adapter->state))) { | ||
7046 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | 7048 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; |
7047 | tx_flags |= IXGBE_TX_FLAGS_TSTAMP; | 7049 | tx_flags |= IXGBE_TX_FLAGS_TSTAMP; |
7048 | 7050 | ||
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 8b527d79d429..63515a6f67fa 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | |||
@@ -493,6 +493,7 @@ static void ixgbe_ptp_tx_hwtstamp(struct ixgbe_adapter *adapter) | |||
493 | 493 | ||
494 | dev_kfree_skb_any(adapter->ptp_tx_skb); | 494 | dev_kfree_skb_any(adapter->ptp_tx_skb); |
495 | adapter->ptp_tx_skb = NULL; | 495 | adapter->ptp_tx_skb = NULL; |
496 | clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state); | ||
496 | } | 497 | } |
497 | 498 | ||
498 | /** | 499 | /** |
@@ -515,6 +516,7 @@ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work) | |||
515 | if (timeout) { | 516 | if (timeout) { |
516 | dev_kfree_skb_any(adapter->ptp_tx_skb); | 517 | dev_kfree_skb_any(adapter->ptp_tx_skb); |
517 | adapter->ptp_tx_skb = NULL; | 518 | adapter->ptp_tx_skb = NULL; |
519 | clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state); | ||
518 | e_warn(drv, "clearing Tx Timestamp hang"); | 520 | e_warn(drv, "clearing Tx Timestamp hang"); |
519 | return; | 521 | return; |
520 | } | 522 | } |
@@ -925,6 +927,7 @@ void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) | |||
925 | if (adapter->ptp_tx_skb) { | 927 | if (adapter->ptp_tx_skb) { |
926 | dev_kfree_skb_any(adapter->ptp_tx_skb); | 928 | dev_kfree_skb_any(adapter->ptp_tx_skb); |
927 | adapter->ptp_tx_skb = NULL; | 929 | adapter->ptp_tx_skb = NULL; |
930 | clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state); | ||
928 | } | 931 | } |
929 | 932 | ||
930 | if (adapter->ptp_clock) { | 933 | if (adapter->ptp_clock) { |