DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions
@ 2018-01-06  1:06 Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 01/15] eal: introduce atomic exchange operation Stephen Hemminger
                   ` (14 more replies)
  0 siblings, 15 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

While writing the hyperv driver, noticed a lot of unnecessary
duplication of code in drivers for handling the eth_dev link status
information. While consolidating this, it also became obvious that
some drivers behave differently for no good reason.

It also was a good chance to introduce atomic exchange primitives
in EAL because there are other places using cmpset where not
necessary (such as bonding).

Mostly only compile tested only, don't have all of the hardware
available (except ixgbe and virtio) to test.

The difference from v1 is that function name changed, rebasing
to current source and the introduction of atomic exchange.

Stephen Hemminger (15):
  eal: introduce atomic exchange operation
  ethdev: add linkstatus get/set helper functions
  virtio: use eth_linkstatus_set
  vmxnet3: use rte_eth_linkstatus_set
  dpaa2: use rte_eth_linkstatus_set
  nfp: use rte_eth_linkstatus functions
  e1000: use rte_eth_linkstatus helpers
  ixgbe: use rte_eth_linkstatus functions
  sfc: use new rte_eth_linkstatus functions
  i40e: use rte_eth_linkstatus functions
  liquidio: use _rte_eth_linkstatus_set
  thunderx: use _rte_eth_linkstatus_set
  szedata: use _rte_eth_linkstatus_set
  octeontx: use rte_eth_linkstatus_set
  enic: use _rte_eth_linkstatus_set

 drivers/net/dpaa2/dpaa2_ethdev.c                   | 65 ++------------
 drivers/net/e1000/em_ethdev.c                      | 70 ++-------------
 drivers/net/e1000/igb_ethdev.c                     | 71 ++--------------
 drivers/net/enic/enic_ethdev.c                     |  5 +-
 drivers/net/enic/enic_main.c                       | 16 ++--
 drivers/net/i40e/i40e_ethdev.c                     | 44 ++--------
 drivers/net/i40e/i40e_ethdev_vf.c                  | 19 +----
 drivers/net/ixgbe/ixgbe_ethdev.c                   | 99 ++++------------------
 drivers/net/liquidio/lio_ethdev.c                  | 54 ++----------
 drivers/net/nfp/nfp_net.c                          | 75 ++--------------
 drivers/net/octeontx/octeontx_ethdev.c             | 16 +---
 drivers/net/sfc/sfc_ethdev.c                       | 27 ++----
 drivers/net/sfc/sfc_ev.c                           | 23 +----
 drivers/net/szedata2/rte_eth_szedata2.c            | 20 ++---
 drivers/net/thunderx/nicvf_ethdev.c                | 17 +---
 drivers/net/virtio/virtio_ethdev.c                 | 67 +++------------
 drivers/net/vmxnet3/vmxnet3_ethdev.c               | 85 ++++---------------
 .../common/include/arch/x86/rte_atomic.h           | 24 ++++++
 .../common/include/arch/x86/rte_atomic_32.h        | 12 +++
 .../common/include/arch/x86/rte_atomic_64.h        | 12 +++
 lib/librte_eal/common/include/generic/rte_atomic.h | 78 +++++++++++++++++
 lib/librte_ether/rte_ethdev.c                      | 35 ++++++++
 lib/librte_ether/rte_ethdev.h                      | 28 ++++++
 23 files changed, 305 insertions(+), 657 deletions(-)

-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 01/15] eal: introduce atomic exchange operation
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 02/15] ethdev: add linkstatus get/set helper functions Stephen Hemminger
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

To handle atomic update of link status (64 bit), every driver
was doing its own version using cmpset.
Atomic exchange is a useful primitive in its own right;
therefore make it a EAL routine.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 .../common/include/arch/x86/rte_atomic.h           | 24 +++++++
 .../common/include/arch/x86/rte_atomic_32.h        | 12 ++++
 .../common/include/arch/x86/rte_atomic_64.h        | 12 ++++
 lib/librte_eal/common/include/generic/rte_atomic.h | 78 ++++++++++++++++++++++
 4 files changed, 126 insertions(+)

diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic.h b/lib/librte_eal/common/include/arch/x86/rte_atomic.h
index 8469f97e193a..20d10cc18e4e 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic.h
@@ -59,6 +59,18 @@ rte_atomic16_cmpset(volatile uint16_t *dst, uint16_t exp, uint16_t src)
 	return res;
 }
 
+static inline uint16_t
+rte_atomic16_exchange(volatile uint16_t *dst, uint16_t val)
+{
+	asm volatile(
+			MPLOCKED
+			"xchgw %0, %1;"
+			: "=r" (val), "=m" (*dst)
+			: "0" (val),  "m" (*dst)
+			: "memory");         /* no-clobber list */
+	return val;
+}
+
 static inline int rte_atomic16_test_and_set(rte_atomic16_t *v)
 {
 	return rte_atomic16_cmpset((volatile uint16_t *)&v->cnt, 0, 1);
@@ -133,6 +145,18 @@ rte_atomic32_cmpset(volatile uint32_t *dst, uint32_t exp, uint32_t src)
 	return res;
 }
 
+static inline uint32_t
+rte_atomic32_exchange(volatile uint32_t *dst, uint32_t val)
+{
+	asm volatile(
+			MPLOCKED
+			"xchgl %0, %1;"
+			: "=r" (val), "=m" (*dst)
+			: "0" (val),  "m" (*dst)
+			: "memory");         /* no-clobber list */
+	return val;
+}
+
 static inline int rte_atomic32_test_and_set(rte_atomic32_t *v)
 {
 	return rte_atomic32_cmpset((volatile uint32_t *)&v->cnt, 0, 1);
diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic_32.h b/lib/librte_eal/common/include/arch/x86/rte_atomic_32.h
index fb3abf187998..43fa59355ac5 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic_32.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic_32.h
@@ -98,6 +98,18 @@ rte_atomic64_cmpset(volatile uint64_t *dst, uint64_t exp, uint64_t src)
 	return res;
 }
 
+static inline uint64_t
+rte_atomic64_exchange(volatile uint64_t *dest, uint64_t val)
+{
+	uint64_t old;
+
+	do {
+		old = *dest;
+	} while (rte_atomic64_t_cmpset(dest, old, val));
+
+	return old;
+}
+
 static inline void
 rte_atomic64_init(rte_atomic64_t *v)
 {
diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
index 1a53a766bd72..fd2ec9c53796 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
@@ -71,6 +71,18 @@ rte_atomic64_cmpset(volatile uint64_t *dst, uint64_t exp, uint64_t src)
 	return res;
 }
 
+static inline uint64_t
+rte_atomic64_exchange(volatile uint64_t *dst, uint64_t val)
+{
+	asm volatile(
+			MPLOCKED
+			"xchgq %0, %1;"
+			: "=r" (val), "=m" (*dst)
+			: "0" (val),  "m" (*dst)
+			: "memory");         /* no-clobber list */
+	return val;
+}
+
 static inline void
 rte_atomic64_init(rte_atomic64_t *v)
 {
diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h b/lib/librte_eal/common/include/generic/rte_atomic.h
index 16af5ca57e01..97854df3d134 100644
--- a/lib/librte_eal/common/include/generic/rte_atomic.h
+++ b/lib/librte_eal/common/include/generic/rte_atomic.h
@@ -139,6 +139,32 @@ rte_atomic16_cmpset(volatile uint16_t *dst, uint16_t exp, uint16_t src)
 }
 #endif
 
+/**
+ * Atomic exchange.
+ *
+ * (atomic) equivalent to:
+ *   ret = *dst
+ *   *dst = val;
+ *   return ret;
+ *
+ * @param dst
+ *   The destination location into which the value will be written.
+ * @param val
+ *   The new value.
+ * @return
+ *   The original value at that location
+ */
+static inline uint16_t
+rte_atomic16_exchange(volatile uint16_t *dst, uint16_t val);
+
+#ifdef RTE_FORCE_INTRINSICS
+static inline uint16_t
+rte_atomic16_exchange(volatile uint16_t *dst, uint16_t val)
+{
+	return __atomic_exchange_2(dst, val, __ATOMIC_SEQ_CST);
+}
+#endif
+
 /**
  * The atomic counter structure.
  */
@@ -392,6 +418,32 @@ rte_atomic32_cmpset(volatile uint32_t *dst, uint32_t exp, uint32_t src)
 }
 #endif
 
+/**
+ * Atomic exchange.
+ *
+ * (atomic) equivalent to:
+ *   ret = *dst
+ *   *dst = val;
+ *   return ret;
+ *
+ * @param dst
+ *   The destination location into which the value will be written.
+ * @param val
+ *   The new value.
+ * @return
+ *   The original value at that location
+ */
+static inline uint32_t
+rte_atomic32_exchange(volatile uint32_t *dst, uint32_t val);
+
+#ifdef RTE_FORCE_INTRINSICS
+static inline uint32_t
+rte_atomic32_exchange(volatile uint32_t *dst, uint32_t val)
+{
+	return __atomic_exchange_4(dst, val, __ATOMIC_SEQ_CST);
+}
+#endif
+
 /**
  * The atomic counter structure.
  */
@@ -644,6 +696,32 @@ rte_atomic64_cmpset(volatile uint64_t *dst, uint64_t exp, uint64_t src)
 }
 #endif
 
+/**
+ * Atomic exchange.
+ *
+ * (atomic) equivalent to:
+ *   ret = *dst
+ *   *dst = val;
+ *   return ret;
+ *
+ * @param dst
+ *   The destination location into which the value will be written.
+ * @param val
+ *   The new value.
+ * @return
+ *   The original value at that location
+ */
+static inline uint64_t
+rte_atomic64_exchange(volatile uint64_t *dst, uint64_t val);
+
+#ifdef RTE_FORCE_INTRINSICS
+static inline uint64_t
+rte_atomic64_exchange(volatile uint64_t *dst, uint64_t val)
+{
+	return __atomic_exchange_4(dst, val, __ATOMIC_SEQ_CST);
+}
+#endif
+
 /**
  * The atomic counter structure.
  */
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 02/15] ethdev: add linkstatus get/set helper functions
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 01/15] eal: introduce atomic exchange operation Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06 10:49   ` Andrew Rybchenko
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 03/15] virtio: use eth_linkstatus_set Stephen Hemminger
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Many drivers are all doing copy/paste of the same code to atomically
update the link status. Reduce duplication, and allow for future
changes by having common function for this.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/librte_ether/rte_ethdev.c | 35 +++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h | 28 ++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 27b52131ef01..4897e1dcda14 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1495,6 +1495,41 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
 	}
 }
 
