ixgbe: fix lockdep annotation issue for ptp's work item
authorJacob Keller <jacob.e.keller@intel.com>
Fri, 21 Jun 2013 08:14:32 +0000 (08:14 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Wed, 31 Jul 2013 08:00:57 +0000 (01:00 -0700)
This patch fixes a lockdep issue created due to ixgbe_ptp_stop always running
cancel_work_sync even if the work item had not been created properly with
INIT_WORK. This is caused because ixgbe_ptp_stop did not check to actually
ensure PTP was running first. The new implementation introduces a state in the
&adapter->state field which is used to indicate that PTP is running. (This
replaces the IXGBE_FLAG2_PTP_ENABLED field). This state will use the atomic
set_bit, test_bit, and test_and_clear_bit functions. ixgbe_ptp_stop will check
to ensure that PTP was enabled, (and if not, it will not attempt to do any
cleanup work from ixgbe_ptp_init). This resolves the lockdep annotation warning
found by Stephen Hemminger

Reported-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Acked-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c

index d882278851d7a6e5dd484fb7a5e4e5f3409d7aa7..6844f39b605b7ab4b245b12d5b61da9b2b574de7 100644 (file)
@@ -618,9 +618,8 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG2_FDIR_REQUIRES_REINIT        (u32)(1 << 7)
 #define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP         (u32)(1 << 8)
 #define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP         (u32)(1 << 9)
-#define IXGBE_FLAG2_PTP_ENABLED                        (u32)(1 << 10)
-#define IXGBE_FLAG2_PTP_PPS_ENABLED            (u32)(1 << 11)
-#define IXGBE_FLAG2_BRIDGE_MODE_VEB            (u32)(1 << 12)
+#define IXGBE_FLAG2_PTP_PPS_ENABLED            (u32)(1 << 10)
+#define IXGBE_FLAG2_BRIDGE_MODE_VEB            (u32)(1 << 11)
 
        /* Tx fast path data */
        int num_tx_queues;
@@ -754,6 +753,7 @@ enum ixgbe_state_t {
        __IXGBE_DOWN,
        __IXGBE_SERVICE_SCHED,
        __IXGBE_IN_SFP_INIT,
+       __IXGBE_PTP_RUNNING,
 };
 
 struct ixgbe_cb {
index 69c6a495aaee15c3bee28b65c8130fe96c813920..785eafae1292c69002a59db308f9b6f66b3d07f8 100644 (file)
@@ -4438,7 +4438,7 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
        if (hw->mac.san_mac_rar_index)
                hw->mac.ops.set_vmdq_san_mac(hw, VMDQ_P(0));
 
-       if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED)
+       if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state))
                ixgbe_ptp_reset(adapter);
 }
 
@@ -5766,7 +5766,7 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
 
        adapter->last_rx_ptp_check = jiffies;
 
-       if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED)
+       if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state))
                ixgbe_ptp_start_cyclecounter(adapter);
 
        e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
@@ -5812,7 +5812,7 @@ static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *adapter)
        if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB)
                adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
 
-       if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED)
+       if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state))
                ixgbe_ptp_start_cyclecounter(adapter);
 
        e_info(drv, "NIC Link is Down\n");
@@ -6119,7 +6119,7 @@ static void ixgbe_service_task(struct work_struct *work)
        ixgbe_fdir_reinit_subtask(adapter);
        ixgbe_check_hang_subtask(adapter);
 
-       if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED) {
+       if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state)) {
                ixgbe_ptp_overflow_check(adapter);
                ixgbe_ptp_rx_hang(adapter);
        }
index 331987d6815c91ef7f6296c1d3062821c3268a1b..5184e2a1a7d8249bc746ce6496e55f5789a0e949 100644 (file)
@@ -885,8 +885,8 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
 
        ixgbe_ptp_reset(adapter);
 
-       /* set the flag that PTP has been enabled */
-       adapter->flags2 |= IXGBE_FLAG2_PTP_ENABLED;
+       /* enter the IXGBE_PTP_RUNNING state */
+       set_bit(__IXGBE_PTP_RUNNING, &adapter->state);
 
        return;
 }
@@ -899,10 +899,12 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
  */
 void ixgbe_ptp_stop(struct ixgbe_adapter *adapter)
 {
-       /* stop the overflow check task */
-       adapter->flags2 &= ~(IXGBE_FLAG2_PTP_ENABLED |
-                            IXGBE_FLAG2_PTP_PPS_ENABLED);
+       /* Leave the IXGBE_PTP_RUNNING state. */
+       if (!test_and_clear_bit(__IXGBE_PTP_RUNNING, &adapter->state))
+               return;
 
+       /* stop the PPS signal */
+       adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED;
        ixgbe_ptp_setup_sdp(adapter);
 
        cancel_work_sync(&adapter->ptp_tx_work);