From 26e713d8508c5e176f09ce66f3f0509b60aa062e Mon Sep 17 00:00:00 2001 From: Yunsheng Lin Date: Fri, 5 Jul 2019 09:30:02 +0800 Subject: [PATCH] net: hns3: fix a BUG_ON when affinity notify is triggered before timer setup driver inclusion category: bugfix bugzilla: NA CVE: NA Currently when a misc affinity notify is triggered before the service timer is setup, the timer->function is null when calling add_timer_on, which causes a BUG_ON problem. This patch fixes it by move the affinity notify setup after service timer setup. Fixes: 99ff3c1cd346 ("net: hns3: add interrupt affinity support for misc interrupt") Feature or Bugfix:Bugfix Signed-off-by: Yunsheng Lin Reviewed-by: lipeng Reviewed-by: Yang Yingliang Signed-off-by: Yang Yingliang --- .../hisilicon/hns3/hns3pf/hclge_main.c | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 41b631cc7ab3..1bbac2d5d050 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -3019,7 +3019,7 @@ static void hclge_irq_affinity_notify(struct irq_affinity_notify *notify, affinity_notify); cpumask_copy(&hdev->affinity_mask, mask); - del_timer(&hdev->service_timer); + del_timer_sync(&hdev->service_timer); hdev->service_timer.expires = jiffies + HZ; add_timer_on(&hdev->service_timer, cpumask_first(&hdev->affinity_mask)); } @@ -3028,6 +3028,23 @@ static void hclge_irq_affinity_release(struct kref *ref) { } +static void hclge_misc_affinity_setup(struct hclge_dev *hdev) +{ + irq_set_affinity_hint(hdev->misc_vector.vector_irq, + &hdev->affinity_mask); + + hdev->affinity_notify.notify = hclge_irq_affinity_notify; + hdev->affinity_notify.release = hclge_irq_affinity_release; + irq_set_affinity_notifier(hdev->misc_vector.vector_irq, + &hdev->affinity_notify); +} + +static void hclge_misc_affinity_teardown(struct hclge_dev *hdev) +{ + irq_set_affinity_notifier(hdev->misc_vector.vector_irq, NULL); + irq_set_affinity_hint(hdev->misc_vector.vector_irq, NULL); +} + static int hclge_misc_irq_init(struct hclge_dev *hdev) { int ret; @@ -3041,24 +3058,13 @@ static int hclge_misc_irq_init(struct hclge_dev *hdev) hclge_free_vector(hdev, 0); dev_err(&hdev->pdev->dev, "request misc irq(%d) fail\n", hdev->misc_vector.vector_irq); - return ret; } - irq_set_affinity_hint(hdev->misc_vector.vector_irq, - &hdev->affinity_mask); - - hdev->affinity_notify.notify = hclge_irq_affinity_notify; - hdev->affinity_notify.release = hclge_irq_affinity_release; - irq_set_affinity_notifier(hdev->misc_vector.vector_irq, - &hdev->affinity_notify); - - return 0; + return ret; } static void hclge_misc_irq_uninit(struct hclge_dev *hdev) { - irq_set_affinity_notifier(hdev->misc_vector.vector_irq, NULL); - irq_set_affinity_hint(hdev->misc_vector.vector_irq, NULL); free_irq(hdev->misc_vector.vector_irq, hdev); hclge_free_vector(hdev, 0); } @@ -6514,7 +6520,7 @@ static void hclge_enable_timer_task(struct hnae3_handle *handle, bool enable) struct hclge_dev *hdev = vport->back; if (enable) { - del_timer(&hdev->service_timer); + del_timer_sync(&hdev->service_timer); hdev->service_timer.expires = jiffies + HZ; add_timer_on(&hdev->service_timer, cpumask_first(&hdev->affinity_mask)); @@ -9164,6 +9170,11 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) INIT_WORK(&hdev->rst_service_task, hclge_reset_service_task); INIT_WORK(&hdev->mbx_service_task, hclge_mailbox_service_task); + /* Setup affinity after service timer setup because add_timer_on + * is called in affinity notify. + */ + hclge_misc_affinity_setup(hdev); + hclge_clear_all_event_cause(hdev); hclge_clear_resetting_state(hdev); @@ -9330,6 +9341,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) struct hclge_dev *hdev = ae_dev->priv; struct hclge_mac *mac = &hdev->hw.mac; + hclge_misc_affinity_teardown(hdev); hclge_state_uninit(hdev); if (mac->phydev) -- GitLab