+int
+_rte_eth_linkstatus_set(struct rte_eth_dev *dev,
+		       const struct rte_eth_link *new_link)
+{
+	volatile uint64_t *dev_link
+		 = (volatile uint64_t *)&(dev->data->dev_link);
+	union {
+		uint64_t val64;
+		struct rte_eth_link link;
+	} orig;
+
+	RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
+
+	orig.val64 = rte_atomic64_exchange(dev_link,
+					   *(const uint64_t *)new_link);
+
+	return (orig.link.link_status == new_link->link_status) ? -1 : 0;
+}
+
+void
+_rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
+			struct rte_eth_link *link)
+{
+	const uint64_t *src = (const uint64_t *)&(dev->data->dev_link);
+	volatile uint64_t *dst = (uint64_t *)link;
+
+	RTE_BUILD_BUG_ON(sizeof(*link) != sizeof(uint64_t));
+
+	/*
+	 * Note: this should never fail since both destination and expected
+	 * values are the same and are a pointer from caller.
+	 */
+	rte_atomic64_cmpset(dst, *dst, *src);
+}
+
 int
 rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index b10e2a92da71..b47402b797c3 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -2218,6 +2218,34 @@ int rte_eth_dev_set_link_down(uint16_t port_id);
  */
 void rte_eth_dev_close(uint16_t port_id);
 
+
+/**
+ * @internal
+ * Atomically set the link status for the specific device.
+ * It is for use by DPDK device driver use only.
+ * User applications should not call it
+ *
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param link
+ *  New link status value.
+ * @return
+ *  -1 if link state has changed, 0 if the same.
+ */
+int _rte_eth_linkstatus_set(struct rte_eth_dev *dev,
+			    const struct rte_eth_link *link);
+
+/**
+ * @internal
+ * Atomically get the link speed and status.
+ * @param dev
+ *  Pointer to struct rte_eth_dev.
+ * @param link
+ *  link status value.
+ */
+void _rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
+			     struct rte_eth_link *link);
+
 /**
  * Reset a Ethernet device and keep its port id.
  *
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 03/15] virtio: use eth_linkstatus_set
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 01/15] eal: introduce atomic exchange operation Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 02/15] ethdev: add linkstatus get/set helper functions Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06  3:10   ` Tiwei Bie
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 04/15] vmxnet3: use rte_eth_linkstatus_set Stephen Hemminger
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use the new comon code in ethdev to handle link status update.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/virtio/virtio_ethdev.c | 67 ++++++++------------------------------
 1 file changed, 14 insertions(+), 53 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 21f2131a9efd..748d40188e5d 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -14,7 +14,6 @@
 #include <rte_string_fns.h>
 #include <rte_memzone.h>
 #include <rte_malloc.h>
-#include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_pci.h>
 #include <rte_bus_pci.h>
@@ -771,46 +770,6 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 	.mac_addr_set            = virtio_mac_addr_set,
 };
 
-static inline int
-virtio_dev_atomic_read_link_status(struct rte_eth_dev *dev,
-				struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = link;
-	struct rte_eth_link *src = &(dev->data->dev_link);
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-			*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
-/**
- * Atomically writes the link status information into global
- * structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static inline int
-virtio_dev_atomic_write_link_status(struct rte_eth_dev *dev,
-		struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &(dev->data->dev_link);
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-					*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
 static void
 virtio_update_stats(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
@@ -1913,8 +1872,13 @@ static void
 virtio_dev_stop(struct rte_eth_dev *dev)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
-	struct rte_eth_link link;
 	struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
+	struct rte_eth_link link = {
+		.link_speed = SPEED_10G,
+		.link_duplex = ETH_LINK_FULL_DUPLEX,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
+		.link_status = ETH_LINK_DOWN,
+	};
 
 	PMD_INIT_LOG(DEBUG, "stop");
 
@@ -1922,21 +1886,19 @@ virtio_dev_stop(struct rte_eth_dev *dev)
 		virtio_intr_disable(dev);
 
 	hw->started = 0;
-	memset(&link, 0, sizeof(link));
-	virtio_dev_atomic_write_link_status(dev, &link);
+	_rte_eth_linkstatus_set(dev, &link);
 }
 
 static int
 virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 {
-	struct rte_eth_link link, old;
-	uint16_t status;
 	struct virtio_hw *hw = dev->data->dev_private;
-	memset(&link, 0, sizeof(link));
-	virtio_dev_atomic_read_link_status(dev, &link);
-	old = link;
-	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	link.link_speed  = SPEED_10G;
+	uint16_t status;
+	struct rte_eth_link link = {
+		.link_speed  = SPEED_10G,
+		.link_duplex = ETH_LINK_FULL_DUPLEX,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
+	};
 
 	if (hw->started == 0) {
 		link.link_status = ETH_LINK_DOWN;
@@ -1957,9 +1919,8 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 	} else {
 		link.link_status = ETH_LINK_UP;
 	}
-	virtio_dev_atomic_write_link_status(dev, &link);
 
-	return (old.link_status == link.link_status) ? -1 : 0;
+	return _rte_eth_linkstatus_set(dev, &link);
 }
 
 static int
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 04/15] vmxnet3: use rte_eth_linkstatus_set
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
                   ` (2 preceding siblings ...)
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 03/15] virtio: use eth_linkstatus_set Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 05/15] dpaa2: " Stephen Hemminger
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use new _rte_eth_link_update helper.
Also remove no longer necessary include of rte_atomic.h

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 85 +++++++-----------------------------
 1 file changed, 15 insertions(+), 70 deletions(-)

diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c2f12cdf2a4d..0149125affe9 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -20,7 +20,6 @@
 #include <rte_debug.h>
 #include <rte_pci.h>
 #include <rte_bus_pci.h>
-#include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
 #include <rte_memzone.h>
@@ -157,59 +156,6 @@ gpa_zone_reserve(struct rte_eth_dev *dev, uint32_t size,
 	return rte_memzone_reserve_aligned(z_name, size, socket_id, 0, align);
 }
 
-/**
- * Atomically reads the link status information from global
- * structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-
-static int
-vmxnet3_dev_atomic_read_link_status(struct rte_eth_dev *dev,
-				    struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = link;
-	struct rte_eth_link *src = &(dev->data->dev_link);
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-				*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
-/**
- * Atomically writes the link status information into global
- * structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to write to.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static int
-vmxnet3_dev_atomic_write_link_status(struct rte_eth_dev *dev,
-				     struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &(dev->data->dev_link);
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-				*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
 /*
  * This function is based on vmxnet3_disable_intr()
  */
