From: Lijun Ou <oulijun@huawei.com>
To: <thomas@monjalon.net>, <ferruh.yigit@intel.com>
Cc: <dev@dpdk.org>, <linuxarm@openeuler.org>
Subject: [dpdk-dev] [PATCH 14/14] net/hns3: support LSC event report
Date: Fri, 22 Jan 2021 18:18:52 +0800 [thread overview]
Message-ID: <1611310732-51975-15-git-send-email-oulijun@huawei.com> (raw)
In-Reply-To: <1611310732-51975-1-git-send-email-oulijun@huawei.com>
From: Chengwen Feng <fengchengwen@huawei.com>
This patch support LSC(Link Status Change) event report.
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Signed-off-by: Lijun Ou <oulijun@huawei.com>
---
drivers/net/hns3/hns3_ethdev.c | 52 +++++++++++++++++++++++++++++++++++----
drivers/net/hns3/hns3_ethdev.h | 4 ++-
drivers/net/hns3/hns3_ethdev_vf.c | 40 +++++++++++++++++++++++++++++-
drivers/net/hns3/hns3_mbx.c | 14 ++++++-----
4 files changed, 97 insertions(+), 13 deletions(-)
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 94b6e44..bc77608 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -19,6 +19,7 @@
#define HNS3_DEFAULT_PORT_CONF_QUEUES_NUM 1
#define HNS3_SERVICE_INTERVAL 1000000 /* us */
+#define HNS3_SERVICE_QUICK_INTERVAL 10
#define HNS3_INVALID_PVID 0xFFFF
#define HNS3_FILTER_TYPE_VF 0
@@ -93,6 +94,7 @@ static int hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
static int hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid,
int on);
static int hns3_update_speed_duplex(struct rte_eth_dev *eth_dev);
+static bool hns3_update_link_status(struct hns3_hw *hw);
static int hns3_add_mc_addr(struct hns3_hw *hw,
struct rte_ether_addr *mac_addr);
@@ -4458,7 +4460,7 @@ hns3_get_mac_link_status(struct hns3_hw *hw)
return !!link_status;
}
-void
+static bool
hns3_update_link_status(struct hns3_hw *hw)
{
int state;
@@ -4467,7 +4469,36 @@ hns3_update_link_status(struct hns3_hw *hw)
if (state != hw->mac.link_status) {
hw->mac.link_status = state;
hns3_warn(hw, "Link status change to %s!", state ? "up" : "down");
+ return true;
}
+
+ return false;
+}
+
+/*
+ * Current, the PF driver get link status by two ways:
+ * 1) Periodic polling in the intr thread context, driver call
+ * hns3_update_link_status to update link status.
+ * 2) Firmware report async interrupt, driver process the event in the intr
+ * thread context, and call hns3_update_link_status to update link status.
+ *
+ * If detect link status changed, driver need report LSE. One method is add the
+ * report LSE logic in hns3_update_link_status.
+ *
+ * But the PF driver ops(link_update) also call hns3_update_link_status to
+ * update link status.
+ * If we report LSE in hns3_update_link_status, it may lead to deadlock in the
+ * bonding application.
+ *
+ * So add the one new API which used only in intr thread context.
+ */
+void
+hns3_update_link_status_and_event(struct hns3_hw *hw)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id];
+ bool changed = hns3_update_link_status(hw);
+ if (changed)
+ rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
}
static void
@@ -4479,9 +4510,10 @@ hns3_service_handler(void *param)
if (!hns3_is_reset_pending(hns)) {
hns3_update_speed_duplex(eth_dev);
- hns3_update_link_status(hw);
- } else
+ hns3_update_link_status_and_event(hw);
+ } else {
hns3_warn(hw, "Cancel the query when reset is pending");
+ }
rte_eal_alarm_set(HNS3_SERVICE_INTERVAL, hns3_service_handler, eth_dev);
}
@@ -5557,8 +5589,10 @@ hns3_stop_service(struct hns3_adapter *hns)
struct rte_eth_dev *eth_dev;
eth_dev = &rte_eth_devices[hw->data->port_id];
- if (hw->adapter_state == HNS3_NIC_STARTED)
+ if (hw->adapter_state == HNS3_NIC_STARTED) {
rte_eal_alarm_cancel(hns3_service_handler, eth_dev);
+ hns3_update_link_status_and_event(hw);
+ }
hw->mac.link_status = ETH_LINK_DOWN;
hns3_set_rxtx_function(eth_dev);
@@ -5601,7 +5635,15 @@ hns3_start_service(struct hns3_adapter *hns)
hns3_set_rxtx_function(eth_dev);
hns3_mp_req_start_rxtx(eth_dev);
if (hw->adapter_state == HNS3_NIC_STARTED) {
- hns3_service_handler(eth_dev);
+ /*
+ * This API parent function already hold the hns3_hw.lock, the
+ * hns3_service_handler may report lse, in bonding application
+ * it will call driver's ops which may acquire the hns3_hw.lock
+ * again, thus lead to deadlock.
+ * We defer calls hns3_service_handler to avoid the deadlock.
+ */
+ rte_eal_alarm_set(HNS3_SERVICE_QUICK_INTERVAL,
+ hns3_service_handler, eth_dev);
/* Enable interrupt of all rx queues before enabling queues */
hns3_dev_all_rx_queue_intr_enable(hw, true);
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 0d17170..547e991 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -946,11 +946,13 @@ int hns3_dev_filter_ctrl(struct rte_eth_dev *dev,
enum rte_filter_op filter_op, void *arg);
bool hns3_is_reset_pending(struct hns3_adapter *hns);
bool hns3vf_is_reset_pending(struct hns3_adapter *hns);
-void hns3_update_link_status(struct hns3_hw *hw);
+void hns3_update_link_status_and_event(struct hns3_hw *hw);
void hns3_ether_format_addr(char *buf, uint16_t size,
const struct rte_ether_addr *ether_addr);
int hns3_dev_infos_get(struct rte_eth_dev *eth_dev,
struct rte_eth_dev_info *info);
+void hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status,
+ uint32_t link_speed, uint8_t link_duplex);
static inline bool
is_reset_pending(struct hns3_adapter *hns)
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 7eb0b11..470aaee 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -1440,6 +1440,41 @@ hns3vf_request_link_info(struct hns3_hw *hw)
hns3_err(hw, "Failed to fetch link status from PF: %d", ret);
}
+void
+hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status,
+ uint32_t link_speed, uint8_t link_duplex)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id];
+ struct hns3_mac *mac = &hw->mac;
+ bool report_lse;
+ bool changed;
+
+ changed = mac->link_status != link_status ||
+ mac->link_speed != link_speed ||
+ mac->link_duplex != link_duplex;
+ if (!changed)
+ return;
+
+ /*
+ * VF's link status/speed/duplex were updated by polling from PF driver,
+ * because the link status/speed/duplex may be changed in the polling
+ * interval, so driver will report lse (lsc event) once any of the above
+ * thress variables changed.
+ * But if the PF's link status is down and driver saved link status is
+ * also down, there are no need to report lse.
+ */
+ report_lse = true;
+ if (link_status == ETH_LINK_DOWN && link_status == mac->link_status)
+ report_lse = false;
+
+ mac->link_status = link_status;
+ mac->link_speed = link_speed;
+ mac->link_duplex = link_duplex;
+
+ if (report_lse)
+ rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+}
+
static int
hns3vf_vlan_filter_configure(struct hns3_adapter *hns, uint16_t vlan_id, int on)
{
@@ -2373,8 +2408,11 @@ hns3vf_stop_service(struct hns3_adapter *hns)
struct rte_eth_dev *eth_dev;
eth_dev = &rte_eth_devices[hw->data->port_id];
- if (hw->adapter_state == HNS3_NIC_STARTED)
+ if (hw->adapter_state == HNS3_NIC_STARTED) {
rte_eal_alarm_cancel(hns3vf_service_handler, eth_dev);
+ hns3vf_update_link_status(hw, ETH_LINK_DOWN, hw->mac.link_speed,
+ hw->mac.link_duplex);
+ }
hw->mac.link_status = ETH_LINK_DOWN;
hns3_set_rxtx_function(eth_dev);
diff --git a/drivers/net/hns3/hns3_mbx.c b/drivers/net/hns3/hns3_mbx.c
index d2a5db8..3e44e3b 100644
--- a/drivers/net/hns3/hns3_mbx.c
+++ b/drivers/net/hns3/hns3_mbx.c
@@ -203,8 +203,9 @@ hns3_cmd_crq_empty(struct hns3_hw *hw)
static void
hns3_mbx_handler(struct hns3_hw *hw)
{
- struct hns3_mac *mac = &hw->mac;
enum hns3_reset_level reset_level;
+ uint8_t link_status, link_duplex;
+ uint32_t link_speed;
uint16_t *msg_q;
uint8_t opcode;
uint32_t tail;
@@ -218,10 +219,11 @@ hns3_mbx_handler(struct hns3_hw *hw)
opcode = msg_q[0] & 0xff;
switch (opcode) {
case HNS3_MBX_LINK_STAT_CHANGE:
- memcpy(&mac->link_speed, &msg_q[2],
- sizeof(mac->link_speed));
- mac->link_status = rte_le_to_cpu_16(msg_q[1]);
- mac->link_duplex = (uint8_t)rte_le_to_cpu_16(msg_q[4]);
+ memcpy(&link_speed, &msg_q[2], sizeof(link_speed));
+ link_status = rte_le_to_cpu_16(msg_q[1]);
+ link_duplex = (uint8_t)rte_le_to_cpu_16(msg_q[4]);
+ hns3vf_update_link_status(hw, link_status, link_speed,
+ link_duplex);
break;
case HNS3_MBX_ASSERTING_RESET:
/* PF has asserted reset hence VF should go in pending
@@ -310,7 +312,7 @@ hns3_handle_link_change_event(struct hns3_hw *hw,
if (!req->msg[LINK_STATUS_OFFSET])
hns3_link_fail_parse(hw, req->msg[LINK_FAIL_CODE_OFFSET]);
- hns3_update_link_status(hw);
+ hns3_update_link_status_and_event(hw);
}
static void
--
2.7.4
next prev parent reply other threads:[~2021-01-22 10:20 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-22 10:18 [dpdk-dev] [PATCH 00/14] Misc updates for hns3 Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 01/14] net/hns3: encapsulate dfx stats in Rx/Tx datapatch Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 02/14] net/hns3: move queue stats to xstats Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 03/14] net/hns3: use array instead of switch-case Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 04/14] net/hns3: move judgment conditions to separated functions Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 05/14] net/hns3: reconstruct the Rx interrupt map Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 06/14] net/hns3: extract common judgments for all FDIR type Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 07/14] net/hns3: refactor reset event report function Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 08/14] net/hns3: fix memory leak with secondary process exit Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 09/14] net/hns3: fix interrupt resources in Rx interrupt mode Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 10/14] net/hns3: rename RSS functions Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 11/14] net/hns3: adjust some comments Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 12/14] net/hns3: remove unnecessary parentheses Lijun Ou
2021-01-22 10:18 ` [dpdk-dev] [PATCH 13/14] net/hns3: use %d instead of %u for enum variable Lijun Ou
2021-01-22 10:18 ` Lijun Ou [this message]
2021-01-28 23:41 ` [dpdk-dev] [PATCH 14/14] net/hns3: support LSC event report Ferruh Yigit
2021-01-29 1:49 ` oulijun
2021-02-02 12:06 ` Ferruh Yigit
2021-02-02 12:12 ` Ferruh Yigit
2021-01-28 23:58 ` [dpdk-dev] [PATCH 00/14] Misc updates for hns3 Ferruh Yigit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1611310732-51975-15-git-send-email-oulijun@huawei.com \
--to=oulijun@huawei.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@intel.com \
--cc=linuxarm@openeuler.org \
--cc=thomas@monjalon.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).