]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
net: hns3: refine the handle for hns3_nic_net_open/stop()
authorJian Shen <shenjian15@huawei.com>
Thu, 20 Dec 2018 03:51:58 +0000 (11:51 +0800)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Mon, 14 Jan 2019 09:28:55 +0000 (09:28 +0000)
BugLink: https://bugs.launchpad.net/bugs/1810457
When triggering nic down, there is a time window between bringing down
the protocol stack and stopping the work task. If the net is up in the
time window, it may bring up the protocol stack again.

This patch fixes it by stop the work task at the beginning of
hns3_nic_net_stop(). To keep symmetrical, start the work task at the
end of hns3_nic_net_open().

Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 8cdb992f0dc36d6382840b1a6320e0c327a7d644)
Signed-off-by: dann frazier <dann.frazier@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c

index e10ba6e1007ceefac5f94bf53c39cc4af2e6d770..c20978b062e3b4070978991676e43cf8b26a54c1 100644 (file)
@@ -458,6 +458,7 @@ struct hnae3_ae_ops {
        bool (*ae_dev_resetting)(struct hnae3_handle *handle);
        unsigned long (*ae_dev_reset_cnt)(struct hnae3_handle *handle);
        u16 (*get_global_queue_id)(struct hnae3_handle *handle, u16 queue_id);
+       void (*set_timer_task)(struct hnae3_handle *handle, bool enable);
 };
 
 struct hnae3_dcb_ops {
index c3270b4300a1b01c4a7ab2887a92a16e1b1dab9c..0602cc02532a94436ff2d0f15f2a6263a6d5334d 100644 (file)
@@ -379,6 +379,7 @@ out_start_err:
 
 static int hns3_nic_net_open(struct net_device *netdev)
 {
+       struct hns3_nic_priv *priv = netdev_priv(netdev);
        struct hnae3_handle *h = hns3_get_handle(netdev);
        struct hnae3_knic_private_info *kinfo;
        int i, ret;
@@ -405,6 +406,9 @@ static int hns3_nic_net_open(struct net_device *netdev)
                                       kinfo->prio_tc[i]);
        }
 
+       if (h->ae_algo->ops->set_timer_task)
+               h->ae_algo->ops->set_timer_task(priv->ae_handle, true);
+
        return 0;
 }
 
@@ -437,10 +441,14 @@ static void hns3_nic_net_down(struct net_device *netdev)
 static int hns3_nic_net_stop(struct net_device *netdev)
 {
        struct hns3_nic_priv *priv = netdev_priv(netdev);
+       struct hnae3_handle *h = hns3_get_handle(netdev);
 
        if (test_and_set_bit(HNS3_NIC_STATE_DOWN, &priv->state))
                return 0;
 
+       if (h->ae_algo->ops->set_timer_task)
+               h->ae_algo->ops->set_timer_task(priv->ae_handle, false);
+
        netif_tx_stop_all_queues(netdev);
        netif_carrier_off(netdev);
 
index aec1039d2707c9808400051d540e7b8c36933448..78960efffe3431b03a423f6267b86e95869d5614 100644 (file)
@@ -5301,6 +5301,20 @@ static void hclge_reset_tqp_stats(struct hnae3_handle *handle)
        }
 }
 
+static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+
+       if (enable) {
+               mod_timer(&hdev->service_timer, jiffies + HZ);
+       } else {
+               del_timer_sync(&hdev->service_timer);
+               cancel_work_sync(&hdev->service_task);
+               clear_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state);
+       }
+}
+
 static int hclge_ae_start(struct hnae3_handle *handle)
 {
        struct hclge_vport *vport = hclge_get_vport(handle);
@@ -5309,7 +5323,6 @@ static int hclge_ae_start(struct hnae3_handle *handle)
        /* mac enable */
        hclge_cfg_mac_mode(hdev, true);
        clear_bit(HCLGE_STATE_DOWN, &hdev->state);
-       mod_timer(&hdev->service_timer, jiffies + HZ);
        hdev->hw.mac.link = 0;
 
        /* reset tqp stats */
@@ -5327,10 +5340,6 @@ static void hclge_ae_stop(struct hnae3_handle *handle)
 
        set_bit(HCLGE_STATE_DOWN, &hdev->state);
 
-       del_timer_sync(&hdev->service_timer);
-       cancel_work_sync(&hdev->service_task);
-       clear_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state);
-
        /* If it is not PF reset, the firmware will disable the MAC,
         * so it only need to stop phy here.
         */
@@ -5347,8 +5356,6 @@ static void hclge_ae_stop(struct hnae3_handle *handle)
 
        /* reset tqp stats */
        hclge_reset_tqp_stats(handle);
-       del_timer_sync(&hdev->service_timer);
-       cancel_work_sync(&hdev->service_task);
        hclge_update_link_status(hdev);
 }
 
@@ -8003,6 +8010,7 @@ static const struct hnae3_ae_ops hclge_ops = {
        .ae_dev_resetting = hclge_ae_dev_resetting,
        .ae_dev_reset_cnt = hclge_ae_dev_reset_cnt,
        .get_global_queue_id = hclge_covert_handle_qid_global,
+       .set_timer_task = hclge_set_timer_task,
 };
 
 static struct hnae3_ae_algo ae_algo = {
index 030f29cd10e0599e9ca25f3454c5867b1eec2698..54df2cb4671393ea8487aec6647a0a9705b0a7b3 100644 (file)
@@ -1840,6 +1840,19 @@ static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev)
                                       false);
 }
 
+static void hclgevf_set_timer_task(struct hnae3_handle *handle, bool enable)
+{
+       struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
+
+       if (enable) {
+               mod_timer(&hdev->service_timer, jiffies + HZ);
+       } else {
+               del_timer_sync(&hdev->service_timer);
+               cancel_work_sync(&hdev->service_task);
+               clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state);
+       }
+}
+
 static int hclgevf_ae_start(struct hnae3_handle *handle)
 {
        struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
@@ -1850,7 +1863,6 @@ static int hclgevf_ae_start(struct hnae3_handle *handle)
        hclgevf_request_link_info(hdev);
 
        clear_bit(HCLGEVF_STATE_DOWN, &hdev->state);
-       mod_timer(&hdev->service_timer, jiffies + HZ);
 
        return 0;
 }
@@ -1863,9 +1875,6 @@ static void hclgevf_ae_stop(struct hnae3_handle *handle)
 
        /* reset tqp stats */
        hclgevf_reset_tqp_stats(handle);
-       del_timer_sync(&hdev->service_timer);
-       cancel_work_sync(&hdev->service_task);
-       clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state);
        hclgevf_update_link_status(hdev, 0);
 }
 
@@ -2655,6 +2664,7 @@ static const struct hnae3_ae_ops hclgevf_ops = {
        .ae_dev_reset_cnt = hclgevf_ae_dev_reset_cnt,
        .set_mtu = hclgevf_set_mtu,
        .get_global_queue_id = hclgevf_get_qid_global,
+       .set_timer_task = hclgevf_set_timer_task,
 };
 
 static struct hnae3_ae_algo ae_algovf = {