@@ -814,9 +760,13 @@ vmxnet3_dev_start(struct rte_eth_dev *dev)
 static void
 vmxnet3_dev_stop(struct rte_eth_dev *dev)
 {
-	struct rte_eth_link link;
 	struct vmxnet3_hw *hw = dev->data->dev_private;
-
+	struct rte_eth_link link = {
+		.link_speed = ETH_SPEED_NUM_10G,
+		.link_duplex = ETH_LINK_FULL_DUPLEX,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
+		.link_status = ETH_LINK_DOWN,
+	};
 	PMD_INIT_FUNC_TRACE();
 
 	if (hw->adapter_stopped == 1) {
@@ -849,8 +799,7 @@ vmxnet3_dev_stop(struct rte_eth_dev *dev)
 	vmxnet3_dev_clear_queues(dev);
 
 	/* Clear recorded link status */
-	memset(&link, 0, sizeof(link));
-	vmxnet3_dev_atomic_write_link_status(dev, &link);
+	_rte_eth_linkstatus_set(dev, &link);
 }
 
 /*
@@ -1130,25 +1079,21 @@ __vmxnet3_dev_link_update(struct rte_eth_dev *dev,
 			  __rte_unused int wait_to_complete)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
-	struct rte_eth_link old = { 0 }, link;
+	struct rte_eth_link link = {
+		.link_speed = ETH_SPEED_NUM_10G,
+		.link_duplex = ETH_LINK_FULL_DUPLEX,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
+		.link_status = ETH_LINK_DOWN,
+	};
 	uint32_t ret;
 
-	memset(&link, 0, sizeof(link));
-	vmxnet3_dev_atomic_read_link_status(dev, &old);
-
 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
 	ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
 
-	if (ret & 0x1) {
+	if (ret & 0x1)
 		link.link_status = ETH_LINK_UP;
-		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		link.link_speed = ETH_SPEED_NUM_10G;
-		link.link_autoneg = ETH_LINK_SPEED_FIXED;
-	}
-
-	vmxnet3_dev_atomic_write_link_status(dev, &link);
 
-	return (old.link_status == link.link_status) ? -1 : 0;
+	return _rte_eth_linkstatus_set(dev, &link);
 }
 
 static int
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 05/15] dpaa2: use rte_eth_linkstatus_set
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
                   ` (3 preceding siblings ...)
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 04/15] vmxnet3: use rte_eth_linkstatus_set Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 06/15] nfp: use rte_eth_linkstatus functions Stephen Hemminger
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use new helper function to update the link status.
As a good side effect this fixes a but because this driver was not
returning correct status (should be -1 in link_status changed).

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/dpaa2/dpaa2_ethdev.c | 65 +++++-----------------------------------
 1 file changed, 7 insertions(+), 58 deletions(-)

diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index 2f99d95d2216..c0fc59ab148f 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -56,58 +56,6 @@ static int dpaa2_dev_set_link_up(struct rte_eth_dev *dev);
 static int dpaa2_dev_set_link_down(struct rte_eth_dev *dev);
 static int dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
-/**
- * Atomically reads the link status information from global
- * structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static inline int
-dpaa2_dev_atomic_read_link_status(struct rte_eth_dev *dev,
-				  struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = link;
-	struct rte_eth_link *src = &dev->data->dev_link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-				*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
-/**
- * Atomically writes the link status information into global
- * structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static inline int
-dpaa2_dev_atomic_write_link_status(struct rte_eth_dev *dev,
-				   struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &dev->data->dev_link;
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-				*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
 static int
 dpaa2_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
@@ -804,7 +752,7 @@ dpaa2_dev_stop(struct rte_eth_dev *dev)
 
 	/* clear the recorded link status */
 	memset(&link, 0, sizeof(link));
-	dpaa2_dev_atomic_write_link_status(dev, &link);
+	_rte_eth_link_write(dev, &link);
 }
 
 static void
@@ -836,7 +784,7 @@ dpaa2_dev_close(struct rte_eth_dev *dev)
 	}
 
 	memset(&link, 0, sizeof(link));
-	dpaa2_dev_atomic_write_link_status(dev, &link);
+	_rte_eth_link_write(dev, &link);
 }
 
 static void
@@ -1291,8 +1239,8 @@ dpaa2_dev_link_update(struct rte_eth_dev *dev,
 		RTE_LOG(ERR, PMD, "dpni is NULL\n");
 		return 0;
 	}
