From c7cf81b52c0297bc08c4994e86c3752e77068ab6 Mon Sep 17 00:00:00 2001 From: Lang Cheng Date: Thu, 3 Nov 2022 18:49:26 +0800 Subject: [PATCH] RDMA/hns: Add support for sending port down event fastly driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I5Z2DS ---------------------------------------------------------- When the netdev port status changes, the roce driver sends a port down event by parsing the netdev event dispatched by IB_CORE, which takes about a few hundred milliseconds. But,it is not fast enough for ULP sometimes. The HNS NIC driver can directly notify the ROCE driver send port event via callback function, this takes only a few milliseconds. This patch implements this callback function. Signed-off-by: Lang Cheng Signed-off-by: Chengchang Tang Reviewed-by: Yangyang Li Reviewed-by: Yue Haibing Signed-off-by: Zheng Zengkai --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 450b7ac4333c..bd45d07619e9 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -7046,9 +7046,43 @@ static int hns_roce_hw_v2_reset_notify(struct hnae3_handle *handle, return ret; } +static void hns_roce_hw_v2_link_status_change(struct hnae3_handle *handle, + bool linkup) +{ + struct net_device *netdev = handle->rinfo.netdev; + struct hns_roce_dev *hr_dev = handle->priv; + struct ib_event event; + unsigned long flags; + u8 phy_port; + + if (linkup || !hr_dev) + return; + + for (phy_port = 0; phy_port < hr_dev->caps.num_ports; phy_port++) + if (netdev == hr_dev->iboe.netdevs[phy_port]) + break; + + if (phy_port == hr_dev->caps.num_ports) + return; + + spin_lock_irqsave(&hr_dev->iboe.lock, flags); + if (hr_dev->iboe.port_state[phy_port] == IB_PORT_DOWN) { + spin_unlock_irqrestore(&hr_dev->iboe.lock, flags); + return; + } + hr_dev->iboe.port_state[phy_port] = IB_PORT_DOWN; + spin_unlock_irqrestore(&hr_dev->iboe.lock, flags); + + event.device = &hr_dev->ib_dev; + event.element.port_num = to_rdma_port_num(phy_port); + event.event = IB_EVENT_PORT_ERR; + ib_dispatch_event(&event); +} + static const struct hnae3_client_ops hns_roce_hw_v2_ops = { .init_instance = hns_roce_hw_v2_init_instance, .uninit_instance = hns_roce_hw_v2_uninit_instance, + .link_status_change = hns_roce_hw_v2_link_status_change, .reset_notify = hns_roce_hw_v2_reset_notify, }; -- GitLab