All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>,
	stable@dpdk.org, Chas Williams <3chas3@gmail.com>,
	"Min Hu (Connor)" <humin29@huawei.com>,
	Declan Doherty <declan.doherty@intel.com>,
	Pablo de Lara <pablo.de.lara.guarch@intel.com>,
	Robert Sanford <rsanford@akamai.com>
Subject: [PATCH v2 4/8] net/bonding: use atomic link status accessors
Date: Mon, 31 Aug 2026 09:06:44 -0700	[thread overview]
Message-ID: <20260831161105.289670-5-stephen@networkplumber.org> (raw)
In-Reply-To: <20260831161105.289670-1-stephen@networkplumber.org>

The bonding PMD read and wrote rte_eth_dev_data.dev_link directly.
Since a struct rte_eth_link is a 64 bit value updated concurrently
it needs to be done atomically. Use existing helpers.

Fixes: 2efb58cbab6e ("bond: new link bonding library")
Cc: stable@dpdk.org

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/bonding/rte_eth_bond_pmd.c | 84 ++++++++++++++++----------
 1 file changed, 51 insertions(+), 33 deletions(-)

diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 7579b97b06..6f3c13d6fb 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1461,8 +1461,12 @@ link_properties_set(struct rte_eth_dev *ethdev, struct rte_eth_link *member_link
 		 * In any other mode the link properties are set to default
 		 * values of AUTONEG/DUPLEX
 		 */
-		ethdev->data->dev_link.link_autoneg = RTE_ETH_LINK_AUTONEG;
-		ethdev->data->dev_link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
+		struct rte_eth_link link;
+
+		rte_eth_linkstatus_get(ethdev, &link);
+		link.link_autoneg = RTE_ETH_LINK_AUTONEG;
+		link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
+		rte_eth_linkstatus_set(ethdev, &link);
 	}
 }
 
@@ -2077,6 +2081,16 @@ bond_ethdev_primary_set(struct bond_dev_private *internals,
 static int
 bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev);
 
+static void
+bond_ethdev_link_down(struct rte_eth_dev *eth_dev)
+{
+	struct rte_eth_link link;
+
+	rte_eth_linkstatus_get(eth_dev, &link);
+	link.link_status = RTE_ETH_LINK_DOWN;
+	rte_eth_linkstatus_set(eth_dev, &link);
+}
+
 static int
 bond_ethdev_start(struct rte_eth_dev *eth_dev)
 {
@@ -2090,7 +2104,7 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
 		return -1;
 	}
 
-	eth_dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN;
+	bond_ethdev_link_down(eth_dev);
 	eth_dev->data->dev_started = 1;
 
 	internals = eth_dev->data->dev_private;
@@ -2242,7 +2256,7 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev)
 			tlb_last_obytets[internals->active_members[i]] = 0;
 	}
 
