struct rte_ether_addr *mac_addr);
 static int hns3_restore_fec(struct hns3_hw *hw);
 static int hns3_query_dev_fec_info(struct hns3_hw *hw);
+static int hns3_do_stop(struct hns3_adapter *hns);
 
 void hns3_ether_format_addr(char *buf, uint16_t size,
                            const struct rte_ether_addr *ether_addr)
                return ret;
        }
        ret = hns3_map_rx_interrupt(dev);
-       if (ret) {
-               hw->adapter_state = HNS3_NIC_CONFIGURED;
-               rte_spinlock_unlock(&hw->lock);
-               return ret;
-       }
+       if (ret)
+               goto map_rx_inter_err;
 
        /*
         * There are three register used to control the status of a TQP
         * status of queue in the dpdk framework.
         */
        ret = hns3_start_all_txqs(dev);
-       if (ret) {
-               hw->adapter_state = HNS3_NIC_CONFIGURED;
-               rte_spinlock_unlock(&hw->lock);
-               return ret;
-       }
+       if (ret)
+               goto map_rx_inter_err;
 
        ret = hns3_start_all_rxqs(dev);
-       if (ret) {
-               hns3_stop_all_txqs(dev);
-               hw->adapter_state = HNS3_NIC_CONFIGURED;
-               rte_spinlock_unlock(&hw->lock);
-               return ret;
-       }
+       if (ret)
+               goto start_all_rxqs_fail;
 
        hw->adapter_state = HNS3_NIC_STARTED;
        rte_spinlock_unlock(&hw->lock);
        hns3_tm_dev_start_proc(hw);
 
        hns3_info(hw, "hns3 dev start successful!");
+
        return 0;
+
+start_all_rxqs_fail:
+       hns3_stop_all_txqs(dev);
+map_rx_inter_err:
+       (void)hns3_do_stop(hns);
+       hw->adapter_state = HNS3_NIC_CONFIGURED;
+       rte_spinlock_unlock(&hw->lock);
+
+       return ret;
 }
 
 static int
        struct hns3_hw *hw = &hns->hw;
        int ret;
 
+       /*
+        * The "hns3_do_stop" function will also be called by .stop_service to
+        * prepare reset. At the time of global or IMP reset, the command cannot
+        * be sent to stop the tx/rx queues. The mbuf in Tx/Rx queues may be
+        * accessed during the reset process. So the mbuf can not be released
+        * during reset and is required to be released after the reset is
+        * completed.
+        */
+       if (__atomic_load_n(&hw->reset.resetting,  __ATOMIC_RELAXED) == 0)
+               hns3_dev_release_mbufs(hns);
+
        ret = hns3_cfg_mac_mode(hw, false);
        if (ret)
                return ret;
                hns3_stop_tqps(hw);
                hns3_do_stop(hns);
                hns3_unmap_rx_interrupt(dev);
-               hns3_dev_release_mbufs(hns);
                hw->adapter_state = HNS3_NIC_CONFIGURED;
        }
        hns3_rx_scattered_reset(dev);
 
 
        hw->mac.link_status = ETH_LINK_DOWN;
 
+       /*
+        * The "hns3vf_do_stop" function will also be called by .stop_service to
+        * prepare reset. At the time of global or IMP reset, the command cannot
+        * be sent to stop the tx/rx queues. The mbuf in Tx/Rx queues may be
+        * accessed during the reset process. So the mbuf can not be released
+        * during reset and is required to be released after the reset is
+        * completed.
+        */
+       if (__atomic_load_n(&hw->reset.resetting,  __ATOMIC_RELAXED) == 0)
+               hns3_dev_release_mbufs(hns);
+
        if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED) == 0) {
                hns3vf_configure_mac_addr(hns, true);
                ret = hns3_reset_all_tqps(hns);
                hns3_stop_tqps(hw);
                hns3vf_do_stop(hns);
                hns3vf_unmap_rx_interrupt(dev);
-               hns3_dev_release_mbufs(hns);
                hw->adapter_state = HNS3_NIC_CONFIGURED;
        }
        hns3_rx_scattered_reset(dev);
                return ret;
        }
        ret = hns3vf_map_rx_interrupt(dev);
-       if (ret) {
-               hw->adapter_state = HNS3_NIC_CONFIGURED;
-               rte_spinlock_unlock(&hw->lock);
-               return ret;
-       }
+       if (ret)
+               goto map_rx_inter_err;
 
        /*
         * There are three register used to control the status of a TQP
         * status of queue in the dpdk framework.
         */
        ret = hns3_start_all_txqs(dev);
-       if (ret) {
-               hw->adapter_state = HNS3_NIC_CONFIGURED;
-               rte_spinlock_unlock(&hw->lock);
-               return ret;
-       }
+       if (ret)
+               goto map_rx_inter_err;
 
        ret = hns3_start_all_rxqs(dev);
-       if (ret) {
-               hns3_stop_all_txqs(dev);
-               hw->adapter_state = HNS3_NIC_CONFIGURED;
-               rte_spinlock_unlock(&hw->lock);
-               return ret;
-       }
+       if (ret)
+               goto start_all_rxqs_fail;
 
        hw->adapter_state = HNS3_NIC_STARTED;
        rte_spinlock_unlock(&hw->lock);
         */
        hns3_start_tqps(hw);
 
+       return ret;
+
+start_all_rxqs_fail:
+       hns3_stop_all_txqs(dev);
+map_rx_inter_err:
+       (void)hns3vf_do_stop(hns);
+       hw->adapter_state = HNS3_NIC_CONFIGURED;
+       rte_spinlock_unlock(&hw->lock);
+
        return ret;
 }