mirror of
https://github.com/torvalds/linux.git
synced 2024-12-03 17:41:22 +00:00
net: hns3: stop schedule reset service while unloading driver
When unloading driver, the reset task should not be scheduled anymore. If disable IRQ before cancel ongoing reset task, the IRQ may be re-enabled by the reset task. This patch uses HCLGE_STATE_REMOVING/HCLGEVF_STATE_REMOVING flag to indicate that the driver is unloading, and we should stop new coming reset service to be scheduled, otherwise, reset service will access some resource which has been freed by unloading. Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com> Signed-off-by: Peng Li <lipeng321@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ada13ee3db
commit
acfc3d55b7
@ -2427,7 +2427,8 @@ static void hclge_mbx_task_schedule(struct hclge_dev *hdev)
|
||||
|
||||
static void hclge_reset_task_schedule(struct hclge_dev *hdev)
|
||||
{
|
||||
if (!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
|
||||
if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
|
||||
!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
|
||||
schedule_work(&hdev->rst_service_task);
|
||||
}
|
||||
|
||||
@ -8385,6 +8386,7 @@ static void hclge_state_init(struct hclge_dev *hdev)
|
||||
static void hclge_state_uninit(struct hclge_dev *hdev)
|
||||
{
|
||||
set_bit(HCLGE_STATE_DOWN, &hdev->state);
|
||||
set_bit(HCLGE_STATE_REMOVING, &hdev->state);
|
||||
|
||||
if (hdev->service_timer.function)
|
||||
del_timer_sync(&hdev->service_timer);
|
||||
|
@ -1621,7 +1621,8 @@ static void hclgevf_get_misc_vector(struct hclgevf_dev *hdev)
|
||||
|
||||
void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev)
|
||||
{
|
||||
if (!test_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state)) {
|
||||
if (!test_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state) &&
|
||||
!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state)) {
|
||||
set_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state);
|
||||
schedule_work(&hdev->rst_service_task);
|
||||
}
|
||||
@ -2132,6 +2133,7 @@ static void hclgevf_state_init(struct hclgevf_dev *hdev)
|
||||
static void hclgevf_state_uninit(struct hclgevf_dev *hdev)
|
||||
{
|
||||
set_bit(HCLGEVF_STATE_DOWN, &hdev->state);
|
||||
set_bit(HCLGEVF_STATE_REMOVING, &hdev->state);
|
||||
|
||||
if (hdev->keep_alive_timer.function)
|
||||
del_timer_sync(&hdev->keep_alive_timer);
|
||||
|
@ -130,6 +130,7 @@ enum hclgevf_states {
|
||||
HCLGEVF_STATE_DOWN,
|
||||
HCLGEVF_STATE_DISABLED,
|
||||
HCLGEVF_STATE_IRQ_INITED,
|
||||
HCLGEVF_STATE_REMOVING,
|
||||
HCLGEVF_STATE_NIC_REGISTERED,
|
||||
/* task states */
|
||||
HCLGEVF_STATE_SERVICE_SCHED,
|
||||
|
Loading…
Reference in New Issue
Block a user