-	eth_dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN;
+	bond_ethdev_link_down(eth_dev);
 	eth_dev->data->dev_started = 0;
 
 	if (internals->link_status_polling_enabled) {
@@ -2537,6 +2551,7 @@ bond_ethdev_member_link_status_change_monitor(void *cb_arg)
 {
 	struct rte_eth_dev *bonding_ethdev, *member_ethdev;
 	struct bond_dev_private *internals;
+	struct rte_eth_link member_link;
 
 	/* Default value for polling member found is true as we don't want to
 	 * disable the polling thread if we cannot get the lock */
@@ -2569,9 +2584,11 @@ bond_ethdev_member_link_status_change_monitor(void *cb_arg)
 			member_ethdev->dev_ops->link_update(member_ethdev,
 					      internals->members[i].link_status_wait_to_complete);
 
+			rte_eth_linkstatus_get(member_ethdev, &member_link);
+
 			/* if link status has changed since last checked then call lsc
 			 * event callback */
-			if (member_ethdev->data->dev_link.link_status !=
+			if (member_link.link_status !=
 					internals->members[i].last_link_status) {
 				bond_ethdev_lsc_event_callback(internals->members[i].port_id,
 						RTE_ETH_EVENT_INTR_LSC,
@@ -2595,6 +2612,7 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
 
 	struct bond_dev_private *bond_ctx;
 	struct rte_eth_link member_link;
+	struct rte_eth_link link;
 
 	bool one_link_update_succeeded;
 	uint32_t idx;
@@ -2602,15 +2620,17 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
 
 	bond_ctx = ethdev->data->dev_private;
 
-	ethdev->data->dev_link.link_speed = RTE_ETH_SPEED_NUM_NONE;
+	rte_eth_linkstatus_get(ethdev, &link);
+	link.link_speed = RTE_ETH_SPEED_NUM_NONE;
 
 	if (ethdev->data->dev_started == 0 ||
 			bond_ctx->active_member_count == 0) {
-		ethdev->data->dev_link.link_status = RTE_ETH_LINK_DOWN;
+		link.link_status = RTE_ETH_LINK_DOWN;
+		rte_eth_linkstatus_set(ethdev, &link);
 		return 0;
 	}
 
-	ethdev->data->dev_link.link_status = RTE_ETH_LINK_UP;
+	link.link_status = RTE_ETH_LINK_UP;
 
 	if (wait_to_complete)
 		link_update = rte_eth_link_get;
@@ -2623,7 +2643,7 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
 		 * Setting link speed to UINT32_MAX to ensure we pick up the
 		 * value of the first active member
 		 */
-		ethdev->data->dev_link.link_speed = UINT32_MAX;
+		link.link_speed = UINT32_MAX;
 
 		/**
 		 * link speed is minimum value of all the members link speed as
@@ -2634,19 +2654,16 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
 			ret = link_update(bond_ctx->active_members[idx],
 					  &member_link);
 			if (ret < 0) {
-				ethdev->data->dev_link.link_speed =
-					RTE_ETH_SPEED_NUM_NONE;
+				link.link_speed = RTE_ETH_SPEED_NUM_NONE;
 				RTE_BOND_LOG(ERR,
 					"Member (port %u) link get failed: %s",
 					bond_ctx->active_members[idx],
 					rte_strerror(-ret));
-				return 0;
+				goto done;
 			}
 
-			if (member_link.link_speed <
-					ethdev->data->dev_link.link_speed)
-				ethdev->data->dev_link.link_speed =
-						member_link.link_speed;
+			if (member_link.link_speed < link.link_speed)
+				link.link_speed = member_link.link_speed;
 		}
 		break;
 	case BONDING_MODE_ACTIVE_BACKUP:
@@ -2656,16 +2673,14 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
 			RTE_BOND_LOG(ERR, "Member (port %u) link get failed: %s",
 				bond_ctx->current_primary_port,
 				rte_strerror(-ret));
-			return 0;
+			goto done;
 		}
 
-		ethdev->data->dev_link.link_speed = member_link.link_speed;
+		link.link_speed = member_link.link_speed;
 		break;
 	case BONDING_MODE_8023AD:
-		ethdev->data->dev_link.link_autoneg =
-				bond_ctx->mode4.member_link.link_autoneg;
-		ethdev->data->dev_link.link_duplex =
-				bond_ctx->mode4.member_link.link_duplex;
+		link.link_autoneg = bond_ctx->mode4.member_link.link_autoneg;
+		link.link_duplex = bond_ctx->mode4.member_link.link_duplex;
 		/* fall through */
 		/* to update link speed */
 	case BONDING_MODE_ROUND_ROBIN:
@@ -2677,7 +2692,7 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
 		 * In theses mode the maximum theoretical link speed is the sum
 		 * of all the members
 		 */
-		ethdev->data->dev_link.link_speed = RTE_ETH_SPEED_NUM_NONE;
+		link.link_speed = RTE_ETH_SPEED_NUM_NONE;
 		one_link_update_succeeded = false;
 
 		for (idx = 0; idx < bond_ctx->active_member_count; idx++) {
@@ -2692,16 +2707,15 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete)
 			}
 
 			one_link_update_succeeded = true;
-			ethdev->data->dev_link.link_speed +=
-					member_link.link_speed;
+			link.link_speed += member_link.link_speed;
 		}
 
-		if (!one_link_update_succeeded) {
+		if (!one_link_update_succeeded)
 			RTE_BOND_LOG(ERR, "All members link get failed");
-			return 0;
-		}
 	}
 
+done:
+	rte_eth_linkstatus_set(ethdev, &link);
 
 	return 0;
 }
@@ -3069,7 +3083,7 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
 {
 	struct rte_eth_dev *bonding_eth_dev;
 	struct bond_dev_private *internals;
-	struct rte_eth_link link;
+	struct rte_eth_link link, bond_link;
 	int rc = -1;
 	int ret;
 
@@ -3122,7 +3136,8 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
 			goto link_update;
 
 		/* check link state properties if bonding link is up*/
-		if (bonding_eth_dev->data->dev_link.link_status == RTE_ETH_LINK_UP) {
+		rte_eth_linkstatus_get(bonding_eth_dev, &bond_link);
+		if (bond_link.link_status == RTE_ETH_LINK_UP) {
 			if (link_properties_valid(bonding_eth_dev, &link) != 0)
 				RTE_BOND_LOG(ERR, "Invalid link properties "
 					     "for member %d in bonding mode %d",
@@ -3137,8 +3152,10 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
 		 */
 		if (internals->active_member_count < 1) {
 			/* If first active member, then change link status */
-			bonding_eth_dev->data->dev_link.link_status =
-								RTE_ETH_LINK_UP;
+			rte_eth_linkstatus_get(bonding_eth_dev, &bond_link);
+			bond_link.link_status = RTE_ETH_LINK_UP;
+			rte_eth_linkstatus_set(bonding_eth_dev, &bond_link);
+
 			internals->current_primary_port = port_id;
 			lsc_flag = 1;
 
@@ -3194,7 +3211,8 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
 			rte_eal_alarm_cancel(bond_ethdev_delayed_lsc_propagation,
 					bonding_eth_dev);
 
-		if (bonding_eth_dev->data->dev_link.link_status) {
+		rte_eth_linkstatus_get(bonding_eth_dev, &bond_link);
+		if (bond_link.link_status) {
 			if (internals->link_up_delay_ms > 0)
 				rte_eal_alarm_set(internals->link_up_delay_ms * 1000,
 						bond_ethdev_delayed_lsc_propagation,
-- 
2.53.0


  parent reply	other threads:[~2026-08-31 16:11 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-08 17:42 [RFC PATCH] net/bonding: reject control operations in secondary Weijun Pan
2026-07-22 23:10 ` Stephen Hemminger
2026-07-26 17:32 ` Stephen Hemminger
2026-08-23 15:16 ` [RFC PATCH v2] net/bonding: restrict secondary control operations Weijun Pan
2026-08-23 15:43   ` Stephen Hemminger
2026-08-24  2:39     ` Weijun Pan
2026-08-24 16:15   ` Stephen Hemminger
2026-08-26 16:10   ` [RFC PATCH v3] " Weijun Pan
2026-08-26 17:53     ` Stephen Hemminger
2026-08-30  1:14     ` [RFC PATCH v4 1/2] net/bonding: skip unavailable member stats Weijun Pan
2026-08-30  1:14       ` [RFC PATCH v4 2/2] net/bonding: restrict secondary control operations Weijun Pan
2026-08-30  4:29         ` Stephen Hemminger
2026-08-30  4:22       ` [RFC PATCH v4 1/2] net/bonding: skip unavailable member stats Stephen Hemminger
2026-08-30 16:35       ` [RFC PATCH v5 " Weijun Pan
2026-08-30 16:35         ` [RFC PATCH v5 2/2] net/bonding: restrict secondary control operations Weijun Pan
2026-08-30 20:23 ` [PATCH 0/8] net/bonding: fixes and per-member statistics Stephen Hemminger
2026-08-30 20:23   ` [PATCH 1/8] net/bonding: fix TLB member ordering with unusable member Stephen Hemminger
2026-08-30 20:23   ` [PATCH 2/8] net/bonding: skip unavailable member stats Stephen Hemminger
2026-08-30 20:23   ` [PATCH 3/8] net/bonding: skip unavailable members in device info Stephen Hemminger
2026-08-30 20:23   ` [PATCH 4/8] net/bonding: use atomic link status accessors Stephen Hemminger
2026-08-30 20:23   ` [PATCH 5/8] net/bonding: restrict control operations in secondary process Stephen Hemminger
2026-08-30 20:23   ` [PATCH 6/8] net/bonding: add extended statistics Stephen Hemminger
2026-08-30 20:23   ` [PATCH 7/8] test/bonding: add extended statistics test Stephen Hemminger
2026-08-30 20:23   ` [PATCH 8/8] doc: add bonding features matrix Stephen Hemminger
2026-08-31 16:06 ` [PATCH v2 0/8] net/bonding: fixes and per-member stats Stephen Hemminger
2026-08-31 16:06   ` [PATCH v2 1/8] net/bonding: fix TLB member ordering with unusable member Stephen Hemminger
2026-08-31 16:06   ` [PATCH v2 2/8] net/bonding: skip unavailable member stats Stephen Hemminger
2026-08-31 16:06   ` [PATCH v2 3/8] net/bonding: skip unavailable members in device info Stephen Hemminger
2026-08-31 16:06   ` Stephen Hemminger [this message]
2026-08-31 16:06   ` [PATCH v2 5/8] net/bonding: restrict control ops in secondary process Stephen Hemminger
2026-08-31 16:06   ` [PATCH v2 6/8] net/bonding: add extended statistics Stephen Hemminger
2026-08-31 16:06   ` [PATCH v2 7/8] test/bonding: add extended statistics test Stephen Hemminger
2026-08-31 16:06   ` [PATCH v2 8/8] doc: add bonding features matrix Stephen Hemminger

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=20260831161105.289670-5-stephen@networkplumber.org \
    --to=stephen@networkplumber.org \
    --cc=3chas3@gmail.com \
    --cc=declan.doherty@intel.com \
    --cc=dev@dpdk.org \
    --cc=humin29@huawei.com \
    --cc=pablo.de.lara.guarch@intel.com \
    --cc=rsanford@akamai.com \
    --cc=stable@dpdk.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.