-	memset(&old, 0, sizeof(old));
-	dpaa2_dev_atomic_read_link_status(dev, &old);
+
+	_rte_eth_link_read(dev, &old);
 
 	ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state);
 	if (ret < 0) {
@@ -1314,13 +1262,14 @@ dpaa2_dev_link_update(struct rte_eth_dev *dev,
 	else
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
-	dpaa2_dev_atomic_write_link_status(dev, &link);
+	ret = _rte_eth_linkstatus_set(dev, &link);
 
 	if (link.link_status)
 		PMD_DRV_LOG(INFO, "Port %d Link is Up\n", dev->data->port_id);
 	else
 		PMD_DRV_LOG(INFO, "Port %d Link is Down", dev->data->port_id);
-	return 0;
+
+	return ret;
 }
 
 /**
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 06/15] nfp: use rte_eth_linkstatus functions
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
                   ` (4 preceding siblings ...)
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 05/15] dpaa2: " Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 07/15] e1000: use rte_eth_linkstatus helpers Stephen Hemminger
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use new _rte_eth_linkstatus_get/set helper function.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/nfp/nfp_net.c | 75 +++++------------------------------------------
 1 file changed, 8 insertions(+), 67 deletions(-)

diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 0501156bacb7..79c031ed2745 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -204,57 +204,6 @@ nn_cfg_writeq(struct nfp_net_hw *hw, int off, uint64_t val)
 	nn_writeq(rte_cpu_to_le_64(val), hw->ctrl_bar + off);
 }
 
-/*
- * Atomically reads link status information from global structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static inline int
-nfp_net_dev_atomic_read_link_status(struct rte_eth_dev *dev,
-				    struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = link;
-	struct rte_eth_link *src = &dev->data->dev_link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-				*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
-/*
- * Atomically writes the link status information into global
- * structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static inline int
-nfp_net_dev_atomic_write_link_status(struct rte_eth_dev *dev,
-				     struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &dev->data->dev_link;
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-				*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
 static void
 nfp_net_rx_queue_release_mbufs(struct nfp_net_rxq *rxq)
 {
@@ -977,7 +926,7 @@ static int
 nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 {
 	struct nfp_net_hw *hw;
-	struct rte_eth_link link, old;
+	struct rte_eth_link link;
 	uint32_t nn_link_status;
 
 	static const uint32_t ls_to_ethtool[] = {
@@ -995,9 +944,6 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-	memset(&old, 0, sizeof(old));
-	nfp_net_dev_atomic_read_link_status(dev, &old);
-
 	nn_link_status = nn_cfg_readl(hw, NFP_NET_CFG_STS);
 
 	memset(&link, 0, sizeof(struct rte_eth_link));
@@ -1015,15 +961,13 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
 	else
 		link.link_speed = ls_to_ethtool[nn_link_status];
 
-	if (old.link_status != link.link_status) {
-		nfp_net_dev_atomic_write_link_status(dev, &link);
-		if (link.link_status)
-			PMD_DRV_LOG(INFO, "NIC Link is Up\n");
-		else
-			PMD_DRV_LOG(INFO, "NIC Link is Down\n");
+	if (_rte_eth_linkstatus_set(dev, &link) == 0)
 		return 0;
-	}
 
+	if (link.link_status)
+		PMD_DRV_LOG(INFO, "NIC Link is Up\n");
+	else
+		PMD_DRV_LOG(INFO, "NIC Link is Down\n");
 	return -1;
 }
 
@@ -1354,8 +1298,7 @@ nfp_net_dev_link_status_print(struct rte_eth_dev *dev)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_eth_link link;
 
-	memset(&link, 0, sizeof(link));
-	nfp_net_dev_atomic_read_link_status(dev, &link);
+	_rte_eth_linkstatus_get(dev, &link);
 	if (link.link_status)
 		RTE_LOG(INFO, PMD, "Port %d: Link Up - speed %u Mbps - %s\n",
 			dev->data->port_id, link.link_speed,
@@ -1408,9 +1351,7 @@ nfp_net_dev_interrupt_handler(void *param)
 
 	PMD_DRV_LOG(DEBUG, "We got a LSC interrupt!!!\n");
 
-	/* get the link status */
-	memset(&link, 0, sizeof(link));
-	nfp_net_dev_atomic_read_link_status(dev, &link);
+	_rte_eth_linkstatus_get(dev, &link);
 
 	nfp_net_link_update(dev, 0);
 
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 07/15] e1000: use rte_eth_linkstatus helpers
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
                   ` (5 preceding siblings ...)
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 06/15] nfp: use rte_eth_linkstatus functions Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 08/15] ixgbe: use rte_eth_linkstatus functions Stephen Hemminger
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use new rte_eth_linkstatus_get/set API.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/e1000/em_ethdev.c  | 70 +++--------------------------------------
 drivers/net/e1000/igb_ethdev.c | 71 +++---------------------------------------
 2 files changed, 10 insertions(+), 131 deletions(-)

diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index f457be55e706..4d32c6aa93be 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -20,7 +20,6 @@
 #include <rte_ethdev_pci.h>
 #include <rte_memory.h>
 #include <rte_eal.h>
-#include <rte_atomic.h>
 #include <rte_malloc.h>
 #include <rte_dev.h>
 
@@ -193,57 +192,6 @@ static const struct eth_dev_ops eth_em_ops = {
 	.txq_info_get         = em_txq_info_get,
 };
 
-/**
- * Atomically reads the link status information from global
- * structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static inline int
-rte_em_dev_atomic_read_link_status(struct rte_eth_dev *dev,
-				struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = link;
-	struct rte_eth_link *src = &(dev->data->dev_link);
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-					*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
-/**
- * Atomically writes the link status information into global
- * structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static inline int
-rte_em_dev_atomic_write_link_status(struct rte_eth_dev *dev,
-				struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &(dev->data->dev_link);
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-					*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
 
 /**
  *  eth_em_dev_is_ich8 - Check for ICH8 device
@@ -769,7 +717,7 @@ eth_em_stop(struct rte_eth_dev *dev)
 
 	/* clear the recorded link status */
 	memset(&link, 0, sizeof(link));
-	rte_em_dev_atomic_write_link_status(dev, &link);
+	_rte_eth_linkstatus_set(dev, &link);
 
 	if (!rte_intr_allow_others(intr_handle))
 		/* resume to the default handler */
@@ -1127,7 +1075,7 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 {
 	struct e1000_hw *hw =
 		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct rte_eth_link link, old;
+	struct rte_eth_link link;
 	int link_check, count;
 
 	link_check = 0;
@@ -1162,8 +1110,6 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		rte_delay_ms(EM_LINK_UPDATE_CHECK_INTERVAL);
 	}
 	memset(&link, 0, sizeof(link));
-	rte_em_dev_atomic_read_link_status(dev, &link);
-	old = link;
 
 	/* Now we check if a transition has happened */
 	if (link_check && (link.link_status == ETH_LINK_DOWN)) {
@@ -1182,14 +1128,8 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_status = ETH_LINK_DOWN;
 		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
-	rte_em_dev_atomic_write_link_status(dev, &link);
-
-	/* not changed */
-	if (old.link_status == link.link_status)
-		return -1;
 
-	/* changed */
-	return 0;
+	return _rte_eth_linkstatus_set(dev, &link);
 }
 
 /*
@@ -1599,8 +1539,8 @@ eth_em_interrupt_action(struct rte_eth_dev *dev,
 	if (ret < 0)
 		return 0;
 
-	memset(&link, 0, sizeof(link));
-	rte_em_dev_atomic_read_link_status(dev, &link);
+	_rte_eth_linkstatus_get(dev, &link);
+
 	if (link.link_status) {
 		PMD_INIT_LOG(INFO, " Port %d: Link Up - speed %u Mbps - %s",
 			     dev->data->port_id, link.link_speed,
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 1333b62c3378..997e7a47ac0e 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -20,7 +20,6 @@
 #include <rte_ethdev_pci.h>
 #include <rte_memory.h>
 #include <rte_eal.h>
-#include <rte_atomic.h>
 #include <rte_malloc.h>
 #include <rte_dev.h>
 
@@ -522,57 +521,6 @@ static const struct rte_igb_xstats_name_off rte_igbvf_stats_strings[] = {
 #define IGBVF_NB_XSTATS (sizeof(rte_igbvf_stats_strings) / \
 		sizeof(rte_igbvf_stats_strings[0]))
 
-/**
- * Atomically reads the link status information from global
- * structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static inline int
-rte_igb_dev_atomic_read_link_status(struct rte_eth_dev *dev,
-				struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = link;
-	struct rte_eth_link *src = &(dev->data->dev_link);
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-					*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
-/**
- * Atomically writes the link status information into global
- * structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static inline int
-rte_igb_dev_atomic_write_link_status(struct rte_eth_dev *dev,
-				struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &(dev->data->dev_link);
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-					*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
 
 static inline void
 igb_intr_enable(struct rte_eth_dev *dev)
@@ -1524,7 +1472,7 @@ eth_igb_stop(struct rte_eth_dev *dev)
 
 	/* clear the recorded link status */
 	memset(&link, 0, sizeof(link));
-	rte_igb_dev_atomic_write_link_status(dev, &link);
+	_rte_eth_linkstatus_set(dev, &link);
 
 	if (!rte_intr_allow_others(intr_handle))
 		/* resume to the default handler */
@@ -1600,7 +1548,7 @@ eth_igb_close(struct rte_eth_dev *dev)
 	}
 
 	memset(&link, 0, sizeof(link));
-	rte_igb_dev_atomic_write_link_status(dev, &link);
+	_rte_eth_linkstatus_set(dev, &link);
 }
 
 static int
@@ -2347,7 +2295,7 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 {
 	struct e1000_hw *hw =
 		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct rte_eth_link link, old;
+	struct rte_eth_link link;
 	int link_check, count;
 
 	link_check = 0;
@@ -2388,8 +2336,6 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		rte_delay_ms(IGB_LINK_UPDATE_CHECK_INTERVAL);
 	}
 	memset(&link, 0, sizeof(link));
-	rte_igb_dev_atomic_read_link_status(dev, &link);
-	old = link;
 
 	/* Now we check if a transition has happened */
 	if (link_check) {
@@ -2408,14 +2354,8 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		link.link_status = ETH_LINK_DOWN;
 		link.link_autoneg = ETH_LINK_SPEED_FIXED;
 	}
-	rte_igb_dev_atomic_write_link_status(dev, &link);
 
-	/* not changed */
-	if (old.link_status == link.link_status)
-		return -1;
-
-	/* changed */
-	return 0;
+	return _rte_eth_linkstatus_set(dev, &link);
 }
 
 /*
@@ -2853,8 +2793,7 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev,
 		if (ret < 0)
 			return 0;
 
-		memset(&link, 0, sizeof(link));
-		rte_igb_dev_atomic_read_link_status(dev, &link);
+		_rte_eth_linkstatus_get(dev, &link);
 		if (link.link_status) {
 			PMD_INIT_LOG(INFO,
 				     " Port %d: Link Up - speed %u Mbps - %s",
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 08/15] ixgbe: use rte_eth_linkstatus functions
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
                   ` (6 preceding siblings ...)
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 07/15] e1000: use rte_eth_linkstatus helpers Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 09/15] sfc: use new " Stephen Hemminger
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use the new helper functions from eth_dev for
handling atomic link_info update.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 99 +++++++---------------------------------
 1 file changed, 17 insertions(+), 82 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 43e0132f81fe..d33ffa626e4a 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -20,7 +20,6 @@
 #include <rte_debug.h>
 #include <rte_pci.h>
 #include <rte_bus_pci.h>
-#include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
 #include <rte_eal.h>
@@ -781,58 +780,6 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbevf_stats_strings[] = {
 #define IXGBEVF_NB_XSTATS (sizeof(rte_ixgbevf_stats_strings) /	\
 		sizeof(rte_ixgbevf_stats_strings[0]))
 
-/**
- * Atomically reads the link status information from global
- * structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static inline int
-rte_ixgbe_dev_atomic_read_link_status(struct rte_eth_dev *dev,
-				struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = link;
-	struct rte_eth_link *src = &(dev->data->dev_link);
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-					*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
-/**
- * Atomically writes the link status information into global
- * structure rte_eth_dev.
- *
- * @param dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static inline int
-rte_ixgbe_dev_atomic_write_link_status(struct rte_eth_dev *dev,
-				struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &(dev->data->dev_link);
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-					*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
 /*
  * This function is the same as ixgbe_is_sfp() in base/ixgbe.h.
  */
@@ -2753,7 +2700,7 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
 
 	/* Clear recorded link status */
 	memset(&link, 0, sizeof(link));
-	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
+	_rte_eth_linkstatus_set(dev, &link);
 
 	if (!rte_intr_allow_others(intr_handle))
 		/* resume to the default handler */
@@ -3938,7 +3885,6 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 			    int wait_to_complete, int vf)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct rte_eth_link link, old;
 	ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
 	struct ixgbe_interrupt *intr =
 		IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
@@ -3947,13 +3893,11 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 	u32 speed = 0;
 	int wait = 1;
 	bool autoneg = false;
-
-	link.link_status = ETH_LINK_DOWN;
-	link.link_speed = 0;
-	link.link_duplex = ETH_LINK_HALF_DUPLEX;
-	link.link_autoneg = ETH_LINK_AUTONEG;
-	memset(&old, 0, sizeof(old));
-	rte_ixgbe_dev_atomic_read_link_status(dev, &old);
+	struct rte_eth_link link = {
+		.link_status = ETH_LINK_DOWN,
+		.link_duplex = ETH_LINK_HALF_DUPLEX,
+		.link_autoneg = ETH_LINK_AUTONEG,
+	};
 
 	hw->mac.get_link_status = true;
 
@@ -3977,19 +3921,15 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 	if (diag != 0) {
 		link.link_speed = ETH_SPEED_NUM_100M;
 		link.link_duplex = ETH_LINK_FULL_DUPLEX;
-		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
-		if (link.link_status == old.link_status)
-			return -1;
-		return 0;
+
+		return _rte_eth_linkstatus_set(dev, &link);
 	}
 
 	if (link_up == 0) {
-		rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 		intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
-		if (link.link_status == old.link_status)
-			return -1;
-		return 0;
+		return _rte_eth_linkstatus_set(dev, &link);
 	}
+
 	intr->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
 	link.link_status = ETH_LINK_UP;
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
@@ -4021,12 +3961,8 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 		link.link_speed = ETH_SPEED_NUM_10G;
 		break;
 	}
-	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
 
-	if (link.link_status == old.link_status)
-		return -1;
-
-	return 0;
+	return _rte_eth_linkstatus_set(dev, &link);
 }
 
 static int
@@ -4225,8 +4161,8 @@ ixgbe_dev_link_status_print(struct rte_eth_dev *dev)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_eth_link link;
 
