aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSalil Mehta <salil.mehta@huawei.com>2017-12-03 20:29:54 -0500
committerDavid S. Miller <davem@davemloft.net>2017-12-05 11:45:17 -0500
commitcb1b9f77c48fb014da7d020f1395eca4fdfcbd9a (patch)
tree67ae6cb08be18701c194d52d70f9eb7a4480b117
parentca1d7669b714d35903fc5dfbf54c990c6122a1d4 (diff)
net: hns3: Add reset service task for handling reset requests
Existing common service task was being used to service the reset requests. This patch tries to make the handling of reset cleaner by separating task to handle the reset requests. This might in turn help in adapting similar handling approach for other interrupt events like mailbox, sharing vector 0 interrupt. Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: lipeng <lipeng321@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c41
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h4
2 files changed, 34 insertions, 11 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 0c0543e84957..345868470201 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2226,6 +2226,12 @@ static int hclge_mac_init(struct hclge_dev *hdev)
2226 return hclge_cfg_func_mta_filter(hdev, 0, hdev->accept_mta_mc); 2226 return hclge_cfg_func_mta_filter(hdev, 0, hdev->accept_mta_mc);
2227} 2227}
2228 2228
2229static void hclge_reset_task_schedule(struct hclge_dev *hdev)
2230{
2231 if (!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
2232 schedule_work(&hdev->rst_service_task);
2233}
2234
2229static void hclge_task_schedule(struct hclge_dev *hdev) 2235static void hclge_task_schedule(struct hclge_dev *hdev)
2230{ 2236{
2231 if (!test_bit(HCLGE_STATE_DOWN, &hdev->state) && 2237 if (!test_bit(HCLGE_STATE_DOWN, &hdev->state) &&
@@ -2421,7 +2427,7 @@ static irqreturn_t hclge_misc_irq_handle(int irq, void *data)
2421 */ 2427 */
2422 switch (event_cause) { 2428 switch (event_cause) {
2423 case HCLGE_VECTOR0_EVENT_RST: 2429 case HCLGE_VECTOR0_EVENT_RST:
2424 /* reset task to be scheduled here */ 2430 hclge_reset_task_schedule(hdev);
2425 break; 2431 break;
2426 default: 2432 default:
2427 dev_dbg(&hdev->pdev->dev, 2433 dev_dbg(&hdev->pdev->dev,
@@ -2584,6 +2590,9 @@ static void hclge_do_reset(struct hclge_dev *hdev, enum hnae3_reset_type type)
2584 case HNAE3_FUNC_RESET: 2590 case HNAE3_FUNC_RESET:
2585 dev_info(&pdev->dev, "PF Reset requested\n"); 2591 dev_info(&pdev->dev, "PF Reset requested\n");
2586 hclge_func_reset_cmd(hdev, 0); 2592 hclge_func_reset_cmd(hdev, 0);
2593 /* schedule again to check later */
2594 set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending);
2595 hclge_reset_task_schedule(hdev);
2587 break; 2596 break;
2588 default: 2597 default:
2589 dev_warn(&pdev->dev, 2598 dev_warn(&pdev->dev,
@@ -2605,14 +2614,9 @@ static void hclge_reset_event(struct hnae3_handle *handle,
2605 case HNAE3_FUNC_RESET: 2614 case HNAE3_FUNC_RESET:
2606 case HNAE3_CORE_RESET: 2615 case HNAE3_CORE_RESET:
2607 case HNAE3_GLOBAL_RESET: 2616 case HNAE3_GLOBAL_RESET:
2608 if (test_bit(HCLGE_STATE_RESET_INT, &hdev->state)) { 2617 /* request reset & schedule reset task */
2609 dev_err(&hdev->pdev->dev, "Already in reset state"); 2618 set_bit(reset, &hdev->reset_request);
2610 return; 2619 hclge_reset_task_schedule(hdev);
2611 }
2612 hdev->reset_type = reset;
2613 set_bit(HCLGE_STATE_RESET_INT, &hdev->state);
2614 set_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state);
2615 schedule_work(&hdev->service_task);
2616 break; 2620 break;
2617 default: 2621 default:
2618 dev_warn(&hdev->pdev->dev, "Unsupported reset event:%d", reset); 2622 dev_warn(&hdev->pdev->dev, "Unsupported reset event:%d", reset);
@@ -2658,9 +2662,19 @@ static void hclge_reset_subtask(struct hclge_dev *hdev)
2658 hdev->reset_type = HNAE3_NONE_RESET; 2662 hdev->reset_type = HNAE3_NONE_RESET;
2659} 2663}
2660 2664
2661static void hclge_misc_irq_service_task(struct hclge_dev *hdev) 2665static void hclge_reset_service_task(struct work_struct *work)
2662{ 2666{
2667 struct hclge_dev *hdev =
2668 container_of(work, struct hclge_dev, rst_service_task);
2669
2670 if (test_and_set_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
2671 return;
2672
2673 clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state);
2674
2663 hclge_reset_subtask(hdev); 2675 hclge_reset_subtask(hdev);
2676
2677 clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
2664} 2678}
2665 2679
2666static void hclge_service_task(struct work_struct *work) 2680static void hclge_service_task(struct work_struct *work)
@@ -2668,7 +2682,6 @@ static void hclge_service_task(struct work_struct *work)
2668 struct hclge_dev *hdev = 2682 struct hclge_dev *hdev =
2669 container_of(work, struct hclge_dev, service_task); 2683 container_of(work, struct hclge_dev, service_task);
2670 2684
2671 hclge_misc_irq_service_task(hdev);
2672 hclge_update_speed_duplex(hdev); 2685 hclge_update_speed_duplex(hdev);
2673 hclge_update_link_status(hdev); 2686 hclge_update_link_status(hdev);
2674 hclge_update_stats_for_all(hdev); 2687 hclge_update_stats_for_all(hdev);
@@ -4699,6 +4712,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
4699 hdev->pdev = pdev; 4712 hdev->pdev = pdev;
4700 hdev->ae_dev = ae_dev; 4713 hdev->ae_dev = ae_dev;
4701 hdev->reset_type = HNAE3_NONE_RESET; 4714 hdev->reset_type = HNAE3_NONE_RESET;
4715 hdev->reset_request = 0;
4702 hdev->reset_pending = 0; 4716 hdev->reset_pending = 0;
4703 ae_dev->priv = hdev; 4717 ae_dev->priv = hdev;
4704 4718
@@ -4811,12 +4825,15 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
4811 4825
4812 timer_setup(&hdev->service_timer, hclge_service_timer, 0); 4826 timer_setup(&hdev->service_timer, hclge_service_timer, 0);
4813 INIT_WORK(&hdev->service_task, hclge_service_task); 4827 INIT_WORK(&hdev->service_task, hclge_service_task);
4828 INIT_WORK(&hdev->rst_service_task, hclge_reset_service_task);
4814 4829
4815 /* Enable MISC vector(vector0) */ 4830 /* Enable MISC vector(vector0) */
4816 hclge_enable_vector(&hdev->misc_vector, true); 4831 hclge_enable_vector(&hdev->misc_vector, true);
4817 4832
4818 set_bit(HCLGE_STATE_SERVICE_INITED, &hdev->state); 4833 set_bit(HCLGE_STATE_SERVICE_INITED, &hdev->state);
4819 set_bit(HCLGE_STATE_DOWN, &hdev->state); 4834 set_bit(HCLGE_STATE_DOWN, &hdev->state);
4835 clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state);
4836 clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
4820 4837
4821 pr_info("%s driver initialization finished.\n", HCLGE_DRIVER_NAME); 4838 pr_info("%s driver initialization finished.\n", HCLGE_DRIVER_NAME);
4822 return 0; 4839 return 0;
@@ -4928,6 +4945,8 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
4928 del_timer_sync(&hdev->service_timer); 4945 del_timer_sync(&hdev->service_timer);
4929 if (hdev->service_task.func) 4946 if (hdev->service_task.func)
4930 cancel_work_sync(&hdev->service_task); 4947 cancel_work_sync(&hdev->service_task);
4948 if (hdev->rst_service_task.func)
4949 cancel_work_sync(&hdev->rst_service_task);
4931 4950
4932 if (mac->phydev) 4951 if (mac->phydev)
4933 mdiobus_unregister(mac->mdio_bus); 4952 mdiobus_unregister(mac->mdio_bus);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index d4429496f4b5..fd04fd23b76a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -99,6 +99,8 @@ enum HCLGE_DEV_STATE {
99 HCLGE_STATE_REMOVING, 99 HCLGE_STATE_REMOVING,
100 HCLGE_STATE_SERVICE_INITED, 100 HCLGE_STATE_SERVICE_INITED,
101 HCLGE_STATE_SERVICE_SCHED, 101 HCLGE_STATE_SERVICE_SCHED,
102 HCLGE_STATE_RST_SERVICE_SCHED,
103 HCLGE_STATE_RST_HANDLING,
102 HCLGE_STATE_MBX_HANDLING, 104 HCLGE_STATE_MBX_HANDLING,
103 HCLGE_STATE_MBX_IRQ, 105 HCLGE_STATE_MBX_IRQ,
104 HCLGE_STATE_RESET_INT, 106 HCLGE_STATE_RESET_INT,
@@ -426,6 +428,7 @@ struct hclge_dev {
426 unsigned long state; 428 unsigned long state;
427 429
428 enum hnae3_reset_type reset_type; 430 enum hnae3_reset_type reset_type;
431 unsigned long reset_request; /* reset has been requested */
429 unsigned long reset_pending; /* client rst is pending to be served */ 432 unsigned long reset_pending; /* client rst is pending to be served */
430 u32 fw_version; 433 u32 fw_version;
431 u16 num_vmdq_vport; /* Num vmdq vport this PF has set up */ 434 u16 num_vmdq_vport; /* Num vmdq vport this PF has set up */
@@ -476,6 +479,7 @@ struct hclge_dev {
476 unsigned long service_timer_previous; 479 unsigned long service_timer_previous;
477 struct timer_list service_timer; 480 struct timer_list service_timer;
478 struct work_struct service_task; 481 struct work_struct service_task;
482 struct work_struct rst_service_task;
479 483
480 bool cur_promisc; 484 bool cur_promisc;
481 int num_alloc_vfs; /* Actual number of VFs allocated */ 485 int num_alloc_vfs; /* Actual number of VFs allocated */