idpf: prevent deinit uninitialized virtchnl core
authorAlan Brady <alan.brady@intel.com>
Thu, 22 Feb 2024 19:04:39 +0000 (11:04 -0800)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Mon, 4 Mar 2024 17:47:33 +0000 (09:47 -0800)
In idpf_remove we need to tear down the virtchnl core with
idpf_vc_core_deinit so we can free up resources and leave things in a
good state. However, in the case where we failed to establish VC
communications we may not have ever actually successfully initialized
the virtchnl core.

This fixes it by setting a bit once we successfully init the virtchnl
core.  Then, in deinit, we'll check for it before going on further,
otherwise we just return. Also clear the bit at the end of deinit so we
know it's gone now.

Tested-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Signed-off-by: Alan Brady <alan.brady@intel.com>
Tested-by: Krishneil Singh <krishneil.k.singh@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/idpf/idpf.h
drivers/net/ethernet/intel/idpf/idpf_virtchnl.c

index 5ed08be1dbc04ed63d4d4ad01432844c87001736..e7a036538246596b419af94c65838efcfa99c7d5 100644 (file)
@@ -83,6 +83,7 @@ enum idpf_state {
  * @IDPF_HR_RESET_IN_PROG: Reset in progress
  * @IDPF_REMOVE_IN_PROG: Driver remove in progress
  * @IDPF_MB_INTR_MODE: Mailbox in interrupt mode
+ * @IDPF_VC_CORE_INIT: virtchnl core has been init
  * @IDPF_FLAGS_NBITS: Must be last
  */
 enum idpf_flags {
@@ -91,6 +92,7 @@ enum idpf_flags {
        IDPF_HR_RESET_IN_PROG,
        IDPF_REMOVE_IN_PROG,
        IDPF_MB_INTR_MODE,
+       IDPF_VC_CORE_INIT,
        IDPF_FLAGS_NBITS,
 };
 
index e89e2bad460d9889241074472722fab64d1b289d..a602ff8d74e0545875ab6853f83b340d4f2db608 100644 (file)
@@ -2990,7 +2990,9 @@ restart:
        queue_delayed_work(adapter->init_wq, &adapter->init_task,
                           msecs_to_jiffies(5 * (adapter->pdev->devfn & 0x07)));
 
-       goto no_err;
+       set_bit(IDPF_VC_CORE_INIT, adapter->flags);
+
+       return 0;
 
 err_intr_req:
        cancel_delayed_work_sync(&adapter->serv_task);
@@ -2999,7 +3001,6 @@ err_intr_req:
 err_netdev_alloc:
        kfree(adapter->vports);
        adapter->vports = NULL;
-no_err:
        return err;
 
 init_failed:
@@ -3034,6 +3035,9 @@ init_failed:
  */
 void idpf_vc_core_deinit(struct idpf_adapter *adapter)
 {
+       if (!test_bit(IDPF_VC_CORE_INIT, adapter->flags))
+               return;
+
        idpf_vc_xn_shutdown(adapter->vcxn_mngr);
        idpf_deinit_task(adapter);
        idpf_intr_rel(adapter);
@@ -3045,6 +3049,8 @@ void idpf_vc_core_deinit(struct idpf_adapter *adapter)
 
        kfree(adapter->vports);
        adapter->vports = NULL;
+
+       clear_bit(IDPF_VC_CORE_INIT, adapter->flags);
 }
 
 /**