-	memset(&link, 0, sizeof(link));
-	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
+	_rte_eth_linkstatus_get(dev, &link);
+
 	if (link.link_status) {
 		PMD_INIT_LOG(INFO, "Port %d: Link Up - speed %u Mbps - %s",
 					(int)(dev->data->port_id),
@@ -4261,7 +4197,6 @@ ixgbe_dev_interrupt_action(struct rte_eth_dev *dev,
 	struct ixgbe_interrupt *intr =
 		IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
 	int64_t timeout;
-	struct rte_eth_link link;
 	struct ixgbe_hw *hw =
 		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
@@ -4278,9 +4213,10 @@ ixgbe_dev_interrupt_action(struct rte_eth_dev *dev,
 	}
 
 	if (intr->flags & IXGBE_FLAG_NEED_LINK_UPDATE) {
+		struct rte_eth_link link;
+
 		/* get the link status before link update, for predicting later */
-		memset(&link, 0, sizeof(link));
-		rte_ixgbe_dev_atomic_read_link_status(dev, &link);
+		_rte_eth_linkstatus_get(dev, &link);
 
 		ixgbe_dev_link_update(dev, 0);
 
@@ -6799,9 +6735,8 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 	uint32_t shift = 0;
 
 	/* Get current link speed. */
-	memset(&link, 0, sizeof(link));
 	ixgbe_dev_link_update(dev, 1);
-	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
+	_rte_eth_linkstatus_get(dev, &link);
 
 	switch (link.link_speed) {
 	case ETH_SPEED_NUM_100M:
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 09/15] sfc: use new rte_eth_linkstatus functions
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
                   ` (7 preceding siblings ...)
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 08/15] ixgbe: use rte_eth_linkstatus functions Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06 11:10   ` Andrew Rybchenko
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 10/15] i40e: use " Stephen Hemminger
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use the new API (_rte_eth_linkstatus_set) to handle link status update.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/sfc/sfc_ethdev.c | 27 +++++++--------------------
 drivers/net/sfc/sfc_ev.c     | 23 ++++-------------------
 2 files changed, 11 insertions(+), 39 deletions(-)

diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 2f5f86f84877..e0a12b32b1a3 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -238,22 +238,12 @@ static int
 sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
-	struct rte_eth_link *dev_link = &dev->data->dev_link;
-	struct rte_eth_link old_link;
 	struct rte_eth_link current_link;
 
 	sfc_log_init(sa, "entry");
 
-retry:
-	EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
-	*(int64_t *)&old_link = rte_atomic64_read((rte_atomic64_t *)dev_link);
-
 	if (sa->state != SFC_ADAPTER_STARTED) {
 		sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, &current_link);
-		if (!rte_atomic64_cmpset((volatile uint64_t *)dev_link,
-					 *(uint64_t *)&old_link,
-					 *(uint64_t *)&current_link))
-			goto retry;
 	} else if (wait_to_complete) {
 		efx_link_mode_t link_mode;
 
@@ -261,21 +251,18 @@ sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 			link_mode = EFX_LINK_UNKNOWN;
 		sfc_port_link_mode_to_info(link_mode, &current_link);
 
-		if (!rte_atomic64_cmpset((volatile uint64_t *)dev_link,
-					 *(uint64_t *)&old_link,
-					 *(uint64_t *)&current_link))
-			goto retry;
 	} else {
 		sfc_ev_mgmt_qpoll(sa);
-		*(int64_t *)&current_link =
-			rte_atomic64_read((rte_atomic64_t *)dev_link);
+		_rte_eth_linkstatus_get(dev, &current_link);
 	}
 
-	if (old_link.link_status != current_link.link_status)
-		sfc_info(sa, "Link status is %s",
-			 current_link.link_status ? "UP" : "DOWN");
+	if (_rte_eth_linkstatus_set(dev, &current_link) == 0)
+		return 0;
+
+	sfc_info(sa, "Link status is %s",
+		 current_link.link_status ? "UP" : "DOWN");
 
-	return old_link.link_status == current_link.link_status ? 0 : -1;
+	return -1;
 }
 
 static void
diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index a16dc27b380e..3e96536a9d60 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -404,29 +404,14 @@ sfc_ev_link_change(void *arg, efx_link_mode_t link_mode)
 {
 	struct sfc_evq *evq = arg;
 	struct sfc_adapter *sa = evq->sa;
-	struct rte_eth_link *dev_link = &sa->eth_dev->data->dev_link;
 	struct rte_eth_link new_link;
-	uint64_t new_link_u64;
-	uint64_t old_link_u64;
-
-	EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
 
 	sfc_port_link_mode_to_info(link_mode, &new_link);
+	if (_rte_eth_linkstatus_set(sa->eth_dev, &new_link) == 0)
+		return B_FALSE;
 
-	new_link_u64 = *(uint64_t *)&new_link;
-	do {
-		old_link_u64 = rte_atomic64_read((rte_atomic64_t *)dev_link);
-		if (old_link_u64 == new_link_u64)
-			break;
-
-		if (rte_atomic64_cmpset((volatile uint64_t *)dev_link,
-					old_link_u64, new_link_u64)) {
-			evq->sa->port.lsc_seq++;
-			break;
-		}
-	} while (B_TRUE);
-
-	return B_FALSE;
+	evq->sa->port.lsc_seq++;
+	return B_TRUE;
 }
 
 static const efx_ev_callbacks_t sfc_ev_callbacks = {
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 10/15] i40e: use rte_eth_linkstatus functions
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
                   ` (8 preceding siblings ...)
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 09/15] sfc: use new " Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 11/15] liquidio: use _rte_eth_linkstatus_set Stephen Hemminger
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use new rte_linkstatus update API

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/i40e/i40e_ethdev.c    | 44 ++++++---------------------------------
 drivers/net/i40e/i40e_ethdev_vf.c | 19 ++---------------
 2 files changed, 8 insertions(+), 55 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 285d92b3e7df..75affed2936f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -627,34 +627,6 @@ static struct rte_pci_driver rte_i40e_pmd = {
 	.remove = eth_i40e_pci_remove,
 };
 
-static inline int
-rte_i40e_dev_atomic_read_link_status(struct rte_eth_dev *dev,
-				     struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = link;
-	struct rte_eth_link *src = &(dev->data->dev_link);
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-					*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
-static inline int
-rte_i40e_dev_atomic_write_link_status(struct rte_eth_dev *dev,
-				      struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &(dev->data->dev_link);
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-					*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
 RTE_PMD_REGISTER_PCI(net_i40e, rte_i40e_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_i40e, pci_id_i40e_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_i40e, "* igb_uio | uio_pci_generic | vfio-pci");
@@ -2327,17 +2299,16 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 #define MAX_REPEAT_TIME 10  /* 1s (10 * 100ms) in total */
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_link_status link_status;
-	struct rte_eth_link link, old;
+	struct rte_eth_link link;
 	int status;
 	unsigned rep_cnt = MAX_REPEAT_TIME;
 	bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false;
 
 	memset(&link, 0, sizeof(link));
-	memset(&old, 0, sizeof(old));
-	memset(&link_status, 0, sizeof(link_status));
-	rte_i40e_dev_atomic_read_link_status(dev, &old);
 
 	do {
+		memset(&link_status, 0, sizeof(link_status));
+
 		/* Get link status information from hardware */
 		status = i40e_aq_get_link_info(hw, enable_lse,
 						&link_status, NULL);
@@ -2390,13 +2361,10 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
 			ETH_LINK_SPEED_FIXED);
 
 out:
-	rte_i40e_dev_atomic_write_link_status(dev, &link);
-	if (link.link_status == old.link_status)
-		return -1;
-
+	status = _rte_eth_linkstatus_set(dev, &link);
 	i40e_notify_all_vfs_link_status(dev);
 
-	return 0;
+	return status;
 }
 
 /* Get all the statistics of a VSI */
@@ -9854,7 +9822,7 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
 	/* Get current link speed. */
 	memset(&link, 0, sizeof(link));
 	i40e_dev_link_update(dev, 1);
-	rte_i40e_dev_atomic_read_link_status(dev, &link);
+	_rte_eth_linkstatus_get(dev, &link);
 
 	switch (link.link_speed) {
 	case ETH_SPEED_NUM_40G:
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index b96d77a0caed..44c6c5b62a90 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1034,20 +1034,6 @@ static const struct rte_pci_id pci_id_i40evf_map[] = {
 	{ .vendor_id = 0, /* sentinel */ },
 };
 
-static inline int
-i40evf_dev_atomic_write_link_status(struct rte_eth_dev *dev,
-				    struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &(dev->data->dev_link);
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-					*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
 /* Disable IRQ0 */
 static inline void
 i40evf_disable_irq0(struct i40e_hw *hw)
@@ -2069,6 +2055,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	 * while Linux driver does not
 	 */
 
+	memset(&new_link, 0, sizeof(new_link));
 	/* Linux driver PF host */
 	switch (vf->link_speed) {
 	case I40E_LINK_SPEED_100MB:
@@ -2100,9 +2087,7 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
 	new_link.link_autoneg =
 		dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED;
 
-	i40evf_dev_atomic_write_link_status(dev, &new_link);
-
-	return 0;
+	return _rte_eth_linkstatus_set(dev, &new_link);
 }
 
 static void
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 11/15] liquidio: use _rte_eth_linkstatus_set
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
                   ` (9 preceding siblings ...)
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 10/15] i40e: use " Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 12/15] thunderx: " Stephen Hemminger
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use the new link update API, and cleanup the logic in the the
link update routine.

