qede: fix crash in rmmod qede while automatic debug collection
[ Upstream commit 1159e25c137422bdc48ee96e3fb014bd942092c6 ] A crash has been observed if rmmod is done while automatic debug collection in progress. It is due to a race condition between both of them. To fix stop the sp_task during unload to avoid running qede_sp_task even if they are schedule during removal process. Signed-off-by: Alok Prasad <palok@marvell.com> Signed-off-by: Shai Malin <smalin@marvell.com> Signed-off-by: Ariel Elior <aelior@marvell.com> Signed-off-by: Prabhakar Kushwaha <pkushwaha@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Sasha Levin

parent
7525f2e4de
commit
410d1ea4ff
@@ -494,6 +494,7 @@ struct qede_fastpath {
|
|||||||
#define QEDE_SP_HW_ERR 4
|
#define QEDE_SP_HW_ERR 4
|
||||||
#define QEDE_SP_ARFS_CONFIG 5
|
#define QEDE_SP_ARFS_CONFIG 5
|
||||||
#define QEDE_SP_AER 7
|
#define QEDE_SP_AER 7
|
||||||
|
#define QEDE_SP_DISABLE 8
|
||||||
|
|
||||||
#ifdef CONFIG_RFS_ACCEL
|
#ifdef CONFIG_RFS_ACCEL
|
||||||
int qede_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
|
int qede_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
|
||||||
|
@@ -1006,6 +1006,13 @@ static void qede_sp_task(struct work_struct *work)
|
|||||||
struct qede_dev *edev = container_of(work, struct qede_dev,
|
struct qede_dev *edev = container_of(work, struct qede_dev,
|
||||||
sp_task.work);
|
sp_task.work);
|
||||||
|
|
||||||
|
/* Disable execution of this deferred work once
|
||||||
|
* qede removal is in progress, this stop any future
|
||||||
|
* scheduling of sp_task.
|
||||||
|
*/
|
||||||
|
if (test_bit(QEDE_SP_DISABLE, &edev->sp_flags))
|
||||||
|
return;
|
||||||
|
|
||||||
/* The locking scheme depends on the specific flag:
|
/* The locking scheme depends on the specific flag:
|
||||||
* In case of QEDE_SP_RECOVERY, acquiring the RTNL lock is required to
|
* In case of QEDE_SP_RECOVERY, acquiring the RTNL lock is required to
|
||||||
* ensure that ongoing flows are ended and new ones are not started.
|
* ensure that ongoing flows are ended and new ones are not started.
|
||||||
@@ -1297,6 +1304,7 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode)
|
|||||||
qede_rdma_dev_remove(edev, (mode == QEDE_REMOVE_RECOVERY));
|
qede_rdma_dev_remove(edev, (mode == QEDE_REMOVE_RECOVERY));
|
||||||
|
|
||||||
if (mode != QEDE_REMOVE_RECOVERY) {
|
if (mode != QEDE_REMOVE_RECOVERY) {
|
||||||
|
set_bit(QEDE_SP_DISABLE, &edev->sp_flags);
|
||||||
unregister_netdev(ndev);
|
unregister_netdev(ndev);
|
||||||
|
|
||||||
cancel_delayed_work_sync(&edev->sp_task);
|
cancel_delayed_work_sync(&edev->sp_task);
|
||||||
|
Reference in New Issue
Block a user