From: Paul Greenwalt <[email protected]>

If a PF reset occurs when the PTP state is ICE_PTP_UNINIT, then
ice_ptp_rebuild() will update the state to ICE_PTP_ERROR. This will
result in the following PTP release call trace during driver unload:

    kernel BUG at lib/list_debug.c:52!
    ice_ptp_release+0x332/0x3c0 [ice]
    ice_deinit_features.part.0+0x10e/0x120 [ice]
    ice_remove+0x100/0x220 [ice]

This was observed when passing PF1 through to a VM. ice_ptp_init()
fails because ctrl_pf is NULL and sets the state to ICE_PTP_UNINIT.

Fix by detecting the ICE_PTP_UNINIT state in ice_ptp_rebuild() and
returning without error, preventing the invalid state transition to
ICE_PTP_ERROR. The only valid path to ICE_PTP_ERROR is from
ICE_PTP_RESETTING after a failed rebuild.

Fixes: 8293e4cb2ff5 ("ice: introduce PTP state machine")
Cc: [email protected]
Signed-off-by: Paul Greenwalt <[email protected]>
Signed-off-by: Aleksandr Loktionov <[email protected]>
---

 drivers/net/ethernet/intel/ice/ice_ptp.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c 
b/drivers/net/ethernet/intel/ice/ice_ptp.c
index 094e962..6848b1c 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
@@ -3041,6 +3041,11 @@ void ice_ptp_rebuild(struct ice_pf *pf, enum 
ice_reset_req reset_type)
        struct ice_ptp *ptp = &pf->ptp;
        int err;
 
+       if (ptp->state == ICE_PTP_UNINIT) {
+               dev_dbg(ice_pf_to_dev(pf), "PTP was not initialized, skipping 
rebuild\n");
+               return;
+       }
+
        if (ptp->state == ICE_PTP_READY) {
                ice_ptp_prepare_for_reset(pf, reset_type);
        } else if (ptp->state != ICE_PTP_RESETTING) {
-- 
2.52.0

Reply via email to