Tested-by: Shijith Thotton <shijith.thotton@caviumnetworks.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/liquidio/lio_ethdev.c | 54 ++++++---------------------------------
 1 file changed, 8 insertions(+), 46 deletions(-)

diff --git a/drivers/net/liquidio/lio_ethdev.c b/drivers/net/liquidio/lio_ethdev.c
index 84b8a3288d12..c7181ebc58de 100644
--- a/drivers/net/liquidio/lio_ethdev.c
+++ b/drivers/net/liquidio/lio_ethdev.c
@@ -930,32 +930,6 @@ lio_dev_vlan_filter_set(struct rte_eth_dev *eth_dev, uint16_t vlan_id, int on)
 	return 0;
 }
 
-/**
- * Atomically writes the link status information into global
- * structure rte_eth_dev.
- *
- * @param eth_dev
- *   - Pointer to the structure rte_eth_dev to read from.
- *   - Pointer to the buffer to be saved with the link status.
- *
- * @return
- *   - On success, zero.
- *   - On failure, negative value.
- */
-static inline int
-lio_dev_atomic_write_link_status(struct rte_eth_dev *eth_dev,
-				 struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &eth_dev->data->dev_link;
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-				*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
 static uint64_t
 lio_hweight64(uint64_t w)
 {
@@ -975,23 +949,17 @@ lio_dev_link_update(struct rte_eth_dev *eth_dev,
 		    int wait_to_complete __rte_unused)
 {
 	struct lio_device *lio_dev = LIO_DEV(eth_dev);
-	struct rte_eth_link link, old;
-
-	/* Initialize */
-	link.link_status = ETH_LINK_DOWN;
-	link.link_speed = ETH_SPEED_NUM_NONE;
-	link.link_duplex = ETH_LINK_HALF_DUPLEX;
-	link.link_autoneg = ETH_LINK_AUTONEG;
-	memset(&old, 0, sizeof(old));
+	struct rte_eth_link link = {
+		.link_status = ETH_LINK_DOWN,
+		.link_speed = ETH_SPEED_NUM_NONE,
+		.link_duplex = ETH_LINK_HALF_DUPLEX,
+		.link_autoneg = ETH_LINK_AUTONEG,
+	};
 
 	/* Return what we found */
 	if (lio_dev->linfo.link.s.link_up == 0) {
 		/* Interface is down */
-		if (lio_dev_atomic_write_link_status(eth_dev, &link))
-			return -1;
-		if (link.link_status == old.link_status)
-			return -1;
-		return 0;
+		return _rte_eth_linkstatus_set(eth_dev, &link);
 	}
 
 	link.link_status = ETH_LINK_UP; /* Interface is up */
@@ -1008,13 +976,7 @@ lio_dev_link_update(struct rte_eth_dev *eth_dev,
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
 	}
 
-	if (lio_dev_atomic_write_link_status(eth_dev, &link))
-		return -1;
-
-	if (link.link_status == old.link_status)
-		return -1;
-
-	return 0;
+	return _rte_eth_linkstatus_set(eth_dev, &link);
 }
 
 /**
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 12/15] thunderx: use _rte_eth_linkstatus_set
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
                   ` (10 preceding siblings ...)
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 11/15] liquidio: use _rte_eth_linkstatus_set Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 13/15] szedata: " Stephen Hemminger
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Use new helper function.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/thunderx/nicvf_ethdev.c | 17 ++---------------
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index d65d3cee727e..e41b379f3c9c 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -43,7 +43,6 @@
 #include <sys/queue.h>
 
 #include <rte_alarm.h>
-#include <rte_atomic.h>
 #include <rte_branch_prediction.h>
 #include <rte_byteorder.h>
 #include <rte_common.h>
@@ -76,19 +75,6 @@ static void nicvf_dev_stop_cleanup(struct rte_eth_dev *dev, bool cleanup);
 static void nicvf_vf_stop(struct rte_eth_dev *dev, struct nicvf *nic,
 			  bool cleanup);
 
-static inline int
-nicvf_atomic_write_link_status(struct rte_eth_dev *dev,
-			       struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &dev->data->dev_link;
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-		*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
 
 static inline void
 nicvf_set_eth_link_status(struct nicvf *nic, struct rte_eth_link *link)
@@ -170,7 +156,8 @@ nicvf_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 		memset(&link, 0, sizeof(link));
 		nicvf_set_eth_link_status(nic, &link);
 	}
-	return nicvf_atomic_write_link_status(dev, &link);
+
+	return _rte_eth_linkstatus_set(dev, &link);
 }
 
 static int
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 13/15] szedata: use _rte_eth_linkstatus_set
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
                   ` (11 preceding siblings ...)
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 12/15] thunderx: " Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 14/15] octeontx: use rte_eth_linkstatus_set Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 15/15] enic: use _rte_eth_linkstatus_set Stephen Hemminger
  14 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Yet another driver which was not returing correct value on
link change.

Since this driver can't be built on x86 could not even
do a compile test.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/szedata2/rte_eth_szedata2.c | 20 ++++++--------------
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 74f151c4ad8e..bb8df1fbd191 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -50,7 +50,6 @@
 #include <rte_memcpy.h>
 #include <rte_kvargs.h>
 #include <rte_dev.h>
-#include <rte_atomic.h>
 
 #include "rte_eth_szedata2.h"
 #include "szedata2_iobuf.h"
@@ -1173,14 +1172,15 @@ static int
 eth_link_update(struct rte_eth_dev *dev,
 		int wait_to_complete __rte_unused)
 {
-	struct rte_eth_link link;
-	struct rte_eth_link *link_ptr = &link;
-	struct rte_eth_link *dev_link = &dev->data->dev_link;
 	struct pmd_internals *internals = (struct pmd_internals *)
 		dev->data->dev_private;
 	const volatile struct szedata2_ibuf *ibuf;
 	uint32_t i;
 	bool link_is_up = false;
+	struct rte_eth_link link = {
+		.link_duplex = ETH_LINK_FULL_DUPLEX,
+		.link_autoneg = ETH_LINK_SPEED_FIXED,
+	};
 
 	switch (get_link_speed(internals)) {
 	case SZEDATA2_LINK_SPEED_10G:
@@ -1197,9 +1197,6 @@ eth_link_update(struct rte_eth_dev *dev,
 		break;
 	}
 
-	/* szedata2 uses only full duplex */
-	link.link_duplex = ETH_LINK_FULL_DUPLEX;
-
 	for (i = 0; i < szedata2_ibuf_count; i++) {
 		ibuf = ibuf_ptr_by_index(internals->pci_rsc, i);
 		/*
@@ -1212,14 +1209,9 @@ eth_link_update(struct rte_eth_dev *dev,
 		}
 	}
 
-	link.link_status = (link_is_up) ? ETH_LINK_UP : ETH_LINK_DOWN;
-
-	link.link_autoneg = ETH_LINK_SPEED_FIXED;
+	link.link_status = link_is_up ? ETH_LINK_UP : ETH_LINK_DOWN;
 
-	rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
-			*(uint64_t *)link_ptr);
-
-	return 0;
+	return _rte_eth_linkstatus_set(dev, &link);
 }
 
 static int
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 14/15] octeontx: use rte_eth_linkstatus_set
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
                   ` (12 preceding siblings ...)
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 13/15] szedata: " Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 15/15] enic: use _rte_eth_linkstatus_set Stephen Hemminger
  14 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Common function matches this drivers usage.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/octeontx/octeontx_ethdev.c | 16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/drivers/net/octeontx/octeontx_ethdev.c b/drivers/net/octeontx/octeontx_ethdev.c
index bd24ec330fce..670cdec0679b 100644
--- a/drivers/net/octeontx/octeontx_ethdev.c
+++ b/drivers/net/octeontx/octeontx_ethdev.c
@@ -490,20 +490,6 @@ octeontx_dev_promisc_disable(struct rte_eth_dev *dev)
 	octeontx_port_promisc_set(nic, 0);
 }
 
-static inline int
-octeontx_atomic_write_link_status(struct rte_eth_dev *dev,
-				  struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &dev->data->dev_link;
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-		*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
 static int
 octeontx_port_link_status(struct octeontx_nic *nic)
 {
@@ -575,7 +561,7 @@ octeontx_dev_link_update(struct rte_eth_dev *dev,
 	link.link_duplex = ETH_LINK_AUTONEG;
 	link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
 
-	return octeontx_atomic_write_link_status(dev, &link);
+	return _rte_eth_linkstatus_set(dev, &link);
 }
 
 static int
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [dpdk-dev] [PATCH v2 15/15] enic: use _rte_eth_linkstatus_set
  2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
                   ` (13 preceding siblings ...)
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 14/15] octeontx: use rte_eth_linkstatus_set Stephen Hemminger
@ 2018-01-06  1:06 ` Stephen Hemminger
  14 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06  1:06 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

This driver was not doing atomic update of link status information.
And the return value was different than others.
The hardware also does not do autonegotiation (at least on Linux).

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/enic/enic_ethdev.c |  5 ++---
 drivers/net/enic/enic_main.c   | 16 +++++++---------
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 669dbf3363fd..fbeb9955d722 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -446,10 +446,9 @@ static void enicpmd_dev_stop(struct rte_eth_dev *eth_dev)
 
 	ENICPMD_FUNC_TRACE();
 	enic_disable(enic);
+
 	memset(&link, 0, sizeof(link));
-	rte_atomic64_cmpset((uint64_t *)&eth_dev->data->dev_link,
-		*(uint64_t *)&eth_dev->data->dev_link,
-		*(uint64_t *)&link);
+	_rte_eth_linkstatus_set(eth_dev, &link);
 }
 
 /*
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 8af0ccd3cdcf..f6238d4373a8 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -413,16 +413,14 @@ enic_free_consistent(void *priv,
 int enic_link_update(struct enic *enic)
 {
 	struct rte_eth_dev *eth_dev = enic->rte_dev;
-	int ret;
-	int link_status = 0;
+	struct rte_eth_link link = {
+		.link_status = enic_get_link_status(enic),
+		.link_duplex = ETH_LINK_FULL_DUPLEX,
+		.link_speed = vnic_dev_port_speed(enic->vdev),
+		.link_autoneg = ETH_LINK_FIXED,
+	};
 
-	link_status = enic_get_link_status(enic);
-	ret = (link_status == enic->link_status);
-	enic->link_status = link_status;
-	eth_dev->data->dev_link.link_status = link_status;
-	eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-	eth_dev->data->dev_link.link_speed = vnic_dev_port_speed(enic->vdev);
-	return ret;
+	return _rte_eth_linkstatus_set(eth_dev, &link);
 }
 
 static void
-- 
2.15.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [dpdk-dev] [PATCH v2 03/15] virtio: use eth_linkstatus_set
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 03/15] virtio: use eth_linkstatus_set Stephen Hemminger
@ 2018-01-06  3:10   ` Tiwei Bie
  2018-01-08 17:03     ` Stephen Hemminger
  0 siblings, 1 reply; 22+ messages in thread
From: Tiwei Bie @ 2018-01-06  3:10 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

Hi Stephen,

On Fri, Jan 05, 2018 at 05:06:44PM -0800, Stephen Hemminger wrote:
> Use the new comon code in ethdev to handle link status update.

Typo: comon -> common

> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
[...]
>  static void
>  virtio_update_stats(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
>  {
> @@ -1913,8 +1872,13 @@ static void
>  virtio_dev_stop(struct rte_eth_dev *dev)
>  {
>  	struct virtio_hw *hw = dev->data->dev_private;
> -	struct rte_eth_link link;
>  	struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
> +	struct rte_eth_link link = {
> +		.link_speed = SPEED_10G,

SPEED_10G has been removed on dpdk-next-virtio:

http://dpdk.org/browse/next/dpdk-next-virtio/commit/?id=ed85aab5ee68d9be552e10fa123e9a0e35590389

I think you could use ETH_SPEED_NUM_10G directly.

> +		.link_duplex = ETH_LINK_FULL_DUPLEX,
> +		.link_autoneg = ETH_LINK_SPEED_FIXED,
> +		.link_status = ETH_LINK_DOWN,
> +	};
[...]
>  static int
>  virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
>  {
> -	struct rte_eth_link link, old;
> -	uint16_t status;
>  	struct virtio_hw *hw = dev->data->dev_private;
> -	memset(&link, 0, sizeof(link));
> -	virtio_dev_atomic_read_link_status(dev, &link);
> -	old = link;
> -	link.link_duplex = ETH_LINK_FULL_DUPLEX;
> -	link.link_speed  = SPEED_10G;
> +	uint16_t status;
> +	struct rte_eth_link link = {
> +		.link_speed  = SPEED_10G,

Ditto.

Thanks for the work!

Best regards,
Tiwei Bie

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [dpdk-dev] [PATCH v2 02/15] ethdev: add linkstatus get/set helper functions
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 02/15] ethdev: add linkstatus get/set helper functions Stephen Hemminger
@ 2018-01-06 10:49   ` Andrew Rybchenko
  2018-01-06 14:24     ` Stephen Hemminger
  0 siblings, 1 reply; 22+ messages in thread
From: Andrew Rybchenko @ 2018-01-06 10:49 UTC (permalink / raw)
  To: Stephen Hemminger, dev

On 01/06/2018 04:06 AM, Stephen Hemminger wrote:
> Many drivers are all doing copy/paste of the same code to atomically
> update the link status. Reduce duplication, and allow for future
> changes by having common function for this.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>   lib/librte_ether/rte_ethdev.c | 35 +++++++++++++++++++++++++++++++++++
>   lib/librte_ether/rte_ethdev.h | 28 ++++++++++++++++++++++++++++
>   2 files changed, 63 insertions(+)
>
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index 27b52131ef01..4897e1dcda14 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -1495,6 +1495,41 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
>   	}
>   }
>   
> +int
> +_rte_eth_linkstatus_set(struct rte_eth_dev *dev,
> +		       const struct rte_eth_link *new_link)
> +{
> +	volatile uint64_t *dev_link
> +		 = (volatile uint64_t *)&(dev->data->dev_link);
> +	union {
> +		uint64_t val64;
> +		struct rte_eth_link link;
> +	} orig;
> +
> +	RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
> +
> +	orig.val64 = rte_atomic64_exchange(dev_link,
> +					   *(const uint64_t *)new_link);
> +
> +	return (orig.link.link_status == new_link->link_status) ? -1 : 0;

It looks like it contradicts to the function description saying that 0 is
returned if link status is the same.

> +}
> +
> +void
> +_rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
> +			struct rte_eth_link *link)
> +{
> +	const uint64_t *src = (const uint64_t *)&(dev->data->dev_link);
> +	volatile uint64_t *dst = (uint64_t *)link;
> +
> +	RTE_BUILD_BUG_ON(sizeof(*link) != sizeof(uint64_t));
> +
> +	/*
> +	 * Note: this should never fail since both destination and expected
> +	 * values are the same and are a pointer from caller.
> +	 */
> +	rte_atomic64_cmpset(dst, *dst, *src);

As I understand nobody says that *link (i.e. *dst) is initialized, so it 
could be
reading uninitialized value. Not fatal, but not good as well.
May be it is better to use something like rte_atomic64_read().

> +}
> +
>   int
>   rte_eth_stats_get(uint16_t port_id, struct rte_eth_stats *stats)
>   {
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index b10e2a92da71..b47402b797c3 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -2218,6 +2218,34 @@ int rte_eth_dev_set_link_down(uint16_t port_id);
>    */
>   void rte_eth_dev_close(uint16_t port_id);
>   
> +
> +/**
> + * @internal
> + * Atomically set the link status for the specific device.
> + * It is for use by DPDK device driver use only.
> + * User applications should not call it
> + *
> + * @param dev
> + *  Pointer to struct rte_eth_dev.
> + * @param link
> + *  New link status value.
> + * @return
> + *  -1 if link state has changed, 0 if the same.
> + */
> +int _rte_eth_linkstatus_set(struct rte_eth_dev *dev,
> +			    const struct rte_eth_link *link);
> +
> +/**
> + * @internal
> + * Atomically get the link speed and status.
> + * @param dev
> + *  Pointer to struct rte_eth_dev.
> + * @param link
> + *  link status value.
> + */
> +void _rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
> +			     struct rte_eth_link *link);
> +
>   /**
>    * Reset a Ethernet device and keep its port id.
>    *

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [dpdk-dev] [PATCH v2 09/15] sfc: use new rte_eth_linkstatus functions
  2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 09/15] sfc: use new " Stephen Hemminger
@ 2018-01-06 11:10   ` Andrew Rybchenko
  0 siblings, 0 replies; 22+ messages in thread
From: Andrew Rybchenko @ 2018-01-06 11:10 UTC (permalink / raw)
  To: Stephen Hemminger, dev

On 01/06/2018 04:06 AM, Stephen Hemminger wrote:
> Use the new API (_rte_eth_linkstatus_set) to handle link status update.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

Many thanks. Good idea since the code is definitely shorter and easier
to read/understand.

The summary should be net/sfc:, not just sfc:. In fact it is applicable
to all network driver patches.

> ---
>   drivers/net/sfc/sfc_ethdev.c | 27 +++++++--------------------
>   drivers/net/sfc/sfc_ev.c     | 23 ++++-------------------
>   2 files changed, 11 insertions(+), 39 deletions(-)
>

<...>

> diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
> index a16dc27b380e..3e96536a9d60 100644
> --- a/drivers/net/sfc/sfc_ev.c
> +++ b/drivers/net/sfc/sfc_ev.c
> @@ -404,29 +404,14 @@ sfc_ev_link_change(void *arg, efx_link_mode_t link_mode)
>   {
>   	struct sfc_evq *evq = arg;
>   	struct sfc_adapter *sa = evq->sa;
> -	struct rte_eth_link *dev_link = &sa->eth_dev->data->dev_link;
>   	struct rte_eth_link new_link;
> -	uint64_t new_link_u64;
> -	uint64_t old_link_u64;
> -
> -	EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
>   
>   	sfc_port_link_mode_to_info(link_mode, &new_link);
> +	if (_rte_eth_linkstatus_set(sa->eth_dev, &new_link) == 0)
> +		return B_FALSE;
>   
> -	new_link_u64 = *(uint64_t *)&new_link;
> -	do {
> -		old_link_u64 = rte_atomic64_read((rte_atomic64_t *)dev_link);
> -		if (old_link_u64 == new_link_u64)
> -			break;
> -
> -		if (rte_atomic64_cmpset((volatile uint64_t *)dev_link,
> -					old_link_u64, new_link_u64)) {
> -			evq->sa->port.lsc_seq++;
> -			break;
> -		}
> -	} while (B_TRUE);
> -
> -	return B_FALSE;
> +	evq->sa->port.lsc_seq++;
> +	return B_TRUE;

It must be return B_FALSE as before the patch..

>   }
>   
>   static const efx_ev_callbacks_t sfc_ev_callbacks = {

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [dpdk-dev] [PATCH v2 02/15] ethdev: add linkstatus get/set helper functions
  2018-01-06 10:49   ` Andrew Rybchenko
@ 2018-01-06 14:24     ` Stephen Hemminger
  2018-01-06 14:35       ` Andrew Rybchenko
  0 siblings, 1 reply; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-06 14:24 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev

On Sat, 6 Jan 2018 13:49:50 +0300
Andrew Rybchenko <arybchenko@solarflare.com> wrote:

> On 01/06/2018 04:06 AM, Stephen Hemminger wrote:
> > Many drivers are all doing copy/paste of the same code to atomically
> > update the link status. Reduce duplication, and allow for future
> > changes by having common function for this.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > ---
> >   lib/librte_ether/rte_ethdev.c | 35 +++++++++++++++++++++++++++++++++++
> >   lib/librte_ether/rte_ethdev.h | 28 ++++++++++++++++++++++++++++
> >   2 files changed, 63 insertions(+)
> >
> > diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> > index 27b52131ef01..4897e1dcda14 100644
> > --- a/lib/librte_ether/rte_ethdev.c
> > +++ b/lib/librte_ether/rte_ethdev.c
> > @@ -1495,6 +1495,41 @@ rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
> >   	}
> >   }
> >   
> > +int
> > +_rte_eth_linkstatus_set(struct rte_eth_dev *dev,
> > +		       const struct rte_eth_link *new_link)
> > +{
> > +	volatile uint64_t *dev_link
> > +		 = (volatile uint64_t *)&(dev->data->dev_link);
> > +	union {
> > +		uint64_t val64;
> > +		struct rte_eth_link link;
> > +	} orig;
> > +
> > +	RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
> > +
> > +	orig.val64 = rte_atomic64_exchange(dev_link,
> > +					   *(const uint64_t *)new_link);
> > +
> > +	return (orig.link.link_status == new_link->link_status) ? -1 : 0;
> 
> It looks like it contradicts to the function description saying that 0 is
> returned if link status is the same.

Looks like a mismatch in original code. Will fix that.
 
> > +}
> > +
> > +void
> > +_rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
> > +			struct rte_eth_link *link)
> > +{
> > +	const uint64_t *src = (const uint64_t *)&(dev->data->dev_link);
> > +	volatile uint64_t *dst = (uint64_t *)link;
> > +
> > +	RTE_BUILD_BUG_ON(sizeof(*link) != sizeof(uint64_t));
> > +
> > +	/*
> > +	 * Note: this should never fail since both destination and expected
> > +	 * values are the same and are a pointer from caller.
> > +	 */
> > +	rte_atomic64_cmpset(dst, *dst, *src);
> 
> As I understand nobody says that *link (i.e. *dst) is initialized, so it 
> could be
> reading uninitialized value. Not fatal, but not good as well.
> May be it is better to use something like rte_atomic64_read().
>

link is a pointer passed in by the caller.
If it is uninitialized, that is still ok since it will have some value.

The different question is that since is almost backwards use of cmpset,
not sure if processor really guarantees atomic read of source pointer.
But this code is cloned from original  in Intel driver so it is bug
for bug compatiable!

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [dpdk-dev] [PATCH v2 02/15] ethdev: add linkstatus get/set helper functions
  2018-01-06 14:24     ` Stephen Hemminger
@ 2018-01-06 14:35       ` Andrew Rybchenko
  0 siblings, 0 replies; 22+ messages in thread
From: Andrew Rybchenko @ 2018-01-06 14:35 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On 01/06/2018 05:24 PM, Stephen Hemminger wrote:
> On Sat, 6 Jan 2018 13:49:50 +0300
> Andrew Rybchenko <arybchenko@solarflare.com> wrote:
>
>> On 01/06/2018 04:06 AM, Stephen Hemminger wrote:
>>> +}
>>> +
>>> +void
>>> +_rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
>>> +			struct rte_eth_link *link)
>>> +{
>>> +	const uint64_t *src = (const uint64_t *)&(dev->data->dev_link);
>>> +	volatile uint64_t *dst = (uint64_t *)link;
>>> +
>>> +	RTE_BUILD_BUG_ON(sizeof(*link) != sizeof(uint64_t));
>>> +
>>> +	/*
>>> +	 * Note: this should never fail since both destination and expected
>>> +	 * values are the same and are a pointer from caller.
>>> +	 */
>>> +	rte_atomic64_cmpset(dst, *dst, *src);
>> As I understand nobody says that *link (i.e. *dst) is initialized, so it
>> could be
>> reading uninitialized value. Not fatal, but not good as well.
>> May be it is better to use something like rte_atomic64_read().
>>
> link is a pointer passed in by the caller.
> If it is uninitialized, that is still ok since it will have some value.

I thought about valgrind. Yes, it is problematic to run with hugepages,
but should be possible (with some patches). If so, it will/can complain
about usage of uninitialized value.

> The different question is that since is almost backwards use of cmpset,
> not sure if processor really guarantees atomic read of source pointer.
> But this code is cloned from original  in Intel driver so it is bug
> for bug compatiable!

I see, but if so it was local to corresponding Intel driver. Now it is
becoming global.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [dpdk-dev] [PATCH v2 03/15] virtio: use eth_linkstatus_set
  2018-01-06  3:10   ` Tiwei Bie
@ 2018-01-08 17:03     ` Stephen Hemminger
  0 siblings, 0 replies; 22+ messages in thread
From: Stephen Hemminger @ 2018-01-08 17:03 UTC (permalink / raw)
  To: Tiwei Bie; +Cc: dev

On Sat, 6 Jan 2018 11:10:08 +0800
Tiwei Bie <tiwei.bie@intel.com> wrote:

> Hi Stephen,
> 
> On Fri, Jan 05, 2018 at 05:06:44PM -0800, Stephen Hemminger wrote:
> > Use the new comon code in ethdev to handle link status update.  
> 
> Typo: comon -> common
> 
> > 
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>  
> [...]
> >  static void
> >  virtio_update_stats(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
> >  {
> > @@ -1913,8 +1872,13 @@ static void
> >  virtio_dev_stop(struct rte_eth_dev *dev)
> >  {
> >  	struct virtio_hw *hw = dev->data->dev_private;
> > -	struct rte_eth_link link;
> >  	struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
> > +	struct rte_eth_link link = {
> > +		.link_speed = SPEED_10G,  
> 
> SPEED_10G has been removed on dpdk-next-virtio:

Patch was intended for current release so not looking at -next

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2018-01-08 17:03 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-06  1:06 [dpdk-dev] [PATCH v2 00/15] common ethdev linkstatus functions Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 01/15] eal: introduce atomic exchange operation Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 02/15] ethdev: add linkstatus get/set helper functions Stephen Hemminger
2018-01-06 10:49   ` Andrew Rybchenko
2018-01-06 14:24     ` Stephen Hemminger
2018-01-06 14:35       ` Andrew Rybchenko
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 03/15] virtio: use eth_linkstatus_set Stephen Hemminger
2018-01-06  3:10   ` Tiwei Bie
2018-01-08 17:03     ` Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 04/15] vmxnet3: use rte_eth_linkstatus_set Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 05/15] dpaa2: " Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 06/15] nfp: use rte_eth_linkstatus functions Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 07/15] e1000: use rte_eth_linkstatus helpers Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 08/15] ixgbe: use rte_eth_linkstatus functions Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 09/15] sfc: use new " Stephen Hemminger
2018-01-06 11:10   ` Andrew Rybchenko
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 10/15] i40e: use " Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 11/15] liquidio: use _rte_eth_linkstatus_set Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 12/15] thunderx: " Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 13/15] szedata: " Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 14/15] octeontx: use rte_eth_linkstatus_set Stephen Hemminger
2018-01-06  1:06 ` [dpdk-dev] [PATCH v2 15/15] enic: use _rte_eth_linkstatus_set Stephen Hemminger

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).