Skip to contentSkip to conversation

net/mlx4: trim and refactor entire PMD

PATCH Superseded Adrien Mazarguil 3 participants 110 messages Aug 1, 2017 – Sep 5, 2017 Network drivers Page 1 of 2

lore
Share & tools
lore
#0 lore raw

cover net/mlx4: trim and refactor entire PMD

The main purpose of this large series is to relieve the mlx4 PMD from its dependency on Mellanox OFED to instead rely on the standard rdma-core package provided by Linux distributions.

While compatibility with Mellanox OFED is preserved, all nonstandard functionality has to be stripped from the PMD in order to re-implement it through an approach compatible with rdma-core.

Due to the amount of changes necessary to achieve this goal, this rework starts off by removing extraneous code to simplify the PMD as much as possible before either replacing or dismantling functionality that relies on nonstandard Verbs.

What remains after applying this series is single-segment Tx/Rx support, without offloads nor RSS, on the default MAC address (which cannot be configured). Support for multiple queues and the flow API (minus the RSS action) are also preserved.

Missing functionality that needs substantial work will be restored later by subsequent series.

Also because the mlx4 PMD is mostly contained in a single very large source file of 6400+ lines (mlx4.c) which has become extremely difficult to maintain, this rework is used as an opportunity to finally group functions into separate files, as in mlx5.

This rework targets DPDK 17.11.

Adrien Mazarguil (48):
net/mlx4: add consistency to copyright notices net/mlx4: remove limitation on number of instances net/mlx4: check max number of ports dynamically net/mlx4: remove useless compilation checks net/mlx4: remove secondary process support net/mlx4: remove useless code
net/mlx4: remove soft counters compilation option net/mlx4: remove scatter mode compilation option net/mlx4: remove Tx inline compilation option net/mlx4: remove allmulti and promisc support net/mlx4: remove VLAN filter support net/mlx4: remove MAC address configuration support net/mlx4: drop MAC flows affecting all Rx queues net/mlx4: revert flow API RSS support net/mlx4: revert RSS parent queue refactoring net/mlx4: drop RSS support
net/mlx4: drop checksum offloads support net/mlx4: drop packet type recognition support net/mlx4: drop scatter/gather support net/mlx4: drop inline receive support net/mlx4: use standard QP attributes net/mlx4: revert resource domain support net/mlx4: revert multicast echo prevention net/mlx4: revert fast Verbs interface for Tx net/mlx4: revert fast Verbs interface for Rx net/mlx4: simplify link update function net/mlx4: standardize on negative errno values net/mlx4: clean up coding style inconsistencies net/mlx4: remove control path locks net/mlx4: remove unnecessary wrapper functions net/mlx4: remove mbuf macro definitions net/mlx4: use standard macro to get array size net/mlx4: separate debugging macros net/mlx4: use a single interrupt handle net/mlx4: rename alarm field
net/mlx4: refactor interrupt FD settings net/mlx4: clean up interrupt functions prototypes net/mlx4: compact interrupt functions net/mlx4: separate interrupt handling net/mlx4: separate Rx/Tx definitions net/mlx4: separate Rx/Tx functions net/mlx4: separate device control functions net/mlx4: separate Tx configuration functions net/mlx4: separate Rx configuration functions net/mlx4: group flow API handlers in common file net/mlx4: rename private functions in flow API net/mlx4: separate memory management functions net/mlx4: clean up includes and comments

 config/common_base                |    3 -
 doc/guides/nics/features/mlx4.ini |   13 -
 doc/guides/nics/mlx4.rst          |   37 +-
 drivers/net/mlx4/Makefile         |   41 +-
 drivers/net/mlx4/mlx4.c           | 6370 ++------------------------------
 drivers/net/mlx4/mlx4.h           |  322 +-
 drivers/net/mlx4/mlx4_ethdev.c    |  792 ++++
 drivers/net/mlx4/mlx4_flow.c      |  457 +--
 drivers/net/mlx4/mlx4_flow.h      |   51 +-
 drivers/net/mlx4/mlx4_intr.c      |  377 ++
 drivers/net/mlx4/mlx4_mr.c        |  183 +
 drivers/net/mlx4/mlx4_rxq.c       |  632 ++++
 drivers/net/mlx4/mlx4_rxtx.c      |  533 +++
 drivers/net/mlx4/mlx4_rxtx.h      |  164 +
 drivers/net/mlx4/mlx4_txq.c       |  472 +++
 drivers/net/mlx4/mlx4_utils.c     |   66 +
 drivers/net/mlx4/mlx4_utils.h     |  105 +
 17 files changed, 3824 insertions(+), 6794 deletions(-)
 create mode 100644 drivers/net/mlx4/mlx4_ethdev.c
 create mode 100644 drivers/net/mlx4/mlx4_intr.c
 create mode 100644 drivers/net/mlx4/mlx4_mr.c
 create mode 100644 drivers/net/mlx4/mlx4_rxq.c
 create mode 100644 drivers/net/mlx4/mlx4_rxtx.c
 create mode 100644 drivers/net/mlx4/mlx4_rxtx.h
 create mode 100644 drivers/net/mlx4/mlx4_txq.c
 create mode 100644 drivers/net/mlx4/mlx4_utils.c
 create mode 100644 drivers/net/mlx4/mlx4_utils.h
Signature · 1 line
2.1.4
#1 lore raw

PATCH 1/48 net/mlx4: add consistency to copyright notices

Copyright lasts long enough not to require notices to be updated yearly.

The current approach of updating them occasionally while working on unrelated tasks should be deprecated in favor of dedicated commits updating all files at once when necessary.

Standardize on a single year per copyright owner.

---
 doc/guides/nics/mlx4.rst     | 2 +-
 drivers/net/mlx4/Makefile    | 4 ++--
 drivers/net/mlx4/mlx4.c      | 4 ++--
 drivers/net/mlx4/mlx4.h      | 4 ++--
 drivers/net/mlx4/mlx4_flow.c | 2 +-
 drivers/net/mlx4/mlx4_flow.h | 2 +-
 6 files changed, 9 insertions(+), 9 deletions(-)
doc/guides/nics/mlx4.rst +1 -1
index d5bf2b3..4c8c299 100644
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright 2012-2015 6WIND S.A.
+    Copyright 2012 6WIND S.A.
     Copyright 2015 Mellanox
 
     Redistribution and use in source and binary forms, with or without
drivers/net/mlx4/Makefile +2 -2
index 755c8a4..ce4b244 100644
@@ -1,7 +1,7 @@
 #   BSD LICENSE
 #
-#   Copyright 2012-2015 6WIND S.A.
-#   Copyright 2012 Mellanox.
+#   Copyright 2012 6WIND S.A.
+#   Copyright 2012 Mellanox
 #
 #   Redistribution and use in source and binary forms, with or without
 #   modification, are permitted provided that the following conditions
drivers/net/mlx4/mlx4.c +2 -2
index 055de49..b5a7607 100644
@@ -1,8 +1,8 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright 2012-2017 6WIND S.A.
- *   Copyright 2012-2017 Mellanox.
+ *   Copyright 2012 6WIND S.A.
+ *   Copyright 2012 Mellanox
  *
  *   Redistribution and use in source and binary forms, with or without
  *   modification, are permitted provided that the following conditions
drivers/net/mlx4/mlx4.h +2 -2
index a2e0ae7..6421c91 100644
@@ -1,8 +1,8 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright 2012-2017 6WIND S.A.
- *   Copyright 2012-2017 Mellanox.
+ *   Copyright 2012 6WIND S.A.
+ *   Copyright 2012 Mellanox
  *
  *   Redistribution and use in source and binary forms, with or without
  *   modification, are permitted provided that the following conditions
drivers/net/mlx4/mlx4_flow.c +1 -1
index 925c89c..ab37e7d 100644
@@ -2,7 +2,7 @@
  *   BSD LICENSE
  *
  *   Copyright 2017 6WIND S.A.
- *   Copyright 2017 Mellanox.
+ *   Copyright 2017 Mellanox
  *
  *   Redistribution and use in source and binary forms, with or without
  *   modification, are permitted provided that the following conditions
drivers/net/mlx4/mlx4_flow.h +1 -1
index beabcf2..4654dc2 100644
@@ -2,7 +2,7 @@
  *   BSD LICENSE
  *
  *   Copyright 2017 6WIND S.A.
- *   Copyright 2017 Mellanox.
+ *   Copyright 2017 Mellanox
  *
  *   Redistribution and use in source and binary forms, with or without
  *   modification, are permitted provided that the following conditions
Signature · 1 line
2.1.4
#2 lore raw

PATCH 2/48 net/mlx4: remove limitation on number of instances

In reply to Adrien Mazarguil

The seemingly artificial limitation on the maximum number of instances for this PMD is an historical leftover that predates its first public release.

It was used as a workaround to support multiple physical ports on a PCI device exposing a single bus address when mlx4 was implemented directly as an Ethernet device driver instead of a PCI driver spawning Ethernet devices.

Getting rid of it simplifies device initialization.

---
 drivers/net/mlx4/mlx4.c | 57 +++-----------------------------------------
 1 file changed, 3 insertions(+), 54 deletions(-)
drivers/net/mlx4/mlx4.c +3 -54
index b5a7607..0ae78e0 100644
@@ -5444,40 +5444,6 @@ priv_get_mac(struct priv *priv, uint8_t (*mac)[ETHER_ADDR_LEN])
 	return 0;
 }
 
-/* Support up to 32 adapters. */
-static struct {
-	struct rte_pci_addr pci_addr; /* associated PCI address */
-	uint32_t ports; /* physical ports bitfield. */
-} mlx4_dev[32];
-
-/**
- * Get device index in mlx4_dev[] from PCI bus address.
- *
- * @param[in] pci_addr
- *   PCI bus address to look for.
- *
- * @return
- *   mlx4_dev[] index on success, -1 on failure.
- */
-static int
-mlx4_dev_idx(struct rte_pci_addr *pci_addr)
-{
-	unsigned int i;
-	int ret = -1;
-
-	assert(pci_addr != NULL);
-	for (i = 0; (i != elemof(mlx4_dev)); ++i) {
-		if ((mlx4_dev[i].pci_addr.domain == pci_addr->domain) &&
-		    (mlx4_dev[i].pci_addr.bus == pci_addr->bus) &&
-		    (mlx4_dev[i].pci_addr.devid == pci_addr->devid) &&
-		    (mlx4_dev[i].pci_addr.function == pci_addr->function))
-			return i;
-		if ((mlx4_dev[i].ports == 0) && (ret == -1))
-			ret = i;
-	}
-	return ret;
-}
-
 /**
  * Retrieve integer value from environment variable.
  *
@@ -6060,21 +6026,11 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		.active_ports = 0,
 	};
 	unsigned int vf;
-	int idx;
 	int i;
 
 	(void)pci_drv;
 	assert(pci_drv == &mlx4_driver);
-	/* Get mlx4_dev[] index. */
-	idx = mlx4_dev_idx(&pci_dev->addr);
-	if (idx == -1) {
-		ERROR("this driver cannot support any more adapters");
-		return -ENOMEM;
-	}
-	DEBUG("using driver device index %d", idx);
 
-	/* Save PCI address. */
-	mlx4_dev[idx].pci_addr = pci_dev->addr;
 	list = ibv_get_device_list(&i);
 	if (list == NULL) {
 		assert(errno);
@@ -6141,7 +6097,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	}
 	for (i = 0; i < device_attr.phys_port_cnt; i++) {
 		uint32_t port = i + 1; /* ports are indexed from one */
-		uint32_t test = (1 << i);
 		struct ibv_context *ctx = NULL;
 		struct ibv_port_attr port_attr;
 		struct ibv_pd *pd = NULL;
@@ -6162,7 +6117,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 #endif /* RSS_SUPPORT */
 #endif /* HAVE_EXP_QUERY_DEVICE */
 
-		DEBUG("using port %u (%08" PRIx32 ")", port, test);
+		DEBUG("using port %u", port);
 
 		ctx = ibv_open_device(ibv_dev);
 		if (ctx == NULL) {
@@ -6198,8 +6153,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			goto port_error;
 		}
 
-		mlx4_dev[idx].ports |= test;
-
 		/* from rte_ethdev.c */
 		priv = rte_zmalloc("ethdev private structure",
 				   sizeof(*priv),
@@ -6405,6 +6358,8 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			rte_eth_dev_release_port(eth_dev);
 		break;
 	}
+	if (i == device_attr.phys_port_cnt)
+		return 0;
 
 	/*
 	 * XXX if something went wrong in the loop above, there is a resource
@@ -6413,12 +6368,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	 * way to enumerate the registered ethdevs to free the previous ones.
 	 */
 
-	/* no port found, complain */
-	if (!mlx4_dev[idx].ports) {
-		err = ENODEV;
-		goto error;
-	}
-
 error:
 	if (attr_ctx)
 		claim_zero(ibv_close_device(attr_ctx));
Signature · 1 line
2.1.4
#3 lore raw

PATCH 3/48 net/mlx4: check max number of ports dynamically

In reply to Adrien Mazarguil

Use maximum number reported by hardware capabilities as replacement for the static check on MLX4_PMD_MAX_PHYS_PORTS.

Cc Gaëtan Rivet <[email protected]>
Cc Allain Legacy <[email protected]>
---
 drivers/net/mlx4/mlx4.c | 43 +++++++++++++++++++++++++------------------
 drivers/net/mlx4/mlx4.h |  3 ---
 2 files changed, 25 insertions(+), 21 deletions(-)
drivers/net/mlx4/mlx4.c +25 -18
index 0ae78e0..e28928c 100644
@@ -118,8 +118,12 @@ struct mlx4_secondary_data {
 	rte_spinlock_t lock; /* Port configuration lock. */
 } mlx4_secondary_data[RTE_MAX_ETHPORTS];
 
+/** Configuration structure for device arguments. */
 struct mlx4_conf {
-	uint8_t active_ports;
+	struct {
+		uint32_t present; /**< Bit-field for existing ports. */
+		uint32_t enabled; /**< Bit-field for user-enabled ports. */
+	} ports;
 };
 
 /* Available parameters list. */
@@ -5927,16 +5931,15 @@ mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
  *   Key argument to verify.
  * @param[in] val
  *   Value associated with key.
- * @param out
- *   User data.
+ * @param[in, out] conf
+ *   Shared configuration data.
  *
  * @return
  *   0 on success, negative errno value on failure.
  */
 static int
-mlx4_arg_parse(const char *key, const char *val, void *out)
+mlx4_arg_parse(const char *key, const char *val, struct mlx4_conf *conf)
 {
-	struct mlx4_conf *conf = out;
 	unsigned long tmp;
 
 	errno = 0;
@@ -5946,12 +5949,11 @@ mlx4_arg_parse(const char *key, const char *val, void *out)
 		return -errno;
 	}
 	if (strcmp(MLX4_PMD_PORT_KVARG, key) == 0) {
-		if (tmp >= MLX4_PMD_MAX_PHYS_PORTS) {
-			ERROR("invalid port index %lu (max: %u)",
-				tmp, MLX4_PMD_MAX_PHYS_PORTS - 1);
+		if (!(conf->ports.present & (1 << tmp))) {
+			ERROR("invalid port index %lu", tmp);
 			return -EINVAL;
 		}
-		conf->active_ports |= 1 << tmp;
+		conf->ports.enabled |= 1 << tmp;
 	} else {
 		WARN("%s: unknown parameter", key);
 		return -EINVAL;
@@ -5987,8 +5989,13 @@ mlx4_args(struct rte_devargs *devargs, struct mlx4_conf *conf)
 	for (i = 0; pmd_mlx4_init_params[i]; ++i) {
 		arg_count = rte_kvargs_count(kvlist, MLX4_PMD_PORT_KVARG);
 		while (arg_count-- > 0) {
-			ret = rte_kvargs_process(kvlist, MLX4_PMD_PORT_KVARG,
-					mlx4_arg_parse, conf);
+			ret = rte_kvargs_process(kvlist,
+						 MLX4_PMD_PORT_KVARG,
+						 (int (*)(const char *,
+							  const char *,
+							  void *))
+						 mlx4_arg_parse,
+						 conf);
 			if (ret != 0)
 				goto free_kvlist;
 		}
@@ -6023,7 +6030,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	struct ibv_context *attr_ctx = NULL;
 	struct ibv_device_attr device_attr;
 	struct mlx4_conf conf = {
-		.active_ports = 0,
+		.ports.present = 0,
 	};
 	unsigned int vf;
 	int i;
@@ -6085,16 +6092,16 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	}
 	INFO("%u port(s) detected", device_attr.phys_port_cnt);
 
+	for (i = 0; i < device_attr.phys_port_cnt; ++i)
+		conf.ports.present |= 1 << i;
 	if (mlx4_args(pci_dev->device.devargs, &conf)) {
 		ERROR("failed to process device arguments");
 		err = EINVAL;
 		goto error;
 	}
 	/* Use all ports when none are defined */
-	if (conf.active_ports == 0) {
-		for (i = 0; i < MLX4_PMD_MAX_PHYS_PORTS; i++)
-			conf.active_ports |= 1 << i;
-	}
+	if (!conf.ports.enabled)
+		conf.ports.enabled = conf.ports.present;
 	for (i = 0; i < device_attr.phys_port_cnt; i++) {
 		uint32_t port = i + 1; /* ports are indexed from one */
 		struct ibv_context *ctx = NULL;
@@ -6107,8 +6114,8 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 #endif /* HAVE_EXP_QUERY_DEVICE */
 		struct ether_addr mac;
 
-		/* If port is not active, skip. */
-		if (!(conf.active_ports & (1 << i)))
+		/* If port is not enabled, skip. */
+		if (!(conf.ports.enabled & (1 << i)))
 			continue;
 #ifdef HAVE_EXP_QUERY_DEVICE
 		exp_device_attr.comp_mask = IBV_EXP_DEVICE_ATTR_EXP_CAP_FLAGS;
drivers/net/mlx4/mlx4.h +0 -3
index 6421c91..25a7212 100644
@@ -81,9 +81,6 @@
 /* Request send completion once in every 64 sends, might be less. */
 #define MLX4_PMD_TX_PER_COMP_REQ 64
 
-/* Maximum number of physical ports. */
-#define MLX4_PMD_MAX_PHYS_PORTS 2
-
 /* Maximum number of Scatter/Gather Elements per Work Request. */
 #ifndef MLX4_PMD_SGE_WR_N
 #define MLX4_PMD_SGE_WR_N 4
Signature · 1 line
2.1.4
#4 lore raw

Re: [PATCH v1 03/48] net/mlx4: check max number of ports dynamically

Quoted 3 lines

-----Original Message-----
From: Adrien Mazarguil [mailto:[email protected]]
Sent: Tuesday, August 01, 2017 12:54 PM

<...>

drivers/net/mlx4/mlx4.c mlx4_arg_parse(const char *key, const char *val, · line 5954

Quoted 10 lines
drivers/net/mlx4/mlx4.c +2 -3
@@ -5946,12 +5949,11 @@ mlx4_arg_parse(const char *key, const char *val,
 void *out)
 		return -errno;
 	}
 	if (strcmp(MLX4_PMD_PORT_KVARG, key) == 0) {
-		if (tmp >= MLX4_PMD_MAX_PHYS_PORTS) {
-			ERROR("invalid port index %lu (max: %u)",
-				tmp, MLX4_PMD_MAX_PHYS_PORTS - 1);
+		if (!(conf->ports.present & (1 << tmp))) {
+			ERROR("invalid port index %lu", tmp);

The original error included the max value. Wouldn't it be useful to report this to the user to help them understand their mistake?

drivers/net/mlx4/mlx4.c mlx4_pci_probe(struct rte_pci_driver *pci_drv, · line 6097

Quoted 7 lines
drivers/net/mlx4/mlx4.c +2 -0
@@ -6085,16 +6092,16 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv,
 struct rte_pci_device *pci_dev)
 	}
 	INFO("%u port(s) detected", device_attr.phys_port_cnt);
 
+	for (i = 0; i < device_attr.phys_port_cnt; ++i)
+		conf.ports.present |= 1 << i;

The loop could be avoided with:

	conf.ports.present = (1 << device_attr.phys_port_cnt) - 1;

Regards,
Allain

#5 lore raw

Re: [PATCH v1 03/48] net/mlx4: check max number of ports dynamically

Quoted 4 lines · Allain
Quoted 3 lines

-----Original Message-----
From: Adrien Mazarguil [mailto:[email protected]]
Sent: Tuesday, August 01, 2017 12:54 PM

<...>

Quoted 13 lines

drivers/net/mlx4/mlx4.c mlx4_arg_parse(const char *key, const char *val, · line 5954

Quoted 10 lines
drivers/net/mlx4/mlx4.c +2 -3
@@ -5946,12 +5949,11 @@ mlx4_arg_parse(const char *key, const char *val,
 void *out)
 		return -errno;
 	}
 	if (strcmp(MLX4_PMD_PORT_KVARG, key) == 0) {
-		if (tmp >= MLX4_PMD_MAX_PHYS_PORTS) {
-			ERROR("invalid port index %lu (max: %u)",
-				tmp, MLX4_PMD_MAX_PHYS_PORTS - 1);
+		if (!(conf->ports.present & (1 << tmp))) {
+			ERROR("invalid port index %lu", tmp);

The original error included the max value. Wouldn't it be useful to report this to the user to help them understand their mistake?

Makes sense, I'll add it back.

Quoted 11 lines

drivers/net/mlx4/mlx4.c mlx4_pci_probe(struct rte_pci_driver *pci_drv, · line 6097

Quoted 7 lines
drivers/net/mlx4/mlx4.c +2 -0
@@ -6085,16 +6092,16 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv,
 struct rte_pci_device *pci_dev)
 	}
 	INFO("%u port(s) detected", device_attr.phys_port_cnt);
 
+	for (i = 0; i < device_attr.phys_port_cnt; ++i)
+		conf.ports.present |= 1 << i;

The loop could be avoided with:

	conf.ports.present = (1 << device_attr.phys_port_cnt) - 1;

I will also make that change in the next iteration, thanks.

Signature · 2 lines
Adrien Mazarguil
6WIND
#6 lore raw

PATCH 4/48 net/mlx4: remove useless compilation checks

In reply to Adrien Mazarguil

Verbs support for RSS, inline receive and extended device query calls has not been optional for a while. Their absence is untested and is therefore unsupported.

Remove the related compilation checks and assume Mellanox OFED is up to date, as described in the documentation.

Use this opportunity to remove a few useless data path debugging messages behind compilation checks on never defined macros.

---
 drivers/net/mlx4/Makefile    | 12 ------------
 drivers/net/mlx4/mlx4.c      | 35 -----------------------------------
 drivers/net/mlx4/mlx4.h      |  2 --
 drivers/net/mlx4/mlx4_flow.c |  3 ---
 4 files changed, 52 deletions(-)
drivers/net/mlx4/Makefile +0 -12
index ce4b244..ab2a867 100644
@@ -100,18 +100,6 @@ mlx4_autoconf.h.new: FORCE
 mlx4_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 	$Q $(RM) -f -- '$@'
 	$Q sh -- '$<' '$@' \
-		RSS_SUPPORT \
-		infiniband/verbs.h \
-		enum IBV_EXP_DEVICE_UD_RSS $(AUTOCONF_OUTPUT)
-	$Q sh -- '$<' '$@' \
-		INLINE_RECV \
-		infiniband/verbs.h \
-		enum IBV_EXP_DEVICE_ATTR_INLINE_RECV_SZ $(AUTOCONF_OUTPUT)
-	$Q sh -- '$<' '$@' \
-		HAVE_EXP_QUERY_DEVICE \
-		infiniband/verbs.h \
-		type 'struct ibv_exp_device_attr' $(AUTOCONF_OUTPUT)
-	$Q sh -- '$<' '$@' \
 		HAVE_EXP_QP_BURST_CREATE_DISABLE_ETH_LOOPBACK \
 		infiniband/verbs.h \
 		enum IBV_EXP_QP_BURST_CREATE_DISABLE_ETH_LOOPBACK \
drivers/net/mlx4/mlx4.c +0 -35
index e28928c..e6fc204 100644
@@ -1103,10 +1103,6 @@ txq_complete(struct txq *txq)
 
 	if (unlikely(elts_comp == 0))
 		return 0;
-#ifdef DEBUG_SEND
-	DEBUG("%p: processing %u work requests completions",
-	      (void *)txq, elts_comp);
-#endif
 	wcs_n = txq->if_cq->poll_cnt(txq->cq, elts_comp);
 	if (unlikely(wcs_n == 0))
 		return 0;
@@ -3155,9 +3151,6 @@ mlx4_rx_burst_sp(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		return 0;
 	*next = NULL;
 	/* Repost WRs. */
-#ifdef DEBUG_RECV
-	DEBUG("%p: reposting %d WRs", (void *)rxq, i);
-#endif
 	ret = ibv_post_recv(rxq->qp, head.next, &bad_wr);
 	if (unlikely(ret)) {
 		/* Inability to repost WRs is fatal. */
@@ -3318,9 +3311,6 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 	if (unlikely(i == 0))
 		return 0;
 	/* Repost WRs. */
-#ifdef DEBUG_RECV
-	DEBUG("%p: reposting %u WRs", (void *)rxq, i);
-#endif
 	ret = rxq->if_qp->recv_burst(rxq->qp, sges, i);
 	if (unlikely(ret)) {
 		/* Inability to repost WRs is fatal. */
@@ -3418,15 +3408,11 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
 		.res_domain = rd,
 	};
 
-#ifdef INLINE_RECV
 	attr.max_inl_recv = priv->inl_recv_size;
 	attr.comp_mask |= IBV_EXP_QP_INIT_ATTR_INL_RECV;
-#endif
 	return ibv_exp_create_qp(priv->ctx, &attr);
 }
 
-#ifdef RSS_SUPPORT
-
 /**
  * Allocate a RSS Queue Pair.
  * Optionally setup inline receive if supported.
@@ -3474,10 +3460,8 @@ rxq_setup_qp_rss(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
 		.res_domain = rd,
 	};
 
-#ifdef INLINE_RECV
 	attr.max_inl_recv = priv->inl_recv_size,
 	attr.comp_mask |= IBV_EXP_QP_INIT_ATTR_INL_RECV;
-#endif
 	if (children_n > 0) {
 		attr.qpg.qpg_type = IBV_EXP_QPG_PARENT;
 		/* TSS isn't necessary. */
@@ -3493,8 +3477,6 @@ rxq_setup_qp_rss(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
 	return ibv_exp_create_qp(priv->ctx, &attr);
 }
 
-#endif /* RSS_SUPPORT */
-
 /**
  * Reconfigure a RX queue with new parameters.
  *
@@ -3728,13 +3710,11 @@ rxq_create_qp(struct rxq *rxq,
 	int parent = (children_n > 0);
 	struct priv *priv = rxq->priv;
 
-#ifdef RSS_SUPPORT
 	if (priv->rss && !inactive && (rxq_parent || parent))
 		rxq->qp = rxq_setup_qp_rss(priv, rxq->cq, desc,
 					   children_n, rxq->rd,
 					   rxq_parent);
 	else
-#endif /* RSS_SUPPORT */
 		rxq->qp = rxq_setup_qp(priv, rxq->cq, desc, rxq->rd);
 	if (rxq->qp == NULL) {
 		ret = (errno ? errno : EINVAL);
@@ -3750,9 +3730,7 @@ rxq_create_qp(struct rxq *rxq,
 	};
 	ret = ibv_exp_modify_qp(rxq->qp, &mod,
 				(IBV_EXP_QP_STATE |
-#ifdef RSS_SUPPORT
 				 (parent ? IBV_EXP_QP_GROUP_RSS : 0) |
-#endif /* RSS_SUPPORT */
 				 IBV_EXP_QP_PORT));
 	if (ret) {
 		ERROR("QP state to IBV_QPS_INIT failed: %s",
@@ -6109,20 +6087,14 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		struct ibv_pd *pd = NULL;
 		struct priv *priv = NULL;
 		struct rte_eth_dev *eth_dev = NULL;
-#ifdef HAVE_EXP_QUERY_DEVICE
 		struct ibv_exp_device_attr exp_device_attr;
-#endif /* HAVE_EXP_QUERY_DEVICE */
 		struct ether_addr mac;
 
 		/* If port is not enabled, skip. */
 		if (!(conf.ports.enabled & (1 << i)))
 			continue;
-#ifdef HAVE_EXP_QUERY_DEVICE
 		exp_device_attr.comp_mask = IBV_EXP_DEVICE_ATTR_EXP_CAP_FLAGS;
-#ifdef RSS_SUPPORT
 		exp_device_attr.comp_mask |= IBV_EXP_DEVICE_ATTR_RSS_TBL_SZ;
-#endif /* RSS_SUPPORT */
-#endif /* HAVE_EXP_QUERY_DEVICE */
 
 		DEBUG("using port %u", port);
 
@@ -6175,13 +6147,11 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		priv->port = port;
 		priv->pd = pd;
 		priv->mtu = ETHER_MTU;
-#ifdef HAVE_EXP_QUERY_DEVICE
 		if (ibv_exp_query_device(ctx, &exp_device_attr)) {
 			ERROR("ibv_exp_query_device() failed");
 			err = ENODEV;
 			goto port_error;
 		}
-#ifdef RSS_SUPPORT
 		if ((exp_device_attr.exp_device_cap_flags &
 		     IBV_EXP_DEVICE_QPG) &&
 		    (exp_device_attr.exp_device_cap_flags &
@@ -6206,7 +6176,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		if (priv->hw_rss)
 			DEBUG("maximum RSS indirection table size: %u",
 			      exp_device_attr.max_rss_tbl_sz);
-#endif /* RSS_SUPPORT */
 
 		priv->hw_csum =
 			((exp_device_attr.exp_device_cap_flags &
@@ -6221,7 +6190,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		DEBUG("L2 tunnel checksum offloads are %ssupported",
 		      (priv->hw_csum_l2tun ? "" : "not "));
 
-#ifdef INLINE_RECV
 		priv->inl_recv_size = mlx4_getenv_int("MLX4_INLINE_RECV_SIZE");
 
 		if (priv->inl_recv_size) {
@@ -6245,10 +6213,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			INFO("Set inline receive size to %u",
 			     priv->inl_recv_size);
 		}
-#endif /* INLINE_RECV */
-#endif /* HAVE_EXP_QUERY_DEVICE */
 
-		(void)mlx4_getenv_int;
 		priv->vf = vf;
 		/* Configure the first MAC address by default. */
 		if (priv_get_mac(priv, &mac.addr_bytes)) {
drivers/net/mlx4/mlx4.h +0 -2
index 25a7212..557b94d 100644
@@ -338,9 +338,7 @@ struct priv {
 	unsigned int vf:1; /* This is a VF device. */
 	unsigned int pending_alarm:1; /* An alarm is pending. */
 	unsigned int isolated:1; /* Toggle isolated mode. */
-#ifdef INLINE_RECV
 	unsigned int inl_recv_size; /* Inline recv size */
-#endif
 	unsigned int max_rss_tbl_sz; /* Maximum number of RSS queues. */
 	/* RX/TX queues. */
 	unsigned int rxqs_n; /* RX queues array size. */
drivers/net/mlx4/mlx4_flow.c +0 -3
index ab37e7d..f5c015e 100644
@@ -37,9 +37,6 @@
 #include <rte_flow_driver.h>
 #include <rte_malloc.h>
 
-/* Generated configuration header. */
-#include "mlx4_autoconf.h"
-
 /* PMD headers. */
 #include "mlx4.h"
 #include "mlx4_flow.h"
Signature · 1 line
2.1.4
#7 lore raw

Re: [PATCH v1 04/48] net/mlx4: remove useless compilation checks

Quoted 6 lines · Adrien Mazarguil

Verbs support for RSS, inline receive and extended device query calls has not been optional for a while. Their absence is untested and is therefore unsupported.

Remove the related compilation checks and assume Mellanox OFED is up to date, as described in the documentation.

So this requires Mellanox OFED 4.1 is there,
is there a check for the OFED version, or do you think does it required?

Quoted 5 lines

Use this opportunity to remove a few useless data path debugging messages behind compilation checks on never defined macros.

<...>

#8 lore raw

Re: [PATCH v1 04/48] net/mlx4: remove useless compilation checks

Hi Ferruh,

Quoted 9 lines · Ferruh Yigit
Quoted 6 lines · Adrien Mazarguil

Verbs support for RSS, inline receive and extended device query calls has not been optional for a while. Their absence is untested and is therefore unsupported.

Remove the related compilation checks and assume Mellanox OFED is up to date, as described in the documentation.

So this requires Mellanox OFED 4.1 is there,

Well, the PMD most likely works with versions older than that, but they are not officially supported anymore. These changes assert that no effort is made to maintain compatibility.

Quoted 1 line

is there a check for the OFED version, or do you think does it required?

I think it's not necessary. You know, the existing checks haven't been validated for a very long time, mlx4 probably does not even compile anymore without these features. Even if it does, it might be unable to perform TX/RX at all. Getting a compilation failure at least makes things clear.

Quoted 9 lines
Quoted 6 lines

Use this opportunity to remove a few useless data path debugging messages behind compilation checks on never defined macros.

<...>

Signature · 2 lines
Adrien Mazarguil
6WIND
#9 lore raw

PATCH 5/48 net/mlx4: remove secondary process support

In reply to Adrien Mazarguil

Current implementation is partial (Tx only), not convenient to use and not of primary concern.

Remove this feature before refactoring the PMD.

---
 doc/guides/nics/features/mlx4.ini |   1 -
 doc/guides/nics/mlx4.rst          |   2 -
 drivers/net/mlx4/mlx4.c           | 349 +--------------------------------
 3 files changed, 8 insertions(+), 344 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -1
index 1d5f266..f6efd21 100644
@@ -27,7 +27,6 @@ Inner L4 checksum    = Y
 Packet type parsing  = Y
 Basic stats          = Y
 Stats per queue      = Y
-Multiprocess aware   = Y
 Other kdrv           = Y
 Power8               = Y
 x86-32               = Y
doc/guides/nics/mlx4.rst +0 -2
index 4c8c299..04788f2 100644
@@ -88,7 +88,6 @@ Features
 - Scattered packets are supported for TX and RX.
 - Inner L3/L4 (IP, TCP and UDP) TX/RX checksum offloading and validation.
 - Outer L3 (IP) TX/RX checksum offloading and validation for VXLAN frames.
-- Secondary process TX is supported.
 - RX interrupts.
 
 Limitations
@@ -99,7 +98,6 @@ Limitations
 - RSS always includes L3 (IPv4/IPv6) and L4 (UDP/TCP). They cannot be
   dissociated.
 - Hardware counters are not implemented (they are software counters).
-- Secondary process RX is not supported.
 
 Configuration
 -------------
drivers/net/mlx4/mlx4.c +8 -341

523 lines not on this page · raw message

Signature · 1 line
2.1.4
#10 lore raw

PATCH 6/48 net/mlx4: remove useless code

In reply to Adrien Mazarguil

Less code makes refactoring easier. No impact on functionality.

---
 drivers/net/mlx4/mlx4.c | 17 +----------------
 drivers/net/mlx4/mlx4.h | 12 ------------
 2 files changed, 1 insertion(+), 28 deletions(-)
drivers/net/mlx4/mlx4.c +1 -16
index e938371..2b5527b 100644
@@ -69,13 +69,13 @@
 #include <rte_malloc.h>
 #include <rte_spinlock.h>
 #include <rte_atomic.h>
-#include <rte_version.h>
 #include <rte_log.h>
 #include <rte_alarm.h>
 #include <rte_memory.h>
 #include <rte_flow.h>
 #include <rte_kvargs.h>
 #include <rte_interrupts.h>
+#include <rte_branch_prediction.h>
 
 /* Generated configuration header. */
 #include "mlx4_autoconf.h"
@@ -4649,10 +4649,6 @@ mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	return -1;
 }
 
-static int
-mlx4_ibv_device_to_pci_addr(const struct ibv_device *device,
-			    struct rte_pci_addr *pci_addr);
-
 /**
  * DPDK callback to change the MTU.
  *
@@ -4998,10 +4994,6 @@ mlx4_dev_filter_ctrl(struct rte_eth_dev *dev,
 			return -EINVAL;
 		*(const void **)arg = &mlx4_flow_ops;
 		return 0;
-	case RTE_ETH_FILTER_FDIR:
-		DEBUG("%p: filter type FDIR is not supported by this PMD",
-		      (void *)dev);
-		break;
 	default:
 		ERROR("%p: filter type (%d) not supported",
 		      (void *)dev, filter_type);
@@ -5024,22 +5016,15 @@ static const struct eth_dev_ops mlx4_dev_ops = {
 	.link_update = mlx4_link_update,
 	.stats_get = mlx4_stats_get,
 	.stats_reset = mlx4_stats_reset,
-	.queue_stats_mapping_set = NULL,
 	.dev_infos_get = mlx4_dev_infos_get,
 	.dev_supported_ptypes_get = mlx4_dev_supported_ptypes_get,
 	.vlan_filter_set = mlx4_vlan_filter_set,
-	.vlan_tpid_set = NULL,
-	.vlan_strip_queue_set = NULL,
-	.vlan_offload_set = NULL,
 	.rx_queue_setup = mlx4_rx_queue_setup,
 	.tx_queue_setup = mlx4_tx_queue_setup,
 	.rx_queue_release = mlx4_rx_queue_release,
 	.tx_queue_release = mlx4_tx_queue_release,
-	.dev_led_on = NULL,
-	.dev_led_off = NULL,
 	.flow_ctrl_get = mlx4_dev_get_flow_ctrl,
 	.flow_ctrl_set = mlx4_dev_set_flow_ctrl,
-	.priority_flow_ctrl_set = NULL,
 	.mac_addr_remove = mlx4_mac_addr_remove,
 	.mac_addr_add = mlx4_mac_addr_add,
 	.mac_addr_set = mlx4_mac_addr_set,
drivers/net/mlx4/mlx4.h +0 -12
index 557b94d..4b42626 100644
@@ -34,7 +34,6 @@
 #ifndef RTE_PMD_MLX4_H_
 #define RTE_PMD_MLX4_H_
 
-#include <stddef.h>
 #include <stdint.h>
 #include <limits.h>
 
@@ -150,17 +149,6 @@ enum {
 /* Number of elements in array. */
 #define elemof(a) (sizeof(a) / sizeof((a)[0]))
 
-/* Cast pointer p to structure member m to its parent structure of type t. */
-#define containerof(p, t, m) ((t *)((uint8_t *)(p) - offsetof(t, m)))
-
-/* Branch prediction helpers. */
-#ifndef likely
-#define likely(c) __builtin_expect(!!(c), 1)
-#endif
-#ifndef unlikely
-#define unlikely(c) __builtin_expect(!!(c), 0)
-#endif
-
 /* Debugging */
 #ifndef NDEBUG
 #include <stdio.h>
Signature · 1 line
2.1.4
#11 lore raw

PATCH 7/48 net/mlx4: remove soft counters compilation option

In reply to Adrien Mazarguil

Software counters are mandatory since hardware counters are not implemented.

---
 config/common_base        |  1 -
 doc/guides/nics/mlx4.rst  |  6 ------
 drivers/net/mlx4/Makefile |  4 ----
 drivers/net/mlx4/mlx4.c   | 37 -------------------------------------
 drivers/net/mlx4/mlx4.h   | 12 ------------
 5 files changed, 60 deletions(-)
config/common_base +0 -1
index 7805605..d768804 100644
@@ -216,7 +216,6 @@ CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
 CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N=4
 CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE=0
 CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
-CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS=1
 
 #
 # Compile burst-oriented Mellanox ConnectX-4 & ConnectX-5 (MLX5) PMD
doc/guides/nics/mlx4.rst +0 -6
index 04788f2..729e6c1 100644
@@ -97,7 +97,6 @@ Limitations
 - RSS RETA cannot be configured
 - RSS always includes L3 (IPv4/IPv6) and L4 (UDP/TCP). They cannot be
   dissociated.
-- Hardware counters are not implemented (they are software counters).
 
 Configuration
 -------------
@@ -137,11 +136,6 @@ These options can be modified in the ``.config`` file.
 
   This value is always 1 for RX queues since they use a single MP.
 
-- ``CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS`` (default **1**)
-
-  Toggle software counters. No counters are available if this option is
-  disabled since hardware counters are not supported.
-
 Environment variables
 ~~~~~~~~~~~~~~~~~~~~~
 
drivers/net/mlx4/Makefile +0 -4
index ab2a867..2db9b10 100644
@@ -80,10 +80,6 @@ ifdef CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE
 CFLAGS += -DMLX4_PMD_TX_MP_CACHE=$(CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE)
 endif
 
-ifdef CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS
-CFLAGS += -DMLX4_PMD_SOFT_COUNTERS=$(CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS)
-endif
-
 include $(RTE_SDK)/mk/rte.lib.mk
 
 # Generate and clean-up mlx4_autoconf.h.
drivers/net/mlx4/mlx4.c +0 -37
index 2b5527b..34ef80f 100644
@@ -34,7 +34,6 @@
 /*
  * Known limitations:
  * - RSS hash key and options cannot be modified.
- * - Hardware counters aren't implemented.
  */
 
 /* System headers. */
@@ -1372,9 +1371,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		struct txq_elt *elt_next = &(*txq->elts)[elts_head_next];
 		struct txq_elt *elt = &(*txq->elts)[elts_head];
 		unsigned int segs = NB_SEGS(buf);
-#ifdef MLX4_PMD_SOFT_COUNTERS
 		unsigned int sent_size = 0;
-#endif
 		uint32_t send_flags = 0;
 
 		/* Clean up old buffer. */
@@ -1452,9 +1449,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 					 send_flags);
 			if (unlikely(err))
 				goto stop;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 			sent_size += length;
-#endif
 		} else {
 #if MLX4_PMD_SGE_WR_N > 1
 			struct ibv_sge sges[MLX4_PMD_SGE_WR_N];
@@ -1473,9 +1468,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 				 send_flags);
 			if (unlikely(err))
 				goto stop;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 			sent_size += ret.length;
-#endif
 #else /* MLX4_PMD_SGE_WR_N > 1 */
 			DEBUG("%p: TX scattered buffers support not"
 			      " compiled in", (void *)txq);
@@ -1483,19 +1476,15 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 #endif /* MLX4_PMD_SGE_WR_N > 1 */
 		}
 		elts_head = elts_head_next;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 		/* Increment sent bytes counter. */
 		txq->stats.obytes += sent_size;
-#endif
 	}
 stop:
 	/* Take a shortcut if nothing must be sent. */
 	if (unlikely(i == 0))
 		return 0;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 	/* Increment sent packets counter. */
 	txq->stats.opackets += i;
-#endif
 	/* Ring QP doorbell. */
 	err = txq->if_qp->send_flush(txq->qp);
 	if (unlikely(err)) {
@@ -2786,10 +2775,8 @@ mlx4_rx_burst_sp(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 				      " completion status (%d): %s",
 				      (void *)rxq, wc.wr_id, wc.status,
 				      ibv_wc_status_str(wc.status));
-#ifdef MLX4_PMD_SOFT_COUNTERS
 				/* Increment dropped packets counter. */
 				++rxq->stats.idropped;
-#endif
 				/* Link completed WRs together for repost. */
 				*next = wr;
 				next = &wr->next;
@@ -2901,10 +2888,8 @@ mlx4_rx_burst_sp(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		/* Return packet. */
 		*(pkts++) = pkt_buf;
 		++pkts_ret;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 		/* Increase bytes counter. */
 		rxq->stats.ibytes += pkt_buf_len;
-#endif
 repost:
 		if (++elts_head >= elts_n)
 			elts_head = 0;
@@ -2924,10 +2909,8 @@ mlx4_rx_burst_sp(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		abort();
 	}
 	rxq->elts_head = elts_head;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 	/* Increase packets counter. */
 	rxq->stats.ipackets += pkts_ret;
-#endif
 	return pkts_ret;
 }
 
@@ -3008,10 +2991,8 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 				      " completion status (%d): %s",
 				      (void *)rxq, wc.wr_id, wc.status,
 				      ibv_wc_status_str(wc.status));
-#ifdef MLX4_PMD_SOFT_COUNTERS
 				/* Increment dropped packets counter. */
 				++rxq->stats.idropped;
-#endif
 				/* Add SGE to array for repost. */
 				sges[i] = elt->sge;
 				goto repost;
@@ -3062,10 +3043,8 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		/* Return packet. */
 		*(pkts++) = seg;
 		++pkts_ret;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 		/* Increase bytes counter. */
 		rxq->stats.ibytes += len;
-#endif
 repost:
 		if (++elts_head >= elts_n)
 			elts_head = 0;
@@ -3083,10 +3062,8 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		abort();
 	}
 	rxq->elts_head = elts_head;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 	/* Increase packets counter. */
 	rxq->stats.ipackets += pkts_ret;
-#endif
 	return pkts_ret;
 }
 
@@ -4270,17 +4247,13 @@ mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 			continue;
 		idx = rxq->stats.idx;
 		if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-#ifdef MLX4_PMD_SOFT_COUNTERS
 			tmp.q_ipackets[idx] += rxq->stats.ipackets;
 			tmp.q_ibytes[idx] += rxq->stats.ibytes;
-#endif
 			tmp.q_errors[idx] += (rxq->stats.idropped +
 					      rxq->stats.rx_nombuf);
 		}
-#ifdef MLX4_PMD_SOFT_COUNTERS
 		tmp.ipackets += rxq->stats.ipackets;
 		tmp.ibytes += rxq->stats.ibytes;
-#endif
 		tmp.ierrors += rxq->stats.idropped;
 		tmp.rx_nombuf += rxq->stats.rx_nombuf;
 	}
@@ -4291,21 +4264,14 @@ mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 			continue;
 		idx = txq->stats.idx;
 		if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-#ifdef MLX4_PMD_SOFT_COUNTERS
 			tmp.q_opackets[idx] += txq->stats.opackets;
 			tmp.q_obytes[idx] += txq->stats.obytes;
-#endif
 			tmp.q_errors[idx] += txq->stats.odropped;
 		}
-#ifdef MLX4_PMD_SOFT_COUNTERS
 		tmp.opackets += txq->stats.opackets;
 		tmp.obytes += txq->stats.obytes;
-#endif
 		tmp.oerrors += txq->stats.odropped;
 	}
-#ifndef MLX4_PMD_SOFT_COUNTERS
-	/* FIXME: retrieve and add hardware counters. */
-#endif
 	*stats = tmp;
 	priv_unlock(priv);
 }
@@ -4340,9 +4306,6 @@ mlx4_stats_reset(struct rte_eth_dev *dev)
 		(*priv->txqs)[i]->stats =
 			(struct mlx4_txq_stats){ .idx = idx };
 	}
-#ifndef MLX4_PMD_SOFT_COUNTERS
-	/* FIXME: reset hardware counters. */
-#endif
 	priv_unlock(priv);
 }
 
drivers/net/mlx4/mlx4.h +0 -12
index 4b42626..b88d8b0 100644
@@ -101,14 +101,6 @@
 #define MLX4_PMD_TX_MP_CACHE 8
 #endif
 
-/*
- * If defined, only use software counters. The PMD will never ask the hardware
- * for these, and many of them won't be available.
- */
-#ifndef MLX4_PMD_SOFT_COUNTERS
-#define MLX4_PMD_SOFT_COUNTERS 1
-#endif
-
 /* Alarm timeout. */
 #define MLX4_ALARM_TIMEOUT_US 100000
 
@@ -180,10 +172,8 @@ enum {
 
 struct mlx4_rxq_stats {
 	unsigned int idx; /**< Mapping index. */
-#ifdef MLX4_PMD_SOFT_COUNTERS
 	uint64_t ipackets; /**< Total of successfully received packets. */
 	uint64_t ibytes; /**< Total of successfully received bytes. */
-#endif
 	uint64_t idropped; /**< Total of packets dropped when RX ring full. */
 	uint64_t rx_nombuf; /**< Total of RX mbuf allocation failures. */
 };
@@ -246,10 +236,8 @@ struct txq_elt {
 
 struct mlx4_txq_stats {
 	unsigned int idx; /**< Mapping index. */
-#ifdef MLX4_PMD_SOFT_COUNTERS
 	uint64_t opackets; /**< Total of successfully sent packets. */
 	uint64_t obytes;   /**< Total of successfully sent bytes. */
-#endif
 	uint64_t odropped; /**< Total of packets not sent when TX ring full. */
 };
 
Signature · 1 line
2.1.4
#12 lore raw

PATCH 8/48 net/mlx4: remove scatter mode compilation option

In reply to Adrien Mazarguil

This option both sets the maximum number of segments for Rx/Tx packets and whether scattered mode is supported at all. This commit removes the latter as well as configuration file exposure since the most appropriate value should be decided at run-time.

---
 config/common_base        |  1 -
 doc/guides/nics/mlx4.rst  |  7 -------
 drivers/net/mlx4/Makefile |  4 ----
 drivers/net/mlx4/mlx4.c   | 10 ----------
 drivers/net/mlx4/mlx4.h   |  2 --
 5 files changed, 24 deletions(-)
config/common_base +0 -1
index d768804..2520bd1 100644
@@ -213,7 +213,6 @@ CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
 #
 CONFIG_RTE_LIBRTE_MLX4_PMD=n
 CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
-CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N=4
 CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE=0
 CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
 
doc/guides/nics/mlx4.rst +0 -7
index 729e6c1..f84d56c 100644
@@ -116,13 +116,6 @@ These options can be modified in the ``.config`` file.
   adds additional run-time checks and debugging messages at the cost of
   lower performance.
 
-- ``CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N`` (default **4**)
-
-  Number of scatter/gather elements (SGEs) per work request (WR). Lowering
-  this number improves performance but also limits the ability to receive
-  scattered packets (packets that do not fit a single mbuf). The default
-  value is a safe tradeoff.
-
 - ``CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE`` (default **0**)
 
   Amount of data to be inlined during TX operations. Improves latency but
drivers/net/mlx4/Makefile +0 -4
index 2db9b10..a9c44ca 100644
@@ -68,10 +68,6 @@ else
 CFLAGS += -DNDEBUG -UPEDANTIC
 endif
 
-ifdef CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N
-CFLAGS += -DMLX4_PMD_SGE_WR_N=$(CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N)
-endif
-
 ifdef CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE
 CFLAGS += -DMLX4_PMD_MAX_INLINE=$(CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE)
 endif
drivers/net/mlx4/mlx4.c +0 -10
index 34ef80f..6dd0863 100644
@@ -1176,8 +1176,6 @@ txq_mp2mr_iter(struct rte_mempool *mp, void *arg)
 	txq_mp2mr(txq, mp);
 }
 
-#if MLX4_PMD_SGE_WR_N > 1
-
 /**
  * Copy scattered mbuf contents to a single linear buffer.
  *
@@ -1324,8 +1322,6 @@ tx_burst_sg(struct txq *txq, unsigned int segs, struct txq_elt *elt,
 	};
 }
 
-#endif /* MLX4_PMD_SGE_WR_N > 1 */
-
 /**
  * DPDK callback for TX.
  *
@@ -1451,7 +1447,6 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 				goto stop;
 			sent_size += length;
 		} else {
-#if MLX4_PMD_SGE_WR_N > 1
 			struct ibv_sge sges[MLX4_PMD_SGE_WR_N];
 			struct tx_burst_sg_ret ret;
 
@@ -1469,11 +1464,6 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			if (unlikely(err))
 				goto stop;
 			sent_size += ret.length;
-#else /* MLX4_PMD_SGE_WR_N > 1 */
-			DEBUG("%p: TX scattered buffers support not"
-			      " compiled in", (void *)txq);
-			goto stop;
-#endif /* MLX4_PMD_SGE_WR_N > 1 */
 		}
 		elts_head = elts_head_next;
 		/* Increment sent bytes counter. */
drivers/net/mlx4/mlx4.h +0 -2
index b88d8b0..785b2ac 100644
@@ -81,9 +81,7 @@
 #define MLX4_PMD_TX_PER_COMP_REQ 64
 
 /* Maximum number of Scatter/Gather Elements per Work Request. */
-#ifndef MLX4_PMD_SGE_WR_N
 #define MLX4_PMD_SGE_WR_N 4
-#endif
 
 /* Maximum size for inline data. */
 #ifndef MLX4_PMD_MAX_INLINE
Signature · 1 line
2.1.4
#13 lore raw

PATCH 9/48 net/mlx4: remove Tx inline compilation option

In reply to Adrien Mazarguil

This should be a run-time parameter.

---
 config/common_base        | 1 -
 drivers/net/mlx4/Makefile | 4 ----
 drivers/net/mlx4/mlx4.c   | 6 ------
 drivers/net/mlx4/mlx4.h   | 4 ----
 4 files changed, 15 deletions(-)
config/common_base +0 -1
index 2520bd1..b6e322c 100644
@@ -213,7 +213,6 @@ CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
 #
 CONFIG_RTE_LIBRTE_MLX4_PMD=n
 CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
-CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE=0
 CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
 
 #
drivers/net/mlx4/Makefile +0 -4
index a9c44ca..8406ba2 100644
@@ -68,10 +68,6 @@ else
 CFLAGS += -DNDEBUG -UPEDANTIC
 endif
 
-ifdef CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE
-CFLAGS += -DMLX4_PMD_MAX_INLINE=$(CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE)
-endif
-
 ifdef CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE
 CFLAGS += -DMLX4_PMD_TX_MP_CACHE=$(CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE)
 endif
drivers/net/mlx4/mlx4.c +0 -6
index 6dd0863..d00ddc6 100644
@@ -1428,7 +1428,6 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 					      (uintptr_t)addr);
 			RTE_MBUF_PREFETCH_TO_FREE(elt_next->buf);
 			/* Put packet into send queue. */
-#if MLX4_PMD_MAX_INLINE > 0
 			if (length <= txq->max_inline)
 				err = txq->if_qp->send_pending_inline
 					(txq->qp,
@@ -1436,7 +1435,6 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 					 length,
 					 send_flags);
 			else
-#endif
 				err = txq->if_qp->send_pending
 					(txq->qp,
 					 addr,
@@ -1578,9 +1576,7 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 					  MLX4_PMD_SGE_WR_N) ?
 					 priv->device_attr.max_sge :
 					 MLX4_PMD_SGE_WR_N),
-#if MLX4_PMD_MAX_INLINE > 0
 			.max_inline_data = MLX4_PMD_MAX_INLINE,
-#endif
 		},
 		.qp_type = IBV_QPT_RAW_PACKET,
 		/* Do *NOT* enable this, completions events are managed per
@@ -1598,10 +1594,8 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		      (void *)dev, strerror(ret));
 		goto error;
 	}
-#if MLX4_PMD_MAX_INLINE > 0
 	/* ibv_create_qp() updates this value. */
 	tmpl.max_inline = attr.init.cap.max_inline_data;
-#endif
 	attr.mod = (struct ibv_exp_qp_attr){
 		/* Move the QP to this state. */
 		.qp_state = IBV_QPS_INIT,
drivers/net/mlx4/mlx4.h +0 -4
index 785b2ac..469ab4b 100644
@@ -84,9 +84,7 @@
 #define MLX4_PMD_SGE_WR_N 4
 
 /* Maximum size for inline data. */
-#ifndef MLX4_PMD_MAX_INLINE
 #define MLX4_PMD_MAX_INLINE 0
-#endif
 
 /*
  * Maximum number of cached Memory Pools (MPs) per TX queue. Each RTE MP
@@ -261,9 +259,7 @@ struct txq {
 	struct ibv_qp *qp; /* Queue Pair. */
 	struct ibv_exp_qp_burst_family *if_qp; /* QP burst interface. */
 	struct ibv_exp_cq_family *if_cq; /* CQ interface. */
-#if MLX4_PMD_MAX_INLINE > 0
 	uint32_t max_inline; /* Max inline send size <= MLX4_PMD_MAX_INLINE. */
-#endif
 	unsigned int elts_n; /* (*elts)[] length. */
 	struct txq_elt (*elts)[]; /* TX elements. */
 	unsigned int elts_head; /* Current index in (*elts)[]. */
Signature · 1 line
2.1.4
#14 lore raw

PATCH 10/48 net/mlx4: remove allmulti and promisc support

In reply to Adrien Mazarguil

This is done in preparation for a major refactoring.

---
 doc/guides/nics/features/mlx4.ini |   2 -
 doc/guides/nics/mlx4.rst          |   2 -
 drivers/net/mlx4/mlx4.c           | 311 ---------------------------------
 drivers/net/mlx4/mlx4.h           |   4 -
 4 files changed, 319 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -2
index f6efd21..344731f 100644
@@ -13,8 +13,6 @@ Queue start/stop     = Y
 MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
-Promiscuous mode     = Y
-Allmulticast mode    = Y
 Unicast MAC filter   = Y
 Multicast MAC filter = Y
 RSS hash             = Y
doc/guides/nics/mlx4.rst +0 -2
index f84d56c..9559261 100644
@@ -82,8 +82,6 @@ Features
   configured RX queues must be a power of two.
 - VLAN filtering is supported.
 - Link state information is provided.
-- Promiscuous mode is supported.
-- All multicast mode is supported.
 - Multiple MAC addresses (unicast, multicast) can be configured.
 - Scattered packets are supported for TX and RX.
 - Inner L3/L4 (IP, TCP and UDP) TX/RX checksum offloading and validation.
drivers/net/mlx4/mlx4.c +0 -311

380 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +0 -4
index 469ab4b..35c9549 100644
@@ -204,8 +204,6 @@ struct rxq {
 	 */
 	BITFIELD_DECLARE(mac_configured, uint32_t, MLX4_MAX_MAC_ADDRESSES);
 	struct ibv_flow *mac_flow[MLX4_MAX_MAC_ADDRESSES][MLX4_MAX_VLAN_IDS];
-	struct ibv_flow *promisc_flow; /* Promiscuous flow. */
-	struct ibv_flow *allmulti_flow; /* Multicast flow. */
 	unsigned int port_id; /* Port ID for incoming packets. */
 	unsigned int elts_n; /* (*elts)[] length. */
 	unsigned int elts_head; /* Current index in (*elts)[]. */
@@ -297,8 +295,6 @@ struct priv {
 	uint16_t mtu; /* Configured MTU. */
 	uint8_t port; /* Physical port number. */
 	unsigned int started:1; /* Device started, flows enabled. */
-	unsigned int promisc:1; /* Device in promiscuous mode. */
-	unsigned int allmulti:1; /* Device receives all multicast packets. */
 	unsigned int hw_qpg:1; /* QP groups are supported. */
 	unsigned int hw_tss:1; /* TSS is supported. */
 	unsigned int hw_rss:1; /* RSS is supported. */
Signature · 1 line
2.1.4
#15 lore raw

PATCH 11/48 net/mlx4: remove VLAN filter support

In reply to Adrien Mazarguil

This is done in preparation for a major refactoring.

---
 doc/guides/nics/features/mlx4.ini |   1 -
 doc/guides/nics/mlx4.rst          |   1 -
 drivers/net/mlx4/mlx4.c           | 206 +++------------------------------
 drivers/net/mlx4/mlx4.h           |  13 +--
 4 files changed, 17 insertions(+), 204 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -1
index 344731f..bfa6948 100644
@@ -17,7 +17,6 @@ Unicast MAC filter   = Y
 Multicast MAC filter = Y
 RSS hash             = Y
 SR-IOV               = Y
-VLAN filter          = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
 Inner L3 checksum    = Y
doc/guides/nics/mlx4.rst +0 -1
index 9559261..9ab8da9 100644
@@ -80,7 +80,6 @@ Features
 - Multi arch support: x86_64 and POWER8.
 - RSS, also known as RCA, is supported. In this mode the number of
   configured RX queues must be a power of two.
-- VLAN filtering is supported.
 - Link state information is provided.
 - Multiple MAC addresses (unicast, multicast) can be configured.
 - Scattered packets are supported for TX and RX.
drivers/net/mlx4/mlx4.c +16 -190

295 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +1 -12
index 35c9549..6b2c83b 100644
@@ -74,9 +74,6 @@
  */
 #define MLX4_MAX_MAC_ADDRESSES 128
 
-/* Maximum number of simultaneous VLAN filters supported. See above. */
-#define MLX4_MAX_VLAN_IDS 127
-
 /* Request send completion once in every 64 sends, might be less. */
 #define MLX4_PMD_TX_PER_COMP_REQ 64
 
@@ -199,11 +196,8 @@ struct rxq {
 	struct ibv_exp_qp_burst_family *if_qp; /* QP burst interface. */
 	struct ibv_exp_cq_family *if_cq; /* CQ interface. */
 	struct ibv_comp_channel *channel;
-	/*
-	 * Each VLAN ID requires a separate flow steering rule.
-	 */
 	BITFIELD_DECLARE(mac_configured, uint32_t, MLX4_MAX_MAC_ADDRESSES);
-	struct ibv_flow *mac_flow[MLX4_MAX_MAC_ADDRESSES][MLX4_MAX_VLAN_IDS];
+	struct ibv_flow *mac_flow[MLX4_MAX_MAC_ADDRESSES];
 	unsigned int port_id; /* Port ID for incoming packets. */
 	unsigned int elts_n; /* (*elts)[] length. */
 	unsigned int elts_head; /* Current index in (*elts)[]. */
@@ -286,11 +280,6 @@ struct priv {
 	 */
 	struct ether_addr mac[MLX4_MAX_MAC_ADDRESSES];
 	BITFIELD_DECLARE(mac_configured, uint32_t, MLX4_MAX_MAC_ADDRESSES);
-	/* VLAN filters. */
-	struct {
-		unsigned int enabled:1; /* If enabled. */
-		unsigned int id:12; /* VLAN ID (0-4095). */
-	} vlan_filter[MLX4_MAX_VLAN_IDS]; /* VLAN filters table. */
 	/* Device properties. */
 	uint16_t mtu; /* Configured MTU. */
 	uint8_t port; /* Physical port number. */
Signature · 1 line
2.1.4
#16 lore raw

PATCH 12/48 net/mlx4: remove MAC address configuration support

In reply to Adrien Mazarguil

Only the default port MAC address remains and is not configurable. This is done in preparation for a major refactoring.

---
 doc/guides/nics/features/mlx4.ini |   2 -
 doc/guides/nics/mlx4.rst          |   1 -
 drivers/net/mlx4/mlx4.c           | 322 ++++-----------------------------
 drivers/net/mlx4/mlx4.h           |  41 +----
 4 files changed, 39 insertions(+), 327 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -2
index bfa6948..3acf8d3 100644
@@ -13,8 +13,6 @@ Queue start/stop     = Y
 MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
-Unicast MAC filter   = Y
-Multicast MAC filter = Y
 RSS hash             = Y
 SR-IOV               = Y
 L3 checksum offload  = Y
doc/guides/nics/mlx4.rst +0 -1
index 9ab8da9..235912a 100644
@@ -81,7 +81,6 @@ Features
 - RSS, also known as RCA, is supported. In this mode the number of
   configured RX queues must be a power of two.
 - Link state information is provided.
-- Multiple MAC addresses (unicast, multicast) can be configured.
 - Scattered packets are supported for TX and RX.
 - Inner L3/L4 (IP, TCP and UDP) TX/RX checksum offloading and validation.
 - Outer L3 (IP) TX/RX checksum offloading and validation for VXLAN frames.
drivers/net/mlx4/mlx4.c +37 -285

506 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +2 -39

71 lines not on this page · raw message

Signature · 1 line
2.1.4
#17 lore raw

PATCH 13/48 net/mlx4: drop MAC flows affecting all Rx queues

In reply to Adrien Mazarguil

Configuring several Rx queues enables RSS, which causes an additional special parent queue to be created to manage them.

MAC flows are associated with the queue supposed to receive packets; either the parent one in case of RSS or the single orphan otherwise.

For historical reasons the current implementation supports another scenario with multiple orphans, in which case MAC flows are configured on all of them. This is harmless but useless since it cannot happen.

Removing this feature allows dissociating the remaining MAC flow from Rx queues and store it inside the private structure where it belongs.

---
 drivers/net/mlx4/mlx4.c | 215 +++++++++++--------------------------------
 drivers/net/mlx4/mlx4.h |   2 +-
 2 files changed, 57 insertions(+), 160 deletions(-)
drivers/net/mlx4/mlx4.c +56 -159
index dd42c96..c11e789 100644
@@ -515,6 +515,9 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 static void
 rxq_cleanup(struct rxq *rxq);
 
+static void
+priv_mac_addr_del(struct priv *priv);
+
 /**
  * Create RSS parent queue.
  *
@@ -641,6 +644,7 @@ dev_configure(struct rte_eth_dev *dev)
 		for (i = 0; (i != priv->rxqs_n); ++i)
 			if ((*priv->rxqs)[i] != NULL)
 				return EINVAL;
+		priv_mac_addr_del(priv);
 		priv_parent_list_cleanup(priv);
 		priv->rss = 0;
 		priv->rxqs_n = 0;
@@ -2065,46 +2069,57 @@ rxq_free_elts(struct rxq *rxq)
 }
 
 /**
- * Unregister a MAC address from a RX queue.
+ * Unregister a MAC address.
  *
- * @param rxq
- *   Pointer to RX queue structure.
+ * @param priv
+ *   Pointer to private structure.
  */
 static void
-rxq_mac_addr_del(struct rxq *rxq)
+priv_mac_addr_del(struct priv *priv)
 {
 #ifndef NDEBUG
-	struct priv *priv = rxq->priv;
-	const uint8_t (*mac)[ETHER_ADDR_LEN] =
-		(const uint8_t (*)[ETHER_ADDR_LEN])
-		priv->mac.addr_bytes;
+	uint8_t (*mac)[ETHER_ADDR_LEN] = &priv->mac.addr_bytes;
 #endif
-	if (!rxq->mac_flow)
+
+	if (!priv->mac_flow)
 		return;
 	DEBUG("%p: removing MAC address %02x:%02x:%02x:%02x:%02x:%02x",
-	      (void *)rxq,
+	      (void *)priv,
 	      (*mac)[0], (*mac)[1], (*mac)[2], (*mac)[3], (*mac)[4], (*mac)[5]);
-	claim_zero(ibv_destroy_flow(rxq->mac_flow));
-	rxq->mac_flow = NULL;
+	claim_zero(ibv_destroy_flow(priv->mac_flow));
+	priv->mac_flow = NULL;
 }
 
 /**
- * Register a MAC address in a RX queue.
+ * Register a MAC address.
  *
- * @param rxq
- *   Pointer to RX queue structure.
+ * In RSS mode, the MAC address is registered in the parent queue,
+ * otherwise it is registered in queue 0.
+ *
+ * @param priv
+ *   Pointer to private structure.
  *
  * @return
  *   0 on success, errno value on failure.
  */
 static int
-rxq_mac_addr_add(struct rxq *rxq)
+priv_mac_addr_add(struct priv *priv)
 {
+	uint8_t (*mac)[ETHER_ADDR_LEN] = &priv->mac.addr_bytes;
+	struct rxq *rxq;
 	struct ibv_flow *flow;
-	struct priv *priv = rxq->priv;
-	const uint8_t (*mac)[ETHER_ADDR_LEN] =
-			(const uint8_t (*)[ETHER_ADDR_LEN])
-			priv->mac.addr_bytes;
+
+	/* If device isn't started, this is all we need to do. */
+	if (!priv->started)
+		return 0;
+	if (priv->isolated)
+		return 0;
+	if (priv->rss)
+		rxq = LIST_FIRST(&priv->parents);
+	else if (*priv->rxqs && (*priv->rxqs)[0])
+		rxq = (*priv->rxqs)[0];
+	else
+		return 0;
 
 	/* Allocate flow specification on the stack. */
 	struct __attribute__((packed)) {
@@ -2114,8 +2129,8 @@ rxq_mac_addr_add(struct rxq *rxq)
 	struct ibv_flow_attr *attr = &data.attr;
 	struct ibv_flow_spec_eth *spec = &data.spec;
 
-	if (rxq->mac_flow)
-		rxq_mac_addr_del(rxq);
+	if (priv->mac_flow)
+		priv_mac_addr_del(priv);
 	/*
 	 * No padding must be inserted by the compiler between attr and spec.
 	 * This layout is expected by libibverbs.
@@ -2142,7 +2157,7 @@ rxq_mac_addr_add(struct rxq *rxq)
 		}
 	};
 	DEBUG("%p: adding MAC address %02x:%02x:%02x:%02x:%02x:%02x",
-	      (void *)rxq,
+	      (void *)priv,
 	      (*mac)[0], (*mac)[1], (*mac)[2], (*mac)[3], (*mac)[4], (*mac)[5]);
 	/* Create related flow. */
 	errno = 0;
@@ -2156,60 +2171,8 @@ rxq_mac_addr_add(struct rxq *rxq)
 			return errno;
 		return EINVAL;
 	}
-	assert(rxq->mac_flow == NULL);
-	rxq->mac_flow = flow;
-	return 0;
-}
-
-/**
- * Register a MAC address.
- *
- * In RSS mode, the MAC address is registered in the parent queue,
- * otherwise it is registered in each queue directly.
- *
- * @param priv
- *   Pointer to private structure.
- * @param mac
- *   MAC address to register.
- *
- * @return
- *   0 on success, errno value on failure.
- */
-static int
-priv_mac_addr_add(struct priv *priv, const uint8_t (*mac)[ETHER_ADDR_LEN])
-{
-	unsigned int i;
-	int ret;
-
-	priv->mac = (struct ether_addr){
-		{
-			(*mac)[0], (*mac)[1], (*mac)[2],
-			(*mac)[3], (*mac)[4], (*mac)[5]
-		}
-	};
-	/* If device isn't started, this is all we need to do. */
-	if (!priv->started) {
-		goto end;
-	}
-	if (priv->rss) {
-		ret = rxq_mac_addr_add(LIST_FIRST(&priv->parents));
-		if (ret)
-			return ret;
-		goto end;
-	}
-	for (i = 0; (i != priv->rxqs_n); ++i) {
-		if ((*priv->rxqs)[i] == NULL)
-			continue;
-		ret = rxq_mac_addr_add((*priv->rxqs)[i]);
-		if (!ret)
-			continue;
-		/* Failure, rollback. */
-		while (i != 0)
-			if ((*priv->rxqs)[(--i)] != NULL)
-				rxq_mac_addr_del((*priv->rxqs)[i]);
-		return ret;
-	}
-end:
+	assert(priv->mac_flow == NULL);
+	priv->mac_flow = flow;
 	return 0;
 }
 
@@ -2253,9 +2216,6 @@ rxq_cleanup(struct rxq *rxq)
 						rxq->if_cq,
 						&params));
 	}
-	if (rxq->qp != NULL && !rxq->priv->isolated) {
-		rxq_mac_addr_del(rxq);
-	}
 	if (rxq->qp != NULL)
 		claim_zero(ibv_destroy_qp(rxq->qp));
 	if (rxq->cq != NULL)
@@ -2894,12 +2854,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 		DEBUG("%p: nothing to do", (void *)dev);
 		return 0;
 	}
-	/* Remove attached flows if RSS is disabled (no parent queue). */
-	if (!priv->rss && !priv->isolated) {
-		rxq_mac_addr_del(&tmpl);
-		/* Update original queue in case of failure. */
-		rxq->mac_flow = NULL;
-	}
 	/* From now on, any failure will render the queue unusable.
 	 * Reinitialize QP. */
 	if (!tmpl.qp)
@@ -2933,12 +2887,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 		assert(err > 0);
 		return err;
 	}
-	/* Reconfigure flows. Do not care for errors. */
-	if (!priv->rss && !priv->isolated) {
-		rxq_mac_addr_add(&tmpl);
-		/* Update original queue in case of failure. */
-		rxq->mac_flow = NULL;
-	}
 	/* Allocate pool. */
 	pool = rte_malloc(__func__, (mbuf_n * sizeof(*pool)), 0);
 	if (pool == NULL) {
@@ -3081,15 +3029,6 @@ rxq_create_qp(struct rxq *rxq,
 		      strerror(ret));
 		return ret;
 	}
-	if (!priv->isolated && (parent || !priv->rss)) {
-		/* Configure MAC and broadcast addresses. */
-		ret = rxq_mac_addr_add(rxq);
-		if (ret) {
-			ERROR("QP flow attachment failed: %s",
-			      strerror(ret));
-			return ret;
-		}
-	}
 	if (!parent) {
 		ret = ibv_post_recv(rxq->qp,
 				    (rxq->sp ?
@@ -3359,6 +3298,8 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 			return -EEXIST;
 		}
 		(*priv->rxqs)[idx] = NULL;
+		if (idx == 0)
+			priv_mac_addr_del(priv);
 		rxq_cleanup(rxq);
 	} else {
 		rxq = rte_calloc_socket("RXQ", 1, sizeof(*rxq), 0, socket);
@@ -3418,6 +3359,8 @@ mlx4_rx_queue_release(void *dpdk_rxq)
 			DEBUG("%p: removing RX queue %p from list",
 			      (void *)priv->dev, (void *)rxq);
 			(*priv->rxqs)[i] = NULL;
+			if (i == 0)
+				priv_mac_addr_del(priv);
 			break;
 		}
 	rxq_cleanup(rxq);
@@ -3449,9 +3392,6 @@ static int
 mlx4_dev_start(struct rte_eth_dev *dev)
 {
 	struct priv *priv = dev->data->dev_private;
-	unsigned int i = 0;
-	unsigned int r;
-	struct rxq *rxq;
 	int ret;
 
 	priv_lock(priv);
@@ -3461,28 +3401,9 @@ mlx4_dev_start(struct rte_eth_dev *dev)
 	}
 	DEBUG("%p: attaching configured flows to all RX queues", (void *)dev);
 	priv->started = 1;
-	if (priv->isolated) {
-		rxq = NULL;
-		r = 1;
-	} else if (priv->rss) {
-		rxq = LIST_FIRST(&priv->parents);
-		r = 1;
-	} else {
-		rxq = (*priv->rxqs)[0];
-		r = priv->rxqs_n;
-	}
-	/* Iterate only once when RSS is enabled. */
-	do {
-		/* Ignore nonexistent RX queues. */
-		if (rxq == NULL)
-			continue;
-		ret = rxq_mac_addr_add(rxq);
-		if (!ret)
-			continue;
-		WARN("%p: QP flow attachment failed: %s",
-		     (void *)dev, strerror(ret));
+	ret = priv_mac_addr_add(priv);
+	if (ret)
 		goto err;
-	} while ((--r) && ((rxq = (*priv->rxqs)[++i]), i));
 	ret = priv_dev_link_interrupt_handler_install(priv, dev);
 	if (ret) {
 		ERROR("%p: LSC handler install failed",
@@ -3511,12 +3432,7 @@ mlx4_dev_start(struct rte_eth_dev *dev)
 	return 0;
 err:
 	/* Rollback. */
-	while (i != 0) {
-		rxq = (*priv->rxqs)[i--];
-		if (rxq != NULL) {
-			rxq_mac_addr_del(rxq);
-		}
-	}
+	priv_mac_addr_del(priv);
 	priv->started = 0;
 	priv_unlock(priv);
 	return -ret;
@@ -3534,9 +3450,6 @@ static void
 mlx4_dev_stop(struct rte_eth_dev *dev)
 {
 	struct priv *priv = dev->data->dev_private;
-	unsigned int i = 0;
-	unsigned int r;
-	struct rxq *rxq;
 
 	priv_lock(priv);
 	if (!priv->started) {
@@ -3545,24 +3458,8 @@ mlx4_dev_stop(struct rte_eth_dev *dev)
 	}
 	DEBUG("%p: detaching flows from all RX queues", (void *)dev);
 	priv->started = 0;
-	if (priv->isolated) {
-		rxq = NULL;
-		r = 1;
-	} else if (priv->rss) {
-		rxq = LIST_FIRST(&priv->parents);
-		r = 1;
-	} else {
-		rxq = (*priv->rxqs)[0];
-		r = priv->rxqs_n;
-	}
 	mlx4_priv_flow_stop(priv);
-	/* Iterate only once when RSS is enabled. */
-	do {
-		/* Ignore nonexistent RX queues. */
-		if (rxq == NULL)
-			continue;
-		rxq_mac_addr_del(rxq);
-	} while ((--r) && ((rxq = (*priv->rxqs)[++i]), i));
+	priv_mac_addr_del(priv);
 	priv_unlock(priv);
 }
 
@@ -3647,6 +3544,7 @@ mlx4_dev_close(struct rte_eth_dev *dev)
 	DEBUG("%p: closing device \"%s\"",
 	      (void *)dev,
 	      ((priv->ctx != NULL) ? priv->ctx->device->name : ""));
+	priv_mac_addr_del(priv);
 	/* Prevent crashes when queues are still in use. This is unfortunately
 	 * still required for DPDK 1.3 because some programs (such as testpmd)
 	 * never release them before closing the device. */
@@ -4036,6 +3934,8 @@ mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	} else
 		DEBUG("adapter port %u MTU set to %u", priv->port, mtu);
 	priv->mtu = mtu;
+	/* Remove MAC flow. */
+	priv_mac_addr_del(priv);
 	/* Temporarily replace RX handler with a fake one, assuming it has not
 	 * been copied elsewhere. */
 	dev->rx_pkt_burst = removed_rx_burst;
@@ -4064,11 +3964,6 @@ mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 				rx_func = mlx4_rx_burst_sp;
 			break;
 		}
-		/* Reenable non-RSS queue attributes. No need to check
-		 * for errors at this stage. */
-		if (!priv->rss && !priv->isolated) {
-			rxq_mac_addr_add(rxq);
-		}
 		/* Scattered burst function takes priority. */
 		if (rxq->sp)
 			rx_func = mlx4_rx_burst_sp;
@@ -4076,6 +3971,8 @@ mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	/* Burst functions can now be called again. */
 	rte_wmb();
 	dev->rx_pkt_burst = rx_func;
+	/* Restore MAC flow. */
+	ret = priv_mac_addr_add(priv);
 out:
 	priv_unlock(priv);
 	assert(ret >= 0);
@@ -5125,9 +5022,9 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		     mac.addr_bytes[2], mac.addr_bytes[3],
 		     mac.addr_bytes[4], mac.addr_bytes[5]);
 		/* Register MAC address. */
-		claim_zero(priv_mac_addr_add(priv,
-					     (const uint8_t (*)[ETHER_ADDR_LEN])
-					     mac.addr_bytes));
+		priv->mac = mac;
+		if (priv_mac_addr_add(priv))
+			goto port_error;
 #ifndef NDEBUG
 		{
 			char ifname[IF_NAMESIZE];
drivers/net/mlx4/mlx4.h +1 -1
index addc2d5..23ffc87 100644
@@ -166,7 +166,6 @@ struct rxq {
 	struct ibv_exp_qp_burst_family *if_qp; /* QP burst interface. */
 	struct ibv_exp_cq_family *if_cq; /* CQ interface. */
 	struct ibv_comp_channel *channel;
-	struct ibv_flow *mac_flow; /* Flow associated with MAC address. */
 	unsigned int port_id; /* Port ID for incoming packets. */
 	unsigned int elts_n; /* (*elts)[] length. */
 	unsigned int elts_head; /* Current index in (*elts)[]. */
@@ -243,6 +242,7 @@ struct priv {
 	struct ibv_device_attr device_attr; /* Device properties. */
 	struct ibv_pd *pd; /* Protection Domain. */
 	struct ether_addr mac; /* MAC address. */
+	struct ibv_flow *mac_flow; /* Flow associated with MAC address. */
 	/* Device properties. */
 	uint16_t mtu; /* Configured MTU. */
 	uint8_t port; /* Physical port number. */
Signature · 1 line
2.1.4
#18 lore raw

PATCH 14/48 net/mlx4: revert flow API RSS support

In reply to Adrien Mazarguil

This reverts commit d7769c7c08cc08a9d1bc4e40b95524d9697707d9.

Existing RSS features rely on experimental Verbs provided by Mellanox OFED.

In order to replace this dependency with standard distribution packages, RSS support must be temporarily removed to be re-implemented using a different API.

Removing support for the RSS flow rule action is the first step toward this goal.

---
 drivers/net/mlx4/mlx4.c      |   6 +-
 drivers/net/mlx4/mlx4.h      |   5 -
 drivers/net/mlx4/mlx4_flow.c | 206 +++-----------------------------------
 drivers/net/mlx4/mlx4_flow.h |   3 +-
 4 files changed, 20 insertions(+), 200 deletions(-)
drivers/net/mlx4/mlx4.c +4 -2
index c11e789..4aef6a3 100644
@@ -533,7 +533,7 @@ priv_mac_addr_del(struct priv *priv);
  * @return
  *   Pointer to a parent rxq structure, NULL on failure.
  */
-struct rxq *
+static struct rxq *
 priv_parent_create(struct priv *priv,
 		   uint16_t queues[],
 		   uint16_t children_n)
@@ -670,8 +670,10 @@ dev_configure(struct rte_eth_dev *dev)
 	priv->rss = 1;
 	tmp = priv->rxqs_n;
 	priv->rxqs_n = rxqs_n;
-	if (priv->isolated)
+	if (priv->isolated) {
+		priv->rss = 0;
 		return 0;
+	}
 	if (priv_parent_create(priv, NULL, priv->rxqs_n))
 		return 0;
 	/* Failure, rollback. */
drivers/net/mlx4/mlx4.h +0 -5
index 23ffc87..301b193 100644
@@ -285,9 +285,4 @@ rxq_create_qp(struct rxq *rxq,
 void
 rxq_parent_cleanup(struct rxq *parent);
 
-struct rxq *
-priv_parent_create(struct priv *priv,
-		   uint16_t queues[],
-		   uint16_t children_n);
-
 #endif /* RTE_PMD_MLX4_H_ */
drivers/net/mlx4/mlx4_flow.c +15 -191

255 lines not on this page · raw message

drivers/net/mlx4/mlx4_flow.h +1 -2
index 4654dc2..17e5f6e 100644
@@ -98,8 +98,7 @@ mlx4_flow_isolate(struct rte_eth_dev *dev,
 struct mlx4_flow_action {
 	uint32_t drop:1; /**< Target is a drop queue. */
 	uint32_t queue:1; /**< Target is a receive queue. */
-	uint16_t queues[RTE_MAX_QUEUES_PER_PORT]; /**< Queue indices to use. */
-	uint16_t queues_n; /**< Number of entries in queue[] */
+	uint32_t queue_id; /**< Identifier of the queue. */
 };
 
 int mlx4_priv_flow_start(struct priv *priv);
Signature · 1 line
2.1.4
#19 lore raw

PATCH 15/48 net/mlx4: revert RSS parent queue refactoring

In reply to Adrien Mazarguil

This reverts commit ff00a0dc5600dbb0a29e4aa7fa4b078f98c7a360.

Support for several RSS parent queues was necessary to implement the RSS flow rule action, dropped in a prior commit.

---
 drivers/net/mlx4/mlx4.c      | 332 +++++++++++---------------------------
 drivers/net/mlx4/mlx4.h      |  17 +-
 drivers/net/mlx4/mlx4_flow.c |  15 --
 3 files changed, 97 insertions(+), 267 deletions(-)
drivers/net/mlx4/mlx4.c +96 -236
index 4aef6a3..42438a2 100644
@@ -507,10 +507,8 @@ txq_cleanup(struct txq *txq);
 
 static int
 rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
-	  unsigned int socket, int inactive,
-	  const struct rte_eth_rxconf *conf,
-	  struct rte_mempool *mp, int children_n,
-	  struct rxq *rxq_parent);
+	  unsigned int socket, int inactive, const struct rte_eth_rxconf *conf,
+	  struct rte_mempool *mp);
 
 static void
 rxq_cleanup(struct rxq *rxq);
@@ -519,84 +517,6 @@ static void
 priv_mac_addr_del(struct priv *priv);
 
 /**
- * Create RSS parent queue.
- *
- * The new parent is inserted in front of the list in the private structure.
- *
- * @param priv
- *   Pointer to private structure.
- * @param queues
- *   Queues indices array, if NULL use all Rx queues.
- * @param children_n
- *   The number of entries in queues[].
- *
- * @return
- *   Pointer to a parent rxq structure, NULL on failure.
- */
-static struct rxq *
-priv_parent_create(struct priv *priv,
-		   uint16_t queues[],
-		   uint16_t children_n)
-{
-	int ret;
-	uint16_t i;
-	struct rxq *parent;
-
-	parent = rte_zmalloc("parent queue",
-			     sizeof(*parent),
-			     RTE_CACHE_LINE_SIZE);
-	if (!parent) {
-		ERROR("cannot allocate memory for RSS parent queue");
-		return NULL;
-	}
-	ret = rxq_setup(priv->dev, parent, 0, 0, 0,
-			NULL, NULL, children_n, NULL);
-	if (ret) {
-		rte_free(parent);
-		return NULL;
-	}
-	parent->rss.queues_n = children_n;
-	if (queues) {
-		for (i = 0; i < children_n; ++i)
-			parent->rss.queues[i] = queues[i];
-	} else {
-		/* the default RSS ring case */
-		assert(priv->rxqs_n == children_n);
-		for (i = 0; i < priv->rxqs_n; ++i)
-			parent->rss.queues[i] = i;
-	}
-	LIST_INSERT_HEAD(&priv->parents, parent, next);
-	return parent;
-}
-
-/**
- * Clean up RX queue parent structure.
- *
- * @param parent
- *   RX queue parent structure.
- */
-void
-rxq_parent_cleanup(struct rxq *parent)
-{
-	LIST_REMOVE(parent, next);
-	rxq_cleanup(parent);
-	rte_free(parent);
-}
-
-/**
- * Clean up parent structures from the parent list.
- *
- * @param priv
- *   Pointer to private structure.
- */
-static void
-priv_parent_list_cleanup(struct priv *priv)
-{
-	while (!LIST_EMPTY(&priv->parents))
-		rxq_parent_cleanup(LIST_FIRST(&priv->parents));
-}
-
-/**
  * Ethernet device configuration.
  *
  * Prepare the driver for a given number of TX and RX queues.
@@ -615,6 +535,7 @@ dev_configure(struct rte_eth_dev *dev)
 	unsigned int rxqs_n = dev->data->nb_rx_queues;
 	unsigned int txqs_n = dev->data->nb_tx_queues;
 	unsigned int tmp;
+	int ret;
 
 	priv->rxqs = (void *)dev->data->rx_queues;
 	priv->txqs = (void *)dev->data->tx_queues;
@@ -645,7 +566,7 @@ dev_configure(struct rte_eth_dev *dev)
 			if ((*priv->rxqs)[i] != NULL)
 				return EINVAL;
 		priv_mac_addr_del(priv);
-		priv_parent_list_cleanup(priv);
+		rxq_cleanup(&priv->rxq_parent);
 		priv->rss = 0;
 		priv->rxqs_n = 0;
 	}
@@ -670,16 +591,14 @@ dev_configure(struct rte_eth_dev *dev)
 	priv->rss = 1;
 	tmp = priv->rxqs_n;
 	priv->rxqs_n = rxqs_n;
-	if (priv->isolated) {
-		priv->rss = 0;
-		return 0;
-	}
-	if (priv_parent_create(priv, NULL, priv->rxqs_n))
+	ret = rxq_setup(dev, &priv->rxq_parent, 0, 0, 0, NULL, NULL);
+	if (!ret)
 		return 0;
 	/* Failure, rollback. */
 	priv->rss = 0;
 	priv->rxqs_n = tmp;
-	return ENOMEM;
+	assert(ret > 0);
+	return ret;
 }
 
 /**
@@ -2117,7 +2036,7 @@ priv_mac_addr_add(struct priv *priv)
 	if (priv->isolated)
 		return 0;
 	if (priv->rss)
-		rxq = LIST_FIRST(&priv->parents);
+		rxq = &priv->rxq_parent;
 	else if (*priv->rxqs && (*priv->rxqs)[0])
 		rxq = (*priv->rxqs)[0];
 	else
@@ -2743,18 +2662,15 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
  *   Completion queue to associate with QP.
  * @param desc
  *   Number of descriptors in QP (hint only).
- * @param children_n
- *   If nonzero, a number of children for parent QP and zero for a child.
- * @param rxq_parent
- *   Pointer for a parent in a child case, NULL otherwise.
+ * @param parent
+ *   If nonzero, create a parent QP, otherwise a child.
  *
  * @return
  *   QP pointer or NULL in case of error.
  */
 static struct ibv_qp *
 rxq_setup_qp_rss(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
-		 int children_n, struct ibv_exp_res_domain *rd,
-		 struct rxq *rxq_parent)
+		 int parent, struct ibv_exp_res_domain *rd)
 {
 	struct ibv_exp_qp_init_attr attr = {
 		/* CQ to be associated with the send queue. */
@@ -2782,16 +2698,16 @@ rxq_setup_qp_rss(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
 
 	attr.max_inl_recv = priv->inl_recv_size,
 	attr.comp_mask |= IBV_EXP_QP_INIT_ATTR_INL_RECV;
-	if (children_n > 0) {
+	if (parent) {
 		attr.qpg.qpg_type = IBV_EXP_QPG_PARENT;
 		/* TSS isn't necessary. */
 		attr.qpg.parent_attrib.tss_child_count = 0;
 		attr.qpg.parent_attrib.rss_child_count =
-			rte_align32pow2(children_n + 1) >> 1;
+			rte_align32pow2(priv->rxqs_n + 1) >> 1;
 		DEBUG("initializing parent RSS queue");
 	} else {
 		attr.qpg.qpg_type = IBV_EXP_QPG_CHILD_RX;
-		attr.qpg.qpg_parent = rxq_parent->qp;
+		attr.qpg.qpg_parent = priv->rxq_parent.qp;
 		DEBUG("initializing child RSS queue");
 	}
 	return ibv_exp_create_qp(priv->ctx, &attr);
@@ -2825,7 +2741,13 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 	struct ibv_recv_wr *bad_wr;
 	unsigned int mb_len;
 	int err;
+	int parent = (rxq == &priv->rxq_parent);
 
+	if (parent) {
+		ERROR("%p: cannot rehash parent queue %p",
+		      (void *)dev, (void *)rxq);
+		return EINVAL;
+	}
 	mb_len = rte_pktmbuf_data_room_size(rxq->mp);
 	DEBUG("%p: rehashing queue %p", (void *)dev, (void *)rxq);
 	/* Number of descriptors and mbufs currently allocated. */
@@ -2858,8 +2780,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 	}
 	/* From now on, any failure will render the queue unusable.
 	 * Reinitialize QP. */
-	if (!tmpl.qp)
-		goto skip_init;
 	mod = (struct ibv_exp_qp_attr){ .qp_state = IBV_QPS_RESET };
 	err = ibv_exp_modify_qp(tmpl.qp, &mod, IBV_EXP_QP_STATE);
 	if (err) {
@@ -2867,6 +2787,12 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 		assert(err > 0);
 		return err;
 	}
+	err = ibv_resize_cq(tmpl.cq, desc_n);
+	if (err) {
+		ERROR("%p: cannot resize CQ: %s", (void *)dev, strerror(err));
+		assert(err > 0);
+		return err;
+	}
 	mod = (struct ibv_exp_qp_attr){
 		/* Move the QP to this state. */
 		.qp_state = IBV_QPS_INIT,
@@ -2875,6 +2801,7 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 	};
 	err = ibv_exp_modify_qp(tmpl.qp, &mod,
 				(IBV_EXP_QP_STATE |
+				 (parent ? IBV_EXP_QP_GROUP_RSS : 0) |
 				 IBV_EXP_QP_PORT));
 	if (err) {
 		ERROR("%p: QP state to IBV_QPS_INIT failed: %s",
@@ -2882,13 +2809,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 		assert(err > 0);
 		return err;
 	};
-skip_init:
-	err = ibv_resize_cq(tmpl.cq, desc_n);
-	if (err) {
-		ERROR("%p: cannot resize CQ: %s", (void *)dev, strerror(err));
-		assert(err > 0);
-		return err;
-	}
 	/* Allocate pool. */
 	pool = rte_malloc(__func__, (mbuf_n * sizeof(*pool)), 0);
 	if (pool == NULL) {
@@ -2942,8 +2862,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 	rxq->elts_n = 0;
 	rte_free(rxq->elts.sp);
 	rxq->elts.sp = NULL;
-	if (!tmpl.qp)
-		goto skip_rtr;
 	/* Post WRs. */
 	err = ibv_post_recv(tmpl.qp,
 			    (tmpl.sp ?
@@ -2971,103 +2889,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 }
 
 /**
- * Create verbs QP resources associated with a rxq.
- *
- * @param rxq
- *   Pointer to RX queue structure.
- * @param desc
- *   Number of descriptors to configure in queue.
- * @param inactive
- *   If true, the queue is disabled because its index is higher or
- *   equal to the real number of queues, which must be a power of 2.
- * @param children_n
- *   The number of children in a parent case, zero for a child.
- * @param rxq_parent
- *   The pointer to a parent RX structure for a child in RSS case,
- *   NULL for parent.
- *
- * @return
- *   0 on success, errno value on failure.
- */
-int
-rxq_create_qp(struct rxq *rxq,
-	      uint16_t desc,
-	      int inactive,
-	      int children_n,
-	      struct rxq *rxq_parent)
-{
-	int ret;
-	struct ibv_exp_qp_attr mod;
-	struct ibv_exp_query_intf_params params;
-	enum ibv_exp_query_intf_status status;
-	struct ibv_recv_wr *bad_wr;
-	int parent = (children_n > 0);
-	struct priv *priv = rxq->priv;
-
-	if (priv->rss && !inactive && (rxq_parent || parent))
-		rxq->qp = rxq_setup_qp_rss(priv, rxq->cq, desc,
-					   children_n, rxq->rd,
-					   rxq_parent);
-	else
-		rxq->qp = rxq_setup_qp(priv, rxq->cq, desc, rxq->rd);
-	if (rxq->qp == NULL) {
-		ret = (errno ? errno : EINVAL);
-		ERROR("QP creation failure: %s",
-		      strerror(ret));
-		return ret;
-	}
-	mod = (struct ibv_exp_qp_attr){
-		/* Move the QP to this state. */
-		.qp_state = IBV_QPS_INIT,
-		/* Primary port number. */
-		.port_num = priv->port
-	};
-	ret = ibv_exp_modify_qp(rxq->qp, &mod,
-				(IBV_EXP_QP_STATE |
-				 (parent ? IBV_EXP_QP_GROUP_RSS : 0) |
-				 IBV_EXP_QP_PORT));
-	if (ret) {
-		ERROR("QP state to IBV_QPS_INIT failed: %s",
-		      strerror(ret));
-		return ret;
-	}
-	if (!parent) {
-		ret = ibv_post_recv(rxq->qp,
-				    (rxq->sp ?
-				     &(*rxq->elts.sp)[0].wr :
-				     &(*rxq->elts.no_sp)[0].wr),
-				    &bad_wr);
-		if (ret) {
-			ERROR("ibv_post_recv() failed for WR %p: %s",
-			      (void *)bad_wr,
-			      strerror(ret));
-			return ret;
-		}
-	}
-	mod = (struct ibv_exp_qp_attr){
-		.qp_state = IBV_QPS_RTR
-	};
-	ret = ibv_exp_modify_qp(rxq->qp, &mod, IBV_EXP_QP_STATE);
-	if (ret) {
-		ERROR("QP state to IBV_QPS_RTR failed: %s",
-		      strerror(ret));
-		return ret;
-	}
-	params = (struct ibv_exp_query_intf_params){
-		.intf_scope = IBV_EXP_INTF_GLOBAL,
-		.intf = IBV_EXP_INTF_QP_BURST,
-		.obj = rxq->qp,
-	};
-	rxq->if_qp = ibv_exp_query_intf(priv->ctx, &params, &status);
-	if (rxq->if_qp == NULL) {
-		ERROR("QP interface family query failed with status %d",
-		      status);
-		return errno;
-	}
-	return 0;
-}
-
-/**
  * Configure a RX queue.
  *
  * @param dev
@@ -3085,21 +2906,14 @@ rxq_create_qp(struct rxq *rxq,
  *   Thresholds parameters.
  * @param mp
  *   Memory pool for buffer allocations.
- * @param children_n
- *   The number of children in a parent case, zero for a child.
- * @param rxq_parent
- *   The pointer to a parent RX structure (or NULL) in a child case,
- *   NULL for parent.
  *
  * @return
  *   0 on success, errno value on failure.
  */
 static int
 rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
-	  unsigned int socket, int inactive,
-	  const struct rte_eth_rxconf *conf,
-	  struct rte_mempool *mp, int children_n,
-	  struct rxq *rxq_parent)
+	  unsigned int socket, int inactive, const struct rte_eth_rxconf *conf,
+	  struct rte_mempool *mp)
 {
 	struct priv *priv = dev->data->dev_private;
 	struct rxq tmpl = {
@@ -3107,15 +2921,17 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 		.mp = mp,
 		.socket = socket
 	};
+	struct ibv_exp_qp_attr mod;
 	union {
 		struct ibv_exp_query_intf_params params;
 		struct ibv_exp_cq_init_attr cq;
 		struct ibv_exp_res_domain_init_attr rd;
 	} attr;
 	enum ibv_exp_query_intf_status status;
+	struct ibv_recv_wr *bad_wr;
 	unsigned int mb_len;
 	int ret = 0;
-	int parent = (children_n > 0);
+	int parent = (rxq == &priv->rxq_parent);
 
 	(void)conf; /* Thresholds configuration (ignored). */
 	/*
@@ -3206,6 +3022,32 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	      priv->device_attr.max_qp_wr);
 	DEBUG("priv->device_attr.max_sge is %d",
 	      priv->device_attr.max_sge);
+	if (priv->rss && !inactive)
+		tmpl.qp = rxq_setup_qp_rss(priv, tmpl.cq, desc, parent,
+					   tmpl.rd);
+	else
+		tmpl.qp = rxq_setup_qp(priv, tmpl.cq, desc, tmpl.rd);
+	if (tmpl.qp == NULL) {
+		ret = (errno ? errno : EINVAL);
+		ERROR("%p: QP creation failure: %s",
+		      (void *)dev, strerror(ret));
+		goto error;
+	}
+	mod = (struct ibv_exp_qp_attr){
+		/* Move the QP to this state. */
+		.qp_state = IBV_QPS_INIT,
+		/* Primary port number. */
+		.port_num = priv->port
+	};
+	ret = ibv_exp_modify_qp(tmpl.qp, &mod,
+				(IBV_EXP_QP_STATE |
+				 (parent ? IBV_EXP_QP_GROUP_RSS : 0) |
+				 IBV_EXP_QP_PORT));
+	if (ret) {
+		ERROR("%p: QP state to IBV_QPS_INIT failed: %s",
+		      (void *)dev, strerror(ret));
+		goto error;
+	}
 	/* Allocate descriptors for RX queues, except for the RSS parent. */
 	if (parent)
 		goto skip_alloc;
@@ -3216,14 +3058,29 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	if (ret) {
 		ERROR("%p: RXQ allocation failed: %s",
 		      (void *)dev, strerror(ret));
-		return ret;
+		goto error;
+	}
+	ret = ibv_post_recv(tmpl.qp,
+			    (tmpl.sp ?
+			     &(*tmpl.elts.sp)[0].wr :
+			     &(*tmpl.elts.no_sp)[0].wr),
+			    &bad_wr);
+	if (ret) {
+		ERROR("%p: ibv_post_recv() failed for WR %p: %s",
+		      (void *)dev,
+		      (void *)bad_wr,
+		      strerror(ret));
+		goto error;
 	}
 skip_alloc:
-	if (parent || rxq_parent || !priv->rss) {
-		ret = rxq_create_qp(&tmpl, desc, inactive,
-				    children_n, rxq_parent);
-		if (ret)
-			goto error;
+	mod = (struct ibv_exp_qp_attr){
+		.qp_state = IBV_QPS_RTR
+	};
+	ret = ibv_exp_modify_qp(tmpl.qp, &mod, IBV_EXP_QP_STATE);
+	if (ret) {
+		ERROR("%p: QP state to IBV_QPS_RTR failed: %s",
+		      (void *)dev, strerror(ret));
+		goto error;
 	}
 	/* Save port ID. */
 	tmpl.port_id = dev->data->port_id;
@@ -3235,11 +3092,21 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	};
 	tmpl.if_cq = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
 	if (tmpl.if_cq == NULL) {
-		ret = EINVAL;
 		ERROR("%p: CQ interface family query failed with status %d",
 		      (void *)dev, status);
 		goto error;
 	}
+	attr.params = (struct ibv_exp_query_intf_params){
+		.intf_scope = IBV_EXP_INTF_GLOBAL,
+		.intf = IBV_EXP_INTF_QP_BURST,
+		.obj = tmpl.qp,
+	};
+	tmpl.if_qp = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
+	if (tmpl.if_qp == NULL) {
+		ERROR("%p: QP interface family query failed with status %d",
+		      (void *)dev, status);
+		goto error;
+	}
 	/* Clean up rxq in case we're reinitializing it. */
 	DEBUG("%p: cleaning-up old rxq just in case", (void *)rxq);
 	rxq_cleanup(rxq);
@@ -3277,7 +3144,6 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		    unsigned int socket, const struct rte_eth_rxconf *conf,
 		    struct rte_mempool *mp)
 {
-	struct rxq *parent;
 	struct priv *priv = dev->data->dev_private;
 	struct rxq *rxq = (*priv->rxqs)[idx];
 	int inactive = 0;
@@ -3312,16 +3178,9 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 			return -ENOMEM;
 		}
 	}
-	if (priv->rss && !priv->isolated) {
-		/* The list consists of the single default one. */
-		parent = LIST_FIRST(&priv->parents);
-		if (idx >= rte_align32pow2(priv->rxqs_n + 1) >> 1)
-			inactive = 1;
-	} else {
-		parent = NULL;
-	}
-	ret = rxq_setup(dev, rxq, desc, socket,
-			inactive, conf, mp, 0, parent);
+	if (idx >= rte_align32pow2(priv->rxqs_n + 1) >> 1)
+		inactive = 1;
+	ret = rxq_setup(dev, rxq, desc, socket, inactive, conf, mp);
 	if (ret)
 		rte_free(rxq);
 	else {
@@ -3356,6 +3215,7 @@ mlx4_rx_queue_release(void *dpdk_rxq)
 		return;
 	priv = rxq->priv;
 	priv_lock(priv);
+	assert(rxq != &priv->rxq_parent);
 	for (i = 0; (i != priv->rxqs_n); ++i)
 		if ((*priv->rxqs)[i] == rxq) {
 			DEBUG("%p: removing RX queue %p from list",
@@ -3581,7 +3441,7 @@ mlx4_dev_close(struct rte_eth_dev *dev)
 		priv->txqs = NULL;
 	}
 	if (priv->rss)
-		priv_parent_list_cleanup(priv);
+		rxq_cleanup(&priv->rxq_parent);
 	if (priv->pd != NULL) {
 		assert(priv->ctx != NULL);
 		claim_zero(ibv_dealloc_pd(priv->pd));
drivers/net/mlx4/mlx4.h +1 -16
index 301b193..726ca2a 100644
@@ -157,7 +157,6 @@ struct rxq_elt {
 
 /* RX queue descriptor. */
 struct rxq {
-	LIST_ENTRY(rxq) next; /* Used by parent queue only */
 	struct priv *priv; /* Back pointer to private data. */
 	struct rte_mempool *mp; /* Memory Pool for allocations. */
 	struct ibv_mr *mr; /* Memory Region (for mp). */
@@ -179,10 +178,6 @@ struct rxq {
 	struct mlx4_rxq_stats stats; /* RX queue counters. */
 	unsigned int socket; /* CPU socket ID for allocations. */
 	struct ibv_exp_res_domain *rd; /* Resource Domain. */
-	struct {
-		uint16_t queues_n;
-		uint16_t queues[RTE_MAX_QUEUES_PER_PORT];
-	} rss;
 };
 
 /* TX element. */
@@ -259,6 +254,7 @@ struct priv {
 	unsigned int inl_recv_size; /* Inline recv size */
 	unsigned int max_rss_tbl_sz; /* Maximum number of RSS queues. */
 	/* RX/TX queues. */
+	struct rxq rxq_parent; /* Parent queue when RSS is enabled. */
 	unsigned int rxqs_n; /* RX queues array size. */
 	unsigned int txqs_n; /* TX queues array size. */
 	struct rxq *(*rxqs)[]; /* RX queues. */
@@ -268,21 +264,10 @@ struct priv {
 	struct rte_flow_drop *flow_drop_queue; /* Flow drop queue. */
 	LIST_HEAD(mlx4_flows, rte_flow) flows;
 	struct rte_intr_conf intr_conf; /* Active interrupt configuration. */
-	LIST_HEAD(mlx4_parents, rxq) parents;
 	rte_spinlock_t lock; /* Lock for control functions. */
 };
 
 void priv_lock(struct priv *priv);
 void priv_unlock(struct priv *priv);
 
-int
-rxq_create_qp(struct rxq *rxq,
-	      uint16_t desc,
-	      int inactive,
-	      int children_n,
-	      struct rxq *rxq_parent);
-
-void
-rxq_parent_cleanup(struct rxq *parent);
-
 #endif /* RTE_PMD_MLX4_H_ */
drivers/net/mlx4/mlx4_flow.c +0 -15
index 827115e..2c5dc3c 100644
@@ -828,23 +828,8 @@ priv_flow_create_action_queue(struct priv *priv,
 	if (action->drop) {
 		qp = priv->flow_drop_queue ? priv->flow_drop_queue->qp : NULL;
 	} else {
-		int ret;
 		struct rxq *rxq = (*priv->rxqs)[action->queue_id];
 
-		if (!rxq->qp) {
-			assert(priv->isolated);
-			ret = rxq_create_qp(rxq, rxq->elts_n,
-					    0, 0, NULL);
-			if (ret) {
-				rte_flow_error_set(
-					error,
-					ENOMEM,
-					RTE_FLOW_ERROR_TYPE_HANDLE,
-					NULL,
-					"flow rule creation failure");
-				goto error;
-			}
-		}
 		qp = rxq->qp;
 		rte_flow->qp = qp;
 	}
Signature · 1 line
2.1.4
#20 lore raw

PATCH 16/48 net/mlx4: drop RSS support

In reply to Adrien Mazarguil

The Verbs RSS API used in this PMD is now obsolete. It is superseded by an enhanced API with fewer constraints already used in the mlx5 PMD.

Drop RSS support in preparation for a major refactoring. The ability to configure several Rx queues is retained, these can be targeted directly by creating specific flow rules.

There is no need for "ignored" Rx queues anymore since their number is no longer limited to powers of two.

---
 doc/guides/nics/features/mlx4.ini |   1 -
 doc/guides/nics/mlx4.rst          |  13 --
 drivers/net/mlx4/mlx4.c           | 212 +++------------------------------
 drivers/net/mlx4/mlx4.h           |   6 -
 4 files changed, 14 insertions(+), 218 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -1
index 3acf8d3..aa1ad21 100644
@@ -13,7 +13,6 @@ Queue start/stop     = Y
 MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
-RSS hash             = Y
 SR-IOV               = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
doc/guides/nics/mlx4.rst +0 -13
index 235912a..e906b8d 100644
@@ -78,22 +78,12 @@ Features
 --------
 
 - Multi arch support: x86_64 and POWER8.
-- RSS, also known as RCA, is supported. In this mode the number of
-  configured RX queues must be a power of two.
 - Link state information is provided.
 - Scattered packets are supported for TX and RX.
 - Inner L3/L4 (IP, TCP and UDP) TX/RX checksum offloading and validation.
 - Outer L3 (IP) TX/RX checksum offloading and validation for VXLAN frames.
 - RX interrupts.
 
-Limitations
------------
-
-- RSS hash key cannot be modified.
-- RSS RETA cannot be configured
-- RSS always includes L3 (IPv4/IPv6) and L4 (UDP/TCP). They cannot be
-  dissociated.
-
 Configuration
 -------------
 
@@ -137,9 +127,6 @@ Environment variables
 Run-time configuration
 ~~~~~~~~~~~~~~~~~~~~~~
 
-- The only constraint when RSS mode is requested is to make sure the number
-  of RX queues is a power of two. This is a hardware requirement.
-
 - librte_pmd_mlx4 brings kernel network interfaces up during initialization
   because it is affected by their state. Forcing them down prevents packets
   reception.
drivers/net/mlx4/mlx4.c +14 -198

362 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +0 -6
index 726ca2a..fa703a2 100644
@@ -242,19 +242,13 @@ struct priv {
 	uint16_t mtu; /* Configured MTU. */
 	uint8_t port; /* Physical port number. */
 	unsigned int started:1; /* Device started, flows enabled. */
-	unsigned int hw_qpg:1; /* QP groups are supported. */
-	unsigned int hw_tss:1; /* TSS is supported. */
-	unsigned int hw_rss:1; /* RSS is supported. */
 	unsigned int hw_csum:1; /* Checksum offload is supported. */
 	unsigned int hw_csum_l2tun:1; /* Same for L2 tunnels. */
-	unsigned int rss:1; /* RSS is enabled. */
 	unsigned int vf:1; /* This is a VF device. */
 	unsigned int pending_alarm:1; /* An alarm is pending. */
 	unsigned int isolated:1; /* Toggle isolated mode. */
 	unsigned int inl_recv_size; /* Inline recv size */
-	unsigned int max_rss_tbl_sz; /* Maximum number of RSS queues. */
 	/* RX/TX queues. */
-	struct rxq rxq_parent; /* Parent queue when RSS is enabled. */
 	unsigned int rxqs_n; /* RX queues array size. */
 	unsigned int txqs_n; /* TX queues array size. */
 	struct rxq *(*rxqs)[]; /* RX queues. */
Signature · 1 line
2.1.4
#21 lore raw

PATCH 17/48 net/mlx4: drop checksum offloads support

In reply to Adrien Mazarguil

The Verbs API used to implement Tx and Rx checksum offloads is deprecated. Support for these will be added back after refactoring the PMD.

---
 doc/guides/nics/features/mlx4.ini |  4 --
 doc/guides/nics/mlx4.rst          |  2 -
 drivers/net/mlx4/mlx4.c           | 91 ++--------------------------------
 drivers/net/mlx4/mlx4.h           |  4 --
 4 files changed, 4 insertions(+), 97 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -4
index aa1ad21..08a2e17 100644
@@ -14,10 +14,6 @@ MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
 SR-IOV               = Y
-L3 checksum offload  = Y
-L4 checksum offload  = Y
-Inner L3 checksum    = Y
-Inner L4 checksum    = Y
 Packet type parsing  = Y
 Basic stats          = Y
 Stats per queue      = Y
doc/guides/nics/mlx4.rst +0 -2
index e906b8d..3f54343 100644
@@ -80,8 +80,6 @@ Features
 - Multi arch support: x86_64 and POWER8.
 - Link state information is provided.
 - Scattered packets are supported for TX and RX.
-- Inner L3/L4 (IP, TCP and UDP) TX/RX checksum offloading and validation.
-- Outer L3 (IP) TX/RX checksum offloading and validation for VXLAN frames.
 - RX interrupts.
 
 Configuration
drivers/net/mlx4/mlx4.c +4 -87

139 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +0 -4
index fa703a2..5a0a7a1 100644
@@ -173,8 +173,6 @@ struct rxq {
 		struct rxq_elt (*no_sp)[]; /* RX elements. */
 	} elts;
 	unsigned int sp:1; /* Use scattered RX elements. */
-	unsigned int csum:1; /* Enable checksum offloading. */
-	unsigned int csum_l2tun:1; /* Same for L2 tunnels. */
 	struct mlx4_rxq_stats stats; /* RX queue counters. */
 	unsigned int socket; /* CPU socket ID for allocations. */
 	struct ibv_exp_res_domain *rd; /* Resource Domain. */
@@ -242,8 +240,6 @@ struct priv {
 	uint16_t mtu; /* Configured MTU. */
 	uint8_t port; /* Physical port number. */
 	unsigned int started:1; /* Device started, flows enabled. */
-	unsigned int hw_csum:1; /* Checksum offload is supported. */
-	unsigned int hw_csum_l2tun:1; /* Same for L2 tunnels. */
 	unsigned int vf:1; /* This is a VF device. */
 	unsigned int pending_alarm:1; /* An alarm is pending. */
 	unsigned int isolated:1; /* Toggle isolated mode. */
Signature · 1 line
2.1.4
#22 lore raw

PATCH 18/48 net/mlx4: drop packet type recognition support

In reply to Adrien Mazarguil

The Verbs API used to implement packet type recognition is deprecated. Support will be added back after refactoring the PMD.

---
 doc/guides/nics/features/mlx4.ini |  1 -
 drivers/net/mlx4/mlx4.c           | 70 +---------------------------------
 2 files changed, 2 insertions(+), 69 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -1
index 08a2e17..27c7ae3 100644
@@ -14,7 +14,6 @@ MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
 SR-IOV               = Y
-Packet type parsing  = Y
 Basic stats          = Y
 Stats per queue      = Y
 Other kdrv           = Y
drivers/net/mlx4/mlx4.c +2 -68

106 lines not on this page · raw message

Signature · 1 line
2.1.4
#23 lore raw

PATCH 19/48 net/mlx4: drop scatter/gather support

In reply to Adrien Mazarguil

The Verbs API used to implement Tx and Rx burst functions is deprecated. Drop scatter/gather support to ease refactoring while maintaining basic single-segment Rx/Tx functionality in the meantime.

---
 doc/guides/nics/features/mlx4.ini |   1 -
 doc/guides/nics/mlx4.rst          |   1 -
 drivers/net/mlx4/mlx4.c           | 845 +--------------------------------
 drivers/net/mlx4/mlx4.h           |  28 +-
 4 files changed, 24 insertions(+), 851 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -1
index 27c7ae3..0812a30 100644
@@ -12,7 +12,6 @@ Rx interrupt         = Y
 Queue start/stop     = Y
 MTU update           = Y
 Jumbo frame          = Y
-Scattered Rx         = Y
 SR-IOV               = Y
 Basic stats          = Y
 Stats per queue      = Y
doc/guides/nics/mlx4.rst +0 -1
index 3f54343..8503804 100644
@@ -79,7 +79,6 @@ Features
 
 - Multi arch support: x86_64 and POWER8.
 - Link state information is provided.
-- Scattered packets are supported for TX and RX.
 - RX interrupts.
 
 Configuration
drivers/net/mlx4/mlx4.c +23 -822

1,035 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +1 -27
index 5a0a7a1..38c93f1 100644
@@ -66,9 +66,6 @@
 /* Request send completion once in every 64 sends, might be less. */
 #define MLX4_PMD_TX_PER_COMP_REQ 64
 
-/* Maximum number of Scatter/Gather Elements per Work Request. */
-#define MLX4_PMD_SGE_WR_N 4
-
 /* Maximum size for inline data. */
 #define MLX4_PMD_MAX_INLINE 0
 
@@ -141,13 +138,6 @@ struct mlx4_rxq_stats {
 	uint64_t rx_nombuf; /**< Total of RX mbuf allocation failures. */
 };
 
-/* RX element (scattered packets). */
-struct rxq_elt_sp {
-	struct ibv_recv_wr wr; /* Work Request. */
-	struct ibv_sge sges[MLX4_PMD_SGE_WR_N]; /* Scatter/Gather Elements. */
-	struct rte_mbuf *bufs[MLX4_PMD_SGE_WR_N]; /* SGEs buffers. */
-};
-
 /* RX element. */
 struct rxq_elt {
 	struct ibv_recv_wr wr; /* Work Request. */
@@ -168,11 +158,7 @@ struct rxq {
 	unsigned int port_id; /* Port ID for incoming packets. */
 	unsigned int elts_n; /* (*elts)[] length. */
 	unsigned int elts_head; /* Current index in (*elts)[]. */
-	union {
-		struct rxq_elt_sp (*sp)[]; /* Scattered RX elements. */
-		struct rxq_elt (*no_sp)[]; /* RX elements. */
-	} elts;
-	unsigned int sp:1; /* Use scattered RX elements. */
+	struct rxq_elt (*elts)[]; /* RX elements. */
 	struct mlx4_rxq_stats stats; /* RX queue counters. */
 	unsigned int socket; /* CPU socket ID for allocations. */
 	struct ibv_exp_res_domain *rd; /* Resource Domain. */
@@ -190,16 +176,6 @@ struct mlx4_txq_stats {
 	uint64_t odropped; /**< Total of packets not sent when TX ring full. */
 };
 
-/*
- * Linear buffer type. It is used when transmitting buffers with too many
- * segments that do not fit the hardware queue (see max_send_sge).
- * Extra segments are copied (linearized) in such buffers, replacing the
- * last SGE during TX.
- * The size is arbitrary but large enough to hold a jumbo frame with
- * 8 segments considering mbuf.buf_len is about 2048 bytes.
- */
-typedef uint8_t linear_t[16384];
-
 /* TX queue descriptor. */
 struct txq {
 	struct priv *priv; /* Back pointer to private data. */
@@ -221,8 +197,6 @@ struct txq {
 	unsigned int elts_comp_cd; /* Countdown for next completion request. */
 	unsigned int elts_comp_cd_init; /* Initial value for countdown. */
 	struct mlx4_txq_stats stats; /* TX queue counters. */
-	linear_t (*elts_linear)[]; /* Linearized buffers. */
-	struct ibv_mr *mr_linear; /* Memory Region for linearized buffers. */
 	unsigned int socket; /* CPU socket ID for allocations. */
 	struct ibv_exp_res_domain *rd; /* Resource Domain. */
 };
Signature · 1 line
2.1.4
#24 lore raw

PATCH 20/48 net/mlx4: drop inline receive support

In reply to Adrien Mazarguil

The Verbs API used to implement inline receive is deprecated. Support will be added back after refactoring the PMD.

---
 drivers/net/mlx4/mlx4.c | 52 --------------------------------------------
 drivers/net/mlx4/mlx4.h |  1 -
 2 files changed, 53 deletions(-)
drivers/net/mlx4/mlx4.c +0 -52
index 5546c0a..227c02c 100644
@@ -1925,8 +1925,6 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
 		.res_domain = rd,
 	};
 
-	attr.max_inl_recv = priv->inl_recv_size,
-	attr.comp_mask |= IBV_EXP_QP_INIT_ATTR_INL_RECV;
 	return ibv_exp_create_qp(priv->ctx, &attr);
 }
 
@@ -2988,25 +2986,6 @@ priv_get_mac(struct priv *priv, uint8_t (*mac)[ETHER_ADDR_LEN])
 	return 0;
 }
 
-/**
- * Retrieve integer value from environment variable.
- *
- * @param[in] name
- *   Environment variable name.
- *
- * @return
- *   Integer value, 0 if the variable is not set.
- */
-static int
-mlx4_getenv_int(const char *name)
-{
-	const char *val = getenv(name);
-
-	if (val == NULL)
-		return 0;
-	return atoi(val);
-}
-
 static void
 mlx4_dev_link_status_handler(void *);
 static void
@@ -3649,13 +3628,11 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		struct ibv_pd *pd = NULL;
 		struct priv *priv = NULL;
 		struct rte_eth_dev *eth_dev = NULL;
-		struct ibv_exp_device_attr exp_device_attr;
 		struct ether_addr mac;
 
 		/* If port is not enabled, skip. */
 		if (!(conf.ports.enabled & (1 << i)))
 			continue;
-		exp_device_attr.comp_mask = IBV_EXP_DEVICE_ATTR_EXP_CAP_FLAGS;
 
 		DEBUG("using port %u", port);
 
@@ -3708,35 +3685,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		priv->port = port;
 		priv->pd = pd;
 		priv->mtu = ETHER_MTU;
-		if (ibv_exp_query_device(ctx, &exp_device_attr)) {
-			ERROR("ibv_exp_query_device() failed");
-			err = ENODEV;
-			goto port_error;
-		}
-
-		priv->inl_recv_size = mlx4_getenv_int("MLX4_INLINE_RECV_SIZE");
-
-		if (priv->inl_recv_size) {
-			exp_device_attr.comp_mask =
-				IBV_EXP_DEVICE_ATTR_INLINE_RECV_SZ;
-			if (ibv_exp_query_device(ctx, &exp_device_attr)) {
-				INFO("Couldn't query device for inline-receive"
-				     " capabilities.");
-				priv->inl_recv_size = 0;
-			} else {
-				if ((unsigned)exp_device_attr.inline_recv_sz <
-				    priv->inl_recv_size) {
-					INFO("Max inline-receive (%d) <"
-					     " requested inline-receive (%u)",
-					     exp_device_attr.inline_recv_sz,
-					     priv->inl_recv_size);
-					priv->inl_recv_size =
-						exp_device_attr.inline_recv_sz;
-				}
-			}
-			INFO("Set inline receive size to %u",
-			     priv->inl_recv_size);
-		}
 
 		priv->vf = vf;
 		/* Configure the first MAC address by default. */
drivers/net/mlx4/mlx4.h +0 -1
index 38c93f1..66efb98 100644
@@ -217,7 +217,6 @@ struct priv {
 	unsigned int vf:1; /* This is a VF device. */
 	unsigned int pending_alarm:1; /* An alarm is pending. */
 	unsigned int isolated:1; /* Toggle isolated mode. */
-	unsigned int inl_recv_size; /* Inline recv size */
 	/* RX/TX queues. */
 	unsigned int rxqs_n; /* RX queues array size. */
 	unsigned int txqs_n; /* TX queues array size. */
Signature · 1 line
2.1.4
#25 lore raw

PATCH 21/48 net/mlx4: use standard QP attributes

In reply to Adrien Mazarguil

The Verbs API used to set QP attributes is deprecated. Revert to the standard API since it actually supports the remaining ones.

---
 drivers/net/mlx4/mlx4.c | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)
drivers/net/mlx4/mlx4.c +11 -14
index 227c02c..773ba62 100644
@@ -1178,7 +1178,7 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		struct ibv_exp_qp_init_attr init;
 		struct ibv_exp_res_domain_init_attr rd;
 		struct ibv_exp_cq_init_attr cq;
-		struct ibv_exp_qp_attr mod;
+		struct ibv_qp_attr mod;
 	} attr;
 	enum ibv_exp_query_intf_status status;
 	int ret = 0;
@@ -1251,14 +1251,13 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 	}
 	/* ibv_create_qp() updates this value. */
 	tmpl.max_inline = attr.init.cap.max_inline_data;
-	attr.mod = (struct ibv_exp_qp_attr){
+	attr.mod = (struct ibv_qp_attr){
 		/* Move the QP to this state. */
 		.qp_state = IBV_QPS_INIT,
 		/* Primary port number. */
 		.port_num = priv->port
 	};
-	ret = ibv_exp_modify_qp(tmpl.qp, &attr.mod,
-				(IBV_EXP_QP_STATE | IBV_EXP_QP_PORT));
+	ret = ibv_modify_qp(tmpl.qp, &attr.mod, IBV_QP_STATE | IBV_QP_PORT);
 	if (ret) {
 		ERROR("%p: QP state to IBV_QPS_INIT failed: %s",
 		      (void *)dev, strerror(ret));
@@ -1270,17 +1269,17 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		      (void *)dev, strerror(ret));
 		goto error;
 	}
-	attr.mod = (struct ibv_exp_qp_attr){
+	attr.mod = (struct ibv_qp_attr){
 		.qp_state = IBV_QPS_RTR
 	};
-	ret = ibv_exp_modify_qp(tmpl.qp, &attr.mod, IBV_EXP_QP_STATE);
+	ret = ibv_modify_qp(tmpl.qp, &attr.mod, IBV_QP_STATE);
 	if (ret) {
 		ERROR("%p: QP state to IBV_QPS_RTR failed: %s",
 		      (void *)dev, strerror(ret));
 		goto error;
 	}
 	attr.mod.qp_state = IBV_QPS_RTS;
-	ret = ibv_exp_modify_qp(tmpl.qp, &attr.mod, IBV_EXP_QP_STATE);
+	ret = ibv_modify_qp(tmpl.qp, &attr.mod, IBV_QP_STATE);
 	if (ret) {
 		ERROR("%p: QP state to IBV_QPS_RTS failed: %s",
 		      (void *)dev, strerror(ret));
@@ -1958,7 +1957,7 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 		.mp = mp,
 		.socket = socket
 	};
-	struct ibv_exp_qp_attr mod;
+	struct ibv_qp_attr mod;
 	union {
 		struct ibv_exp_query_intf_params params;
 		struct ibv_exp_cq_init_attr cq;
@@ -2046,15 +2045,13 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 		      (void *)dev, strerror(ret));
 		goto error;
 	}
-	mod = (struct ibv_exp_qp_attr){
+	mod = (struct ibv_qp_attr){
 		/* Move the QP to this state. */
 		.qp_state = IBV_QPS_INIT,
 		/* Primary port number. */
 		.port_num = priv->port
 	};
-	ret = ibv_exp_modify_qp(tmpl.qp, &mod,
-				IBV_EXP_QP_STATE |
-				IBV_EXP_QP_PORT);
+	ret = ibv_modify_qp(tmpl.qp, &mod, IBV_QP_STATE | IBV_QP_PORT);
 	if (ret) {
 		ERROR("%p: QP state to IBV_QPS_INIT failed: %s",
 		      (void *)dev, strerror(ret));
@@ -2074,10 +2071,10 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 		      strerror(ret));
 		goto error;
 	}
-	mod = (struct ibv_exp_qp_attr){
+	mod = (struct ibv_qp_attr){
 		.qp_state = IBV_QPS_RTR
 	};
-	ret = ibv_exp_modify_qp(tmpl.qp, &mod, IBV_EXP_QP_STATE);
+	ret = ibv_modify_qp(tmpl.qp, &mod, IBV_QP_STATE);
 	if (ret) {
 		ERROR("%p: QP state to IBV_QPS_RTR failed: %s",
 		      (void *)dev, strerror(ret));
Signature · 1 line
2.1.4
#26 lore raw

PATCH 22/48 net/mlx4: revert resource domain support

In reply to Adrien Mazarguil

This reverts commit 3e49c148b715c3c0a12c1200295bb9b312f7028e.

Resource domains are not part of the standard Verbs interface. The performance improvement they bring will be restored later through a different data path implementation.

This commit makes the PMD not rely on the non-standard QP allocation interface.

---
 drivers/net/mlx4/mlx4.c      | 88 ++++-----------------------------------
 drivers/net/mlx4/mlx4.h      |  2 -
 drivers/net/mlx4/mlx4_flow.c | 30 +++++--------
 3 files changed, 20 insertions(+), 100 deletions(-)
drivers/net/mlx4/mlx4.c +9 -79
index 773ba62..144cfb0 100644
@@ -697,17 +697,6 @@ txq_cleanup(struct txq *txq)
 		claim_zero(ibv_destroy_qp(txq->qp));
 	if (txq->cq != NULL)
 		claim_zero(ibv_destroy_cq(txq->cq));
-	if (txq->rd != NULL) {
-		struct ibv_exp_destroy_res_domain_attr attr = {
-			.comp_mask = 0,
-		};
-
-		assert(txq->priv != NULL);
-		assert(txq->priv->ctx != NULL);
-		claim_zero(ibv_exp_destroy_res_domain(txq->priv->ctx,
-						      txq->rd,
-						      &attr));
-	}
 	for (i = 0; (i != elemof(txq->mp2mr)); ++i) {
 		if (txq->mp2mr[i].mp == NULL)
 			break;
@@ -1175,9 +1164,7 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 	};
 	union {
 		struct ibv_exp_query_intf_params params;
-		struct ibv_exp_qp_init_attr init;
-		struct ibv_exp_res_domain_init_attr rd;
-		struct ibv_exp_cq_init_attr cq;
+		struct ibv_qp_init_attr init;
 		struct ibv_qp_attr mod;
 	} attr;
 	enum ibv_exp_query_intf_status status;
@@ -1191,24 +1178,7 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		return EINVAL;
 	}
 	/* MRs will be registered in mp2mr[] later. */
-	attr.rd = (struct ibv_exp_res_domain_init_attr){
-		.comp_mask = (IBV_EXP_RES_DOMAIN_THREAD_MODEL |
-			      IBV_EXP_RES_DOMAIN_MSG_MODEL),
-		.thread_model = IBV_EXP_THREAD_SINGLE,
-		.msg_model = IBV_EXP_MSG_HIGH_BW,
-	};
-	tmpl.rd = ibv_exp_create_res_domain(priv->ctx, &attr.rd);
-	if (tmpl.rd == NULL) {
-		ret = ENOMEM;
-		ERROR("%p: RD creation failure: %s",
-		      (void *)dev, strerror(ret));
-		goto error;
-	}
-	attr.cq = (struct ibv_exp_cq_init_attr){
-		.comp_mask = IBV_EXP_CQ_INIT_ATTR_RES_DOMAIN,
-		.res_domain = tmpl.rd,
-	};
-	tmpl.cq = ibv_exp_create_cq(priv->ctx, desc, NULL, NULL, 0, &attr.cq);
+	tmpl.cq = ibv_create_cq(priv->ctx, desc, NULL, NULL, 0);
 	if (tmpl.cq == NULL) {
 		ret = ENOMEM;
 		ERROR("%p: CQ creation failure: %s",
@@ -1219,7 +1189,7 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 	      priv->device_attr.max_qp_wr);
 	DEBUG("priv->device_attr.max_sge is %d",
 	      priv->device_attr.max_sge);
-	attr.init = (struct ibv_exp_qp_init_attr){
+	attr.init = (struct ibv_qp_init_attr){
 		/* CQ to be associated with the send queue. */
 		.send_cq = tmpl.cq,
 		/* CQ to be associated with the receive queue. */
@@ -1237,12 +1207,8 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		/* Do *NOT* enable this, completions events are managed per
 		 * TX burst. */
 		.sq_sig_all = 0,
-		.pd = priv->pd,
-		.res_domain = tmpl.rd,
-		.comp_mask = (IBV_EXP_QP_INIT_ATTR_PD |
-			      IBV_EXP_QP_INIT_ATTR_RES_DOMAIN),
 	};
-	tmpl.qp = ibv_exp_create_qp(priv->ctx, &attr.init);
+	tmpl.qp = ibv_create_qp(priv->pd, &attr.init);
 	if (tmpl.qp == NULL) {
 		ret = (errno ? errno : EINVAL);
 		ERROR("%p: QP creation failure: %s",
@@ -1721,17 +1687,6 @@ rxq_cleanup(struct rxq *rxq)
 		claim_zero(ibv_destroy_cq(rxq->cq));
 	if (rxq->channel != NULL)
 		claim_zero(ibv_destroy_comp_channel(rxq->channel));
-	if (rxq->rd != NULL) {
-		struct ibv_exp_destroy_res_domain_attr attr = {
-			.comp_mask = 0,
-		};
-
-		assert(rxq->priv != NULL);
-		assert(rxq->priv->ctx != NULL);
-		claim_zero(ibv_exp_destroy_res_domain(rxq->priv->ctx,
-						      rxq->rd,
-						      &attr));
-	}
 	if (rxq->mr != NULL)
 		claim_zero(ibv_dereg_mr(rxq->mr));
 	memset(rxq, 0, sizeof(*rxq));
@@ -1901,10 +1856,9 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
  *   QP pointer or NULL in case of error.
  */
 static struct ibv_qp *
-rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
-	     struct ibv_exp_res_domain *rd)
+rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc)
 {
-	struct ibv_exp_qp_init_attr attr = {
+	struct ibv_qp_init_attr attr = {
 		/* CQ to be associated with the send queue. */
 		.send_cq = cq,
 		/* CQ to be associated with the receive queue. */
@@ -1918,13 +1872,9 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
 			.max_recv_sge = 1,
 		},
 		.qp_type = IBV_QPT_RAW_PACKET,
-		.comp_mask = (IBV_EXP_QP_INIT_ATTR_PD |
-			      IBV_EXP_QP_INIT_ATTR_RES_DOMAIN),
-		.pd = priv->pd,
-		.res_domain = rd,
 	};
 
-	return ibv_exp_create_qp(priv->ctx, &attr);
+	return ibv_create_qp(priv->pd, &attr);
 }
 
 /**
@@ -1960,8 +1910,6 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	struct ibv_qp_attr mod;
 	union {
 		struct ibv_exp_query_intf_params params;
-		struct ibv_exp_cq_init_attr cq;
-		struct ibv_exp_res_domain_init_attr rd;
 	} attr;
 	enum ibv_exp_query_intf_status status;
 	struct ibv_recv_wr *bad_wr;
@@ -1999,19 +1947,6 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 		      (void *)dev, strerror(ret));
 		goto error;
 	}
-	attr.rd = (struct ibv_exp_res_domain_init_attr){
-		.comp_mask = (IBV_EXP_RES_DOMAIN_THREAD_MODEL |
-			      IBV_EXP_RES_DOMAIN_MSG_MODEL),
-		.thread_model = IBV_EXP_THREAD_SINGLE,
-		.msg_model = IBV_EXP_MSG_HIGH_BW,
-	};
-	tmpl.rd = ibv_exp_create_res_domain(priv->ctx, &attr.rd);
-	if (tmpl.rd == NULL) {
-		ret = ENOMEM;
-		ERROR("%p: RD creation failure: %s",
-		      (void *)dev, strerror(ret));
-		goto error;
-	}
 	if (dev->data->dev_conf.intr_conf.rxq) {
 		tmpl.channel = ibv_create_comp_channel(priv->ctx);
 		if (tmpl.channel == NULL) {
@@ -2022,12 +1957,7 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 			goto error;
 		}
 	}
-	attr.cq = (struct ibv_exp_cq_init_attr){
-		.comp_mask = IBV_EXP_CQ_INIT_ATTR_RES_DOMAIN,
-		.res_domain = tmpl.rd,
-	};
-	tmpl.cq = ibv_exp_create_cq(priv->ctx, desc, NULL, tmpl.channel, 0,
-				    &attr.cq);
+	tmpl.cq = ibv_create_cq(priv->ctx, desc, NULL, tmpl.channel, 0);
 	if (tmpl.cq == NULL) {
 		ret = ENOMEM;
 		ERROR("%p: CQ creation failure: %s",
@@ -2038,7 +1968,7 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	      priv->device_attr.max_qp_wr);
 	DEBUG("priv->device_attr.max_sge is %d",
 	      priv->device_attr.max_sge);
-	tmpl.qp = rxq_setup_qp(priv, tmpl.cq, desc, tmpl.rd);
+	tmpl.qp = rxq_setup_qp(priv, tmpl.cq, desc);
 	if (tmpl.qp == NULL) {
 		ret = (errno ? errno : EINVAL);
 		ERROR("%p: QP creation failure: %s",
drivers/net/mlx4/mlx4.h +0 -2
index 66efb98..6a5df5c 100644
@@ -161,7 +161,6 @@ struct rxq {
 	struct rxq_elt (*elts)[]; /* RX elements. */
 	struct mlx4_rxq_stats stats; /* RX queue counters. */
 	unsigned int socket; /* CPU socket ID for allocations. */
-	struct ibv_exp_res_domain *rd; /* Resource Domain. */
 };
 
 /* TX element. */
@@ -198,7 +197,6 @@ struct txq {
 	unsigned int elts_comp_cd_init; /* Initial value for countdown. */
 	struct mlx4_txq_stats stats; /* TX queue counters. */
 	unsigned int socket; /* CPU socket ID for allocations. */
-	struct ibv_exp_res_domain *rd; /* Resource Domain. */
 };
 
 struct rte_flow;
drivers/net/mlx4/mlx4_flow.c +11 -19
index 2c5dc3c..58d4698 100644
@@ -752,29 +752,21 @@ mlx4_flow_create_drop_queue(struct priv *priv)
 		ERROR("Cannot allocate memory for drop struct");
 		goto err;
 	}
-	cq = ibv_exp_create_cq(priv->ctx, 1, NULL, NULL, 0,
-			      &(struct ibv_exp_cq_init_attr){
-					.comp_mask = 0,
-			      });
+	cq = ibv_create_cq(priv->ctx, 1, NULL, NULL, 0);
 	if (!cq) {
 		ERROR("Cannot create drop CQ");
 		goto err_create_cq;
 	}
-	qp = ibv_exp_create_qp(priv->ctx,
-			      &(struct ibv_exp_qp_init_attr){
-					.send_cq = cq,
-					.recv_cq = cq,
-					.cap = {
-						.max_recv_wr = 1,
-						.max_recv_sge = 1,
-					},
-					.qp_type = IBV_QPT_RAW_PACKET,
-					.comp_mask =
-						IBV_EXP_QP_INIT_ATTR_PD |
-						IBV_EXP_QP_INIT_ATTR_PORT,
-					.pd = priv->pd,
-					.port_num = priv->port,
-			      });
+	qp = ibv_create_qp(priv->pd,
+			   &(struct ibv_qp_init_attr){
+				.send_cq = cq,
+				.recv_cq = cq,
+				.cap = {
+					.max_recv_wr = 1,
+					.max_recv_sge = 1,
+				},
+				.qp_type = IBV_QPT_RAW_PACKET,
+			   });
 	if (!qp) {
 		ERROR("Cannot create drop QP");
 		goto err_create_qp;
Signature · 1 line
2.1.4
#27 lore raw

PATCH 23/48 net/mlx4: revert multicast echo prevention

In reply to Adrien Mazarguil

This reverts commit 8b3ffe95e75d6d305992505005cbb95969874a15.

Multicast loopback prevention is not part of the standard Verbs interface. Remove it temporarily.

---
 drivers/net/mlx4/Makefile | 6 +-----
 drivers/net/mlx4/mlx4.c   | 7 -------
 2 files changed, 1 insertion(+), 12 deletions(-)
drivers/net/mlx4/Makefile +1 -5
index 8406ba2..78ea350 100644
@@ -87,11 +87,7 @@ mlx4_autoconf.h.new: FORCE
 
 mlx4_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 	$Q $(RM) -f -- '$@'
-	$Q sh -- '$<' '$@' \
-		HAVE_EXP_QP_BURST_CREATE_DISABLE_ETH_LOOPBACK \
-		infiniband/verbs.h \
-		enum IBV_EXP_QP_BURST_CREATE_DISABLE_ETH_LOOPBACK \
-		$(AUTOCONF_OUTPUT)
+	$Q : > '$@'
 
 # Create mlx4_autoconf.h or update it in case it differs from the new one.
 
drivers/net/mlx4/mlx4.c +0 -7
index 144cfb0..ffad5a4 100644
@@ -1266,13 +1266,6 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		.intf_scope = IBV_EXP_INTF_GLOBAL,
 		.intf = IBV_EXP_INTF_QP_BURST,
 		.obj = tmpl.qp,
-#ifdef HAVE_EXP_QP_BURST_CREATE_DISABLE_ETH_LOOPBACK
-		/* MC loopback must be disabled when not using a VF. */
-		.family_flags =
-			(!priv->vf ?
-			 IBV_EXP_QP_BURST_CREATE_DISABLE_ETH_LOOPBACK :
-			 0),
-#endif
 	};
 	tmpl.if_qp = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
 	if (tmpl.if_qp == NULL) {
Signature · 1 line
2.1.4
#28 lore raw

PATCH 24/48 net/mlx4: revert fast Verbs interface for Tx

In reply to Adrien Mazarguil

This reverts commit 9980f81dc2623291b89cf1c281a6a9f116fd2394.

"Fast Verbs" is a nonstandard experimental interface that must be reverted for compatibility reasons. Its replacement is slower but temporary, performance will be restored by a subsequent commit through an enhanced data path implementation. This one focuses on maintaining basic functionality in the meantime.

---
 drivers/net/mlx4/mlx4.c | 120 ++++++++++++++++++-------------------------
 drivers/net/mlx4/mlx4.h |   4 +-
 2 files changed, 52 insertions(+), 72 deletions(-)
drivers/net/mlx4/mlx4.c +50 -70
index ffad5a4..812f29c 100644
@@ -666,33 +666,10 @@ txq_free_elts(struct txq *txq)
 static void
 txq_cleanup(struct txq *txq)
 {
-	struct ibv_exp_release_intf_params params;
 	size_t i;
 
 	DEBUG("cleaning up %p", (void *)txq);
 	txq_free_elts(txq);
-	if (txq->if_qp != NULL) {
-		assert(txq->priv != NULL);
-		assert(txq->priv->ctx != NULL);
-		assert(txq->qp != NULL);
-		params = (struct ibv_exp_release_intf_params){
-			.comp_mask = 0,
-		};
-		claim_zero(ibv_exp_release_intf(txq->priv->ctx,
-						txq->if_qp,
-						&params));
-	}
-	if (txq->if_cq != NULL) {
-		assert(txq->priv != NULL);
-		assert(txq->priv->ctx != NULL);
-		assert(txq->cq != NULL);
-		params = (struct ibv_exp_release_intf_params){
-			.comp_mask = 0,
-		};
-		claim_zero(ibv_exp_release_intf(txq->priv->ctx,
-						txq->if_cq,
-						&params));
-	}
 	if (txq->qp != NULL)
 		claim_zero(ibv_destroy_qp(txq->qp));
 	if (txq->cq != NULL)
@@ -726,11 +703,12 @@ txq_complete(struct txq *txq)
 	unsigned int elts_comp = txq->elts_comp;
 	unsigned int elts_tail = txq->elts_tail;
 	const unsigned int elts_n = txq->elts_n;
+	struct ibv_wc wcs[elts_comp];
 	int wcs_n;
 
 	if (unlikely(elts_comp == 0))
 		return 0;
-	wcs_n = txq->if_cq->poll_cnt(txq->cq, elts_comp);
+	wcs_n = ibv_poll_cq(txq->cq, elts_comp, wcs);
 	if (unlikely(wcs_n == 0))
 		return 0;
 	if (unlikely(wcs_n < 0)) {
@@ -1014,6 +992,9 @@ static uint16_t
 mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 {
 	struct txq *txq = (struct txq *)dpdk_txq;
+	struct ibv_send_wr *wr_head = NULL;
+	struct ibv_send_wr **wr_next = &wr_head;
+	struct ibv_send_wr *wr_bad = NULL;
 	unsigned int elts_head = txq->elts_head;
 	const unsigned int elts_n = txq->elts_n;
 	unsigned int elts_comp_cd = txq->elts_comp_cd;
@@ -1041,6 +1022,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			(((elts_head + 1) == elts_n) ? 0 : elts_head + 1);
 		struct txq_elt *elt_next = &(*txq->elts)[elts_head_next];
 		struct txq_elt *elt = &(*txq->elts)[elts_head];
+		struct ibv_send_wr *wr = &elt->wr;
 		unsigned int segs = NB_SEGS(buf);
 		unsigned int sent_size = 0;
 		uint32_t send_flags = 0;
@@ -1065,9 +1047,10 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		if (unlikely(--elts_comp_cd == 0)) {
 			elts_comp_cd = txq->elts_comp_cd_init;
 			++elts_comp;
-			send_flags |= IBV_EXP_QP_BURST_SIGNALED;
+			send_flags |= IBV_SEND_SIGNALED;
 		}
 		if (likely(segs == 1)) {
+			struct ibv_sge *sge = &elt->sge;
 			uintptr_t addr;
 			uint32_t length;
 			uint32_t lkey;
@@ -1091,30 +1074,26 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 				rte_prefetch0((volatile void *)
 					      (uintptr_t)addr);
 			RTE_MBUF_PREFETCH_TO_FREE(elt_next->buf);
-			/* Put packet into send queue. */
-			if (length <= txq->max_inline)
-				err = txq->if_qp->send_pending_inline
-					(txq->qp,
-					 (void *)addr,
-					 length,
-					 send_flags);
-			else
-				err = txq->if_qp->send_pending
-					(txq->qp,
-					 addr,
-					 length,
-					 lkey,
-					 send_flags);
-			if (unlikely(err))
-				goto stop;
+			sge->addr = addr;
+			sge->length = length;
+			sge->lkey = lkey;
 			sent_size += length;
 		} else {
 			err = -1;
 			goto stop;
 		}
+		if (sent_size <= txq->max_inline)
+			send_flags |= IBV_SEND_INLINE;
 		elts_head = elts_head_next;
 		/* Increment sent bytes counter. */
 		txq->stats.obytes += sent_size;
+		/* Set up WR. */
+		wr->sg_list = &elt->sge;
+		wr->num_sge = segs;
+		wr->opcode = IBV_WR_SEND;
+		wr->send_flags = send_flags;
+		*wr_next = wr;
+		wr_next = &wr->next;
 	}
 stop:
 	/* Take a shortcut if nothing must be sent. */
@@ -1123,12 +1102,37 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 	/* Increment sent packets counter. */
 	txq->stats.opackets += i;
 	/* Ring QP doorbell. */
-	err = txq->if_qp->send_flush(txq->qp);
+	*wr_next = NULL;
+	assert(wr_head);
+	err = ibv_post_send(txq->qp, wr_head, &wr_bad);
 	if (unlikely(err)) {
-		/* A nonzero value is not supposed to be returned.
-		 * Nothing can be done about it. */
-		DEBUG("%p: send_flush() failed with error %d",
-		      (void *)txq, err);
+		uint64_t obytes = 0;
+		uint64_t opackets = 0;
+
+		/* Rewind bad WRs. */
+		while (wr_bad != NULL) {
+			int j;
+
+			/* Force completion request if one was lost. */
+			if (wr_bad->send_flags & IBV_SEND_SIGNALED) {
+				elts_comp_cd = 1;
+				--elts_comp;
+			}
+			++opackets;
+			for (j = 0; j < wr_bad->num_sge; ++j)
+				obytes += wr_bad->sg_list[j].length;
+			elts_head = (elts_head ? elts_head : elts_n) - 1;
+			wr_bad = wr_bad->next;
+		}
+		txq->stats.opackets -= opackets;
+		txq->stats.obytes -= obytes;
+		i -= opackets;
+		DEBUG("%p: ibv_post_send() failed, %" PRIu64 " packets"
+		      " (%" PRIu64 " bytes) rejected: %s",
+		      (void *)txq,
+		      opackets,
+		      obytes,
+		      (err <= -1) ? "Internal error" : strerror(err));
 	}
 	txq->elts_head = elts_head;
 	txq->elts_comp += elts_comp;
@@ -1163,11 +1167,9 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		.socket = socket
 	};
 	union {
-		struct ibv_exp_query_intf_params params;
 		struct ibv_qp_init_attr init;
 		struct ibv_qp_attr mod;
 	} attr;
-	enum ibv_exp_query_intf_status status;
 	int ret = 0;
 
 	(void)conf; /* Thresholds configuration (ignored). */
@@ -1251,28 +1253,6 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		      (void *)dev, strerror(ret));
 		goto error;
 	}
-	attr.params = (struct ibv_exp_query_intf_params){
-		.intf_scope = IBV_EXP_INTF_GLOBAL,
-		.intf = IBV_EXP_INTF_CQ,
-		.obj = tmpl.cq,
-	};
-	tmpl.if_cq = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
-	if (tmpl.if_cq == NULL) {
-		ERROR("%p: CQ interface family query failed with status %d",
-		      (void *)dev, status);
-		goto error;
-	}
-	attr.params = (struct ibv_exp_query_intf_params){
-		.intf_scope = IBV_EXP_INTF_GLOBAL,
-		.intf = IBV_EXP_INTF_QP_BURST,
-		.obj = tmpl.qp,
-	};
-	tmpl.if_qp = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
-	if (tmpl.if_qp == NULL) {
-		ERROR("%p: QP interface family query failed with status %d",
-		      (void *)dev, status);
-		goto error;
-	}
 	/* Clean up txq in case we're reinitializing it. */
 	DEBUG("%p: cleaning-up old txq just in case", (void *)txq);
 	txq_cleanup(txq);
drivers/net/mlx4/mlx4.h +2 -2
index 6a5df5c..11c8885 100644
@@ -165,6 +165,8 @@ struct rxq {
 
 /* TX element. */
 struct txq_elt {
+	struct ibv_send_wr wr; /* Work request. */
+	struct ibv_sge sge; /* Scatter/gather element. */
 	struct rte_mbuf *buf;
 };
 
@@ -185,8 +187,6 @@ struct txq {
 	} mp2mr[MLX4_PMD_TX_MP_CACHE]; /* MP to MR translation table. */
 	struct ibv_cq *cq; /* Completion Queue. */
 	struct ibv_qp *qp; /* Queue Pair. */
-	struct ibv_exp_qp_burst_family *if_qp; /* QP burst interface. */
-	struct ibv_exp_cq_family *if_cq; /* CQ interface. */
 	uint32_t max_inline; /* Max inline send size <= MLX4_PMD_MAX_INLINE. */
 	unsigned int elts_n; /* (*elts)[] length. */
 	struct txq_elt (*elts)[]; /* TX elements. */
Signature · 1 line
2.1.4
#29 lore raw

PATCH 25/48 net/mlx4: revert fast Verbs interface for Rx

In reply to Adrien Mazarguil

This reverts commit acac55f164128fc76da8d93cae1e8c1e560e99f6.

"Fast Verbs" is a nonstandard experimental interface that must be reverted for compatibility reasons. Its replacement is slower but temporary, performance will be restored by a subsequent commit through an enhanced data path implementation. This one focuses on maintaining basic functionality in the meantime.

---
 drivers/net/mlx4/mlx4.c | 127 +++++++++++--------------------------------
 drivers/net/mlx4/mlx4.h |   2 -
 2 files changed, 33 insertions(+), 96 deletions(-)
drivers/net/mlx4/mlx4.c +33 -94
index 812f29c..5b7238e 100644
@@ -1628,32 +1628,8 @@ priv_mac_addr_add(struct priv *priv)
 static void
 rxq_cleanup(struct rxq *rxq)
 {
-	struct ibv_exp_release_intf_params params;
-
 	DEBUG("cleaning up %p", (void *)rxq);
 	rxq_free_elts(rxq);
-	if (rxq->if_qp != NULL) {
-		assert(rxq->priv != NULL);
-		assert(rxq->priv->ctx != NULL);
-		assert(rxq->qp != NULL);
-		params = (struct ibv_exp_release_intf_params){
-			.comp_mask = 0,
-		};
-		claim_zero(ibv_exp_release_intf(rxq->priv->ctx,
-						rxq->if_qp,
-						&params));
-	}
-	if (rxq->if_cq != NULL) {
-		assert(rxq->priv != NULL);
-		assert(rxq->priv->ctx != NULL);
-		assert(rxq->cq != NULL);
-		params = (struct ibv_exp_release_intf_params){
-			.comp_mask = 0,
-		};
-		claim_zero(ibv_exp_release_intf(rxq->priv->ctx,
-						rxq->if_cq,
-						&params));
-	}
 	if (rxq->qp != NULL)
 		claim_zero(ibv_destroy_qp(rxq->qp));
 	if (rxq->cq != NULL)
@@ -1687,23 +1663,37 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 	struct rxq_elt (*elts)[rxq->elts_n] = rxq->elts;
 	const unsigned int elts_n = rxq->elts_n;
 	unsigned int elts_head = rxq->elts_head;
-	struct ibv_sge sges[pkts_n];
+	struct ibv_wc wcs[pkts_n];
+	struct ibv_recv_wr *wr_head = NULL;
+	struct ibv_recv_wr **wr_next = &wr_head;
+	struct ibv_recv_wr *wr_bad = NULL;
 	unsigned int i;
 	unsigned int pkts_ret = 0;
 	int ret;
 
-	for (i = 0; (i != pkts_n); ++i) {
+	ret = ibv_poll_cq(rxq->cq, pkts_n, wcs);
+	if (unlikely(ret == 0))
+		return 0;
+	if (unlikely(ret < 0)) {
+		DEBUG("rxq=%p, ibv_poll_cq() failed (wc_n=%d)",
+		      (void *)rxq, ret);
+		return 0;
+	}
+	assert(ret <= (int)pkts_n);
+	/* For each work completion. */
+	for (i = 0; i != (unsigned int)ret; ++i) {
+		struct ibv_wc *wc = &wcs[i];
 		struct rxq_elt *elt = &(*elts)[elts_head];
 		struct ibv_recv_wr *wr = &elt->wr;
 		uint64_t wr_id = wr->wr_id;
-		unsigned int len;
+		uint32_t len = wc->byte_len;
 		struct rte_mbuf *seg = (void *)((uintptr_t)elt->sge.addr -
 			WR_ID(wr_id).offset);
 		struct rte_mbuf *rep;
-		uint32_t flags;
 
 		/* Sanity checks. */
 		assert(WR_ID(wr_id).id < rxq->elts_n);
+		assert(wr_id == wc->wr_id);
 		assert(wr->sg_list == &elt->sge);
 		assert(wr->num_sge == 1);
 		assert(elts_head < rxq->elts_n);
@@ -1714,41 +1704,19 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		 */
 		rte_mbuf_prefetch_part1(seg);
 		rte_mbuf_prefetch_part2(seg);
-		ret = rxq->if_cq->poll_length_flags(rxq->cq, NULL, NULL,
-						    &flags);
-		if (unlikely(ret < 0)) {
-			struct ibv_wc wc;
-			int wcs_n;
-
-			DEBUG("rxq=%p, poll_length() failed (ret=%d)",
-			      (void *)rxq, ret);
-			/* ibv_poll_cq() must be used in case of failure. */
-			wcs_n = ibv_poll_cq(rxq->cq, 1, &wc);
-			if (unlikely(wcs_n == 0))
-				break;
-			if (unlikely(wcs_n < 0)) {
-				DEBUG("rxq=%p, ibv_poll_cq() failed (wcs_n=%d)",
-				      (void *)rxq, wcs_n);
-				break;
-			}
-			assert(wcs_n == 1);
-			if (unlikely(wc.status != IBV_WC_SUCCESS)) {
-				/* Whatever, just repost the offending WR. */
-				DEBUG("rxq=%p, wr_id=%" PRIu64 ": bad work"
-				      " completion status (%d): %s",
-				      (void *)rxq, wc.wr_id, wc.status,
-				      ibv_wc_status_str(wc.status));
-				/* Increment dropped packets counter. */
-				++rxq->stats.idropped;
-				/* Add SGE to array for repost. */
-				sges[i] = elt->sge;
-				goto repost;
-			}
-			ret = wc.byte_len;
+		/* Link completed WRs together for repost. */
+		*wr_next = wr;
+		wr_next = &wr->next;
+		if (unlikely(wc->status != IBV_WC_SUCCESS)) {
+			/* Whatever, just repost the offending WR. */
+			DEBUG("rxq=%p, wr_id=%" PRIu64 ": bad work completion"
+			      " status (%d): %s",
+			      (void *)rxq, wr_id, wc->status,
+			      ibv_wc_status_str(wc->status));
+			/* Increment dropped packets counter. */
+			++rxq->stats.idropped;
+			goto repost;
 		}
-		if (ret == 0)
-			break;
-		len = ret;
 		rep = rte_mbuf_raw_alloc(rxq->mp);
 		if (unlikely(rep == NULL)) {
 			/*
@@ -1761,8 +1729,6 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			/* Increase out of memory counters. */
 			++rxq->stats.rx_nombuf;
 			++rxq->priv->dev->data->rx_mbuf_alloc_failed;
-			/* Add SGE to array for repost. */
-			sges[i] = elt->sge;
 			goto repost;
 		}
 
@@ -1774,9 +1740,6 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			 (uintptr_t)rep);
 		assert(WR_ID(wr->wr_id).id == WR_ID(wr_id).id);
 
-		/* Add SGE to array for repost. */
-		sges[i] = elt->sge;
-
 		/* Update seg information. */
 		SET_DATA_OFF(seg, RTE_PKTMBUF_HEADROOM);
 		NB_SEGS(seg) = 1;
@@ -1800,7 +1763,9 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 	if (unlikely(i == 0))
 		return 0;
 	/* Repost WRs. */
-	ret = rxq->if_qp->recv_burst(rxq->qp, sges, i);
+	*wr_next = NULL;
+	assert(wr_head);
+	ret = ibv_post_recv(rxq->qp, wr_head, &wr_bad);
 	if (unlikely(ret)) {
 		/* Inability to repost WRs is fatal. */
 		DEBUG("%p: recv_burst(): failed (ret=%d)",
@@ -1881,10 +1846,6 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 		.socket = socket
 	};
 	struct ibv_qp_attr mod;
-	union {
-		struct ibv_exp_query_intf_params params;
-	} attr;
-	enum ibv_exp_query_intf_status status;
 	struct ibv_recv_wr *bad_wr;
 	unsigned int mb_len;
 	int ret = 0;
@@ -1986,28 +1947,6 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	/* Save port ID. */
 	tmpl.port_id = dev->data->port_id;
 	DEBUG("%p: RTE port ID: %u", (void *)rxq, tmpl.port_id);
-	attr.params = (struct ibv_exp_query_intf_params){
-		.intf_scope = IBV_EXP_INTF_GLOBAL,
-		.intf = IBV_EXP_INTF_CQ,
-		.obj = tmpl.cq,
-	};
-	tmpl.if_cq = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
-	if (tmpl.if_cq == NULL) {
-		ERROR("%p: CQ interface family query failed with status %d",
-		      (void *)dev, status);
-		goto error;
-	}
-	attr.params = (struct ibv_exp_query_intf_params){
-		.intf_scope = IBV_EXP_INTF_GLOBAL,
-		.intf = IBV_EXP_INTF_QP_BURST,
-		.obj = tmpl.qp,
-	};
-	tmpl.if_qp = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
-	if (tmpl.if_qp == NULL) {
-		ERROR("%p: QP interface family query failed with status %d",
-		      (void *)dev, status);
-		goto error;
-	}
 	/* Clean up rxq in case we're reinitializing it. */
 	DEBUG("%p: cleaning-up old rxq just in case", (void *)rxq);
 	rxq_cleanup(rxq);
drivers/net/mlx4/mlx4.h +0 -2
index 11c8885..635036e 100644
@@ -152,8 +152,6 @@ struct rxq {
 	struct ibv_mr *mr; /* Memory Region (for mp). */
 	struct ibv_cq *cq; /* Completion Queue. */
 	struct ibv_qp *qp; /* Queue Pair. */
-	struct ibv_exp_qp_burst_family *if_qp; /* QP burst interface. */
-	struct ibv_exp_cq_family *if_cq; /* CQ interface. */
 	struct ibv_comp_channel *channel;
 	unsigned int port_id; /* Port ID for incoming packets. */
 	unsigned int elts_n; /* (*elts)[] length. */
Signature · 1 line
2.1.4
#30 lore raw

PATCH 26/48 net/mlx4: simplify link update function

In reply to Adrien Mazarguil

Returning a different value when the current link status differs from the previous one was probably useful at some point in the past but is now meaningless; this value is ignored both internally (mlx4 PMD) and externally (ethdev wrapper).

---
 drivers/net/mlx4/mlx4.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)
drivers/net/mlx4/mlx4.c +2 -7
index 5b7238e..7312482 100644
@@ -2543,13 +2543,8 @@ mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
 	dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
 			ETH_LINK_SPEED_FIXED);
-	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
-		/* Link status changed. */
-		dev->data->dev_link = dev_link;
-		return 0;
-	}
-	/* Link status is still the same. */
-	return -1;
+	dev->data->dev_link = dev_link;
+	return 0;
 }
 
 /**
Signature · 1 line
2.1.4
#31 lore raw

PATCH 27/48 net/mlx4: standardize on negative errno values

In reply to Adrien Mazarguil

Due to its reliance on system calls, the mlx4 PMD uses positive errno values internally and negative ones at the ethdev API border. Although most internal functions are documented, this mixed design is unusual and prone to mistakes (e.g. flow API implementation uses negative values exclusively).

Standardize on negative errno values and rely on rte_errno instead of errno in all functions.

---
 drivers/net/mlx4/mlx4.c | 485 ++++++++++++++++++++++++-------------------
 1 file changed, 274 insertions(+), 211 deletions(-)
drivers/net/mlx4/mlx4.c +274 -211
index 7312482..8cfeab2 100644
@@ -159,7 +159,7 @@ void priv_unlock(struct priv *priv)
  *   Interface name output buffer.
  *
  * @return
- *   0 on success, -1 on failure and errno is set.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_get_ifname(const struct priv *priv, char (*ifname)[IF_NAMESIZE])
@@ -174,8 +174,10 @@ priv_get_ifname(const struct priv *priv, char (*ifname)[IF_NAMESIZE])
 		MKSTR(path, "%s/device/net", priv->ctx->device->ibdev_path);
 
 		dir = opendir(path);
-		if (dir == NULL)
-			return -1;
+		if (dir == NULL) {
+			rte_errno = errno;
+			return -rte_errno;
+		}
 	}
 	while ((dent = readdir(dir)) != NULL) {
 		char *name = dent->d_name;
@@ -225,8 +227,10 @@ priv_get_ifname(const struct priv *priv, char (*ifname)[IF_NAMESIZE])
 			snprintf(match, sizeof(match), "%s", name);
 	}
 	closedir(dir);
-	if (match[0] == '\0')
-		return -1;
+	if (match[0] == '\0') {
+		rte_errno = ENODEV;
+		return -rte_errno;
+	}
 	strncpy(*ifname, match, sizeof(*ifname));
 	return 0;
 }
@@ -244,7 +248,8 @@ priv_get_ifname(const struct priv *priv, char (*ifname)[IF_NAMESIZE])
  *   Buffer size.
  *
  * @return
- *   0 on success, -1 on failure and errno is set.
+ *   Number of bytes read on success, negative errno value otherwise and
+ *   rte_errno is set.
  */
 static int
 priv_sysfs_read(const struct priv *priv, const char *entry,
@@ -253,25 +258,27 @@ priv_sysfs_read(const struct priv *priv, const char *entry,
 	char ifname[IF_NAMESIZE];
 	FILE *file;
 	int ret;
-	int err;
 
-	if (priv_get_ifname(priv, &ifname))
-		return -1;
+	ret = priv_get_ifname(priv, &ifname);
+	if (ret)
+		return ret;
 
 	MKSTR(path, "%s/device/net/%s/%s", priv->ctx->device->ibdev_path,
 	      ifname, entry);
 
 	file = fopen(path, "rb");
-	if (file == NULL)
-		return -1;
+	if (file == NULL) {
+		rte_errno = errno;
+		return -rte_errno;
+	}
 	ret = fread(buf, 1, size, file);
-	err = errno;
-	if (((size_t)ret < size) && (ferror(file)))
-		ret = -1;
-	else
+	if ((size_t)ret < size && ferror(file)) {
+		rte_errno = EIO;
+		ret = -rte_errno;
+	} else {
 		ret = size;
+	}
 	fclose(file);
-	errno = err;
 	return ret;
 }
 
@@ -288,7 +295,8 @@ priv_sysfs_read(const struct priv *priv, const char *entry,
  *   Buffer size.
  *
  * @return
- *   0 on success, -1 on failure and errno is set.
+ *   Number of bytes written on success, negative errno value otherwise and
+ *   rte_errno is set.
  */
 static int
 priv_sysfs_write(const struct priv *priv, const char *entry,
@@ -297,25 +305,27 @@ priv_sysfs_write(const struct priv *priv, const char *entry,
 	char ifname[IF_NAMESIZE];
 	FILE *file;
 	int ret;
-	int err;
 
-	if (priv_get_ifname(priv, &ifname))
-		return -1;
+	ret = priv_get_ifname(priv, &ifname);
+	if (ret)
+		return ret;
 
 	MKSTR(path, "%s/device/net/%s/%s", priv->ctx->device->ibdev_path,
 	      ifname, entry);
 
 	file = fopen(path, "wb");
-	if (file == NULL)
-		return -1;
+	if (file == NULL) {
+		rte_errno = errno;
+		return -rte_errno;
+	}
 	ret = fwrite(buf, 1, size, file);
-	err = errno;
-	if (((size_t)ret < size) || (ferror(file)))
-		ret = -1;
-	else
+	if ((size_t)ret < size || ferror(file)) {
+		rte_errno = EIO;
+		ret = -rte_errno;
+	} else {
 		ret = size;
+	}
 	fclose(file);
-	errno = err;
 	return ret;
 }
 
@@ -330,7 +340,7 @@ priv_sysfs_write(const struct priv *priv, const char *entry,
  *   Value output buffer.
  *
  * @return
- *   0 on success, -1 on failure and errno is set.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_get_sysfs_ulong(struct priv *priv, const char *name, unsigned long *value)
@@ -340,18 +350,19 @@ priv_get_sysfs_ulong(struct priv *priv, const char *name, unsigned long *value)
 	char value_str[32];
 
 	ret = priv_sysfs_read(priv, name, value_str, (sizeof(value_str) - 1));
-	if (ret == -1) {
+	if (ret < 0) {
 		DEBUG("cannot read %s value from sysfs: %s",
-		      name, strerror(errno));
-		return -1;
+		      name, strerror(rte_errno));
+		return ret;
 	}
 	value_str[ret] = '\0';
 	errno = 0;
 	value_ret = strtoul(value_str, NULL, 0);
 	if (errno) {
+		rte_errno = errno;
 		DEBUG("invalid %s value `%s': %s", name, value_str,
-		      strerror(errno));
-		return -1;
+		      strerror(rte_errno));
+		return -rte_errno;
 	}
 	*value = value_ret;
 	return 0;
@@ -368,7 +379,7 @@ priv_get_sysfs_ulong(struct priv *priv, const char *name, unsigned long *value)
  *   Value to set.
  *
  * @return
- *   0 on success, -1 on failure and errno is set.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_set_sysfs_ulong(struct priv *priv, const char *name, unsigned long value)
@@ -377,10 +388,10 @@ priv_set_sysfs_ulong(struct priv *priv, const char *name, unsigned long value)
 	MKSTR(value_str, "%lu", value);
 
 	ret = priv_sysfs_write(priv, name, value_str, (sizeof(value_str) - 1));
-	if (ret == -1) {
+	if (ret < 0) {
 		DEBUG("cannot write %s `%s' (%lu) to sysfs: %s",
-		      name, value_str, value, strerror(errno));
-		return -1;
+		      name, value_str, value, strerror(rte_errno));
+		return ret;
 	}
 	return 0;
 }
@@ -396,18 +407,23 @@ priv_set_sysfs_ulong(struct priv *priv, const char *name, unsigned long value)
  *   Interface request structure output buffer.
  *
  * @return
- *   0 on success, -1 on failure and errno is set.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_ifreq(const struct priv *priv, int req, struct ifreq *ifr)
 {
 	int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
-	int ret = -1;
+	int ret;
 
-	if (sock == -1)
-		return ret;
-	if (priv_get_ifname(priv, &ifr->ifr_name) == 0)
-		ret = ioctl(sock, req, ifr);
+	if (sock == -1) {
+		rte_errno = errno;
+		return -rte_errno;
+	}
+	ret = priv_get_ifname(priv, &ifr->ifr_name);
+	if (!ret && ioctl(sock, req, ifr) == -1) {
+		rte_errno = errno;
+		ret = -rte_errno;
+	}
 	close(sock);
 	return ret;
 }
@@ -421,15 +437,16 @@ priv_ifreq(const struct priv *priv, int req, struct ifreq *ifr)
  *   MTU value output buffer.
  *
  * @return
- *   0 on success, -1 on failure and errno is set.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_get_mtu(struct priv *priv, uint16_t *mtu)
 {
-	unsigned long ulong_mtu;
+	unsigned long ulong_mtu = 0;
+	int ret = priv_get_sysfs_ulong(priv, "mtu", &ulong_mtu);
 
-	if (priv_get_sysfs_ulong(priv, "mtu", &ulong_mtu) == -1)
-		return -1;
+	if (ret)
+		return ret;
 	*mtu = ulong_mtu;
 	return 0;
 }
@@ -443,20 +460,23 @@ priv_get_mtu(struct priv *priv, uint16_t *mtu)
  *   MTU value to set.
  *
  * @return
- *   0 on success, -1 on failure and errno is set.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_set_mtu(struct priv *priv, uint16_t mtu)
 {
 	uint16_t new_mtu;
+	int ret = priv_set_sysfs_ulong(priv, "mtu", mtu);
 
-	if (priv_set_sysfs_ulong(priv, "mtu", mtu) ||
-	    priv_get_mtu(priv, &new_mtu))
-		return -1;
+	if (ret)
+		return ret;
+	ret = priv_get_mtu(priv, &new_mtu);
+	if (ret)
+		return ret;
 	if (new_mtu == mtu)
 		return 0;
-	errno = EINVAL;
-	return -1;
+	rte_errno = EINVAL;
+	return -rte_errno;
 }
 
 /**
@@ -470,15 +490,16 @@ priv_set_mtu(struct priv *priv, uint16_t mtu)
  *   Bitmask for flags to modify.
  *
  * @return
- *   0 on success, -1 on failure and errno is set.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_set_flags(struct priv *priv, unsigned int keep, unsigned int flags)
 {
-	unsigned long tmp;
+	unsigned long tmp = 0;
+	int ret = priv_get_sysfs_ulong(priv, "flags", &tmp);
 
-	if (priv_get_sysfs_ulong(priv, "flags", &tmp) == -1)
-		return -1;
+	if (ret)
+		return ret;
 	tmp &= keep;
 	tmp |= (flags & (~keep));
 	return priv_set_sysfs_ulong(priv, "flags", tmp);
@@ -513,7 +534,7 @@ priv_mac_addr_del(struct priv *priv);
  *   Pointer to Ethernet device structure.
  *
  * @return
- *   0 on success, errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 dev_configure(struct rte_eth_dev *dev)
@@ -544,7 +565,7 @@ dev_configure(struct rte_eth_dev *dev)
  *   Pointer to Ethernet device structure.
  *
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_dev_configure(struct rte_eth_dev *dev)
@@ -554,9 +575,8 @@ mlx4_dev_configure(struct rte_eth_dev *dev)
 
 	priv_lock(priv);
 	ret = dev_configure(dev);
-	assert(ret >= 0);
 	priv_unlock(priv);
-	return -ret;
+	return ret;
 }
 
 static uint16_t mlx4_tx_burst(void *, struct rte_mbuf **, uint16_t);
@@ -573,7 +593,7 @@ static uint16_t removed_rx_burst(void *, struct rte_mbuf **, uint16_t);
  *   Number of elements to allocate.
  *
  * @return
- *   0 on success, errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 txq_alloc_elts(struct txq *txq, unsigned int elts_n)
@@ -612,7 +632,8 @@ txq_alloc_elts(struct txq *txq, unsigned int elts_n)
 
 	DEBUG("%p: failed, freed everything", (void *)txq);
 	assert(ret > 0);
-	return ret;
+	rte_errno = ret;
+	return -rte_errno;
 }
 
 /**
@@ -806,7 +827,7 @@ static struct ibv_mr *mlx4_mp2mr(struct ibv_pd *, struct rte_mempool *)
  *   Pointer to memory pool.
  *
  * @return
- *   Memory region pointer, NULL in case of error.
+ *   Memory region pointer, NULL in case of error and rte_errno is set.
  */
 static struct ibv_mr *
 mlx4_mp2mr(struct ibv_pd *pd, struct rte_mempool *mp)
@@ -815,8 +836,10 @@ mlx4_mp2mr(struct ibv_pd *pd, struct rte_mempool *mp)
 	uintptr_t start;
 	uintptr_t end;
 	unsigned int i;
+	struct ibv_mr *mr;
 
 	if (mlx4_check_mempool(mp, &start, &end) != 0) {
+		rte_errno = EINVAL;
 		ERROR("mempool %p: not virtually contiguous",
 			(void *)mp);
 		return NULL;
@@ -839,10 +862,13 @@ mlx4_mp2mr(struct ibv_pd *pd, struct rte_mempool *mp)
 	DEBUG("mempool %p using start=%p end=%p size=%zu for MR",
 	      (void *)mp, (void *)start, (void *)end,
 	      (size_t)(end - start));
-	return ibv_reg_mr(pd,
-			  (void *)start,
-			  end - start,
-			  IBV_ACCESS_LOCAL_WRITE);
+	mr = ibv_reg_mr(pd,
+			(void *)start,
+			end - start,
+			IBV_ACCESS_LOCAL_WRITE);
+	if (!mr)
+		rte_errno = errno ? errno : EINVAL;
+	return mr;
 }
 
 /**
@@ -1155,7 +1181,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
  *   Thresholds parameters.
  *
  * @return
- *   0 on success, errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
@@ -1170,21 +1196,24 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		struct ibv_qp_init_attr init;
 		struct ibv_qp_attr mod;
 	} attr;
-	int ret = 0;
+	int ret;
 
 	(void)conf; /* Thresholds configuration (ignored). */
-	if (priv == NULL)
-		return EINVAL;
+	if (priv == NULL) {
+		rte_errno = EINVAL;
+		goto error;
+	}
 	if (desc == 0) {
+		rte_errno = EINVAL;
 		ERROR("%p: invalid number of TX descriptors", (void *)dev);
-		return EINVAL;
+		goto error;
 	}
 	/* MRs will be registered in mp2mr[] later. */
 	tmpl.cq = ibv_create_cq(priv->ctx, desc, NULL, NULL, 0);
 	if (tmpl.cq == NULL) {
-		ret = ENOMEM;
+		rte_errno = ENOMEM;
 		ERROR("%p: CQ creation failure: %s",
-		      (void *)dev, strerror(ret));
+		      (void *)dev, strerror(rte_errno));
 		goto error;
 	}
 	DEBUG("priv->device_attr.max_qp_wr is %d",
@@ -1212,9 +1241,9 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 	};
 	tmpl.qp = ibv_create_qp(priv->pd, &attr.init);
 	if (tmpl.qp == NULL) {
-		ret = (errno ? errno : EINVAL);
+		rte_errno = errno ? errno : EINVAL;
 		ERROR("%p: QP creation failure: %s",
-		      (void *)dev, strerror(ret));
+		      (void *)dev, strerror(rte_errno));
 		goto error;
 	}
 	/* ibv_create_qp() updates this value. */
@@ -1227,14 +1256,16 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 	};
 	ret = ibv_modify_qp(tmpl.qp, &attr.mod, IBV_QP_STATE | IBV_QP_PORT);
 	if (ret) {
+		rte_errno = ret;
 		ERROR("%p: QP state to IBV_QPS_INIT failed: %s",
-		      (void *)dev, strerror(ret));
+		      (void *)dev, strerror(rte_errno));
 		goto error;
 	}
 	ret = txq_alloc_elts(&tmpl, desc);
 	if (ret) {
+		rte_errno = ret;
 		ERROR("%p: TXQ allocation failed: %s",
-		      (void *)dev, strerror(ret));
+		      (void *)dev, strerror(rte_errno));
 		goto error;
 	}
 	attr.mod = (struct ibv_qp_attr){
@@ -1242,15 +1273,17 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 	};
 	ret = ibv_modify_qp(tmpl.qp, &attr.mod, IBV_QP_STATE);
 	if (ret) {
+		rte_errno = ret;
 		ERROR("%p: QP state to IBV_QPS_RTR failed: %s",
-		      (void *)dev, strerror(ret));
+		      (void *)dev, strerror(rte_errno));
 		goto error;
 	}
 	attr.mod.qp_state = IBV_QPS_RTS;
 	ret = ibv_modify_qp(tmpl.qp, &attr.mod, IBV_QP_STATE);
 	if (ret) {
+		rte_errno = ret;
 		ERROR("%p: QP state to IBV_QPS_RTS failed: %s",
-		      (void *)dev, strerror(ret));
+		      (void *)dev, strerror(rte_errno));
 		goto error;
 	}
 	/* Clean up txq in case we're reinitializing it. */
@@ -1260,12 +1293,13 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 	DEBUG("%p: txq updated with %p", (void *)txq, (void *)&tmpl);
 	/* Pre-register known mempools. */
 	rte_mempool_walk(txq_mp2mr_iter, txq);
-	assert(ret == 0);
 	return 0;
 error:
+	ret = rte_errno;
 	txq_cleanup(&tmpl);
-	assert(ret > 0);
-	return ret;
+	rte_errno = ret;
+	assert(rte_errno > 0);
+	return -rte_errno;
 }
 
 /**
@@ -1283,7 +1317,7 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
  *   Thresholds parameters.
  *
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
@@ -1297,27 +1331,30 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
 	if (idx >= priv->txqs_n) {
+		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
 		      (void *)dev, idx, priv->txqs_n);
 		priv_unlock(priv);
-		return -EOVERFLOW;
+		return -rte_errno;
 	}
 	if (txq != NULL) {
 		DEBUG("%p: reusing already allocated queue index %u (%p)",
 		      (void *)dev, idx, (void *)txq);
 		if (priv->started) {
+			rte_errno = EEXIST;
 			priv_unlock(priv);
-			return -EEXIST;
+			return -rte_errno;
 		}
 		(*priv->txqs)[idx] = NULL;
 		txq_cleanup(txq);
 	} else {
 		txq = rte_calloc_socket("TXQ", 1, sizeof(*txq), 0, socket);
 		if (txq == NULL) {
+			rte_errno = ENOMEM;
 			ERROR("%p: unable to allocate queue index %u",
 			      (void *)dev, idx);
 			priv_unlock(priv);
-			return -ENOMEM;
+			return -rte_errno;
 		}
 	}
 	ret = txq_setup(dev, txq, desc, socket, conf);
@@ -1332,7 +1369,7 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		dev->tx_pkt_burst = mlx4_tx_burst;
 	}
 	priv_unlock(priv);
-	return -ret;
+	return ret;
 }
 
 /**
@@ -1378,7 +1415,7 @@ mlx4_tx_queue_release(void *dpdk_txq)
  *   with rte_pktmbuf_alloc().
  *
  * @return
- *   0 on success, errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n, struct rte_mbuf **pool)
@@ -1387,11 +1424,10 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n, struct rte_mbuf **pool)
 	struct rxq_elt (*elts)[elts_n] =
 		rte_calloc_socket("RXQ elements", 1, sizeof(*elts), 0,
 				  rxq->socket);
-	int ret = 0;
 
 	if (elts == NULL) {
+		rte_errno = ENOMEM;
 		ERROR("%p: can't allocate packets array", (void *)rxq);
-		ret = ENOMEM;
 		goto error;
 	}
 	/* For each WR (packet). */
@@ -1408,9 +1444,9 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n, struct rte_mbuf **pool)
 		} else
 			buf = rte_pktmbuf_alloc(rxq->mp);
 		if (buf == NULL) {
+			rte_errno = ENOMEM;
 			assert(pool == NULL);
 			ERROR("%p: empty mbuf pool", (void *)rxq);
-			ret = ENOMEM;
 			goto error;
 		}
 		/* Configure WR. Work request ID contains its own index in
@@ -1442,11 +1478,11 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n, struct rte_mbuf **pool)
 		if ((WR_ID(wr->wr_id).id != i) ||
 		    ((void *)((uintptr_t)sge->addr -
 			WR_ID(wr->wr_id).offset) != buf)) {
+			rte_errno = EOVERFLOW;
 			ERROR("%p: cannot store index and offset in WR ID",
 			      (void *)rxq);
 			sge->addr = 0;
 			rte_pktmbuf_free(buf);
-			ret = EOVERFLOW;
 			goto error;
 		}
 	}
@@ -1457,7 +1493,6 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n, struct rte_mbuf **pool)
 	rxq->elts_n = elts_n;
 	rxq->elts_head = 0;
 	rxq->elts = elts;
-	assert(ret == 0);
 	return 0;
 error:
 	if (elts != NULL) {
@@ -1476,8 +1511,8 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n, struct rte_mbuf **pool)
 		rte_free(elts);
 	}
 	DEBUG("%p: failed, freed everything", (void *)rxq);
-	assert(ret > 0);
-	return ret;
+	assert(rte_errno > 0);
+	return -rte_errno;
 }
 
 /**
@@ -1543,7 +1578,7 @@ priv_mac_addr_del(struct priv *priv)
  *   Pointer to private structure.
  *
  * @return
- *   0 on success, errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_mac_addr_add(struct priv *priv)
@@ -1601,16 +1636,12 @@ priv_mac_addr_add(struct priv *priv)
 	      (void *)priv,
 	      (*mac)[0], (*mac)[1], (*mac)[2], (*mac)[3], (*mac)[4], (*mac)[5]);
 	/* Create related flow. */
-	errno = 0;
 	flow = ibv_create_flow(rxq->qp, attr);
 	if (flow == NULL) {
-		/* It's not clear whether errno is always set in this case. */
+		rte_errno = errno ? errno : EINVAL;
 		ERROR("%p: flow configuration failed, errno=%d: %s",
-		      (void *)rxq, errno,
-		      (errno ? strerror(errno) : "Unknown error"));
-		if (errno)
-			return errno;
-		return EINVAL;
+		      (void *)rxq, rte_errno, strerror(errno));
+		return -rte_errno;
 	}
 	assert(priv->mac_flow == NULL);
 	priv->mac_flow = flow;
@@ -1791,11 +1822,12 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
  *   Number of descriptors in QP (hint only).
  *
  * @return
- *   QP pointer or NULL in case of error.
+ *   QP pointer or NULL in case of error and rte_errno is set.
  */
 static struct ibv_qp *
 rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc)
 {
+	struct ibv_qp *qp;
 	struct ibv_qp_init_attr attr = {
 		/* CQ to be associated with the send queue. */
 		.send_cq = cq,
@@ -1812,7 +1844,10 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc)
 		.qp_type = IBV_QPT_RAW_PACKET,
 	};
 
-	return ibv_create_qp(priv->pd, &attr);
+	qp = ibv_create_qp(priv->pd, &attr);
+	if (!qp)
+		rte_errno = errno ? errno : EINVAL;
+	return qp;
 }
 
 /**
@@ -1832,7 +1867,7 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc)
  *   Memory pool for buffer allocations.
  *
  * @return
- *   0 on success, errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
@@ -1848,13 +1883,14 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	struct ibv_qp_attr mod;
 	struct ibv_recv_wr *bad_wr;
 	unsigned int mb_len;
-	int ret = 0;
+	int ret;
 
 	(void)conf; /* Thresholds configuration (ignored). */
 	mb_len = rte_pktmbuf_data_room_size(mp);
 	if (desc == 0) {
+		rte_errno = EINVAL;
 		ERROR("%p: invalid number of RX descriptors", (void *)dev);
-		return EINVAL;
+		goto error;
 	}
 	/* Enable scattered packets support for this queue if necessary. */
 	assert(mb_len >= RTE_PKTMBUF_HEADROOM);
@@ -1876,26 +1912,26 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	/* Use the entire RX mempool as the memory region. */
 	tmpl.mr = mlx4_mp2mr(priv->pd, mp);
 	if (tmpl.mr == NULL) {
-		ret = EINVAL;
+		rte_errno = EINVAL;
 		ERROR("%p: MR creation failure: %s",
-		      (void *)dev, strerror(ret));
+		      (void *)dev, strerror(rte_errno));
 		goto error;
 	}
 	if (dev->data->dev_conf.intr_conf.rxq) {
 		tmpl.channel = ibv_create_comp_channel(priv->ctx);
 		if (tmpl.channel == NULL) {
-			ret = ENOMEM;
+			rte_errno = ENOMEM;
 			ERROR("%p: Rx interrupt completion channel creation"
 			      " failure: %s",
-			      (void *)dev, strerror(ret));
+			      (void *)dev, strerror(rte_errno));
 			goto error;
 		}
 	}
 	tmpl.cq = ibv_create_cq(priv->ctx, desc, NULL, tmpl.channel, 0);
 	if (tmpl.cq == NULL) {
-		ret = ENOMEM;
+		rte_errno = ENOMEM;
 		ERROR("%p: CQ creation failure: %s",
-		      (void *)dev, strerror(ret));
+		      (void *)dev, strerror(rte_errno));
 		goto error;
 	}
 	DEBUG("priv->device_attr.max_qp_wr is %d",
@@ -1904,9 +1940,8 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	      priv->device_attr.max_sge);
 	tmpl.qp = rxq_setup_qp(priv, tmpl.cq, desc);
 	if (tmpl.qp == NULL) {
-		ret = (errno ? errno : EINVAL);
 		ERROR("%p: QP creation failure: %s",
-		      (void *)dev, strerror(ret));
+		      (void *)dev, strerror(rte_errno));
 		goto error;
 	}
 	mod = (struct ibv_qp_attr){
@@ -1917,22 +1952,24 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	};
 	ret = ibv_modify_qp(tmpl.qp, &mod, IBV_QP_STATE | IBV_QP_PORT);
 	if (ret) {
+		rte_errno = ret;
 		ERROR("%p: QP state to IBV_QPS_INIT failed: %s",
-		      (void *)dev, strerror(ret));
+		      (void *)dev, strerror(rte_errno));
 		goto error;
 	}
 	ret = rxq_alloc_elts(&tmpl, desc, NULL);
 	if (ret) {
 		ERROR("%p: RXQ allocation failed: %s",
-		      (void *)dev, strerror(ret));
+		      (void *)dev, strerror(rte_errno));
 		goto error;
 	}
 	ret = ibv_post_recv(tmpl.qp, &(*tmpl.elts)[0].wr, &bad_wr);
 	if (ret) {
+		rte_errno = ret;
 		ERROR("%p: ibv_post_recv() failed for WR %p: %s",
 		      (void *)dev,
 		      (void *)bad_wr,
-		      strerror(ret));
+		      strerror(rte_errno));
 		goto error;
 	}
 	mod = (struct ibv_qp_attr){
@@ -1940,8 +1977,9 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	};
 	ret = ibv_modify_qp(tmpl.qp, &mod, IBV_QP_STATE);
 	if (ret) {
+		rte_errno = ret;
 		ERROR("%p: QP state to IBV_QPS_RTR failed: %s",
-		      (void *)dev, strerror(ret));
+		      (void *)dev, strerror(rte_errno));
 		goto error;
 	}
 	/* Save port ID. */
@@ -1952,12 +1990,13 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	rxq_cleanup(rxq);
 	*rxq = tmpl;
 	DEBUG("%p: rxq updated with %p", (void *)rxq, (void *)&tmpl);
-	assert(ret == 0);
 	return 0;
 error:
+	ret = rte_errno;
 	rxq_cleanup(&tmpl);
-	assert(ret > 0);
-	return ret;
+	rte_errno = ret;
+	assert(rte_errno > 0);
+	return -rte_errno;
 }
 
 /**
@@ -1977,7 +2016,7 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
  *   Memory pool for buffer allocations.
  *
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
@@ -1992,17 +2031,19 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
 	if (idx >= priv->rxqs_n) {
+		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
 		      (void *)dev, idx, priv->rxqs_n);
 		priv_unlock(priv);
-		return -EOVERFLOW;
+		return -rte_errno;
 	}
 	if (rxq != NULL) {
 		DEBUG("%p: reusing already allocated queue index %u (%p)",
 		      (void *)dev, idx, (void *)rxq);
 		if (priv->started) {
+			rte_errno = EEXIST;
 			priv_unlock(priv);
-			return -EEXIST;
+			return -rte_errno;
 		}
 		(*priv->rxqs)[idx] = NULL;
 		if (idx == 0)
@@ -2011,10 +2052,11 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	} else {
 		rxq = rte_calloc_socket("RXQ", 1, sizeof(*rxq), 0, socket);
 		if (rxq == NULL) {
+			rte_errno = ENOMEM;
 			ERROR("%p: unable to allocate queue index %u",
 			      (void *)dev, idx);
 			priv_unlock(priv);
-			return -ENOMEM;
+			return -rte_errno;
 		}
 	}
 	ret = rxq_setup(dev, rxq, desc, socket, conf, mp);
@@ -2029,7 +2071,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		dev->rx_pkt_burst = mlx4_rx_burst;
 	}
 	priv_unlock(priv);
-	return -ret;
+	return ret;
 }
 
 /**
@@ -2081,7 +2123,7 @@ priv_dev_link_interrupt_handler_install(struct priv *, struct rte_eth_dev *);
  *   Pointer to Ethernet device structure.
  *
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_dev_start(struct rte_eth_dev *dev)
@@ -2130,7 +2172,7 @@ mlx4_dev_start(struct rte_eth_dev *dev)
 	priv_mac_addr_del(priv);
 	priv->started = 0;
 	priv_unlock(priv);
-	return -ret;
+	return ret;
 }
 
 /**
@@ -2295,7 +2337,7 @@ mlx4_dev_close(struct rte_eth_dev *dev)
  *   Nonzero for link up, otherwise link down.
  *
  * @return
- *   0 on success, errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_set_link(struct priv *priv, int up)
@@ -2325,7 +2367,7 @@ priv_set_link(struct priv *priv, int up)
  *   Pointer to Ethernet device structure.
  *
  * @return
- *   0 on success, errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_set_link_down(struct rte_eth_dev *dev)
@@ -2346,7 +2388,7 @@ mlx4_set_link_down(struct rte_eth_dev *dev)
  *   Pointer to Ethernet device structure.
  *
  * @return
- *   0 on success, errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_set_link_up(struct rte_eth_dev *dev)
@@ -2504,6 +2546,9 @@ mlx4_stats_reset(struct rte_eth_dev *dev)
  *   Pointer to Ethernet device structure.
  * @param wait_to_complete
  *   Wait for request completion (ignored).
+ *
+ * @return
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
@@ -2518,12 +2563,14 @@ mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
 	/* priv_lock() is not taken to allow concurrent calls. */
 
-	if (priv == NULL)
-		return -EINVAL;
+	if (priv == NULL) {
+		rte_errno = EINVAL;
+		return -rte_errno;
+	}
 	(void)wait_to_complete;
 	if (priv_ifreq(priv, SIOCGIFFLAGS, &ifr)) {
-		WARN("ioctl(SIOCGIFFLAGS) failed: %s", strerror(errno));
-		return -1;
+		WARN("ioctl(SIOCGIFFLAGS) failed: %s", strerror(rte_errno));
+		return -rte_errno;
 	}
 	memset(&dev_link, 0, sizeof(dev_link));
 	dev_link.link_status = ((ifr.ifr_flags & IFF_UP) &&
@@ -2531,8 +2578,8 @@ mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	ifr.ifr_data = (void *)&edata;
 	if (priv_ifreq(priv, SIOCETHTOOL, &ifr)) {
 		WARN("ioctl(SIOCETHTOOL, ETHTOOL_GSET) failed: %s",
-		     strerror(errno));
-		return -1;
+		     strerror(rte_errno));
+		return -rte_errno;
 	}
 	link_speed = ethtool_cmd_speed(&edata);
 	if (link_speed == -1)
@@ -2556,7 +2603,7 @@ mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
  *   New MTU.
  *
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
@@ -2567,9 +2614,9 @@ mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	priv_lock(priv);
 	/* Set kernel interface MTU first. */
 	if (priv_set_mtu(priv, mtu)) {
-		ret = errno;
+		ret = rte_errno;
 		WARN("cannot set port %u MTU to %u: %s", priv->port, mtu,
-		     strerror(ret));
+		     strerror(rte_errno));
 		goto out;
 	} else
 		DEBUG("adapter port %u MTU set to %u", priv->port, mtu);
@@ -2589,7 +2636,7 @@ mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
  *   Flow control output buffer.
  *
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
@@ -2604,10 +2651,10 @@ mlx4_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 	ifr.ifr_data = (void *)&ethpause;
 	priv_lock(priv);
 	if (priv_ifreq(priv, SIOCETHTOOL, &ifr)) {
-		ret = errno;
+		ret = rte_errno;
 		WARN("ioctl(SIOCETHTOOL, ETHTOOL_GPAUSEPARAM)"
 		     " failed: %s",
-		     strerror(ret));
+		     strerror(rte_errno));
 		goto out;
 	}
 
@@ -2637,7 +2684,7 @@ mlx4_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
  *   Flow control parameters.
  *
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
@@ -2665,10 +2712,10 @@ mlx4_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 
 	priv_lock(priv);
 	if (priv_ifreq(priv, SIOCETHTOOL, &ifr)) {
-		ret = errno;
+		ret = rte_errno;
 		WARN("ioctl(SIOCETHTOOL, ETHTOOL_SPAUSEPARAM)"
 		     " failed: %s",
-		     strerror(ret));
+		     strerror(rte_errno));
 		goto out;
 	}
 	ret = 0;
@@ -2701,7 +2748,7 @@ const struct rte_flow_ops mlx4_flow_ops = {
  *   Pointer to operation-specific structure.
  *
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_dev_filter_ctrl(struct rte_eth_dev *dev,
@@ -2709,12 +2756,10 @@ mlx4_dev_filter_ctrl(struct rte_eth_dev *dev,
 		     enum rte_filter_op filter_op,
 		     void *arg)
 {
-	int ret = EINVAL;
-
 	switch (filter_type) {
 	case RTE_ETH_FILTER_GENERIC:
 		if (filter_op != RTE_ETH_FILTER_GET)
-			return -EINVAL;
+			break;
 		*(const void **)arg = &mlx4_flow_ops;
 		return 0;
 	default:
@@ -2722,7 +2767,8 @@ mlx4_dev_filter_ctrl(struct rte_eth_dev *dev,
 		      (void *)dev, filter_type);
 		break;
 	}
-	return -ret;
+	rte_errno = ENOTSUP;
+	return -rte_errno;
 }
 
 static const struct eth_dev_ops mlx4_dev_ops = {
@@ -2757,7 +2803,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
  *   PCI bus address output buffer.
  *
  * @return
- *   0 on success, -1 on failure and errno is set.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_ibv_device_to_pci_addr(const struct ibv_device *device,
@@ -2768,8 +2814,10 @@ mlx4_ibv_device_to_pci_addr(const struct ibv_device *device,
 	MKSTR(path, "%s/device/uevent", device->ibdev_path);
 
 	file = fopen(path, "rb");
-	if (file == NULL)
-		return -1;
+	if (file == NULL) {
+		rte_errno = errno;
+		return -rte_errno;
+	}
 	while (fgets(line, sizeof(line), file) == line) {
 		size_t len = strlen(line);
 		int ret;
@@ -2807,15 +2855,16 @@ mlx4_ibv_device_to_pci_addr(const struct ibv_device *device,
  *   MAC address output buffer.
  *
  * @return
- *   0 on success, -1 on failure and errno is set.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_get_mac(struct priv *priv, uint8_t (*mac)[ETHER_ADDR_LEN])
 {
 	struct ifreq request;
+	int ret = priv_ifreq(priv, SIOCGIFHWADDR, &request);
 
-	if (priv_ifreq(priv, SIOCGIFHWADDR, &request))
-		return -1;
+	if (ret)
+		return ret;
 	memcpy(mac, request.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
 	return 0;
 }
@@ -2953,7 +3002,7 @@ mlx4_dev_interrupt_handler(void *cb_arg)
  * @param dev
  *   Pointer to the rte_eth_dev structure.
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_dev_interrupt_handler_uninstall(struct priv *priv, struct rte_eth_dev *dev)
@@ -2967,11 +3016,9 @@ priv_dev_interrupt_handler_uninstall(struct priv *priv, struct rte_eth_dev *dev)
 					   mlx4_dev_interrupt_handler,
 					   dev);
 	if (ret < 0) {
-		ERROR("rte_intr_callback_unregister failed with %d"
-		      "%s%s%s", ret,
-		      (errno ? " (errno: " : ""),
-		      (errno ? strerror(errno) : ""),
-		      (errno ? ")" : ""));
+		rte_errno = ret;
+		ERROR("rte_intr_callback_unregister failed with %d %s",
+		      ret, strerror(rte_errno));
 	}
 	priv->intr_handle.fd = 0;
 	priv->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
@@ -2986,7 +3033,7 @@ priv_dev_interrupt_handler_uninstall(struct priv *priv, struct rte_eth_dev *dev)
  * @param dev
  *   Pointer to the rte_eth_dev structure.
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_dev_interrupt_handler_install(struct priv *priv,
@@ -3006,10 +3053,11 @@ priv_dev_interrupt_handler_install(struct priv *priv,
 	flags = fcntl(priv->ctx->async_fd, F_GETFL);
 	rc = fcntl(priv->ctx->async_fd, F_SETFL, flags | O_NONBLOCK);
 	if (rc < 0) {
+		rte_errno = errno ? errno : EINVAL;
 		INFO("failed to change file descriptor async event queue");
 		dev->data->dev_conf.intr_conf.lsc = 0;
 		dev->data->dev_conf.intr_conf.rmv = 0;
-		return -errno;
+		return -rte_errno;
 	} else {
 		priv->intr_handle.fd = priv->ctx->async_fd;
 		priv->intr_handle.type = RTE_INTR_HANDLE_EXT;
@@ -3017,9 +3065,10 @@ priv_dev_interrupt_handler_install(struct priv *priv,
 						 mlx4_dev_interrupt_handler,
 						 dev);
 		if (rc) {
+			rte_errno = -rc;
 			ERROR("rte_intr_callback_register failed "
-			      " (errno: %s)", strerror(errno));
-			return rc;
+			      " (rte_errno: %s)", strerror(rte_errno));
+			return -rte_errno;
 		}
 	}
 	return 0;
@@ -3033,7 +3082,7 @@ priv_dev_interrupt_handler_install(struct priv *priv,
  * @param dev
  *   Pointer to the rte_eth_dev structure.
  * @return
- *   0 on success, negative value on error.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_dev_removal_interrupt_handler_uninstall(struct priv *priv,
@@ -3054,7 +3103,7 @@ priv_dev_removal_interrupt_handler_uninstall(struct priv *priv,
  * @param dev
  *   Pointer to the rte_eth_dev structure.
  * @return
- *   0 on success, negative value on error,
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_dev_link_interrupt_handler_uninstall(struct priv *priv,
@@ -3072,7 +3121,7 @@ priv_dev_link_interrupt_handler_uninstall(struct priv *priv,
 		if (rte_eal_alarm_cancel(mlx4_dev_link_status_handler,
 					 dev)) {
 			ERROR("rte_eal_alarm_cancel failed "
-			      " (errno: %s)", strerror(rte_errno));
+			      " (rte_errno: %s)", strerror(rte_errno));
 			return -rte_errno;
 		}
 	priv->pending_alarm = 0;
@@ -3087,7 +3136,7 @@ priv_dev_link_interrupt_handler_uninstall(struct priv *priv,
  * @param dev
  *   Pointer to the rte_eth_dev structure.
  * @return
- *   0 on success, negative value on error.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_dev_link_interrupt_handler_install(struct priv *priv,
@@ -3112,7 +3161,7 @@ priv_dev_link_interrupt_handler_install(struct priv *priv,
  * @param dev
  *   Pointer to the rte_eth_dev structure.
  * @return
- *   0 on success, negative value on error.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_dev_removal_interrupt_handler_install(struct priv *priv,
@@ -3136,7 +3185,7 @@ priv_dev_removal_interrupt_handler_install(struct priv *priv,
  *   Pointer to private structure.
  *
  * @return
- *   0 on success, negative on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 priv_rx_intr_vec_enable(struct priv *priv)
@@ -3152,9 +3201,10 @@ priv_rx_intr_vec_enable(struct priv *priv)
 	priv_rx_intr_vec_disable(priv);
 	intr_handle->intr_vec = malloc(sizeof(intr_handle->intr_vec[rxqs_n]));
 	if (intr_handle->intr_vec == NULL) {
+		rte_errno = ENOMEM;
 		ERROR("failed to allocate memory for interrupt vector,"
 		      " Rx interrupts will not be supported");
-		return -ENOMEM;
+		return -rte_errno;
 	}
 	intr_handle->type = RTE_INTR_HANDLE_EXT;
 	for (i = 0; i != n; ++i) {
@@ -3172,20 +3222,22 @@ priv_rx_intr_vec_enable(struct priv *priv)
 			continue;
 		}
 		if (count >= RTE_MAX_RXTX_INTR_VEC_ID) {
+			rte_errno = E2BIG;
 			ERROR("too many Rx queues for interrupt vector size"
 			      " (%d), Rx interrupts cannot be enabled",
 			      RTE_MAX_RXTX_INTR_VEC_ID);
 			priv_rx_intr_vec_disable(priv);
-			return -1;
+			return -rte_errno;
 		}
 		fd = rxq->channel->fd;
 		flags = fcntl(fd, F_GETFL);
 		rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
 		if (rc < 0) {
+			rte_errno = errno;
 			ERROR("failed to make Rx interrupt file descriptor"
 			      " %d non-blocking for queue index %d", fd, i);
 			priv_rx_intr_vec_disable(priv);
-			return rc;
+			return -rte_errno;
 		}
 		intr_handle->intr_vec[i] = RTE_INTR_VEC_RXTX_OFFSET + count;
 		intr_handle->efds[count] = fd;
@@ -3224,7 +3276,7 @@ priv_rx_intr_vec_disable(struct priv *priv)
  *   Rx queue index.
  *
  * @return
- *   0 on success, negative on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx)
@@ -3237,8 +3289,10 @@ mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx)
 		ret = EINVAL;
 	else
 		ret = ibv_req_notify_cq(rxq->cq, 0);
-	if (ret)
+	if (ret) {
+		rte_errno = ret;
 		WARN("unable to arm interrupt on rx queue %d", idx);
+	}
 	return -ret;
 }
 
@@ -3251,7 +3305,7 @@ mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx)
  *   Rx queue index.
  *
  * @return
- *   0 on success, negative on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
@@ -3269,11 +3323,13 @@ mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
 		if (ret || ev_cq != rxq->cq)
 			ret = EINVAL;
 	}
-	if (ret)
+	if (ret) {
+		rte_errno = ret;
 		WARN("unable to disable interrupt on rx queue %d",
 		     idx);
-	else
+	} else {
 		ibv_ack_cq_events(rxq->cq, 1);
+	}
 	return -ret;
 }
 
@@ -3288,7 +3344,7 @@ mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
  *   Shared configuration data.
  *
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_arg_parse(const char *key, const char *val, struct mlx4_conf *conf)
@@ -3298,18 +3354,21 @@ mlx4_arg_parse(const char *key, const char *val, struct mlx4_conf *conf)
 	errno = 0;
 	tmp = strtoul(val, NULL, 0);
 	if (errno) {
+		rte_errno = errno;
 		WARN("%s: \"%s\" is not a valid integer", key, val);
-		return -errno;
+		return -rte_errno;
 	}
 	if (strcmp(MLX4_PMD_PORT_KVARG, key) == 0) {
 		if (!(conf->ports.present & (1 << tmp))) {
+			rte_errno = EINVAL;
 			ERROR("invalid port index %lu", tmp);
-			return -EINVAL;
+			return -rte_errno;
 		}
 		conf->ports.enabled |= 1 << tmp;
 	} else {
+		rte_errno = EINVAL;
 		WARN("%s: unknown parameter", key);
-		return -EINVAL;
+		return -rte_errno;
 	}
 	return 0;
 }
@@ -3321,7 +3380,7 @@ mlx4_arg_parse(const char *key, const char *val, struct mlx4_conf *conf)
  *   Device arguments structure.
  *
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_args(struct rte_devargs *devargs, struct mlx4_conf *conf)
@@ -3335,8 +3394,9 @@ mlx4_args(struct rte_devargs *devargs, struct mlx4_conf *conf)
 		return 0;
 	kvlist = rte_kvargs_parse(devargs->args, pmd_mlx4_init_params);
 	if (kvlist == NULL) {
+		rte_errno = EINVAL;
 		ERROR("failed to parse kvargs");
-		return -EINVAL;
+		return -rte_errno;
 	}
 	/* Process parameters. */
 	for (i = 0; pmd_mlx4_init_params[i]; ++i) {
@@ -3372,7 +3432,7 @@ static struct rte_pci_driver mlx4_driver;
  *   PCI device information.
  *
  * @return
- *   0 on success, negative errno value on failure.
+ *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
 mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
@@ -3393,10 +3453,11 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 
 	list = ibv_get_device_list(&i);
 	if (list == NULL) {
-		assert(errno);
-		if (errno == ENOSYS)
+		rte_errno = errno;
+		assert(rte_errno);
+		if (rte_errno == ENOSYS)
 			ERROR("cannot list devices, is ib_uverbs loaded?");
-		return -errno;
+		return -rte_errno;
 	}
 	assert(i >= 0);
 	/*
@@ -3427,20 +3488,23 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		ibv_free_device_list(list);
 		switch (err) {
 		case 0:
+			rte_errno = ENODEV;
 			ERROR("cannot access device, is mlx4_ib loaded?");
-			return -ENODEV;
+			return -rte_errno;
 		case EINVAL:
+			rte_errno = EINVAL;
 			ERROR("cannot use device, are drivers up to date?");
-			return -EINVAL;
+			return -rte_errno;
 		}
 		assert(err > 0);
-		return -err;
+		rte_errno = err;
+		return -rte_errno;
 	}
 	ibv_dev = list[i];
 
 	DEBUG("device opened");
 	if (ibv_query_device(attr_ctx, &device_attr)) {
-		err = ENODEV;
+		rte_errno = ENODEV;
 		goto error;
 	}
 	INFO("%u port(s) detected", device_attr.phys_port_cnt);
@@ -3449,7 +3513,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		conf.ports.present |= 1 << i;
 	if (mlx4_args(pci_dev->device.devargs, &conf)) {
 		ERROR("failed to process device arguments");
-		err = EINVAL;
+		rte_errno = EINVAL;
 		goto error;
 	}
 	/* Use all ports when none are defined */
@@ -3472,22 +3536,22 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 
 		ctx = ibv_open_device(ibv_dev);
 		if (ctx == NULL) {
-			err = ENODEV;
+			rte_errno = ENODEV;
 			goto port_error;
 		}
 
 		/* Check port status. */
 		err = ibv_query_port(ctx, port, &port_attr);
 		if (err) {
-			ERROR("port query failed: %s", strerror(err));
-			err = ENODEV;
+			rte_errno = err;
+			ERROR("port query failed: %s", strerror(rte_errno));
 			goto port_error;
 		}
 
 		if (port_attr.link_layer != IBV_LINK_LAYER_ETHERNET) {
+			rte_errno = ENOTSUP;
 			ERROR("port %d is not configured in Ethernet mode",
 			      port);
-			err = EINVAL;
 			goto port_error;
 		}
 
@@ -3499,8 +3563,8 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		/* Allocate protection domain. */
 		pd = ibv_alloc_pd(ctx);
 		if (pd == NULL) {
+			rte_errno = ENOMEM;
 			ERROR("PD allocation failure");
-			err = ENOMEM;
 			goto port_error;
 		}
 
@@ -3509,8 +3573,8 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 				   sizeof(*priv),
 				   RTE_CACHE_LINE_SIZE);
 		if (priv == NULL) {
+			rte_errno = ENOMEM;
 			ERROR("priv allocation failure");
-			err = ENOMEM;
 			goto port_error;
 		}
 
@@ -3524,8 +3588,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		/* Configure the first MAC address by default. */
 		if (priv_get_mac(priv, &mac.addr_bytes)) {
 			ERROR("cannot get MAC address, is mlx4_en loaded?"
-			      " (errno: %s)", strerror(errno));
-			err = ENODEV;
+			      " (rte_errno: %s)", strerror(rte_errno));
 			goto port_error;
 		}
 		INFO("port %u MAC address is %02x:%02x:%02x:%02x:%02x:%02x",
@@ -3562,7 +3625,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		}
 		if (eth_dev == NULL) {
 			ERROR("can not allocate rte ethdev");
-			err = ENOMEM;
+			rte_errno = ENOMEM;
 			goto port_error;
 		}
 
@@ -3620,8 +3683,8 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		claim_zero(ibv_close_device(attr_ctx));
 	if (list)
 		ibv_free_device_list(list);
-	assert(err >= 0);
-	return -err;
+	assert(rte_errno >= 0);
+	return -rte_errno;
 }
 
 static const struct rte_pci_id mlx4_pci_id_map[] = {
Signature · 1 line
2.1.4
#32 lore raw

PATCH 28/48 net/mlx4: clean up coding style inconsistencies

In reply to Adrien Mazarguil

This addresses badly formatted comments and needless empty lines before refactoring functions into different files.

---
 drivers/net/mlx4/mlx4.c      | 89 ++++++++++++++++-----------------------
 drivers/net/mlx4/mlx4_flow.c |  1 -
 2 files changed, 36 insertions(+), 54 deletions(-)
drivers/net/mlx4/mlx4.c +36 -53
index 8cfeab2..8f3377c 100644
@@ -619,8 +619,10 @@ txq_alloc_elts(struct txq *txq, unsigned int elts_n)
 	txq->elts_head = 0;
 	txq->elts_tail = 0;
 	txq->elts_comp = 0;
-	/* Request send completion every MLX4_PMD_TX_PER_COMP_REQ packets or
-	 * at least 4 times per ring. */
+	/*
+	 * Request send completion every MLX4_PMD_TX_PER_COMP_REQ packets or
+	 * at least 4 times per ring.
+	 */
 	txq->elts_comp_cd_init =
 		((MLX4_PMD_TX_PER_COMP_REQ < (elts_n / 4)) ?
 		 MLX4_PMD_TX_PER_COMP_REQ : (elts_n / 4));
@@ -629,7 +631,6 @@ txq_alloc_elts(struct txq *txq, unsigned int elts_n)
 	return 0;
 error:
 	rte_free(elts);
-
 	DEBUG("%p: failed, freed everything", (void *)txq);
 	assert(ret > 0);
 	rte_errno = ret;
@@ -675,7 +676,6 @@ txq_free_elts(struct txq *txq)
 	rte_free(elts);
 }
 
-
 /**
  * Clean up a TX queue.
  *
@@ -766,7 +766,6 @@ static void mlx4_check_mempool_cb(struct rte_mempool *mp,
 
 	(void)mp;
 	(void)mem_idx;
-
 	/* It already failed, skip the next chunks. */
 	if (data->ret != 0)
 		return;
@@ -810,7 +809,6 @@ static int mlx4_check_mempool(struct rte_mempool *mp, uintptr_t *start,
 	rte_mempool_mem_iter(mp, mlx4_check_mempool_cb, &data);
 	*start = (uintptr_t)data.start;
 	*end = (uintptr_t)data.end;
-
 	return data.ret;
 }
 
@@ -844,7 +842,6 @@ mlx4_mp2mr(struct ibv_pd *pd, struct rte_mempool *mp)
 			(void *)mp);
 		return NULL;
 	}
-
 	DEBUG("mempool %p area start=%p end=%p size=%zu",
 	      (void *)mp, (void *)start, (void *)end,
 	      (size_t)(end - start));
@@ -971,8 +968,10 @@ txq_mp2mr_mbuf_check(struct rte_mempool *mp, void *arg, void *obj,
 	struct txq_mp2mr_mbuf_check_data *data = arg;
 	struct rte_mbuf *buf = obj;
 
-	/* Check whether mbuf structure fits element size and whether mempool
-	 * pointer is valid. */
+	/*
+	 * Check whether mbuf structure fits element size and whether mempool
+	 * pointer is valid.
+	 */
 	if (sizeof(*buf) > mp->elt_size || buf->pool != mp)
 		data->ret = -1;
 }
@@ -1235,8 +1234,10 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 			.max_inline_data = MLX4_PMD_MAX_INLINE,
 		},
 		.qp_type = IBV_QPT_RAW_PACKET,
-		/* Do *NOT* enable this, completions events are managed per
-		 * TX burst. */
+		/*
+		 * Do *NOT* enable this, completions events are managed per
+		 * TX burst.
+		 */
 		.sq_sig_all = 0,
 	};
 	tmpl.qp = ibv_create_qp(priv->pd, &attr.init);
@@ -1449,9 +1450,11 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n, struct rte_mbuf **pool)
 			ERROR("%p: empty mbuf pool", (void *)rxq);
 			goto error;
 		}
-		/* Configure WR. Work request ID contains its own index in
+		/*
+		 * Configure WR. Work request ID contains its own index in
 		 * the elts array and the offset between SGE buffer header and
-		 * its data. */
+		 * its data.
+		 */
 		WR_ID(wr->wr_id).id = i;
 		WR_ID(wr->wr_id).offset =
 			(((uintptr_t)buf->buf_addr + RTE_PKTMBUF_HEADROOM) -
@@ -1473,8 +1476,10 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n, struct rte_mbuf **pool)
 		sge->lkey = rxq->mr->lkey;
 		/* Redundant check for tailroom. */
 		assert(sge->length == rte_pktmbuf_tailroom(buf));
-		/* Make sure elts index and SGE mbuf pointer can be deduced
-		 * from WR ID. */
+		/*
+		 * Make sure elts index and SGE mbuf pointer can be deduced
+		 * from WR ID.
+		 */
 		if ((WR_ID(wr->wr_id).id != i) ||
 		    ((void *)((uintptr_t)sge->addr -
 			WR_ID(wr->wr_id).offset) != buf)) {
@@ -1762,7 +1767,6 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			++rxq->priv->dev->data->rx_mbuf_alloc_failed;
 			goto repost;
 		}
-
 		/* Reconfigure sge to use rep instead of seg. */
 		elt->sge.addr = (uintptr_t)rep->buf_addr + RTE_PKTMBUF_HEADROOM;
 		assert(elt->sge.lkey == rxq->mr->lkey);
@@ -1770,7 +1774,6 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			(((uintptr_t)rep->buf_addr + RTE_PKTMBUF_HEADROOM) -
 			 (uintptr_t)rep);
 		assert(WR_ID(wr->wr_id).id == WR_ID(wr_id).id);
-
 		/* Update seg information. */
 		SET_DATA_OFF(seg, RTE_PKTMBUF_HEADROOM);
 		NB_SEGS(seg) = 1;
@@ -1780,7 +1783,6 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		DATA_LEN(seg) = len;
 		seg->packet_type = 0;
 		seg->ol_flags = 0;
-
 		/* Return packet. */
 		*(pkts++) = seg;
 		++pkts_ret;
@@ -2282,9 +2284,11 @@ mlx4_dev_close(struct rte_eth_dev *dev)
 	      (void *)dev,
 	      ((priv->ctx != NULL) ? priv->ctx->device->name : ""));
 	priv_mac_addr_del(priv);
-	/* Prevent crashes when queues are still in use. This is unfortunately
+	/*
+	 * Prevent crashes when queues are still in use. This is unfortunately
 	 * still required for DPDK 1.3 because some programs (such as testpmd)
-	 * never release them before closing the device. */
+	 * never release them before closing the device.
+	 */
 	dev->rx_pkt_burst = removed_rx_burst;
 	dev->tx_pkt_burst = removed_tx_burst;
 	if (priv->rxqs != NULL) {
@@ -2401,6 +2405,7 @@ mlx4_set_link_up(struct rte_eth_dev *dev)
 	priv_unlock(priv);
 	return err;
 }
+
 /**
  * DPDK callback to get information about the device.
  *
@@ -2417,7 +2422,6 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	char ifname[IF_NAMESIZE];
 
 	info->pci_dev = RTE_ETH_DEV_TO_PCI(dev);
-
 	if (priv == NULL)
 		return;
 	priv_lock(priv);
@@ -2562,7 +2566,6 @@ mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	int link_speed = 0;
 
 	/* priv_lock() is not taken to allow concurrent calls. */
-
 	if (priv == NULL) {
 		rte_errno = EINVAL;
 		return -rte_errno;
@@ -2657,7 +2660,6 @@ mlx4_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 		     strerror(rte_errno));
 		goto out;
 	}
-
 	fc_conf->autoneg = ethpause.autoneg;
 	if (ethpause.rx_pause && ethpause.tx_pause)
 		fc_conf->mode = RTE_FC_FULL;
@@ -2668,7 +2670,6 @@ mlx4_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 	else
 		fc_conf->mode = RTE_FC_NONE;
 	ret = 0;
-
 out:
 	priv_unlock(priv);
 	assert(ret >= 0);
@@ -2703,13 +2704,11 @@ mlx4_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 		ethpause.rx_pause = 1;
 	else
 		ethpause.rx_pause = 0;
-
 	if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) ||
 	    (fc_conf->mode & RTE_FC_TX_PAUSE))
 		ethpause.tx_pause = 1;
 	else
 		ethpause.tx_pause = 0;
-
 	priv_lock(priv);
 	if (priv_ifreq(priv, SIOCETHTOOL, &ifr)) {
 		ret = rte_errno;
@@ -2719,7 +2718,6 @@ mlx4_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 		goto out;
 	}
 	ret = 0;
-
 out:
 	priv_unlock(priv);
 	assert(ret >= 0);
@@ -2953,8 +2951,8 @@ mlx4_dev_link_status_handler(void *arg)
 	ret = priv_dev_status_handler(priv, dev, &events);
 	priv_unlock(priv);
 	if (ret > 0 && events & (1 << RTE_ETH_EVENT_INTR_LSC))
-		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL,
-					      NULL);
+		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
+					      NULL, NULL);
 }
 
 /**
@@ -3001,6 +2999,7 @@ mlx4_dev_interrupt_handler(void *cb_arg)
  *   Pointer to private structure.
  * @param dev
  *   Pointer to the rte_eth_dev structure.
+ *
  * @return
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
@@ -3032,6 +3031,7 @@ priv_dev_interrupt_handler_uninstall(struct priv *priv, struct rte_eth_dev *dev)
  *   Pointer to private structure.
  * @param dev
  *   Pointer to the rte_eth_dev structure.
+ *
  * @return
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
@@ -3042,8 +3042,9 @@ priv_dev_interrupt_handler_install(struct priv *priv,
 	int flags;
 	int rc;
 
-	/* Check whether the interrupt handler has already been installed
-	 * for either type of interrupt
+	/*
+	 * Check whether the interrupt handler has already been installed
+	 * for either type of interrupt.
 	 */
 	if (priv->intr_conf.lsc &&
 	    priv->intr_conf.rmv &&
@@ -3081,6 +3082,7 @@ priv_dev_interrupt_handler_install(struct priv *priv,
  *   Pointer to private structure.
  * @param dev
  *   Pointer to the rte_eth_dev structure.
+ *
  * @return
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
@@ -3102,6 +3104,7 @@ priv_dev_removal_interrupt_handler_uninstall(struct priv *priv,
  *   Pointer to private structure.
  * @param dev
  *   Pointer to the rte_eth_dev structure.
+ *
  * @return
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
@@ -3135,6 +3138,7 @@ priv_dev_link_interrupt_handler_uninstall(struct priv *priv,
  *   Pointer to private structure.
  * @param dev
  *   Pointer to the rte_eth_dev structure.
+ *
  * @return
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
@@ -3160,6 +3164,7 @@ priv_dev_link_interrupt_handler_install(struct priv *priv,
  *   Pointer to private structure.
  * @param dev
  *   Pointer to the rte_eth_dev structure.
+ *
  * @return
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
@@ -3450,7 +3455,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 
 	(void)pci_drv;
 	assert(pci_drv == &mlx4_driver);
-
 	list = ibv_get_device_list(&i);
 	if (list == NULL) {
 		rte_errno = errno;
@@ -3501,14 +3505,12 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		return -rte_errno;
 	}
 	ibv_dev = list[i];
-
 	DEBUG("device opened");
 	if (ibv_query_device(attr_ctx, &device_attr)) {
 		rte_errno = ENODEV;
 		goto error;
 	}
 	INFO("%u port(s) detected", device_attr.phys_port_cnt);
-
 	for (i = 0; i < device_attr.phys_port_cnt; ++i)
 		conf.ports.present |= 1 << i;
 	if (mlx4_args(pci_dev->device.devargs, &conf)) {
@@ -3531,15 +3533,12 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		/* If port is not enabled, skip. */
 		if (!(conf.ports.enabled & (1 << i)))
 			continue;
-
 		DEBUG("using port %u", port);
-
 		ctx = ibv_open_device(ibv_dev);
 		if (ctx == NULL) {
 			rte_errno = ENODEV;
 			goto port_error;
 		}
-
 		/* Check port status. */
 		err = ibv_query_port(ctx, port, &port_attr);
 		if (err) {
@@ -3547,19 +3546,16 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			ERROR("port query failed: %s", strerror(rte_errno));
 			goto port_error;
 		}
-
 		if (port_attr.link_layer != IBV_LINK_LAYER_ETHERNET) {
 			rte_errno = ENOTSUP;
 			ERROR("port %d is not configured in Ethernet mode",
 			      port);
 			goto port_error;
 		}
-
 		if (port_attr.state != IBV_PORT_ACTIVE)
 			DEBUG("port %d is not active: \"%s\" (%d)",
 			      port, ibv_port_state_str(port_attr.state),
 			      port_attr.state);
-
 		/* Allocate protection domain. */
 		pd = ibv_alloc_pd(ctx);
 		if (pd == NULL) {
@@ -3567,7 +3563,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			ERROR("PD allocation failure");
 			goto port_error;
 		}
-
 		/* from rte_ethdev.c */
 		priv = rte_zmalloc("ethdev private structure",
 				   sizeof(*priv),
@@ -3577,13 +3572,11 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			ERROR("priv allocation failure");
 			goto port_error;
 		}
-
 		priv->ctx = ctx;
 		priv->device_attr = device_attr;
 		priv->port = port;
 		priv->pd = pd;
 		priv->mtu = ETHER_MTU;
-
 		priv->vf = vf;
 		/* Configure the first MAC address by default. */
 		if (priv_get_mac(priv, &mac.addr_bytes)) {
@@ -3614,7 +3607,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		/* Get actual MTU if possible. */
 		priv_get_mtu(priv, &priv->mtu);
 		DEBUG("port %u MTU is %u", priv->port, priv->mtu);
-
 		/* from rte_ethdev.c */
 		{
 			char name[RTE_ETH_NAME_MAX_LEN];
@@ -3628,15 +3620,11 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			rte_errno = ENOMEM;
 			goto port_error;
 		}
-
 		eth_dev->data->dev_private = priv;
 		eth_dev->data->mac_addrs = &priv->mac;
 		eth_dev->device = &pci_dev->device;
-
 		rte_eth_copy_pci_info(eth_dev, pci_dev);
-
 		eth_dev->device->driver = &mlx4_driver.driver;
-
 		/*
 		 * Copy and override interrupt handle to prevent it from
 		 * being shared between all ethdev instances of a given PCI
@@ -3645,11 +3633,9 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		 */
 		priv->intr_handle_dev = *eth_dev->intr_handle;
 		eth_dev->intr_handle = &priv->intr_handle_dev;
-
 		priv->dev = eth_dev;
 		eth_dev->dev_ops = &mlx4_dev_ops;
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
-
 		/* Bring Ethernet device up. */
 		DEBUG("forcing Ethernet interface up");
 		priv_set_flags(priv, ~IFF_UP, IFF_UP);
@@ -3657,7 +3643,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
 			mlx4_link_update(eth_dev, 0);
 		continue;
-
 port_error:
 		rte_free(priv);
 		if (pd)
@@ -3670,14 +3655,12 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	}
 	if (i == device_attr.phys_port_cnt)
 		return 0;
-
 	/*
 	 * XXX if something went wrong in the loop above, there is a resource
 	 * leak (ctx, pd, priv, dpdk ethdev) but we can do nothing about it as
 	 * long as the dpdk does not provide a way to deallocate a ethdev and a
 	 * way to enumerate the registered ethdevs to free the previous ones.
 	 */
-
 error:
 	if (attr_ctx)
 		claim_zero(ibv_close_device(attr_ctx));
drivers/net/mlx4/mlx4_flow.c +0 -1
index 58d4698..7dcb059 100644
@@ -835,7 +835,6 @@ priv_flow_create_action_queue(struct priv *priv,
 		goto error;
 	}
 	return rte_flow;
-
 error:
 	rte_free(rte_flow);
 	return NULL;
Signature · 1 line
2.1.4
#33 lore raw

PATCH 29/48 net/mlx4: remove control path locks

In reply to Adrien Mazarguil

Concurrent use of various control path functions (e.g. configuring a queue and destroying it simultaneously) may lead to undefined behavior.

PMD are not supposed to protect themselves from misbehaving applications, and mlx4 is one of the few with internal locks on most control path operations. This adds unnecessary complexity.

Leave this role to wrapper functions in ethdev.

---
 drivers/net/mlx4/mlx4.c      | 90 +++------------------------------------
 drivers/net/mlx4/mlx4.h      |  4 --
 drivers/net/mlx4/mlx4_flow.c | 15 +------
 3 files changed, 6 insertions(+), 103 deletions(-)
drivers/net/mlx4/mlx4.c +5 -85
index 8f3377c..71ee016 100644
@@ -59,7 +59,6 @@
 #include <rte_mempool.h>
 #include <rte_prefetch.h>
 #include <rte_malloc.h>
-#include <rte_spinlock.h>
 #include <rte_log.h>
 #include <rte_alarm.h>
 #include <rte_memory.h>
@@ -121,29 +120,6 @@ priv_rx_intr_vec_enable(struct priv *priv);
 static void
 priv_rx_intr_vec_disable(struct priv *priv);
 
-/**
- * Lock private structure to protect it from concurrent access in the
- * control path.
- *
- * @param priv
- *   Pointer to private structure.
- */
-void priv_lock(struct priv *priv)
-{
-	rte_spinlock_lock(&priv->lock);
-}
-
-/**
- * Unlock private structure.
- *
- * @param priv
- *   Pointer to private structure.
- */
-void priv_unlock(struct priv *priv)
-{
-	rte_spinlock_unlock(&priv->lock);
-}
-
 /* Allocate a buffer on the stack and fill it with a printf format string. */
 #define MKSTR(name, ...) \
 	char name[snprintf(NULL, 0, __VA_ARGS__) + 1]; \
@@ -570,13 +546,7 @@ dev_configure(struct rte_eth_dev *dev)
 static int
 mlx4_dev_configure(struct rte_eth_dev *dev)
 {
-	struct priv *priv = dev->data->dev_private;
-	int ret;
-
-	priv_lock(priv);
-	ret = dev_configure(dev);
-	priv_unlock(priv);
-	return ret;
+	return dev_configure(dev);
 }
 
 static uint16_t mlx4_tx_burst(void *, struct rte_mbuf **, uint16_t);
@@ -1328,14 +1298,12 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct txq *txq = (*priv->txqs)[idx];
 	int ret;
 
-	priv_lock(priv);
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
 	if (idx >= priv->txqs_n) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
 		      (void *)dev, idx, priv->txqs_n);
-		priv_unlock(priv);
 		return -rte_errno;
 	}
 	if (txq != NULL) {
@@ -1343,7 +1311,6 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		      (void *)dev, idx, (void *)txq);
 		if (priv->started) {
 			rte_errno = EEXIST;
-			priv_unlock(priv);
 			return -rte_errno;
 		}
 		(*priv->txqs)[idx] = NULL;
@@ -1354,7 +1321,6 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 			rte_errno = ENOMEM;
 			ERROR("%p: unable to allocate queue index %u",
 			      (void *)dev, idx);
-			priv_unlock(priv);
 			return -rte_errno;
 		}
 	}
@@ -1369,7 +1335,6 @@ mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		/* Update send callback. */
 		dev->tx_pkt_burst = mlx4_tx_burst;
 	}
-	priv_unlock(priv);
 	return ret;
 }
 
@@ -1389,7 +1354,6 @@ mlx4_tx_queue_release(void *dpdk_txq)
 	if (txq == NULL)
 		return;
 	priv = txq->priv;
-	priv_lock(priv);
 	for (i = 0; (i != priv->txqs_n); ++i)
 		if ((*priv->txqs)[i] == txq) {
 			DEBUG("%p: removing TX queue %p from list",
@@ -1399,7 +1363,6 @@ mlx4_tx_queue_release(void *dpdk_txq)
 		}
 	txq_cleanup(txq);
 	rte_free(txq);
-	priv_unlock(priv);
 }
 
 /* RX queues handling. */
@@ -2029,14 +1992,12 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	struct rxq *rxq = (*priv->rxqs)[idx];
 	int ret;
 
-	priv_lock(priv);
 	DEBUG("%p: configuring queue %u for %u descriptors",
 	      (void *)dev, idx, desc);
 	if (idx >= priv->rxqs_n) {
 		rte_errno = EOVERFLOW;
 		ERROR("%p: queue index out of range (%u >= %u)",
 		      (void *)dev, idx, priv->rxqs_n);
-		priv_unlock(priv);
 		return -rte_errno;
 	}
 	if (rxq != NULL) {
@@ -2044,7 +2005,6 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		      (void *)dev, idx, (void *)rxq);
 		if (priv->started) {
 			rte_errno = EEXIST;
-			priv_unlock(priv);
 			return -rte_errno;
 		}
 		(*priv->rxqs)[idx] = NULL;
@@ -2057,7 +2017,6 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 			rte_errno = ENOMEM;
 			ERROR("%p: unable to allocate queue index %u",
 			      (void *)dev, idx);
-			priv_unlock(priv);
 			return -rte_errno;
 		}
 	}
@@ -2072,7 +2031,6 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		/* Update receive callback. */
 		dev->rx_pkt_burst = mlx4_rx_burst;
 	}
-	priv_unlock(priv);
 	return ret;
 }
 
@@ -2092,7 +2050,6 @@ mlx4_rx_queue_release(void *dpdk_rxq)
 	if (rxq == NULL)
 		return;
 	priv = rxq->priv;
-	priv_lock(priv);
 	for (i = 0; (i != priv->rxqs_n); ++i)
 		if ((*priv->rxqs)[i] == rxq) {
 			DEBUG("%p: removing RX queue %p from list",
@@ -2104,7 +2061,6 @@ mlx4_rx_queue_release(void *dpdk_rxq)
 		}
 	rxq_cleanup(rxq);
 	rte_free(rxq);
-	priv_unlock(priv);
 }
 
 static int
@@ -2133,11 +2089,8 @@ mlx4_dev_start(struct rte_eth_dev *dev)
 	struct priv *priv = dev->data->dev_private;
 	int ret;
 
-	priv_lock(priv);
-	if (priv->started) {
-		priv_unlock(priv);
+	if (priv->started)
 		return 0;
-	}
 	DEBUG("%p: attaching configured flows to all RX queues", (void *)dev);
 	priv->started = 1;
 	ret = priv_mac_addr_add(priv);
@@ -2167,13 +2120,11 @@ mlx4_dev_start(struct rte_eth_dev *dev)
 		      (void *)dev, strerror(ret));
 		goto err;
 	}
-	priv_unlock(priv);
 	return 0;
 err:
 	/* Rollback. */
 	priv_mac_addr_del(priv);
 	priv->started = 0;
-	priv_unlock(priv);
 	return ret;
 }
 
@@ -2190,16 +2141,12 @@ mlx4_dev_stop(struct rte_eth_dev *dev)
 {
 	struct priv *priv = dev->data->dev_private;
 
-	priv_lock(priv);
-	if (!priv->started) {
-		priv_unlock(priv);
+	if (!priv->started)
 		return;
-	}
 	DEBUG("%p: detaching flows from all RX queues", (void *)dev);
 	priv->started = 0;
 	mlx4_priv_flow_stop(priv);
 	priv_mac_addr_del(priv);
-	priv_unlock(priv);
 }
 
 /**
@@ -2279,7 +2226,6 @@ mlx4_dev_close(struct rte_eth_dev *dev)
 
 	if (priv == NULL)
 		return;
-	priv_lock(priv);
 	DEBUG("%p: closing device \"%s\"",
 	      (void *)dev,
 	      ((priv->ctx != NULL) ? priv->ctx->device->name : ""));
@@ -2328,7 +2274,6 @@ mlx4_dev_close(struct rte_eth_dev *dev)
 	priv_dev_removal_interrupt_handler_uninstall(priv, dev);
 	priv_dev_link_interrupt_handler_uninstall(priv, dev);
 	priv_rx_intr_vec_disable(priv);
-	priv_unlock(priv);
 	memset(priv, 0, sizeof(*priv));
 }
 
@@ -2377,12 +2322,8 @@ static int
 mlx4_set_link_down(struct rte_eth_dev *dev)
 {
 	struct priv *priv = dev->data->dev_private;
-	int err;
 
-	priv_lock(priv);
-	err = priv_set_link(priv, 0);
-	priv_unlock(priv);
-	return err;
+	return priv_set_link(priv, 0);
 }
 
 /**
@@ -2398,12 +2339,8 @@ static int
 mlx4_set_link_up(struct rte_eth_dev *dev)
 {
 	struct priv *priv = dev->data->dev_private;
-	int err;
 
-	priv_lock(priv);
-	err = priv_set_link(priv, 1);
-	priv_unlock(priv);
-	return err;
+	return priv_set_link(priv, 1);
 }
 
 /**
@@ -2424,7 +2361,6 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	info->pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	if (priv == NULL)
 		return;
-	priv_lock(priv);
 	/* FIXME: we should ask the device for these values. */
 	info->min_rx_bufsize = 32;
 	info->max_rx_pktlen = 65536;
@@ -2451,7 +2387,6 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 			ETH_LINK_SPEED_20G |
 			ETH_LINK_SPEED_40G |
 			ETH_LINK_SPEED_56G;
-	priv_unlock(priv);
 }
 
 /**
@@ -2472,7 +2407,6 @@ mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 
 	if (priv == NULL)
 		return;
-	priv_lock(priv);
 	/* Add software counters. */
 	for (i = 0; (i != priv->rxqs_n); ++i) {
 		struct rxq *rxq = (*priv->rxqs)[i];
@@ -2507,7 +2441,6 @@ mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 		tmp.oerrors += txq->stats.odropped;
 	}
 	*stats = tmp;
-	priv_unlock(priv);
 }
 
 /**
@@ -2525,7 +2458,6 @@ mlx4_stats_reset(struct rte_eth_dev *dev)
 
 	if (priv == NULL)
 		return;
-	priv_lock(priv);
 	for (i = 0; (i != priv->rxqs_n); ++i) {
 		if ((*priv->rxqs)[i] == NULL)
 			continue;
@@ -2540,7 +2472,6 @@ mlx4_stats_reset(struct rte_eth_dev *dev)
 		(*priv->txqs)[i]->stats =
 			(struct mlx4_txq_stats){ .idx = idx };
 	}
-	priv_unlock(priv);
 }
 
 /**
@@ -2565,7 +2496,6 @@ mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	struct rte_eth_link dev_link;
 	int link_speed = 0;
 
-	/* priv_lock() is not taken to allow concurrent calls. */
 	if (priv == NULL) {
 		rte_errno = EINVAL;
 		return -rte_errno;
@@ -2614,7 +2544,6 @@ mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	struct priv *priv = dev->data->dev_private;
 	int ret = 0;
 
-	priv_lock(priv);
 	/* Set kernel interface MTU first. */
 	if (priv_set_mtu(priv, mtu)) {
 		ret = rte_errno;
@@ -2625,7 +2554,6 @@ mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 		DEBUG("adapter port %u MTU set to %u", priv->port, mtu);
 	priv->mtu = mtu;
 out:
-	priv_unlock(priv);
 	assert(ret >= 0);
 	return -ret;
 }
@@ -2652,7 +2580,6 @@ mlx4_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 	int ret;
 
 	ifr.ifr_data = (void *)&ethpause;
-	priv_lock(priv);
 	if (priv_ifreq(priv, SIOCETHTOOL, &ifr)) {
 		ret = rte_errno;
 		WARN("ioctl(SIOCETHTOOL, ETHTOOL_GPAUSEPARAM)"
@@ -2671,7 +2598,6 @@ mlx4_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 		fc_conf->mode = RTE_FC_NONE;
 	ret = 0;
 out:
-	priv_unlock(priv);
 	assert(ret >= 0);
 	return -ret;
 }
@@ -2709,7 +2635,6 @@ mlx4_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 		ethpause.tx_pause = 1;
 	else
 		ethpause.tx_pause = 0;
-	priv_lock(priv);
 	if (priv_ifreq(priv, SIOCETHTOOL, &ifr)) {
 		ret = rte_errno;
 		WARN("ioctl(SIOCETHTOOL, ETHTOOL_SPAUSEPARAM)"
@@ -2719,7 +2644,6 @@ mlx4_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 	}
 	ret = 0;
 out:
-	priv_unlock(priv);
 	assert(ret >= 0);
 	return -ret;
 }
@@ -2945,11 +2869,9 @@ mlx4_dev_link_status_handler(void *arg)
 	uint32_t events;
 	int ret;
 
-	priv_lock(priv);
 	assert(priv->pending_alarm == 1);
 	priv->pending_alarm = 0;
 	ret = priv_dev_status_handler(priv, dev, &events);
-	priv_unlock(priv);
 	if (ret > 0 && events & (1 << RTE_ETH_EVENT_INTR_LSC))
 		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
 					      NULL, NULL);
@@ -2972,9 +2894,7 @@ mlx4_dev_interrupt_handler(void *cb_arg)
 	uint32_t ev;
 	int i;
 
-	priv_lock(priv);
 	ret = priv_dev_status_handler(priv, dev, &ev);
-	priv_unlock(priv);
 	if (ret > 0) {
 		for (i = RTE_ETH_EVENT_UNKNOWN;
 		     i < RTE_ETH_EVENT_MAX;
drivers/net/mlx4/mlx4.h +0 -4
index 635036e..3580e05 100644
@@ -223,10 +223,6 @@ struct priv {
 	struct rte_flow_drop *flow_drop_queue; /* Flow drop queue. */
 	LIST_HEAD(mlx4_flows, rte_flow) flows;
 	struct rte_intr_conf intr_conf; /* Active interrupt configuration. */
-	rte_spinlock_t lock; /* Lock for control functions. */
 };
 
-void priv_lock(struct priv *priv);
-void priv_unlock(struct priv *priv);
-
 #endif /* RTE_PMD_MLX4_H_ */
drivers/net/mlx4/mlx4_flow.c +1 -14
index 7dcb059..07305f1 100644
@@ -703,13 +703,9 @@ mlx4_flow_validate(struct rte_eth_dev *dev,
 		   struct rte_flow_error *error)
 {
 	struct priv *priv = dev->data->dev_private;
-	int ret;
 	struct mlx4_flow flow = { .offset = sizeof(struct ibv_flow_attr) };
 
-	priv_lock(priv);
-	ret = priv_flow_validate(priv, attr, items, actions, error, &flow);
-	priv_unlock(priv);
-	return ret;
+	return priv_flow_validate(priv, attr, items, actions, error, &flow);
 }
 
 /**
@@ -936,13 +932,11 @@ mlx4_flow_create(struct rte_eth_dev *dev,
 	struct priv *priv = dev->data->dev_private;
 	struct rte_flow *flow;
 
-	priv_lock(priv);
 	flow = priv_flow_create(priv, attr, items, actions, error);
 	if (flow) {
 		LIST_INSERT_HEAD(&priv->flows, flow, next);
 		DEBUG("Flow created %p", (void *)flow);
 	}
-	priv_unlock(priv);
 	return flow;
 }
 
@@ -969,17 +963,14 @@ mlx4_flow_isolate(struct rte_eth_dev *dev,
 {
 	struct priv *priv = dev->data->dev_private;
 
-	priv_lock(priv);
 	if (priv->rxqs) {
 		rte_flow_error_set(error, ENOTSUP,
 				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 				   NULL, "isolated mode must be set"
 				   " before configuring the device");
-		priv_unlock(priv);
 		return -rte_errno;
 	}
 	priv->isolated = !!enable;
-	priv_unlock(priv);
 	return 0;
 }
 
@@ -1017,9 +1008,7 @@ mlx4_flow_destroy(struct rte_eth_dev *dev,
 	struct priv *priv = dev->data->dev_private;
 
 	(void)error;
-	priv_lock(priv);
 	priv_flow_destroy(priv, flow);
-	priv_unlock(priv);
 	return 0;
 }
 
@@ -1053,9 +1042,7 @@ mlx4_flow_flush(struct rte_eth_dev *dev,
 	struct priv *priv = dev->data->dev_private;
 
 	(void)error;
-	priv_lock(priv);
 	priv_flow_flush(priv);
-	priv_unlock(priv);
 	return 0;
 }
 
Signature · 1 line
2.1.4
#34 lore raw

PATCH 30/48 net/mlx4: remove unnecessary wrapper functions

In reply to Adrien Mazarguil

Wrapper functions whose main purpose was to take a lock on the private structure are no longer needed since this lock does not exist anymore.

---
 drivers/net/mlx4/mlx4.c      |  61 ++++------------------
 drivers/net/mlx4/mlx4_flow.c | 106 +++++++++-----------------------------
 2 files changed, 32 insertions(+), 135 deletions(-)
drivers/net/mlx4/mlx4.c +9 -52
index 71ee016..d831729 100644
@@ -428,10 +428,10 @@ priv_get_mtu(struct priv *priv, uint16_t *mtu)
 }
 
 /**
- * Set device MTU.
+ * DPDK callback to change the MTU.
  *
  * @param priv
- *   Pointer to private structure.
+ *   Pointer to Ethernet device structure.
  * @param mtu
  *   MTU value to set.
  *
@@ -439,8 +439,9 @@ priv_get_mtu(struct priv *priv, uint16_t *mtu)
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
-priv_set_mtu(struct priv *priv, uint16_t mtu)
+mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 {
+	struct priv *priv = dev->data->dev_private;
 	uint16_t new_mtu;
 	int ret = priv_set_sysfs_ulong(priv, "mtu", mtu);
 
@@ -449,8 +450,10 @@ priv_set_mtu(struct priv *priv, uint16_t mtu)
 	ret = priv_get_mtu(priv, &new_mtu);
 	if (ret)
 		return ret;
-	if (new_mtu == mtu)
+	if (new_mtu == mtu) {
+		priv->mtu = mtu;
 		return 0;
+	}
 	rte_errno = EINVAL;
 	return -rte_errno;
 }
@@ -502,7 +505,7 @@ static void
 priv_mac_addr_del(struct priv *priv);
 
 /**
- * Ethernet device configuration.
+ * DPDK callback for Ethernet device configuration.
  *
  * Prepare the driver for a given number of TX and RX queues.
  *
@@ -513,7 +516,7 @@ priv_mac_addr_del(struct priv *priv);
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
-dev_configure(struct rte_eth_dev *dev)
+mlx4_dev_configure(struct rte_eth_dev *dev)
 {
 	struct priv *priv = dev->data->dev_private;
 	unsigned int rxqs_n = dev->data->nb_rx_queues;
@@ -534,21 +537,6 @@ dev_configure(struct rte_eth_dev *dev)
 	return 0;
 }
 
-/**
- * DPDK callback for Ethernet device configuration.
- *
- * @param dev
- *   Pointer to Ethernet device structure.
- *
- * @return
- *   0 on success, negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx4_dev_configure(struct rte_eth_dev *dev)
-{
-	return dev_configure(dev);
-}
-
 static uint16_t mlx4_tx_burst(void *, struct rte_mbuf **, uint16_t);
 static uint16_t removed_rx_burst(void *, struct rte_mbuf **, uint16_t);
 
@@ -2528,37 +2516,6 @@ mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 }
 
 /**
- * DPDK callback to change the MTU.
- *
- * @param dev
- *   Pointer to Ethernet device structure.
- * @param in_mtu
- *   New MTU.
- *
- * @return
- *   0 on success, negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
-{
-	struct priv *priv = dev->data->dev_private;
-	int ret = 0;
-
-	/* Set kernel interface MTU first. */
-	if (priv_set_mtu(priv, mtu)) {
-		ret = rte_errno;
-		WARN("cannot set port %u MTU to %u: %s", priv->port, mtu,
-		     strerror(rte_errno));
-		goto out;
-	} else
-		DEBUG("adapter port %u MTU set to %u", priv->port, mtu);
-	priv->mtu = mtu;
-out:
-	assert(ret >= 0);
-	return -ret;
-}
-
-/**
  * DPDK callback to get flow control status.
  *
  * @param dev
drivers/net/mlx4/mlx4_flow.c +23 -83

157 lines not on this page · raw message

Signature · 1 line
2.1.4
#35 lore raw

PATCH 31/48 net/mlx4: remove mbuf macro definitions

In reply to Adrien Mazarguil

These were originally used for compatibility between DPDK releases when this PMD was built out of tree.

---
 drivers/net/mlx4/mlx4.c | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)
drivers/net/mlx4/mlx4.c +10 -19
index d831729..0f1169c 100644
@@ -74,15 +74,6 @@
 #include "mlx4.h"
 #include "mlx4_flow.h"
 
-/* Convenience macros for accessing mbuf fields. */
-#define NEXT(m) ((m)->next)
-#define DATA_LEN(m) ((m)->data_len)
-#define PKT_LEN(m) ((m)->pkt_len)
-#define DATA_OFF(m) ((m)->data_off)
-#define SET_DATA_OFF(m, o) ((m)->data_off = (o))
-#define NB_SEGS(m) ((m)->nb_segs)
-#define PORT(m) ((m)->port)
-
 /* Work Request ID data type (64 bit). */
 typedef union {
 	struct {
@@ -1006,7 +997,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		struct txq_elt *elt_next = &(*txq->elts)[elts_head_next];
 		struct txq_elt *elt = &(*txq->elts)[elts_head];
 		struct ibv_send_wr *wr = &elt->wr;
-		unsigned int segs = NB_SEGS(buf);
+		unsigned int segs = buf->nb_segs;
 		unsigned int sent_size = 0;
 		uint32_t send_flags = 0;
 
@@ -1020,7 +1011,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 #endif
 			/* Faster than rte_pktmbuf_free(). */
 			do {
-				struct rte_mbuf *next = NEXT(tmp);
+				struct rte_mbuf *next = tmp->next;
 
 				rte_pktmbuf_free_seg(tmp);
 				tmp = next;
@@ -1040,7 +1031,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 
 			/* Retrieve buffer information. */
 			addr = rte_pktmbuf_mtod(buf, uintptr_t);
-			length = DATA_LEN(buf);
+			length = buf->data_len;
 			/* Retrieve Memory Region key for this memory pool. */
 			lkey = txq_mp2mr(txq, txq_mb2mp(buf));
 			if (unlikely(lkey == (uint32_t)-1)) {
@@ -1414,7 +1405,7 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n, struct rte_mbuf **pool)
 		wr->sg_list = sge;
 		wr->num_sge = 1;
 		/* Headroom is reserved by rte_pktmbuf_alloc(). */
-		assert(DATA_OFF(buf) == RTE_PKTMBUF_HEADROOM);
+		assert(buf->data_off == RTE_PKTMBUF_HEADROOM);
 		/* Buffer is supposed to be empty. */
 		assert(rte_pktmbuf_data_len(buf) == 0);
 		assert(rte_pktmbuf_pkt_len(buf) == 0);
@@ -1726,12 +1717,12 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			 (uintptr_t)rep);
 		assert(WR_ID(wr->wr_id).id == WR_ID(wr_id).id);
 		/* Update seg information. */
-		SET_DATA_OFF(seg, RTE_PKTMBUF_HEADROOM);
-		NB_SEGS(seg) = 1;
-		PORT(seg) = rxq->port_id;
-		NEXT(seg) = NULL;
-		PKT_LEN(seg) = len;
-		DATA_LEN(seg) = len;
+		seg->data_off = RTE_PKTMBUF_HEADROOM;
+		seg->nb_segs = 1;
+		seg->port = rxq->port_id;
+		seg->next = NULL;
+		seg->pkt_len = len;
+		seg->data_len = len;
 		seg->packet_type = 0;
 		seg->ol_flags = 0;
 		/* Return packet. */
Signature · 1 line
2.1.4
#36 lore raw

PATCH 32/48 net/mlx4: use standard macro to get array size

In reply to Adrien Mazarguil
---
 drivers/net/mlx4/mlx4.c | 11 ++++++-----
 drivers/net/mlx4/mlx4.h |  3 ---
 2 files changed, 6 insertions(+), 8 deletions(-)
drivers/net/mlx4/mlx4.c +6 -5
index 0f1169c..f4dc67f 100644
@@ -66,6 +66,7 @@
 #include <rte_kvargs.h>
 #include <rte_interrupts.h>
 #include <rte_branch_prediction.h>
+#include <rte_common.h>
 
 /* Generated configuration header. */
 #include "mlx4_autoconf.h"
@@ -644,7 +645,7 @@ txq_cleanup(struct txq *txq)
 		claim_zero(ibv_destroy_qp(txq->qp));
 	if (txq->cq != NULL)
 		claim_zero(ibv_destroy_cq(txq->cq));
-	for (i = 0; (i != elemof(txq->mp2mr)); ++i) {
+	for (i = 0; (i != RTE_DIM(txq->mp2mr)); ++i) {
 		if (txq->mp2mr[i].mp == NULL)
 			break;
 		assert(txq->mp2mr[i].mr != NULL);
@@ -854,7 +855,7 @@ txq_mp2mr(struct txq *txq, struct rte_mempool *mp)
 	unsigned int i;
 	struct ibv_mr *mr;
 
-	for (i = 0; (i != elemof(txq->mp2mr)); ++i) {
+	for (i = 0; (i != RTE_DIM(txq->mp2mr)); ++i) {
 		if (unlikely(txq->mp2mr[i].mp == NULL)) {
 			/* Unknown MP, add a new MR for it. */
 			break;
@@ -874,7 +875,7 @@ txq_mp2mr(struct txq *txq, struct rte_mempool *mp)
 		      (void *)txq);
 		return (uint32_t)-1;
 	}
-	if (unlikely(i == elemof(txq->mp2mr))) {
+	if (unlikely(i == RTE_DIM(txq->mp2mr))) {
 		/* Table is full, remove oldest entry. */
 		DEBUG("%p: MR <-> MP table full, dropping oldest entry.",
 		      (void *)txq);
@@ -1444,7 +1445,7 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n, struct rte_mbuf **pool)
 error:
 	if (elts != NULL) {
 		assert(pool == NULL);
-		for (i = 0; (i != elemof(*elts)); ++i) {
+		for (i = 0; (i != RTE_DIM(*elts)); ++i) {
 			struct rxq_elt *elt = &(*elts)[i];
 			struct rte_mbuf *buf;
 
@@ -1480,7 +1481,7 @@ rxq_free_elts(struct rxq *rxq)
 	rxq->elts = NULL;
 	if (elts == NULL)
 		return;
-	for (i = 0; (i != elemof(*elts)); ++i) {
+	for (i = 0; (i != RTE_DIM(*elts)); ++i) {
 		struct rxq_elt *elt = &(*elts)[i];
 		struct rte_mbuf *buf;
 
drivers/net/mlx4/mlx4.h +0 -3
index 3580e05..7ec6317 100644
@@ -98,9 +98,6 @@ enum {
 
 #define MLX4_DRIVER_NAME "net_mlx4"
 
-/* Number of elements in array. */
-#define elemof(a) (sizeof(a) / sizeof((a)[0]))
-
 /* Debugging */
 #ifndef NDEBUG
 #include <stdio.h>
Signature · 1 line
2.1.4
#37 lore raw

PATCH 33/48 net/mlx4: separate debugging macros

In reply to Adrien Mazarguil

The new definitions also rely on the existing DPDK logging subsystem instead of using fprintf() directly.

---
 drivers/net/mlx4/mlx4.c       |  2 +-
 drivers/net/mlx4/mlx4.h       | 46 -------------------
 drivers/net/mlx4/mlx4_flow.c  |  1 +
 drivers/net/mlx4/mlx4_utils.h | 92 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 94 insertions(+), 47 deletions(-)
drivers/net/mlx4/mlx4.c +1 -1
index f4dc67f..07a47ea 100644
@@ -59,7 +59,6 @@
 #include <rte_mempool.h>
 #include <rte_prefetch.h>
 #include <rte_malloc.h>
-#include <rte_log.h>
 #include <rte_alarm.h>
 #include <rte_memory.h>
 #include <rte_flow.h>
@@ -74,6 +73,7 @@
 /* PMD headers. */
 #include "mlx4.h"
 #include "mlx4_flow.h"
+#include "mlx4_utils.h"
 
 /* Work Request ID data type (64 bit). */
 typedef union {
drivers/net/mlx4/mlx4.h +0 -46

58 lines not on this page · raw message

drivers/net/mlx4/mlx4_flow.c +1 -0
index 3463713..6f6f455 100644
@@ -40,6 +40,7 @@
 /* PMD headers. */
 #include "mlx4.h"
 #include "mlx4_flow.h"
+#include "mlx4_utils.h"
 
 /** Static initializer for items. */
 #define ITEMS(...) \
drivers/net/mlx4/mlx4_utils.h new file +92 -0

92 lines not on this page · raw message

Signature · 1 line
2.1.4
#38 lore raw

PATCH 34/48 net/mlx4: use a single interrupt handle

In reply to Adrien Mazarguil

The reason one interrupt handle is currently used for RMV/LSC events and another one for Rx traffic is because these come from distinct file descriptors.

This can be simplified however as Rx interrupt file descriptors are stored elsewhere and are registered separately.

Modifying the interrupt handle type to RTE_INTR_HANDLE_UNKNOWN has never been necessary as disabling interrupts is actually done by unregistering the associated callback (RMV/LSC) or emptying the EFD array (Rx). Instead, make clear that the base handle file descriptor is invalid by setting it to -1 when disabled.

---
 drivers/net/mlx4/mlx4.c | 32 ++++++++++++++++++++------------
 drivers/net/mlx4/mlx4.h |  3 +--
 2 files changed, 21 insertions(+), 14 deletions(-)
drivers/net/mlx4/mlx4.c +20 -12
index 07a47ea..7fc9b4c 100644
@@ -2888,8 +2888,7 @@ priv_dev_interrupt_handler_uninstall(struct priv *priv, struct rte_eth_dev *dev)
 		ERROR("rte_intr_callback_unregister failed with %d %s",
 		      ret, strerror(rte_errno));
 	}
-	priv->intr_handle.fd = 0;
-	priv->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+	priv->intr_handle.fd = -1;
 	return ret;
 }
 
@@ -2930,7 +2929,6 @@ priv_dev_interrupt_handler_install(struct priv *priv,
 		return -rte_errno;
 	} else {
 		priv->intr_handle.fd = priv->ctx->async_fd;
-		priv->intr_handle.type = RTE_INTR_HANDLE_EXT;
 		rc = rte_intr_callback_register(&priv->intr_handle,
 						 mlx4_dev_interrupt_handler,
 						 dev);
@@ -2938,6 +2936,7 @@ priv_dev_interrupt_handler_install(struct priv *priv,
 			rte_errno = -rc;
 			ERROR("rte_intr_callback_register failed "
 			      " (rte_errno: %s)", strerror(rte_errno));
+			priv->intr_handle.fd = -1;
 			return -rte_errno;
 		}
 	}
@@ -3068,7 +3067,7 @@ priv_rx_intr_vec_enable(struct priv *priv)
 	unsigned int rxqs_n = priv->rxqs_n;
 	unsigned int n = RTE_MIN(rxqs_n, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID);
 	unsigned int count = 0;
-	struct rte_intr_handle *intr_handle = priv->dev->intr_handle;
+	struct rte_intr_handle *intr_handle = &priv->intr_handle;
 
 	if (!priv->dev->data->dev_conf.intr_conf.rxq)
 		return 0;
@@ -3080,7 +3079,6 @@ priv_rx_intr_vec_enable(struct priv *priv)
 		      " Rx interrupts will not be supported");
 		return -rte_errno;
 	}
-	intr_handle->type = RTE_INTR_HANDLE_EXT;
 	for (i = 0; i != n; ++i) {
 		struct rxq *rxq = (*priv->rxqs)[i];
 		int fd;
@@ -3133,7 +3131,7 @@ priv_rx_intr_vec_enable(struct priv *priv)
 static void
 priv_rx_intr_vec_disable(struct priv *priv)
 {
-	struct rte_intr_handle *intr_handle = priv->dev->intr_handle;
+	struct rte_intr_handle *intr_handle = &priv->intr_handle;
 
 	rte_intr_free_epoll_fd(intr_handle);
 	free(intr_handle->intr_vec);
@@ -3494,14 +3492,24 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		eth_dev->device = &pci_dev->device;
 		rte_eth_copy_pci_info(eth_dev, pci_dev);
 		eth_dev->device->driver = &mlx4_driver.driver;
+		/* Initialize local interrupt handle for current port. */
+		priv->intr_handle = (struct rte_intr_handle){
+			.fd = -1,
+			.type = RTE_INTR_HANDLE_EXT,
+		};
 		/*
-		 * Copy and override interrupt handle to prevent it from
-		 * being shared between all ethdev instances of a given PCI
-		 * device. This is required to properly handle Rx interrupts
-		 * on all ports.
+		 * Override ethdev interrupt handle pointer with private
+		 * handle instead of that of the parent PCI device used by
+		 * default. This prevents it from being shared between all
+		 * ports of the same PCI device since each of them is
+		 * associated its own Verbs context.
+		 *
+		 * Rx interrupts in particular require this as the PMD has
+		 * no control over the registration of queue interrupts
+		 * besides setting up eth_dev->intr_handle, the rest is
+		 * handled by rte_intr_rx_ctl().
 		 */
-		priv->intr_handle_dev = *eth_dev->intr_handle;
-		eth_dev->intr_handle = &priv->intr_handle_dev;
+		eth_dev->intr_handle = &priv->intr_handle;
 		priv->dev = eth_dev;
 		eth_dev->dev_ops = &mlx4_dev_ops;
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
drivers/net/mlx4/mlx4.h +1 -2
index da3e16b..087c831 100644
@@ -169,8 +169,7 @@ struct priv {
 	unsigned int txqs_n; /* TX queues array size. */
 	struct rxq *(*rxqs)[]; /* RX queues. */
 	struct txq *(*txqs)[]; /* TX queues. */
-	struct rte_intr_handle intr_handle_dev; /* Device interrupt handler. */
-	struct rte_intr_handle intr_handle; /* Interrupt handler. */
+	struct rte_intr_handle intr_handle; /* Port interrupt handle. */
 	struct rte_flow_drop *flow_drop_queue; /* Flow drop queue. */
 	LIST_HEAD(mlx4_flows, rte_flow) flows;
 	struct rte_intr_conf intr_conf; /* Active interrupt configuration. */
Signature · 1 line
2.1.4
#39 lore raw

PATCH 35/48 net/mlx4: rename alarm field

In reply to Adrien Mazarguil

Make clear this field is related to interrupt handling.

---
 drivers/net/mlx4/mlx4.c | 14 +++++++-------
 drivers/net/mlx4/mlx4.h |  6 +++---
 2 files changed, 10 insertions(+), 10 deletions(-)
drivers/net/mlx4/mlx4.c +7 -7
index 7fc9b4c..9f1eb4e 100644
@@ -2791,10 +2791,10 @@ priv_dev_status_handler(struct priv *priv, struct rte_eth_dev *dev,
 	mlx4_link_update(dev, 0);
 	if (((link->link_speed == 0) && link->link_status) ||
 	    ((link->link_speed != 0) && !link->link_status)) {
-		if (!priv->pending_alarm) {
+		if (!priv->intr_alarm) {
 			/* Inconsistent status, check again later. */
-			priv->pending_alarm = 1;
-			rte_eal_alarm_set(MLX4_ALARM_TIMEOUT_US,
+			priv->intr_alarm = 1;
+			rte_eal_alarm_set(MLX4_INTR_ALARM_TIMEOUT,
 					  mlx4_dev_link_status_handler,
 					  dev);
 		}
@@ -2818,8 +2818,8 @@ mlx4_dev_link_status_handler(void *arg)
 	uint32_t events;
 	int ret;
 
-	assert(priv->pending_alarm == 1);
-	priv->pending_alarm = 0;
+	assert(priv->intr_alarm == 1);
+	priv->intr_alarm = 0;
 	ret = priv_dev_status_handler(priv, dev, &events);
 	if (ret > 0 && events & (1 << RTE_ETH_EVENT_INTR_LSC))
 		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
@@ -2988,14 +2988,14 @@ priv_dev_link_interrupt_handler_uninstall(struct priv *priv,
 		if (ret)
 			return ret;
 	}
-	if (priv->pending_alarm)
+	if (priv->intr_alarm)
 		if (rte_eal_alarm_cancel(mlx4_dev_link_status_handler,
 					 dev)) {
 			ERROR("rte_eal_alarm_cancel failed "
 			      " (rte_errno: %s)", strerror(rte_errno));
 			return -rte_errno;
 		}
-	priv->pending_alarm = 0;
+	priv->intr_alarm = 0;
 	return 0;
 }
 
drivers/net/mlx4/mlx4.h +3 -3
index 087c831..ed0e6cd 100644
@@ -63,8 +63,8 @@
 #define MLX4_PMD_TX_MP_CACHE 8
 #endif
 
-/* Alarm timeout. */
-#define MLX4_ALARM_TIMEOUT_US 100000
+/* Interrupt alarm timeout value in microseconds. */
+#define MLX4_INTR_ALARM_TIMEOUT 100000
 
 /* Port parameter. */
 #define MLX4_PMD_PORT_KVARG "port"
@@ -162,7 +162,7 @@ struct priv {
 	uint8_t port; /* Physical port number. */
 	unsigned int started:1; /* Device started, flows enabled. */
 	unsigned int vf:1; /* This is a VF device. */
-	unsigned int pending_alarm:1; /* An alarm is pending. */
+	unsigned int intr_alarm:1; /* An interrupt alarm is scheduled. */
 	unsigned int isolated:1; /* Toggle isolated mode. */
 	/* RX/TX queues. */
 	unsigned int rxqs_n; /* RX queues array size. */
Signature · 1 line
2.1.4
#40 lore raw

PATCH 36/48 net/mlx4: refactor interrupt FD settings

In reply to Adrien Mazarguil

File descriptors used for interrupts processing must be made non-blocking.

Doing so as soon as they are opened instead of waiting until they are needed is more efficient as it avoids performing redundant system calls and run through their associated error-handling code later on.

---
 drivers/net/mlx4/Makefile     |  1 +
 drivers/net/mlx4/mlx4.c       | 63 ++++++++++++++----------------------
 drivers/net/mlx4/mlx4.h       |  4 +++
 drivers/net/mlx4/mlx4_utils.c | 66 ++++++++++++++++++++++++++++++++++++++
 drivers/net/mlx4/mlx4_utils.h |  4 +++
 5 files changed, 99 insertions(+), 39 deletions(-)
drivers/net/mlx4/Makefile +1 -0
index 78ea350..77aaad2 100644
@@ -37,6 +37,7 @@ LIB = librte_pmd_mlx4.a
 # Sources.
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_flow.c
+SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_utils.c
 
 # Basic CFLAGS.
 CFLAGS += -O3
drivers/net/mlx4/mlx4.c +24 -39

106 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +4 -0
index ed0e6cd..6104842 100644
@@ -46,6 +46,10 @@
 #pragma GCC diagnostic error "-Wpedantic"
 #endif
 
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_interrupts.h>
+
 /* Request send completion once in every 64 sends, might be less. */
 #define MLX4_PMD_TX_PER_COMP_REQ 64
 
drivers/net/mlx4/mlx4_utils.c new file +66 -0

66 lines not on this page · raw message

drivers/net/mlx4/mlx4_utils.h +4 -0
index c404de2..0b9a96a 100644
@@ -89,4 +89,8 @@ pmd_drv_log_basename(const char *s)
 #define WARN(...) PMD_DRV_LOG(WARNING, __VA_ARGS__)
 #define ERROR(...) PMD_DRV_LOG(ERR, __VA_ARGS__)
 
+/* mlx4_utils.c */
+
+int mlx4_fd_set_non_blocking(int fd);
+
 #endif /* MLX4_UTILS_H_ */
Signature · 1 line
2.1.4
#41 lore raw

PATCH 37/48 net/mlx4: clean up interrupt functions prototypes

In reply to Adrien Mazarguil

The naming scheme for these functions is overly verbose and not accurate enough, with too many "handler" functions that are difficult to differentiate (e.g. mlx4_dev_link_status_handler(), mlx4_dev_interrupt_handler() and priv_dev_status_handler()).

This commit renames them and removes the unnecessary dev argument which can be retrieved through the private structure where needed. Documentation is updated accordingly.

---
 drivers/net/mlx4/mlx4.c | 145 ++++++++++++++++---------------------------
 1 file changed, 55 insertions(+), 90 deletions(-)
drivers/net/mlx4/mlx4.c +55 -90
index d6d4be7..50e0687 100644
@@ -2048,14 +2048,9 @@ mlx4_rx_queue_release(void *dpdk_rxq)
 	rte_free(rxq);
 }
 
-static int
-priv_dev_interrupt_handler_install(struct priv *, struct rte_eth_dev *);
-
-static int
-priv_dev_removal_interrupt_handler_install(struct priv *, struct rte_eth_dev *);
-
-static int
-priv_dev_link_interrupt_handler_install(struct priv *, struct rte_eth_dev *);
+static int priv_interrupt_handler_install(struct priv *priv);
+static int priv_removal_interrupt_handler_install(struct priv *priv);
+static int priv_link_interrupt_handler_install(struct priv *priv);
 
 /**
  * DPDK callback to start the device.
@@ -2081,13 +2076,13 @@ mlx4_dev_start(struct rte_eth_dev *dev)
 	ret = priv_mac_addr_add(priv);
 	if (ret)
 		goto err;
-	ret = priv_dev_link_interrupt_handler_install(priv, dev);
+	ret = priv_link_interrupt_handler_install(priv);
 	if (ret) {
 		ERROR("%p: LSC handler install failed",
 		     (void *)dev);
 		goto err;
 	}
-	ret = priv_dev_removal_interrupt_handler_install(priv, dev);
+	ret = priv_removal_interrupt_handler_install(priv);
 	if (ret) {
 		ERROR("%p: RMV handler install failed",
 		     (void *)dev);
@@ -2184,15 +2179,9 @@ removed_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 	return 0;
 }
 
-static int
-priv_dev_interrupt_handler_uninstall(struct priv *, struct rte_eth_dev *);
-
-static int
-priv_dev_removal_interrupt_handler_uninstall(struct priv *,
-					     struct rte_eth_dev *);
-
-static int
-priv_dev_link_interrupt_handler_uninstall(struct priv *, struct rte_eth_dev *);
+static int priv_interrupt_handler_uninstall(struct priv *priv);
+static int priv_removal_interrupt_handler_uninstall(struct priv *priv);
+static int priv_link_interrupt_handler_uninstall(struct priv *priv);
 
 /**
  * DPDK callback to close the device.
@@ -2256,8 +2245,8 @@ mlx4_dev_close(struct rte_eth_dev *dev)
 		claim_zero(ibv_close_device(priv->ctx));
 	} else
 		assert(priv->ctx == NULL);
-	priv_dev_removal_interrupt_handler_uninstall(priv, dev);
-	priv_dev_link_interrupt_handler_uninstall(priv, dev);
+	priv_removal_interrupt_handler_uninstall(priv);
+	priv_link_interrupt_handler_uninstall(priv);
 	priv_rx_intr_vec_disable(priv);
 	memset(priv, 0, sizeof(*priv));
 }
@@ -2745,31 +2734,25 @@ priv_get_mac(struct priv *priv, uint8_t (*mac)[ETHER_ADDR_LEN])
 	return 0;
 }
 
-static void
-mlx4_dev_link_status_handler(void *);
-static void
-mlx4_dev_interrupt_handler(void *);
+static void mlx4_link_status_alarm(struct priv *priv);
 
 /**
- * Link/device status handler.
+ * Collect interrupt events.
  *
  * @param priv
  *   Pointer to private structure.
- * @param dev
- *   Pointer to the rte_eth_dev structure.
  * @param events
  *   Pointer to event flags holder.
  *
  * @return
- *   Number of events
+ *   Number of events.
  */
 static int
-priv_dev_status_handler(struct priv *priv, struct rte_eth_dev *dev,
-			uint32_t *events)
+priv_collect_interrupt_events(struct priv *priv, uint32_t *events)
 {
 	struct ibv_async_event event;
 	int port_change = 0;
-	struct rte_eth_link *link = &dev->data->dev_link;
+	struct rte_eth_link *link = &priv->dev->data->dev_link;
 	int ret = 0;
 
 	*events = 0;
@@ -2793,15 +2776,16 @@ priv_dev_status_handler(struct priv *priv, struct rte_eth_dev *dev,
 	}
 	if (!port_change)
 		return ret;
-	mlx4_link_update(dev, 0);
+	mlx4_link_update(priv->dev, 0);
 	if (((link->link_speed == 0) && link->link_status) ||
 	    ((link->link_speed != 0) && !link->link_status)) {
 		if (!priv->intr_alarm) {
 			/* Inconsistent status, check again later. */
 			priv->intr_alarm = 1;
 			rte_eal_alarm_set(MLX4_INTR_ALARM_TIMEOUT,
-					  mlx4_dev_link_status_handler,
-					  dev);
+					  (void (*)(void *))
+					  mlx4_link_status_alarm,
+					  priv);
 		}
 	} else {
 		*events |= (1 << RTE_ETH_EVENT_INTR_LSC);
@@ -2810,53 +2794,48 @@ priv_dev_status_handler(struct priv *priv, struct rte_eth_dev *dev,
 }
 
 /**
- * Handle delayed link status event.
+ * Process scheduled link status check.
  *
- * @param arg
- *   Registered argument.
+ * @param priv
+ *   Pointer to private structure.
  */
 static void
-mlx4_dev_link_status_handler(void *arg)
+mlx4_link_status_alarm(struct priv *priv)
 {
-	struct rte_eth_dev *dev = arg;
-	struct priv *priv = dev->data->dev_private;
 	uint32_t events;
 	int ret;
 
 	assert(priv->intr_alarm == 1);
 	priv->intr_alarm = 0;
-	ret = priv_dev_status_handler(priv, dev, &events);
+	ret = priv_collect_interrupt_events(priv, &events);
 	if (ret > 0 && events & (1 << RTE_ETH_EVENT_INTR_LSC))
-		_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
+		_rte_eth_dev_callback_process(priv->dev,
+					      RTE_ETH_EVENT_INTR_LSC,
 					      NULL, NULL);
 }
 
 /**
  * Handle interrupts from the NIC.
  *
- * @param[in] intr_handle
- *   Interrupt handler.
- * @param cb_arg
- *   Callback argument.
+ * @param priv
+ *   Pointer to private structure.
  */
 static void
-mlx4_dev_interrupt_handler(void *cb_arg)
+mlx4_interrupt_handler(struct priv *priv)
 {
-	struct rte_eth_dev *dev = cb_arg;
-	struct priv *priv = dev->data->dev_private;
 	int ret;
 	uint32_t ev;
 	int i;
 
-	ret = priv_dev_status_handler(priv, dev, &ev);
+	ret = priv_collect_interrupt_events(priv, &ev);
 	if (ret > 0) {
 		for (i = RTE_ETH_EVENT_UNKNOWN;
 		     i < RTE_ETH_EVENT_MAX;
 		     i++) {
 			if (ev & (1 << i)) {
 				ev &= ~(1 << i);
-				_rte_eth_dev_callback_process(dev, i, NULL,
-							      NULL);
+				_rte_eth_dev_callback_process(priv->dev, i,
+							      NULL, NULL);
 				ret--;
 			}
 		}
@@ -2871,14 +2850,12 @@ mlx4_dev_interrupt_handler(void *cb_arg)
  *
  * @param priv
  *   Pointer to private structure.
- * @param dev
- *   Pointer to the rte_eth_dev structure.
  *
  * @return
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
-priv_dev_interrupt_handler_uninstall(struct priv *priv, struct rte_eth_dev *dev)
+priv_interrupt_handler_uninstall(struct priv *priv)
 {
 	int ret;
 
@@ -2886,8 +2863,9 @@ priv_dev_interrupt_handler_uninstall(struct priv *priv, struct rte_eth_dev *dev)
 	    priv->intr_conf.rmv)
 		return 0;
 	ret = rte_intr_callback_unregister(&priv->intr_handle,
-					   mlx4_dev_interrupt_handler,
-					   dev);
+					   (void (*)(void *))
+					   mlx4_interrupt_handler,
+					   priv);
 	if (ret < 0) {
 		rte_errno = ret;
 		ERROR("rte_intr_callback_unregister failed with %d %s",
@@ -2902,15 +2880,12 @@ priv_dev_interrupt_handler_uninstall(struct priv *priv, struct rte_eth_dev *dev)
  *
  * @param priv
  *   Pointer to private structure.
- * @param dev
- *   Pointer to the rte_eth_dev structure.
  *
  * @return
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
-priv_dev_interrupt_handler_install(struct priv *priv,
-				   struct rte_eth_dev *dev)
+priv_interrupt_handler_install(struct priv *priv)
 {
 	int rc;
 
@@ -2924,8 +2899,9 @@ priv_dev_interrupt_handler_install(struct priv *priv,
 		return 0;
 	priv->intr_handle.fd = priv->ctx->async_fd;
 	rc = rte_intr_callback_register(&priv->intr_handle,
-					mlx4_dev_interrupt_handler,
-					dev);
+					(void (*)(void *))
+					mlx4_interrupt_handler,
+					priv);
 	if (!rc)
 		return 0;
 	rte_errno = -rc;
@@ -2940,19 +2916,16 @@ priv_dev_interrupt_handler_install(struct priv *priv,
  *
  * @param priv
  *   Pointer to private structure.
- * @param dev
- *   Pointer to the rte_eth_dev structure.
  *
  * @return
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
-priv_dev_removal_interrupt_handler_uninstall(struct priv *priv,
-					    struct rte_eth_dev *dev)
+priv_removal_interrupt_handler_uninstall(struct priv *priv)
 {
-	if (dev->data->dev_conf.intr_conf.rmv) {
+	if (priv->dev->data->dev_conf.intr_conf.rmv) {
 		priv->intr_conf.rmv = 0;
-		return priv_dev_interrupt_handler_uninstall(priv, dev);
+		return priv_interrupt_handler_uninstall(priv);
 	}
 	return 0;
 }
@@ -2962,27 +2935,25 @@ priv_dev_removal_interrupt_handler_uninstall(struct priv *priv,
  *
  * @param priv
  *   Pointer to private structure.
- * @param dev
- *   Pointer to the rte_eth_dev structure.
  *
  * @return
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
-priv_dev_link_interrupt_handler_uninstall(struct priv *priv,
-					  struct rte_eth_dev *dev)
+priv_link_interrupt_handler_uninstall(struct priv *priv)
 {
 	int ret = 0;
 
-	if (dev->data->dev_conf.intr_conf.lsc) {
+	if (priv->dev->data->dev_conf.intr_conf.lsc) {
 		priv->intr_conf.lsc = 0;
-		ret = priv_dev_interrupt_handler_uninstall(priv, dev);
+		ret = priv_interrupt_handler_uninstall(priv);
 		if (ret)
 			return ret;
 	}
 	if (priv->intr_alarm)
-		if (rte_eal_alarm_cancel(mlx4_dev_link_status_handler,
-					 dev)) {
+		if (rte_eal_alarm_cancel((void (*)(void *))
+					 mlx4_link_status_alarm,
+					 priv)) {
 			ERROR("rte_eal_alarm_cancel failed "
 			      " (rte_errno: %s)", strerror(rte_errno));
 			return -rte_errno;
@@ -2996,20 +2967,17 @@ priv_dev_link_interrupt_handler_uninstall(struct priv *priv,
  *
  * @param priv
  *   Pointer to private structure.
- * @param dev
- *   Pointer to the rte_eth_dev structure.
  *
  * @return
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
-priv_dev_link_interrupt_handler_install(struct priv *priv,
-					struct rte_eth_dev *dev)
+priv_link_interrupt_handler_install(struct priv *priv)
 {
 	int ret;
 
-	if (dev->data->dev_conf.intr_conf.lsc) {
-		ret = priv_dev_interrupt_handler_install(priv, dev);
+	if (priv->dev->data->dev_conf.intr_conf.lsc) {
+		ret = priv_interrupt_handler_install(priv);
 		if (ret)
 			return ret;
 		priv->intr_conf.lsc = 1;
@@ -3022,20 +2990,17 @@ priv_dev_link_interrupt_handler_install(struct priv *priv,
  *
  * @param priv
  *   Pointer to private structure.
- * @param dev
- *   Pointer to the rte_eth_dev structure.
  *
  * @return
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
-priv_dev_removal_interrupt_handler_install(struct priv *priv,
-					   struct rte_eth_dev *dev)
+priv_removal_interrupt_handler_install(struct priv *priv)
 {
 	int ret;
 
-	if (dev->data->dev_conf.intr_conf.rmv) {
-		ret = priv_dev_interrupt_handler_install(priv, dev);
+	if (priv->dev->data->dev_conf.intr_conf.rmv) {
+		ret = priv_interrupt_handler_install(priv);
 		if (ret)
 			return ret;
 		priv->intr_conf.rmv = 1;
Signature · 1 line
2.1.4
#42 lore raw

PATCH 38/48 net/mlx4: compact interrupt functions

In reply to Adrien Mazarguil

Link status (LSC) and removal (RMV) interrupts share a common handler and are toggled simultaneously from common install/uninstall functions.

Four additional wrapper functions (two for each interrupt type) are currently necessary because the PMD maintains an internal configuration state for interrupts (priv->intr_conf).

This complexity can be avoided entirely since the PMD does not disable interrupts configuration parameters in case of error anymore.

With this commit, only two functions are necessary to toggle interrupts (including Rx) during start/stop cycles.

---
 drivers/net/mlx4/mlx4.c | 199 +++++++++----------------------------------
 drivers/net/mlx4/mlx4.h |   1 -
 2 files changed, 41 insertions(+), 159 deletions(-)
drivers/net/mlx4/mlx4.c +41 -158
index 50e0687..c99f040 100644
@@ -2048,9 +2048,8 @@ mlx4_rx_queue_release(void *dpdk_rxq)
 	rte_free(rxq);
 }
 
-static int priv_interrupt_handler_install(struct priv *priv);
-static int priv_removal_interrupt_handler_install(struct priv *priv);
-static int priv_link_interrupt_handler_install(struct priv *priv);
+static int priv_intr_uninstall(struct priv *priv);
+static int priv_intr_install(struct priv *priv);
 
 /**
  * DPDK callback to start the device.
@@ -2076,24 +2075,12 @@ mlx4_dev_start(struct rte_eth_dev *dev)
 	ret = priv_mac_addr_add(priv);
 	if (ret)
 		goto err;
-	ret = priv_link_interrupt_handler_install(priv);
+	ret = priv_intr_install(priv);
 	if (ret) {
-		ERROR("%p: LSC handler install failed",
+		ERROR("%p: interrupt handler installation failed",
 		     (void *)dev);
 		goto err;
 	}
-	ret = priv_removal_interrupt_handler_install(priv);
-	if (ret) {
-		ERROR("%p: RMV handler install failed",
-		     (void *)dev);
-		goto err;
-	}
-	ret = priv_rx_intr_vec_enable(priv);
-	if (ret) {
-		ERROR("%p: Rx interrupt vector creation failed",
-		      (void *)dev);
-		goto err;
-	}
 	ret = mlx4_priv_flow_start(priv);
 	if (ret) {
 		ERROR("%p: flow start failed: %s",
@@ -2126,6 +2113,7 @@ mlx4_dev_stop(struct rte_eth_dev *dev)
 	DEBUG("%p: detaching flows from all RX queues", (void *)dev);
 	priv->started = 0;
 	mlx4_priv_flow_stop(priv);
+	priv_intr_uninstall(priv);
 	priv_mac_addr_del(priv);
 }
 
@@ -2179,10 +2167,6 @@ removed_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 	return 0;
 }
 
-static int priv_interrupt_handler_uninstall(struct priv *priv);
-static int priv_removal_interrupt_handler_uninstall(struct priv *priv);
-static int priv_link_interrupt_handler_uninstall(struct priv *priv);
-
 /**
  * DPDK callback to close the device.
  *
@@ -2245,9 +2229,7 @@ mlx4_dev_close(struct rte_eth_dev *dev)
 		claim_zero(ibv_close_device(priv->ctx));
 	} else
 		assert(priv->ctx == NULL);
-	priv_removal_interrupt_handler_uninstall(priv);
-	priv_link_interrupt_handler_uninstall(priv);
-	priv_rx_intr_vec_disable(priv);
+	priv_intr_uninstall(priv);
 	memset(priv, 0, sizeof(*priv));
 }
 
@@ -2753,6 +2735,8 @@ priv_collect_interrupt_events(struct priv *priv, uint32_t *events)
 	struct ibv_async_event event;
 	int port_change = 0;
 	struct rte_eth_link *link = &priv->dev->data->dev_link;
+	const struct rte_intr_conf *const intr_conf =
+		&priv->dev->data->dev_conf.intr_conf;
 	int ret = 0;
 
 	*events = 0;
@@ -2762,11 +2746,11 @@ priv_collect_interrupt_events(struct priv *priv, uint32_t *events)
 			break;
 		if ((event.event_type == IBV_EVENT_PORT_ACTIVE ||
 		     event.event_type == IBV_EVENT_PORT_ERR) &&
-		    (priv->intr_conf.lsc == 1)) {
+		    intr_conf->lsc) {
 			port_change = 1;
 			ret++;
 		} else if (event.event_type == IBV_EVENT_DEVICE_FATAL &&
-			   priv->intr_conf.rmv == 1) {
+			   intr_conf->rmv) {
 			*events |= (1 << RTE_ETH_EVENT_INTR_RMV);
 			ret++;
 		} else
@@ -2855,24 +2839,22 @@ mlx4_interrupt_handler(struct priv *priv)
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
-priv_interrupt_handler_uninstall(struct priv *priv)
+priv_intr_uninstall(struct priv *priv)
 {
-	int ret;
+	int err = rte_errno; /* Make sure rte_errno remains unchanged. */
 
-	if (priv->intr_conf.lsc ||
-	    priv->intr_conf.rmv)
-		return 0;
-	ret = rte_intr_callback_unregister(&priv->intr_handle,
-					   (void (*)(void *))
-					   mlx4_interrupt_handler,
-					   priv);
-	if (ret < 0) {
-		rte_errno = ret;
-		ERROR("rte_intr_callback_unregister failed with %d %s",
-		      ret, strerror(rte_errno));
+	if (priv->intr_handle.fd != -1) {
+		rte_intr_callback_unregister(&priv->intr_handle,
+					     (void (*)(void *))
+					     mlx4_interrupt_handler,
+					     priv);
+		priv->intr_handle.fd = -1;
 	}
-	priv->intr_handle.fd = -1;
-	return ret;
+	rte_eal_alarm_cancel((void (*)(void *))mlx4_link_status_alarm, priv);
+	priv->intr_alarm = 0;
+	priv_rx_intr_vec_disable(priv);
+	rte_errno = err;
+	return 0;
 }
 
 /**
@@ -2885,127 +2867,30 @@ priv_interrupt_handler_uninstall(struct priv *priv)
  *   0 on success, negative errno value otherwise and rte_errno is set.
  */
 static int
-priv_interrupt_handler_install(struct priv *priv)
+priv_intr_install(struct priv *priv)
 {
+	const struct rte_intr_conf *const intr_conf =
+		&priv->dev->data->dev_conf.intr_conf;
 	int rc;
 
-	/*
-	 * Check whether the interrupt handler has already been installed
-	 * for either type of interrupt.
-	 */
-	if (priv->intr_conf.lsc &&
-	    priv->intr_conf.rmv &&
-	    priv->intr_handle.fd)
-		return 0;
-	priv->intr_handle.fd = priv->ctx->async_fd;
-	rc = rte_intr_callback_register(&priv->intr_handle,
-					(void (*)(void *))
-					mlx4_interrupt_handler,
-					priv);
-	if (!rc)
-		return 0;
-	rte_errno = -rc;
-	ERROR("rte_intr_callback_register failed (rte_errno: %s)",
-	      strerror(rte_errno));
-	priv->intr_handle.fd = -1;
-	return -rte_errno;
-}
-
-/**
- * Uninstall interrupt handler.
- *
- * @param priv
- *   Pointer to private structure.
- *
- * @return
- *   0 on success, negative errno value otherwise and rte_errno is set.
- */
-static int
-priv_removal_interrupt_handler_uninstall(struct priv *priv)
-{
-	if (priv->dev->data->dev_conf.intr_conf.rmv) {
-		priv->intr_conf.rmv = 0;
-		return priv_interrupt_handler_uninstall(priv);
-	}
-	return 0;
-}
-
-/**
- * Uninstall interrupt handler.
- *
- * @param priv
- *   Pointer to private structure.
- *
- * @return
- *   0 on success, negative errno value otherwise and rte_errno is set.
- */
-static int
-priv_link_interrupt_handler_uninstall(struct priv *priv)
-{
-	int ret = 0;
-
-	if (priv->dev->data->dev_conf.intr_conf.lsc) {
-		priv->intr_conf.lsc = 0;
-		ret = priv_interrupt_handler_uninstall(priv);
-		if (ret)
-			return ret;
-	}
-	if (priv->intr_alarm)
-		if (rte_eal_alarm_cancel((void (*)(void *))
-					 mlx4_link_status_alarm,
-					 priv)) {
-			ERROR("rte_eal_alarm_cancel failed "
-			      " (rte_errno: %s)", strerror(rte_errno));
-			return -rte_errno;
+	priv_intr_uninstall(priv);
+	if (intr_conf->rxq && priv_rx_intr_vec_enable(priv) < 0)
+		goto error;
+	if (intr_conf->lsc | intr_conf->rmv) {
+		priv->intr_handle.fd = priv->ctx->async_fd;
+		rc = rte_intr_callback_register(&priv->intr_handle,
+						(void (*)(void *))
+						mlx4_interrupt_handler,
+						priv);
+		if (rc < 0) {
+			rte_errno = -rc;
+			goto error;
 		}
-	priv->intr_alarm = 0;
-	return 0;
-}
-
-/**
- * Install link interrupt handler.
- *
- * @param priv
- *   Pointer to private structure.
- *
- * @return
- *   0 on success, negative errno value otherwise and rte_errno is set.
- */
-static int
-priv_link_interrupt_handler_install(struct priv *priv)
-{
-	int ret;
-
-	if (priv->dev->data->dev_conf.intr_conf.lsc) {
-		ret = priv_interrupt_handler_install(priv);
-		if (ret)
-			return ret;
-		priv->intr_conf.lsc = 1;
-	}
-	return 0;
-}
-
-/**
- * Install removal interrupt handler.
- *
- * @param priv
- *   Pointer to private structure.
- *
- * @return
- *   0 on success, negative errno value otherwise and rte_errno is set.
- */
-static int
-priv_removal_interrupt_handler_install(struct priv *priv)
-{
-	int ret;
-
-	if (priv->dev->data->dev_conf.intr_conf.rmv) {
-		ret = priv_interrupt_handler_install(priv);
-		if (ret)
-			return ret;
-		priv->intr_conf.rmv = 1;
 	}
 	return 0;
+error:
+	priv_intr_uninstall(priv);
+	return -rte_errno;
 }
 
 /**
@@ -3026,8 +2911,6 @@ priv_rx_intr_vec_enable(struct priv *priv)
 	unsigned int count = 0;
 	struct rte_intr_handle *intr_handle = &priv->intr_handle;
 
-	if (!priv->dev->data->dev_conf.intr_conf.rxq)
-		return 0;
 	priv_rx_intr_vec_disable(priv);
 	intr_handle->intr_vec = malloc(sizeof(intr_handle->intr_vec[rxqs_n]));
 	if (intr_handle->intr_vec == NULL) {
drivers/net/mlx4/mlx4.h +0 -1
index 6104842..528607c 100644
@@ -176,7 +176,6 @@ struct priv {
 	struct rte_intr_handle intr_handle; /* Port interrupt handle. */
 	struct rte_flow_drop *flow_drop_queue; /* Flow drop queue. */
 	LIST_HEAD(mlx4_flows, rte_flow) flows;
-	struct rte_intr_conf intr_conf; /* Active interrupt configuration. */
 };
 
 #endif /* RTE_PMD_MLX4_H_ */
Signature · 1 line
2.1.4
#43 lore raw

PATCH 39/48 net/mlx4: separate interrupt handling

In reply to Adrien Mazarguil

Private functions are now prefixed with "mlx4_" to prevent them from conflicting with their mlx5 PMD counterparts at link time.

No impact on functionality.

---
 drivers/net/mlx4/Makefile    |   1 +
 drivers/net/mlx4/mlx4.c      | 340 +---------------------------------
 drivers/net/mlx4/mlx4.h      |  11 ++
 drivers/net/mlx4/mlx4_intr.c | 376 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 392 insertions(+), 336 deletions(-)
drivers/net/mlx4/Makefile +1 -0
index 77aaad2..37dcdf7 100644
@@ -37,6 +37,7 @@ LIB = librte_pmd_mlx4.a
 # Sources.
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_flow.c
+SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_intr.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_utils.c
 
 # Basic CFLAGS.
drivers/net/mlx4/mlx4.c +4 -336

388 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +11 -0
index 528607c..f815dd8 100644
@@ -178,4 +178,15 @@ struct priv {
 	LIST_HEAD(mlx4_flows, rte_flow) flows;
 };
 
+/* mlx4.c */
+
+int mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete);
+
+/* mlx4_intr.c */
+
+int mlx4_intr_uninstall(struct priv *priv);
+int mlx4_intr_install(struct priv *priv);
+int mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx);
+int mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx);
+
 #endif /* RTE_PMD_MLX4_H_ */
drivers/net/mlx4/mlx4_intr.c new file +376 -0

376 lines not on this page · raw message

Signature · 1 line
2.1.4
#44 lore raw

PATCH 40/48 net/mlx4: separate Rx/Tx definitions

In reply to Adrien Mazarguil

Except for a minor documentation update on internal structure definitions to make them more Doxygen-friendly, there is no impact on functionality.

---
 drivers/net/mlx4/mlx4.c      |  13 +---
 drivers/net/mlx4/mlx4.h      |  69 +-------------------
 drivers/net/mlx4/mlx4_flow.c |   1 +
 drivers/net/mlx4/mlx4_intr.c |   1 +
 drivers/net/mlx4/mlx4_rxtx.h | 132 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 137 insertions(+), 79 deletions(-)
drivers/net/mlx4/mlx4.c +1 -12
index 284575c..21f0664 100644
@@ -71,19 +71,9 @@
 /* PMD headers. */
 #include "mlx4.h"
 #include "mlx4_flow.h"
+#include "mlx4_rxtx.h"
 #include "mlx4_utils.h"
 
-/* Work Request ID data type (64 bit). */
-typedef union {
-	struct {
-		uint32_t id;
-		uint16_t offset;
-	} data;
-	uint64_t raw;
-} wr_id_t;
-
-#define WR_ID(o) (((wr_id_t *)&(o))->data)
-
 /** Configuration structure for device arguments. */
 struct mlx4_conf {
 	struct {
@@ -3083,7 +3073,6 @@ RTE_INIT(rte_mlx4_pmd_init);
 static void
 rte_mlx4_pmd_init(void)
 {
-	RTE_BUILD_BUG_ON(sizeof(wr_id_t) != sizeof(uint64_t));
 	/*
 	 * RDMAV_HUGEPAGES_SAFE tells ibv_fork_init() we intend to use
 	 * huge pages. Calling ibv_fork_init() during init allows
drivers/net/mlx4/mlx4.h +2 -67

75 lines not on this page · raw message

drivers/net/mlx4/mlx4_flow.c +1 -0
index 6f6f455..61455ce 100644
@@ -40,6 +40,7 @@
 /* PMD headers. */
 #include "mlx4.h"
 #include "mlx4_flow.h"
+#include "mlx4_rxtx.h"
 #include "mlx4_utils.h"
 
 /** Static initializer for items. */
drivers/net/mlx4/mlx4_intr.c +1 -0
index bcf4d59..76d2e01 100644
@@ -56,6 +56,7 @@
 #include <rte_interrupts.h>
 
 #include "mlx4.h"
+#include "mlx4_rxtx.h"
 #include "mlx4_utils.h"
 
 static void mlx4_link_status_alarm(struct priv *priv);
drivers/net/mlx4/mlx4_rxtx.h new file +132 -0

132 lines not on this page · raw message

Signature · 1 line
2.1.4
#45 lore raw

PATCH 41/48 net/mlx4: separate Rx/Tx functions

In reply to Adrien Mazarguil

This commit groups all data plane functions (Rx/Tx) into a separate file and adjusts header files accordingly.

Private functions are now prefixed with "mlx4_" to prevent them from conflicting with their mlx5 PMD counterparts at link time.

No impact on functionality.

---
 drivers/net/mlx4/Makefile    |   1 +
 drivers/net/mlx4/mlx4.c      | 493 +----------------------------------
 drivers/net/mlx4/mlx4.h      |   2 +
 drivers/net/mlx4/mlx4_rxtx.c | 533 ++++++++++++++++++++++++++++++++++++++
 drivers/net/mlx4/mlx4_rxtx.h |  12 +
 5 files changed, 554 insertions(+), 487 deletions(-)
drivers/net/mlx4/Makefile +1 -0
index 37dcdf7..1a7e847 100644
@@ -38,6 +38,7 @@ LIB = librte_pmd_mlx4.a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_intr.c
+SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_rxtx.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_utils.c
 
 # Basic CFLAGS.
drivers/net/mlx4/mlx4.c +6 -487

564 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +2 -0
index edbece6..efccf1a 100644
@@ -49,6 +49,7 @@
 #include <rte_ethdev.h>
 #include <rte_ether.h>
 #include <rte_interrupts.h>
+#include <rte_mempool.h>
 
 /* Request send completion once in every 64 sends, might be less. */
 #define MLX4_PMD_TX_PER_COMP_REQ 64
@@ -115,6 +116,7 @@ struct priv {
 
 /* mlx4.c */
 
+struct ibv_mr *mlx4_mp2mr(struct ibv_pd *pd, struct rte_mempool *mp);
 int mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete);
 
 /* mlx4_intr.c */
drivers/net/mlx4/mlx4_rxtx.c new file +533 -0

533 lines not on this page · raw message

drivers/net/mlx4/mlx4_rxtx.h +12 -0
index 1d46e1e..ab44af5 100644
@@ -129,4 +129,16 @@ struct txq {
 	unsigned int socket; /**< CPU socket ID for allocations. */
 };
 
+/* mlx4_rxtx.c */
+
+uint32_t mlx4_txq_mp2mr(struct txq *txq, struct rte_mempool *mp);
+uint16_t mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts,
+		       uint16_t pkts_n);
+uint16_t mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts,
+		       uint16_t pkts_n);
+uint16_t mlx4_tx_burst_removed(void *dpdk_txq, struct rte_mbuf **pkts,
+			       uint16_t pkts_n);
+uint16_t mlx4_rx_burst_removed(void *dpdk_rxq, struct rte_mbuf **pkts,
+			       uint16_t pkts_n);
+
 #endif /* MLX4_RXTX_H_ */
Signature · 1 line
2.1.4
#46 lore raw

PATCH 42/48 net/mlx4: separate device control functions

In reply to Adrien Mazarguil

Private functions are now prefixed with "mlx4_" to prevent them from conflicting with their mlx5 PMD counterparts at link time.

No impact on functionality.

---
 drivers/net/mlx4/Makefile      |   1 +
 drivers/net/mlx4/mlx4.c        | 752 +---------------------------------
 drivers/net/mlx4/mlx4.h        |  18 +
 drivers/net/mlx4/mlx4_ethdev.c | 792 ++++++++++++++++++++++++++++++++++++
 drivers/net/mlx4/mlx4_utils.h  |   9 +
 5 files changed, 829 insertions(+), 743 deletions(-)
drivers/net/mlx4/Makefile +1 -0
index 1a7e847..6498eef 100644
@@ -36,6 +36,7 @@ LIB = librte_pmd_mlx4.a
 
 # Sources.
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4.c
+SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_intr.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_rxtx.c
drivers/net/mlx4/mlx4.c +9 -743

812 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +18 -0
index efccf1a..b5f2953 100644
@@ -34,6 +34,7 @@
 #ifndef RTE_PMD_MLX4_H_
 #define RTE_PMD_MLX4_H_
 
+#include <net/if.h>
 #include <stdint.h>
 
 /* Verbs header. */
@@ -117,7 +118,24 @@ struct priv {
 /* mlx4.c */
 
 struct ibv_mr *mlx4_mp2mr(struct ibv_pd *pd, struct rte_mempool *mp);
+
+/* mlx4_ethdev.c */
+
+int mlx4_get_ifname(const struct priv *priv, char (*ifname)[IF_NAMESIZE]);
+int mlx4_get_mac(struct priv *priv, uint8_t (*mac)[ETHER_ADDR_LEN]);
+int mlx4_mtu_get(struct priv *priv, uint16_t *mtu);
+int mlx4_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
+int mlx4_dev_set_link_down(struct rte_eth_dev *dev);
+int mlx4_dev_set_link_up(struct rte_eth_dev *dev);
+void mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
+void mlx4_stats_reset(struct rte_eth_dev *dev);
+void mlx4_dev_infos_get(struct rte_eth_dev *dev,
+			struct rte_eth_dev_info *info);
 int mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete);
+int mlx4_flow_ctrl_get(struct rte_eth_dev *dev,
+		       struct rte_eth_fc_conf *fc_conf);
+int mlx4_flow_ctrl_set(struct rte_eth_dev *dev,
+		       struct rte_eth_fc_conf *fc_conf);
 
 /* mlx4_intr.c */
 
drivers/net/mlx4/mlx4_ethdev.c new file +792 -0

792 lines not on this page · raw message

drivers/net/mlx4/mlx4_utils.h +9 -0
index 0b9a96a..e74b61b 100644
@@ -34,6 +34,9 @@
 #ifndef MLX4_UTILS_H_
 #define MLX4_UTILS_H_
 
+#include <stddef.h>
+#include <stdio.h>
+
 #include <rte_common.h>
 #include <rte_log.h>
 
@@ -89,6 +92,12 @@ pmd_drv_log_basename(const char *s)
 #define WARN(...) PMD_DRV_LOG(WARNING, __VA_ARGS__)
 #define ERROR(...) PMD_DRV_LOG(ERR, __VA_ARGS__)
 
+/* Allocate a buffer on the stack and fill it with a printf format string. */
+#define MKSTR(name, ...) \
+	char name[snprintf(NULL, 0, __VA_ARGS__) + 1]; \
+	\
+	snprintf(name, sizeof(name), __VA_ARGS__)
+
 /* mlx4_utils.c */
 
 int mlx4_fd_set_non_blocking(int fd);
Signature · 1 line
2.1.4
#47 lore raw

PATCH 43/48 net/mlx4: separate Tx configuration functions

In reply to Adrien Mazarguil

Private functions are now prefixed with "mlx4_" to prevent them from conflicting with their mlx5 PMD counterparts at link time.

No impact on functionality.

---
 drivers/net/mlx4/Makefile    |   1 +
 drivers/net/mlx4/mlx4.c      | 421 +---------------------------------
 drivers/net/mlx4/mlx4_rxtx.h |   9 +
 drivers/net/mlx4/mlx4_txq.c  | 472 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 483 insertions(+), 420 deletions(-)
drivers/net/mlx4/Makefile +1 -0
index 6498eef..22820ab 100644
@@ -40,6 +40,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_intr.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_rxtx.c
+SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_txq.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_utils.c
 
 # Basic CFLAGS.
drivers/net/mlx4/mlx4.c +1 -420

451 lines not on this page · raw message

drivers/net/mlx4/mlx4_rxtx.h +9 -0
index ab44af5..b02af8e 100644
@@ -45,6 +45,7 @@
 #pragma GCC diagnostic error "-Wpedantic"
 #endif
 
+#include <rte_ethdev.h>
 #include <rte_mbuf.h>
 #include <rte_mempool.h>
 
@@ -141,4 +142,12 @@ uint16_t mlx4_tx_burst_removed(void *dpdk_txq, struct rte_mbuf **pkts,
 uint16_t mlx4_rx_burst_removed(void *dpdk_rxq, struct rte_mbuf **pkts,
 			       uint16_t pkts_n);
 
+/* mlx4_txq.c */
+
+void mlx4_txq_cleanup(struct txq *txq);
+int mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx,
+			uint16_t desc, unsigned int socket,
+			const struct rte_eth_txconf *conf);
+void mlx4_tx_queue_release(void *dpdk_txq);
+
 #endif /* MLX4_RXTX_H_ */
drivers/net/mlx4/mlx4_txq.c new file +472 -0

472 lines not on this page · raw message

Signature · 1 line
2.1.4
#48 lore raw

PATCH 44/48 net/mlx4: separate Rx configuration functions

In reply to Adrien Mazarguil

Private functions are now prefixed with "mlx4_" to prevent them from conflicting with their mlx5 PMD counterparts at link time.

No impact on functionality.

---
 drivers/net/mlx4/Makefile    |   1 +
 drivers/net/mlx4/mlx4.c      | 592 +----------------------------------
 drivers/net/mlx4/mlx4_rxq.c  | 632 ++++++++++++++++++++++++++++++++++++++
 drivers/net/mlx4/mlx4_rxtx.h |  11 +
 4 files changed, 650 insertions(+), 586 deletions(-)
drivers/net/mlx4/Makefile +1 -0
index 22820ab..00ccba0 100644
@@ -39,6 +39,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_intr.c
+SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_rxq.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_rxtx.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_txq.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_utils.c
drivers/net/mlx4/mlx4.c +6 -586

640 lines not on this page · raw message

drivers/net/mlx4/mlx4_rxq.c new file +632 -0

632 lines not on this page · raw message

drivers/net/mlx4/mlx4_rxtx.h +11 -0
index b02af8e..a3d972b 100644
@@ -130,6 +130,17 @@ struct txq {
 	unsigned int socket; /**< CPU socket ID for allocations. */
 };
 
+/* mlx4_rxq.c */
+
+void mlx4_rxq_cleanup(struct rxq *rxq);
+int mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx,
+			uint16_t desc, unsigned int socket,
+			const struct rte_eth_rxconf *conf,
+			struct rte_mempool *mp);
+void mlx4_rx_queue_release(void *dpdk_rxq);
+void mlx4_mac_addr_del(struct priv *priv);
+int mlx4_mac_addr_add(struct priv *priv);
+
 /* mlx4_rxtx.c */
 
 uint32_t mlx4_txq_mp2mr(struct txq *txq, struct rte_mempool *mp);
Signature · 1 line
2.1.4
#49 lore raw

PATCH 45/48 net/mlx4: group flow API handlers in common file

In reply to Adrien Mazarguil

Only the common filter control operation callback needs to be exposed.

No impact on functionality.

---
 drivers/net/mlx4/mlx4.c      | 48 +-------------------------
 drivers/net/mlx4/mlx4_flow.c | 72 ++++++++++++++++++++++++++++++++++++---
 drivers/net/mlx4/mlx4_flow.h | 39 +++++----------------
 3 files changed, 76 insertions(+), 83 deletions(-)
drivers/net/mlx4/mlx4.c +1 -47
index b54a569..6424d8b 100644
@@ -51,7 +51,6 @@
 #include <rte_mempool.h>
 #include <rte_malloc.h>
 #include <rte_memory.h>
-#include <rte_flow.h>
 #include <rte_kvargs.h>
 #include <rte_interrupts.h>
 #include <rte_common.h>
@@ -356,51 +355,6 @@ mlx4_dev_close(struct rte_eth_dev *dev)
 	memset(priv, 0, sizeof(*priv));
 }
 
-const struct rte_flow_ops mlx4_flow_ops = {
-	.validate = mlx4_flow_validate,
-	.create = mlx4_flow_create,
-	.destroy = mlx4_flow_destroy,
-	.flush = mlx4_flow_flush,
-	.query = NULL,
-	.isolate = mlx4_flow_isolate,
-};
-
-/**
- * Manage filter operations.
- *
- * @param dev
- *   Pointer to Ethernet device structure.
- * @param filter_type
- *   Filter type.
- * @param filter_op
- *   Operation to perform.
- * @param arg
- *   Pointer to operation-specific structure.
- *
- * @return
- *   0 on success, negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx4_dev_filter_ctrl(struct rte_eth_dev *dev,
-		     enum rte_filter_type filter_type,
-		     enum rte_filter_op filter_op,
-		     void *arg)
-{
-	switch (filter_type) {
-	case RTE_ETH_FILTER_GENERIC:
-		if (filter_op != RTE_ETH_FILTER_GET)
-			break;
-		*(const void **)arg = &mlx4_flow_ops;
-		return 0;
-	default:
-		ERROR("%p: filter type (%d) not supported",
-		      (void *)dev, filter_type);
-		break;
-	}
-	rte_errno = ENOTSUP;
-	return -rte_errno;
-}
-
 static const struct eth_dev_ops mlx4_dev_ops = {
 	.dev_configure = mlx4_dev_configure,
 	.dev_start = mlx4_dev_start,
@@ -419,7 +373,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
 	.flow_ctrl_get = mlx4_flow_ctrl_get,
 	.flow_ctrl_set = mlx4_flow_ctrl_set,
 	.mtu_set = mlx4_mtu_set,
-	.filter_ctrl = mlx4_dev_filter_ctrl,
+	.filter_ctrl = mlx4_filter_ctrl,
 	.rx_queue_intr_enable = mlx4_rx_intr_enable,
 	.rx_queue_intr_disable = mlx4_rx_intr_disable,
 };
drivers/net/mlx4/mlx4_flow.c +67 -5

113 lines not on this page · raw message

drivers/net/mlx4/mlx4_flow.h +8 -31
index 17e5f6e..8bd659c 100644
@@ -34,7 +34,6 @@
 #ifndef RTE_PMD_MLX4_FLOW_H_
 #define RTE_PMD_MLX4_FLOW_H_
 
-#include <stddef.h>
 #include <stdint.h>
 #include <sys/queue.h>
 
@@ -48,12 +47,12 @@
 #pragma GCC diagnostic error "-Wpedantic"
 #endif
 
+#include <rte_eth_ctrl.h>
+#include <rte_ethdev.h>
 #include <rte_flow.h>
 #include <rte_flow_driver.h>
 #include <rte_byteorder.h>
 
-#include "mlx4.h"
-
 struct rte_flow {
 	LIST_ENTRY(rte_flow) next; /**< Pointer to the next flow structure. */
 	struct ibv_flow *ibv_flow; /**< Verbs flow. */
@@ -61,47 +60,25 @@ struct rte_flow {
 	struct ibv_qp *qp; /**< Verbs queue pair. */
 };
 
-int
-mlx4_flow_validate(struct rte_eth_dev *dev,
-		   const struct rte_flow_attr *attr,
-		   const struct rte_flow_item items[],
-		   const struct rte_flow_action actions[],
-		   struct rte_flow_error *error);
-
-struct rte_flow *
-mlx4_flow_create(struct rte_eth_dev *dev,
-		 const struct rte_flow_attr *attr,
-		 const struct rte_flow_item items[],
-		 const struct rte_flow_action actions[],
-		 struct rte_flow_error *error);
-
-int
-mlx4_flow_destroy(struct rte_eth_dev *dev,
-		  struct rte_flow *flow,
-		  struct rte_flow_error *error);
-
-int
-mlx4_flow_flush(struct rte_eth_dev *dev,
-		struct rte_flow_error *error);
-
 /** Structure to pass to the conversion function. */
 struct mlx4_flow {
 	struct ibv_flow_attr *ibv_attr; /**< Verbs attribute. */
 	unsigned int offset; /**< Offset in bytes in the ibv_attr buffer. */
 };
 
-int
-mlx4_flow_isolate(struct rte_eth_dev *dev,
-		  int enable,
-		  struct rte_flow_error *error);
-
 struct mlx4_flow_action {
 	uint32_t drop:1; /**< Target is a drop queue. */
 	uint32_t queue:1; /**< Target is a receive queue. */
 	uint32_t queue_id; /**< Identifier of the queue. */
 };
 
+/* mlx4_flow.c */
+
 int mlx4_priv_flow_start(struct priv *priv);
 void mlx4_priv_flow_stop(struct priv *priv);
+int mlx4_filter_ctrl(struct rte_eth_dev *dev,
+		     enum rte_filter_type filter_type,
+		     enum rte_filter_op filter_op,
+		     void *arg);
 
 #endif /* RTE_PMD_MLX4_FLOW_H_ */
Signature · 1 line
2.1.4
#50 lore raw

PATCH 46/48 net/mlx4: rename private functions in flow API

In reply to Adrien Mazarguil

While internal static functions do not cause link time conflicts, this differentiates them from their mlx5 PMD counterparts while debugging.

No impact on functionality.

---
 drivers/net/mlx4/mlx4.c      |  4 ++--
 drivers/net/mlx4/mlx4_flow.c | 30 +++++++++++++++---------------
 drivers/net/mlx4/mlx4_flow.h |  4 ++--
 3 files changed, 19 insertions(+), 19 deletions(-)
drivers/net/mlx4/mlx4.c +2 -2
index 6424d8b..1f09b47 100644
@@ -253,7 +253,7 @@ mlx4_dev_start(struct rte_eth_dev *dev)
 		     (void *)dev);
 		goto err;
 	}
-	ret = mlx4_priv_flow_start(priv);
+	ret = mlx4_flow_start(priv);
 	if (ret) {
 		ERROR("%p: flow start failed: %s",
 		      (void *)dev, strerror(ret));
@@ -284,7 +284,7 @@ mlx4_dev_stop(struct rte_eth_dev *dev)
 		return;
 	DEBUG("%p: detaching flows from all RX queues", (void *)dev);
 	priv->started = 0;
-	mlx4_priv_flow_stop(priv);
+	mlx4_flow_stop(priv);
 	mlx4_intr_uninstall(priv);
 	mlx4_mac_addr_del(priv);
 }
drivers/net/mlx4/mlx4_flow.c +15 -15
index 6401a83..5616b83 100644
@@ -561,7 +561,7 @@ static const struct mlx4_flow_items mlx4_flow_items[] = {
 };
 
 /**
- * Validate a flow supported by the NIC.
+ * Make sure a flow rule is supported and initialize associated structure.
  *
  * @param priv
  *   Pointer to private structure.
@@ -580,12 +580,12 @@ static const struct mlx4_flow_items mlx4_flow_items[] = {
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 static int
-priv_flow_validate(struct priv *priv,
-		   const struct rte_flow_attr *attr,
-		   const struct rte_flow_item items[],
-		   const struct rte_flow_action actions[],
-		   struct rte_flow_error *error,
-		   struct mlx4_flow *flow)
+mlx4_flow_prepare(struct priv *priv,
+		  const struct rte_flow_attr *attr,
+		  const struct rte_flow_item items[],
+		  const struct rte_flow_action actions[],
+		  struct rte_flow_error *error,
+		  struct mlx4_flow *flow)
 {
 	const struct mlx4_flow_items *cur_item = mlx4_flow_items;
 	struct mlx4_flow_action action = {
@@ -725,7 +725,7 @@ mlx4_flow_validate(struct rte_eth_dev *dev,
 	struct priv *priv = dev->data->dev_private;
 	struct mlx4_flow flow = { .offset = sizeof(struct ibv_flow_attr) };
 
-	return priv_flow_validate(priv, attr, items, actions, error, &flow);
+	return mlx4_flow_prepare(priv, attr, items, actions, error, &flow);
 }
 
 /**
@@ -817,7 +817,7 @@ mlx4_flow_create_drop_queue(struct priv *priv)
  *   A flow if the rule could be created.
  */
 static struct rte_flow *
-priv_flow_create_action_queue(struct priv *priv,
+mlx4_flow_create_action_queue(struct priv *priv,
 			      struct ibv_flow_attr *ibv_attr,
 			      struct mlx4_flow_action *action,
 			      struct rte_flow_error *error)
@@ -875,7 +875,7 @@ mlx4_flow_create(struct rte_eth_dev *dev,
 	struct mlx4_flow flow = { .offset = sizeof(struct ibv_flow_attr), };
 	int err;
 
-	err = priv_flow_validate(priv, attr, items, actions, error, &flow);
+	err = mlx4_flow_prepare(priv, attr, items, actions, error, &flow);
 	if (err)
 		return NULL;
 	flow.ibv_attr = rte_malloc(__func__, flow.offset, 0);
@@ -894,8 +894,8 @@ mlx4_flow_create(struct rte_eth_dev *dev,
 		.port = priv->port,
 		.flags = 0,
 	};
-	claim_zero(priv_flow_validate(priv, attr, items, actions,
-				      error, &flow));
+	claim_zero(mlx4_flow_prepare(priv, attr, items, actions,
+				     error, &flow));
 	action = (struct mlx4_flow_action){
 		.queue = 0,
 		.drop = 0,
@@ -917,7 +917,7 @@ mlx4_flow_create(struct rte_eth_dev *dev,
 			goto exit;
 		}
 	}
-	rte_flow = priv_flow_create_action_queue(priv, flow.ibv_attr,
+	rte_flow = mlx4_flow_create_action_queue(priv, flow.ibv_attr,
 						 &action, error);
 	if (rte_flow) {
 		LIST_INSERT_HEAD(&priv->flows, rte_flow, next);
@@ -1015,7 +1015,7 @@ mlx4_flow_flush(struct rte_eth_dev *dev,
  *   Pointer to private structure.
  */
 void
-mlx4_priv_flow_stop(struct priv *priv)
+mlx4_flow_stop(struct priv *priv)
 {
 	struct rte_flow *flow;
 
@@ -1039,7 +1039,7 @@ mlx4_priv_flow_stop(struct priv *priv)
  *   0 on success, a errno value otherwise and rte_errno is set.
  */
 int
-mlx4_priv_flow_start(struct priv *priv)
+mlx4_flow_start(struct priv *priv)
 {
 	int ret;
 	struct ibv_qp *qp;
drivers/net/mlx4/mlx4_flow.h +2 -2
index 8bd659c..a24ae31 100644
@@ -74,8 +74,8 @@ struct mlx4_flow_action {
 
 /* mlx4_flow.c */
 
-int mlx4_priv_flow_start(struct priv *priv);
-void mlx4_priv_flow_stop(struct priv *priv);
+int mlx4_flow_start(struct priv *priv);
+void mlx4_flow_stop(struct priv *priv);
 int mlx4_filter_ctrl(struct rte_eth_dev *dev,
 		     enum rte_filter_type filter_type,
 		     enum rte_filter_op filter_op,
Signature · 1 line
2.1.4
#51 lore raw

PATCH 47/48 net/mlx4: separate memory management functions

In reply to Adrien Mazarguil

No impact on functionality.

---
 drivers/net/mlx4/Makefile  |   1 +
 drivers/net/mlx4/mlx4.c    | 115 -------------------------
 drivers/net/mlx4/mlx4.h    |   8 +-
 drivers/net/mlx4/mlx4_mr.c | 183 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 188 insertions(+), 119 deletions(-)
drivers/net/mlx4/Makefile +1 -0
index 00ccba0..41a61d7 100644
@@ -39,6 +39,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_intr.c
+SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_mr.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_rxq.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_rxtx.c
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_txq.c
drivers/net/mlx4/mlx4.c +0 -115

128 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +4 -4
index b5f2953..94b5f1e 100644
@@ -115,10 +115,6 @@ struct priv {
 	LIST_HEAD(mlx4_flows, rte_flow) flows;
 };
 
-/* mlx4.c */
-
-struct ibv_mr *mlx4_mp2mr(struct ibv_pd *pd, struct rte_mempool *mp);
-
 /* mlx4_ethdev.c */
 
 int mlx4_get_ifname(const struct priv *priv, char (*ifname)[IF_NAMESIZE]);
@@ -144,4 +140,8 @@ int mlx4_intr_install(struct priv *priv);
 int mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx);
 int mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx);
 
+/* mlx4_mr.c */
+
+struct ibv_mr *mlx4_mp2mr(struct ibv_pd *pd, struct rte_mempool *mp);
+
 #endif /* RTE_PMD_MLX4_H_ */
drivers/net/mlx4/mlx4_mr.c new file +183 -0

183 lines not on this page · raw message

Signature · 1 line
2.1.4
#52 lore raw

PATCH 48/48 net/mlx4: clean up includes and comments

In reply to Adrien Mazarguil

Add missing includes and sort them, then update/remove comments around them for consistency.

---
 drivers/net/mlx4/mlx4.c      | 40 ++++++++++++++++++++++++---------------
 drivers/net/mlx4/mlx4.h      |  3 +--
 drivers/net/mlx4/mlx4_flow.c |  5 +++++
 drivers/net/mlx4/mlx4_flow.h |  3 +--
 4 files changed, 32 insertions(+), 19 deletions(-)
drivers/net/mlx4/mlx4.c +25 -15
index c16803e..8573e14 100644
@@ -31,29 +31,41 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* System headers. */
+/**
+ * @file
+ * mlx4 driver initialization.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
 #include <string.h>
-#include <errno.h>
 #include <unistd.h>
-#include <assert.h>
 
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_ethdev_pci.h>
+/* Verbs headers do not support -pedantic. */
+#ifdef PEDANTIC
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+#include <infiniband/verbs.h>
+#ifdef PEDANTIC
+#pragma GCC diagnostic error "-Wpedantic"
+#endif
+
+#include <rte_common.h>
 #include <rte_dev.h>
-#include <rte_mbuf.h>
 #include <rte_errno.h>
-#include <rte_malloc.h>
-#include <rte_kvargs.h>
+#include <rte_ethdev.h>
+#include <rte_ethdev_pci.h>
+#include <rte_ether.h>
 #include <rte_interrupts.h>
-#include <rte_common.h>
+#include <rte_kvargs.h>
+#include <rte_malloc.h>
+#include <rte_mbuf.h>
 
-/* PMD headers. */
 #include "mlx4.h"
 #include "mlx4_flow.h"
 #include "mlx4_rxtx.h"
@@ -73,8 +85,6 @@ const char *pmd_mlx4_init_params[] = {
 	NULL,
 };
 
-/* Device configuration. */
-
 /**
  * DPDK callback for Ethernet device configuration.
  *
drivers/net/mlx4/mlx4.h +1 -2
index 94b5f1e..1cd4db3 100644
@@ -37,8 +37,7 @@
 #include <net/if.h>
 #include <stdint.h>
 
-/* Verbs header. */
-/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
+/* Verbs headers do not support -pedantic. */
 #ifdef PEDANTIC
 #pragma GCC diagnostic ignored "-Wpedantic"
 #endif
drivers/net/mlx4/mlx4_flow.c +5 -0
index 5616b83..e2798f6 100644
@@ -31,6 +31,11 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+/**
+ * @file
+ * Flow API operations for mlx4 driver.
+ */
+
 #include <arpa/inet.h>
 #include <assert.h>
 #include <errno.h>
drivers/net/mlx4/mlx4_flow.h +1 -2
index a24ae31..fbb775d 100644
@@ -37,8 +37,7 @@
 #include <stdint.h>
 #include <sys/queue.h>
 
-/* Verbs header. */
-/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
+/* Verbs headers do not support -pedantic. */
 #ifdef PEDANTIC
 #pragma GCC diagnostic ignored "-Wpedantic"
 #endif
Signature · 1 line
2.1.4
#53 lore raw
In reply to Adrien Mazarguil
Quoted 18 lines · Adrien Mazarguil

The main purpose of this large series is to relieve the mlx4 PMD from its dependency on Mellanox OFED to instead rely on the standard rdma-core package provided by Linux distributions.

While compatibility with Mellanox OFED is preserved, all nonstandard functionality has to be stripped from the PMD in order to re-implement it through an approach compatible with rdma-core.

Due to the amount of changes necessary to achieve this goal, this rework starts off by removing extraneous code to simplify the PMD as much as possible before either replacing or dismantling functionality that relies on nonstandard Verbs.

What remains after applying this series is single-segment Tx/Rx support, without offloads nor RSS, on the default MAC address (which cannot be configured). Support for multiple queues and the flow API (minus the RSS action) are also preserved.

Quoted 8 lines

Missing functionality that needs substantial work will be restored later by subsequent series.

Also because the mlx4 PMD is mostly contained in a single very large source file of 6400+ lines (mlx4.c) which has become extremely difficult to maintain, this rework is used as an opportunity to finally group functions into separate files, as in mlx5.

Hi Adrien,

Thanks for this big clean-up.

Patchset does not applies cleanly to latest tree, because of the driver fixes sent after this patchset, can you please rebase patchset on top of latest tree?

Thanks,
ferruh

Quoted 2 lines

This rework targets DPDK 17.11.

<...>

#54 lore raw

v2 cover net/mlx4: trim and refactor entire PMD

In reply to Adrien Mazarguil

The main purpose of this large series is to relieve the mlx4 PMD from its dependency on Mellanox OFED to instead rely on the standard rdma-core package provided by Linux distributions.

While compatibility with Mellanox OFED is preserved, all nonstandard functionality has to be stripped from the PMD in order to re-implement it through an approach compatible with rdma-core.

Due to the amount of changes necessary to achieve this goal, this rework starts off by removing extraneous code to simplify the PMD as much as possible before either replacing or dismantling functionality that relies on nonstandard Verbs.

What remains after applying this series is single-segment Tx/Rx support, without offloads nor RSS, on the default MAC address (which cannot be configured). Support for multiple queues and the flow API (minus the RSS action) are also preserved.

Missing functionality that needs substantial work will be restored later by subsequent series.

Also because the mlx4 PMD is mostly contained in a single very large source file of 6400+ lines (mlx4.c) which has become extremely difficult to maintain, this rework is used as an opportunity to finally group functions into separate files, as in mlx5.

This rework targets DPDK 17.11.

Changes since v1:

- Rebased series on top of the latest upstream fixes.

- Cleaned up remaining typos and coding style issues.

- "net/mlx4: check max number of ports dynamically":
Removed extra loop and added error message on maximum number of ports according to Allain's suggestion.

- "net/mlx4: drop scatter/gather support":
Additionally removed unnecessary mbuf pool from rxq_alloc_elts().

- "net/mlx4: simplify Rx buffer handling":
New patch removing unnecessary code from the simplified Rx path.

- "net/mlx4: remove isolated mode constraint":
New patch removing needless constraint for isolated mode, which can now be toggled anytime.

- "net/mlx4: rely on ethdev for Tx/Rx queue arrays":
New patch refactoring duplicated information from ethdev.

Adrien Mazarguil (51):
net/mlx4: add consistency to copyright notices net/mlx4: remove limitation on number of instances net/mlx4: check max number of ports dynamically net/mlx4: remove useless compilation checks net/mlx4: remove secondary process support net/mlx4: remove useless code
net/mlx4: remove soft counters compilation option net/mlx4: remove scatter mode compilation option net/mlx4: remove Tx inline compilation option net/mlx4: remove allmulti and promisc support net/mlx4: remove VLAN filter support net/mlx4: remove MAC address configuration support net/mlx4: drop MAC flows affecting all Rx queues net/mlx4: revert flow API RSS support net/mlx4: revert RSS parent queue refactoring net/mlx4: drop RSS support
net/mlx4: drop checksum offloads support net/mlx4: drop packet type recognition support net/mlx4: drop scatter/gather support net/mlx4: drop inline receive support net/mlx4: use standard QP attributes net/mlx4: revert resource domain support net/mlx4: revert multicast echo prevention net/mlx4: revert fast Verbs interface for Tx net/mlx4: revert fast Verbs interface for Rx net/mlx4: simplify Rx buffer handling net/mlx4: simplify link update function net/mlx4: standardize on negative errno values net/mlx4: clean up coding style inconsistencies net/mlx4: remove control path locks net/mlx4: remove unnecessary wrapper functions net/mlx4: remove mbuf macro definitions net/mlx4: use standard macro to get array size net/mlx4: separate debugging macros net/mlx4: use a single interrupt handle net/mlx4: rename alarm field
net/mlx4: refactor interrupt FD settings net/mlx4: clean up interrupt functions prototypes net/mlx4: compact interrupt functions net/mlx4: separate interrupt handling net/mlx4: separate Rx/Tx definitions net/mlx4: separate Rx/Tx functions net/mlx4: separate device control functions net/mlx4: separate Tx configuration functions net/mlx4: separate Rx configuration functions net/mlx4: group flow API handlers in common file net/mlx4: rename private functions in flow API net/mlx4: separate memory management functions net/mlx4: clean up includes and comments net/mlx4: remove isolated mode constraint net/mlx4: rely on ethdev for Tx/Rx queue arrays

 config/common_base                |    3 -
 doc/guides/nics/features/mlx4.ini |   13 -
 doc/guides/nics/mlx4.rst          |   37 +-
 drivers/net/mlx4/Makefile         |   41 +-
 drivers/net/mlx4/mlx4.c           | 6354 ++------------------------------
 drivers/net/mlx4/mlx4.h           |  333 +-
 drivers/net/mlx4/mlx4_ethdev.c    |  788 ++++
 drivers/net/mlx4/mlx4_flow.c      |  491 +--
 drivers/net/mlx4/mlx4_flow.h      |   51 +-
 drivers/net/mlx4/mlx4_intr.c      |  375 ++
 drivers/net/mlx4/mlx4_mr.c        |  183 +
 drivers/net/mlx4/mlx4_rxq.c       |  579 +++
 drivers/net/mlx4/mlx4_rxtx.c      |  524 +++
 drivers/net/mlx4/mlx4_rxtx.h      |  154 +
 drivers/net/mlx4/mlx4_txq.c       |  472 +++
 drivers/net/mlx4/mlx4_utils.c     |   66 +
 drivers/net/mlx4/mlx4_utils.h     |  111 +
 17 files changed, 3737 insertions(+), 6838 deletions(-)
 create mode 100644 drivers/net/mlx4/mlx4_ethdev.c
 create mode 100644 drivers/net/mlx4/mlx4_intr.c
 create mode 100644 drivers/net/mlx4/mlx4_mr.c
 create mode 100644 drivers/net/mlx4/mlx4_rxq.c
 create mode 100644 drivers/net/mlx4/mlx4_rxtx.c
 create mode 100644 drivers/net/mlx4/mlx4_rxtx.h
 create mode 100644 drivers/net/mlx4/mlx4_txq.c
 create mode 100644 drivers/net/mlx4/mlx4_utils.c
 create mode 100644 drivers/net/mlx4/mlx4_utils.h
Signature · 1 line
2.1.4
#55 lore raw

PATCH v2 1/51 net/mlx4: add consistency to copyright notices

Copyright lasts long enough not to require notices to be updated yearly.

The current approach of updating them occasionally while working on unrelated tasks should be deprecated in favor of dedicated commits updating all files at once when necessary.

Standardize on a single year per copyright owner.

---
 doc/guides/nics/mlx4.rst     | 2 +-
 drivers/net/mlx4/Makefile    | 4 ++--
 drivers/net/mlx4/mlx4.c      | 4 ++--
 drivers/net/mlx4/mlx4.h      | 4 ++--
 drivers/net/mlx4/mlx4_flow.c | 2 +-
 drivers/net/mlx4/mlx4_flow.h | 2 +-
 6 files changed, 9 insertions(+), 9 deletions(-)
doc/guides/nics/mlx4.rst +1 -1
index f8885b2..388aaf3 100644
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright 2012-2015 6WIND S.A.
+    Copyright 2012 6WIND S.A.
     Copyright 2015 Mellanox
 
     Redistribution and use in source and binary forms, with or without
drivers/net/mlx4/Makefile +2 -2
index c045bd7..b2ef128 100644
@@ -1,7 +1,7 @@
 #   BSD LICENSE
 #
-#   Copyright 2012-2015 6WIND S.A.
-#   Copyright 2012 Mellanox.
+#   Copyright 2012 6WIND S.A.
+#   Copyright 2012 Mellanox
 #
 #   Redistribution and use in source and binary forms, with or without
 #   modification, are permitted provided that the following conditions
drivers/net/mlx4/mlx4.c +2 -2
index 055de49..b5a7607 100644
@@ -1,8 +1,8 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright 2012-2017 6WIND S.A.
- *   Copyright 2012-2017 Mellanox.
+ *   Copyright 2012 6WIND S.A.
+ *   Copyright 2012 Mellanox
  *
  *   Redistribution and use in source and binary forms, with or without
  *   modification, are permitted provided that the following conditions
drivers/net/mlx4/mlx4.h +2 -2
index c0ade4f..5fd1454 100644
@@ -1,8 +1,8 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright 2012-2017 6WIND S.A.
- *   Copyright 2012-2017 Mellanox.
+ *   Copyright 2012 6WIND S.A.
+ *   Copyright 2012 Mellanox
  *
  *   Redistribution and use in source and binary forms, with or without
  *   modification, are permitted provided that the following conditions
drivers/net/mlx4/mlx4_flow.c +1 -1
index 925c89c..ab37e7d 100644
@@ -2,7 +2,7 @@
  *   BSD LICENSE
  *
  *   Copyright 2017 6WIND S.A.
- *   Copyright 2017 Mellanox.
+ *   Copyright 2017 Mellanox
  *
  *   Redistribution and use in source and binary forms, with or without
  *   modification, are permitted provided that the following conditions
drivers/net/mlx4/mlx4_flow.h +1 -1
index beabcf2..4654dc2 100644
@@ -2,7 +2,7 @@
  *   BSD LICENSE
  *
  *   Copyright 2017 6WIND S.A.
- *   Copyright 2017 Mellanox.
+ *   Copyright 2017 Mellanox
  *
  *   Redistribution and use in source and binary forms, with or without
  *   modification, are permitted provided that the following conditions
Signature · 1 line
2.1.4
#56 lore raw

PATCH v2 2/51 net/mlx4: remove limitation on number of instances

In reply to Adrien Mazarguil

The seemingly artificial limitation on the maximum number of instances for this PMD is an historical leftover that predates its first public release.

It was used as a workaround to support multiple physical ports on a PCI device exposing a single bus address when mlx4 was implemented directly as an Ethernet device driver instead of a PCI driver spawning Ethernet devices.

Getting rid of it simplifies device initialization.

---
 drivers/net/mlx4/mlx4.c | 57 +++-----------------------------------------
 1 file changed, 3 insertions(+), 54 deletions(-)
drivers/net/mlx4/mlx4.c +3 -54
index b5a7607..0ae78e0 100644
@@ -5444,40 +5444,6 @@ priv_get_mac(struct priv *priv, uint8_t (*mac)[ETHER_ADDR_LEN])
 	return 0;
 }
 
-/* Support up to 32 adapters. */
-static struct {
-	struct rte_pci_addr pci_addr; /* associated PCI address */
-	uint32_t ports; /* physical ports bitfield. */
-} mlx4_dev[32];
-
-/**
- * Get device index in mlx4_dev[] from PCI bus address.
- *
- * @param[in] pci_addr
- *   PCI bus address to look for.
- *
- * @return
- *   mlx4_dev[] index on success, -1 on failure.
- */
-static int
-mlx4_dev_idx(struct rte_pci_addr *pci_addr)
-{
-	unsigned int i;
-	int ret = -1;
-
-	assert(pci_addr != NULL);
-	for (i = 0; (i != elemof(mlx4_dev)); ++i) {
-		if ((mlx4_dev[i].pci_addr.domain == pci_addr->domain) &&
-		    (mlx4_dev[i].pci_addr.bus == pci_addr->bus) &&
-		    (mlx4_dev[i].pci_addr.devid == pci_addr->devid) &&
-		    (mlx4_dev[i].pci_addr.function == pci_addr->function))
-			return i;
-		if ((mlx4_dev[i].ports == 0) && (ret == -1))
-			ret = i;
-	}
-	return ret;
-}
-
 /**
  * Retrieve integer value from environment variable.
  *
@@ -6060,21 +6026,11 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		.active_ports = 0,
 	};
 	unsigned int vf;
-	int idx;
 	int i;
 
 	(void)pci_drv;
 	assert(pci_drv == &mlx4_driver);
-	/* Get mlx4_dev[] index. */
-	idx = mlx4_dev_idx(&pci_dev->addr);
-	if (idx == -1) {
-		ERROR("this driver cannot support any more adapters");
-		return -ENOMEM;
-	}
-	DEBUG("using driver device index %d", idx);
 
-	/* Save PCI address. */
-	mlx4_dev[idx].pci_addr = pci_dev->addr;
 	list = ibv_get_device_list(&i);
 	if (list == NULL) {
 		assert(errno);
@@ -6141,7 +6097,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	}
 	for (i = 0; i < device_attr.phys_port_cnt; i++) {
 		uint32_t port = i + 1; /* ports are indexed from one */
-		uint32_t test = (1 << i);
 		struct ibv_context *ctx = NULL;
 		struct ibv_port_attr port_attr;
 		struct ibv_pd *pd = NULL;
@@ -6162,7 +6117,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 #endif /* RSS_SUPPORT */
 #endif /* HAVE_EXP_QUERY_DEVICE */
 
-		DEBUG("using port %u (%08" PRIx32 ")", port, test);
+		DEBUG("using port %u", port);
 
 		ctx = ibv_open_device(ibv_dev);
 		if (ctx == NULL) {
@@ -6198,8 +6153,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			goto port_error;
 		}
 
-		mlx4_dev[idx].ports |= test;
-
 		/* from rte_ethdev.c */
 		priv = rte_zmalloc("ethdev private structure",
 				   sizeof(*priv),
@@ -6405,6 +6358,8 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			rte_eth_dev_release_port(eth_dev);
 		break;
 	}
+	if (i == device_attr.phys_port_cnt)
+		return 0;
 
 	/*
 	 * XXX if something went wrong in the loop above, there is a resource
@@ -6413,12 +6368,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	 * way to enumerate the registered ethdevs to free the previous ones.
 	 */
 
-	/* no port found, complain */
-	if (!mlx4_dev[idx].ports) {
-		err = ENODEV;
-		goto error;
-	}
-
 error:
 	if (attr_ctx)
 		claim_zero(ibv_close_device(attr_ctx));
Signature · 1 line
2.1.4
#57 lore raw

PATCH v2 3/51 net/mlx4: check max number of ports dynamically

In reply to Adrien Mazarguil

Use maximum number reported by hardware capabilities as replacement for the static check on MLX4_PMD_MAX_PHYS_PORTS.

Cc Gaëtan Rivet <[email protected]>
Cc Allain Legacy <[email protected]>
---
 drivers/net/mlx4/mlx4.c | 49 ++++++++++++++++++++++++++++----------------
 drivers/net/mlx4/mlx4.h |  3 ---
 2 files changed, 31 insertions(+), 21 deletions(-)
drivers/net/mlx4/mlx4.c +31 -18
index 0ae78e0..7a93462 100644
@@ -118,8 +118,12 @@ struct mlx4_secondary_data {
 	rte_spinlock_t lock; /* Port configuration lock. */
 } mlx4_secondary_data[RTE_MAX_ETHPORTS];
 
+/** Configuration structure for device arguments. */
 struct mlx4_conf {
-	uint8_t active_ports;
+	struct {
+		uint32_t present; /**< Bit-field for existing ports. */
+		uint32_t enabled; /**< Bit-field for user-enabled ports. */
+	} ports;
 };
 
 /* Available parameters list. */
@@ -5927,16 +5931,15 @@ mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
  *   Key argument to verify.
  * @param[in] val
  *   Value associated with key.
- * @param out
- *   User data.
+ * @param[in, out] conf
+ *   Shared configuration data.
  *
  * @return
  *   0 on success, negative errno value on failure.
  */
 static int
-mlx4_arg_parse(const char *key, const char *val, void *out)
+mlx4_arg_parse(const char *key, const char *val, struct mlx4_conf *conf)
 {
-	struct mlx4_conf *conf = out;
 	unsigned long tmp;
 
 	errno = 0;
@@ -5946,12 +5949,18 @@ mlx4_arg_parse(const char *key, const char *val, void *out)
 		return -errno;
 	}
 	if (strcmp(MLX4_PMD_PORT_KVARG, key) == 0) {
-		if (tmp >= MLX4_PMD_MAX_PHYS_PORTS) {
-			ERROR("invalid port index %lu (max: %u)",
-				tmp, MLX4_PMD_MAX_PHYS_PORTS - 1);
+		uint32_t ports = rte_log2_u32(conf->ports.present);
+
+		if (tmp >= ports) {
+			ERROR("port index %lu outside range [0,%" PRIu32 ")",
+			      tmp, ports);
 			return -EINVAL;
 		}
-		conf->active_ports |= 1 << tmp;
+		if (!(conf->ports.present & (1 << tmp))) {
+			ERROR("invalid port index %lu", tmp);
+			return -EINVAL;
+		}
+		conf->ports.enabled |= 1 << tmp;
 	} else {
 		WARN("%s: unknown parameter", key);
 		return -EINVAL;
@@ -5987,8 +5996,13 @@ mlx4_args(struct rte_devargs *devargs, struct mlx4_conf *conf)
 	for (i = 0; pmd_mlx4_init_params[i]; ++i) {
 		arg_count = rte_kvargs_count(kvlist, MLX4_PMD_PORT_KVARG);
 		while (arg_count-- > 0) {
-			ret = rte_kvargs_process(kvlist, MLX4_PMD_PORT_KVARG,
-					mlx4_arg_parse, conf);
+			ret = rte_kvargs_process(kvlist,
+						 MLX4_PMD_PORT_KVARG,
+						 (int (*)(const char *,
+							  const char *,
+							  void *))
+						 mlx4_arg_parse,
+						 conf);
 			if (ret != 0)
 				goto free_kvlist;
 		}
@@ -6023,7 +6037,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	struct ibv_context *attr_ctx = NULL;
 	struct ibv_device_attr device_attr;
 	struct mlx4_conf conf = {
-		.active_ports = 0,
+		.ports.present = 0,
 	};
 	unsigned int vf;
 	int i;
@@ -6085,16 +6099,15 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	}
 	INFO("%u port(s) detected", device_attr.phys_port_cnt);
 
+	conf.ports.present |= (UINT64_C(1) << device_attr.phys_port_cnt) - 1;
 	if (mlx4_args(pci_dev->device.devargs, &conf)) {
 		ERROR("failed to process device arguments");
 		err = EINVAL;
 		goto error;
 	}
 	/* Use all ports when none are defined */
-	if (conf.active_ports == 0) {
-		for (i = 0; i < MLX4_PMD_MAX_PHYS_PORTS; i++)
-			conf.active_ports |= 1 << i;
-	}
+	if (!conf.ports.enabled)
+		conf.ports.enabled = conf.ports.present;
 	for (i = 0; i < device_attr.phys_port_cnt; i++) {
 		uint32_t port = i + 1; /* ports are indexed from one */
 		struct ibv_context *ctx = NULL;
@@ -6107,8 +6120,8 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 #endif /* HAVE_EXP_QUERY_DEVICE */
 		struct ether_addr mac;
 
-		/* If port is not active, skip. */
-		if (!(conf.active_ports & (1 << i)))
+		/* If port is not enabled, skip. */
+		if (!(conf.ports.enabled & (1 << i)))
 			continue;
 #ifdef HAVE_EXP_QUERY_DEVICE
 		exp_device_attr.comp_mask = IBV_EXP_DEVICE_ATTR_EXP_CAP_FLAGS;
drivers/net/mlx4/mlx4.h +0 -3
index 5fd1454..109cd1b 100644
@@ -81,9 +81,6 @@
 /* Request send completion once in every 64 sends, might be less. */
 #define MLX4_PMD_TX_PER_COMP_REQ 64
 
-/* Maximum number of physical ports. */
-#define MLX4_PMD_MAX_PHYS_PORTS 2
-
 /* Maximum number of Scatter/Gather Elements per Work Request. */
 #ifndef MLX4_PMD_SGE_WR_N
 #define MLX4_PMD_SGE_WR_N 4
Signature · 1 line
2.1.4
Acked-by on v2 3/51
#58 lore raw

Re: [PATCH v2 03/51] net/mlx4: check max number of ports dynamically

Quoted 8 lines

-----Original Message-----
From: Adrien Mazarguil [mailto:[email protected]]
Sent: Friday, September 01, 2017 4:06 AM
To: [email protected]
Cc: Gaëtan Rivet; Legacy, Allain
Subject: [PATCH v2 03/51] net/mlx4: check max number of ports dynamically

Quoted 6 lines

Use maximum number reported by hardware capabilities as replacement for the static check on MLX4_PMD_MAX_PHYS_PORTS.

Cc Gaëtan Rivet <[email protected]>
Cc Allain Legacy <[email protected]>
#59 lore raw

PATCH v2 4/51 net/mlx4: remove useless compilation checks

In reply to Adrien Mazarguil

Verbs support for RSS, inline receive and extended device query calls has not been optional for a while. Their absence is untested and is therefore unsupported.

Remove the related compilation checks and assume Mellanox OFED is up to date, as described in the documentation.

Use this opportunity to remove a few useless data path debugging messages behind compilation checks on never defined macros.

---
 drivers/net/mlx4/Makefile    | 12 ------------
 drivers/net/mlx4/mlx4.c      | 35 -----------------------------------
 drivers/net/mlx4/mlx4.h      |  2 --
 drivers/net/mlx4/mlx4_flow.c |  3 ---
 4 files changed, 52 deletions(-)
drivers/net/mlx4/Makefile +0 -12
index b2ef128..07a66c4 100644
@@ -104,18 +104,6 @@ mlx4_autoconf.h.new: FORCE
 mlx4_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 	$Q $(RM) -f -- '$@'
 	$Q sh -- '$<' '$@' \
-		RSS_SUPPORT \
-		infiniband/verbs.h \
-		enum IBV_EXP_DEVICE_UD_RSS $(AUTOCONF_OUTPUT)
-	$Q sh -- '$<' '$@' \
-		INLINE_RECV \
-		infiniband/verbs.h \
-		enum IBV_EXP_DEVICE_ATTR_INLINE_RECV_SZ $(AUTOCONF_OUTPUT)
-	$Q sh -- '$<' '$@' \
-		HAVE_EXP_QUERY_DEVICE \
-		infiniband/verbs.h \
-		type 'struct ibv_exp_device_attr' $(AUTOCONF_OUTPUT)
-	$Q sh -- '$<' '$@' \
 		HAVE_EXP_QP_BURST_CREATE_DISABLE_ETH_LOOPBACK \
 		infiniband/verbs.h \
 		enum IBV_EXP_QP_BURST_CREATE_DISABLE_ETH_LOOPBACK \
drivers/net/mlx4/mlx4.c +0 -35
index 7a93462..cef024a 100644
@@ -1103,10 +1103,6 @@ txq_complete(struct txq *txq)
 
 	if (unlikely(elts_comp == 0))
 		return 0;
-#ifdef DEBUG_SEND
-	DEBUG("%p: processing %u work requests completions",
-	      (void *)txq, elts_comp);
-#endif
 	wcs_n = txq->if_cq->poll_cnt(txq->cq, elts_comp);
 	if (unlikely(wcs_n == 0))
 		return 0;
@@ -3155,9 +3151,6 @@ mlx4_rx_burst_sp(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		return 0;
 	*next = NULL;
 	/* Repost WRs. */
-#ifdef DEBUG_RECV
-	DEBUG("%p: reposting %d WRs", (void *)rxq, i);
-#endif
 	ret = ibv_post_recv(rxq->qp, head.next, &bad_wr);
 	if (unlikely(ret)) {
 		/* Inability to repost WRs is fatal. */
@@ -3318,9 +3311,6 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 	if (unlikely(i == 0))
 		return 0;
 	/* Repost WRs. */
-#ifdef DEBUG_RECV
-	DEBUG("%p: reposting %u WRs", (void *)rxq, i);
-#endif
 	ret = rxq->if_qp->recv_burst(rxq->qp, sges, i);
 	if (unlikely(ret)) {
 		/* Inability to repost WRs is fatal. */
@@ -3418,15 +3408,11 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
 		.res_domain = rd,
 	};
 
-#ifdef INLINE_RECV
 	attr.max_inl_recv = priv->inl_recv_size;
 	attr.comp_mask |= IBV_EXP_QP_INIT_ATTR_INL_RECV;
-#endif
 	return ibv_exp_create_qp(priv->ctx, &attr);
 }
 
-#ifdef RSS_SUPPORT
-
 /**
  * Allocate a RSS Queue Pair.
  * Optionally setup inline receive if supported.
@@ -3474,10 +3460,8 @@ rxq_setup_qp_rss(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
 		.res_domain = rd,
 	};
 
-#ifdef INLINE_RECV
 	attr.max_inl_recv = priv->inl_recv_size,
 	attr.comp_mask |= IBV_EXP_QP_INIT_ATTR_INL_RECV;
-#endif
 	if (children_n > 0) {
 		attr.qpg.qpg_type = IBV_EXP_QPG_PARENT;
 		/* TSS isn't necessary. */
@@ -3493,8 +3477,6 @@ rxq_setup_qp_rss(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
 	return ibv_exp_create_qp(priv->ctx, &attr);
 }
 
-#endif /* RSS_SUPPORT */
-
 /**
  * Reconfigure a RX queue with new parameters.
  *
@@ -3728,13 +3710,11 @@ rxq_create_qp(struct rxq *rxq,
 	int parent = (children_n > 0);
 	struct priv *priv = rxq->priv;
 
-#ifdef RSS_SUPPORT
 	if (priv->rss && !inactive && (rxq_parent || parent))
 		rxq->qp = rxq_setup_qp_rss(priv, rxq->cq, desc,
 					   children_n, rxq->rd,
 					   rxq_parent);
 	else
-#endif /* RSS_SUPPORT */
 		rxq->qp = rxq_setup_qp(priv, rxq->cq, desc, rxq->rd);
 	if (rxq->qp == NULL) {
 		ret = (errno ? errno : EINVAL);
@@ -3750,9 +3730,7 @@ rxq_create_qp(struct rxq *rxq,
 	};
 	ret = ibv_exp_modify_qp(rxq->qp, &mod,
 				(IBV_EXP_QP_STATE |
-#ifdef RSS_SUPPORT
 				 (parent ? IBV_EXP_QP_GROUP_RSS : 0) |
-#endif /* RSS_SUPPORT */
 				 IBV_EXP_QP_PORT));
 	if (ret) {
 		ERROR("QP state to IBV_QPS_INIT failed: %s",
@@ -6115,20 +6093,14 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		struct ibv_pd *pd = NULL;
 		struct priv *priv = NULL;
 		struct rte_eth_dev *eth_dev = NULL;
-#ifdef HAVE_EXP_QUERY_DEVICE
 		struct ibv_exp_device_attr exp_device_attr;
-#endif /* HAVE_EXP_QUERY_DEVICE */
 		struct ether_addr mac;
 
 		/* If port is not enabled, skip. */
 		if (!(conf.ports.enabled & (1 << i)))
 			continue;
-#ifdef HAVE_EXP_QUERY_DEVICE
 		exp_device_attr.comp_mask = IBV_EXP_DEVICE_ATTR_EXP_CAP_FLAGS;
-#ifdef RSS_SUPPORT
 		exp_device_attr.comp_mask |= IBV_EXP_DEVICE_ATTR_RSS_TBL_SZ;
-#endif /* RSS_SUPPORT */
-#endif /* HAVE_EXP_QUERY_DEVICE */
 
 		DEBUG("using port %u", port);
 
@@ -6181,13 +6153,11 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		priv->port = port;
 		priv->pd = pd;
 		priv->mtu = ETHER_MTU;
-#ifdef HAVE_EXP_QUERY_DEVICE
 		if (ibv_exp_query_device(ctx, &exp_device_attr)) {
 			ERROR("ibv_exp_query_device() failed");
 			err = ENODEV;
 			goto port_error;
 		}
-#ifdef RSS_SUPPORT
 		if ((exp_device_attr.exp_device_cap_flags &
 		     IBV_EXP_DEVICE_QPG) &&
 		    (exp_device_attr.exp_device_cap_flags &
@@ -6212,7 +6182,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		if (priv->hw_rss)
 			DEBUG("maximum RSS indirection table size: %u",
 			      exp_device_attr.max_rss_tbl_sz);
-#endif /* RSS_SUPPORT */
 
 		priv->hw_csum =
 			((exp_device_attr.exp_device_cap_flags &
@@ -6227,7 +6196,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		DEBUG("L2 tunnel checksum offloads are %ssupported",
 		      (priv->hw_csum_l2tun ? "" : "not "));
 
-#ifdef INLINE_RECV
 		priv->inl_recv_size = mlx4_getenv_int("MLX4_INLINE_RECV_SIZE");
 
 		if (priv->inl_recv_size) {
@@ -6251,10 +6219,7 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 			INFO("Set inline receive size to %u",
 			     priv->inl_recv_size);
 		}
-#endif /* INLINE_RECV */
-#endif /* HAVE_EXP_QUERY_DEVICE */
 
-		(void)mlx4_getenv_int;
 		priv->vf = vf;
 		/* Configure the first MAC address by default. */
 		if (priv_get_mac(priv, &mac.addr_bytes)) {
drivers/net/mlx4/mlx4.h +0 -2
index 109cd1b..a12d1fa 100644
@@ -344,9 +344,7 @@ struct priv {
 	unsigned int vf:1; /* This is a VF device. */
 	unsigned int pending_alarm:1; /* An alarm is pending. */
 	unsigned int isolated:1; /* Toggle isolated mode. */
-#ifdef INLINE_RECV
 	unsigned int inl_recv_size; /* Inline recv size */
-#endif
 	unsigned int max_rss_tbl_sz; /* Maximum number of RSS queues. */
 	/* RX/TX queues. */
 	unsigned int rxqs_n; /* RX queues array size. */
drivers/net/mlx4/mlx4_flow.c +0 -3
index ab37e7d..f5c015e 100644
@@ -37,9 +37,6 @@
 #include <rte_flow_driver.h>
 #include <rte_malloc.h>
 
-/* Generated configuration header. */
-#include "mlx4_autoconf.h"
-
 /* PMD headers. */
 #include "mlx4.h"
 #include "mlx4_flow.h"
Signature · 1 line
2.1.4
#60 lore raw

PATCH v2 5/51 net/mlx4: remove secondary process support

In reply to Adrien Mazarguil

Current implementation is partial (Tx only), not convenient to use and not of primary concern.

Remove this feature before refactoring the PMD.

---
 doc/guides/nics/features/mlx4.ini |   1 -
 doc/guides/nics/mlx4.rst          |   2 -
 drivers/net/mlx4/mlx4.c           | 349 +--------------------------------
 3 files changed, 8 insertions(+), 344 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -1
index 1d5f266..f6efd21 100644
@@ -27,7 +27,6 @@ Inner L4 checksum    = Y
 Packet type parsing  = Y
 Basic stats          = Y
 Stats per queue      = Y
-Multiprocess aware   = Y
 Other kdrv           = Y
 Power8               = Y
 x86-32               = Y
doc/guides/nics/mlx4.rst +0 -2
index 388aaf3..bba1034 100644
@@ -88,7 +88,6 @@ Features
 - Scattered packets are supported for TX and RX.
 - Inner L3/L4 (IP, TCP and UDP) TX/RX checksum offloading and validation.
 - Outer L3 (IP) TX/RX checksum offloading and validation for VXLAN frames.
-- Secondary process TX is supported.
 - RX interrupts.
 
 Limitations
@@ -99,7 +98,6 @@ Limitations
 - RSS always includes L3 (IPv4/IPv6) and L4 (UDP/TCP). They cannot be
   dissociated.
 - Hardware counters are not implemented (they are software counters).
-- Secondary process RX is not supported.
 
 Configuration
 -------------
drivers/net/mlx4/mlx4.c +8 -341

523 lines not on this page · raw message

Signature · 1 line
2.1.4
#61 lore raw

PATCH v2 6/51 net/mlx4: remove useless code

In reply to Adrien Mazarguil

Less code makes refactoring easier. No impact on functionality.

---
 drivers/net/mlx4/mlx4.c | 17 +----------------
 drivers/net/mlx4/mlx4.h | 12 ------------
 2 files changed, 1 insertion(+), 28 deletions(-)
drivers/net/mlx4/mlx4.c +1 -16
index 6f8d328..cb07a53 100644
@@ -69,13 +69,13 @@
 #include <rte_malloc.h>
 #include <rte_spinlock.h>
 #include <rte_atomic.h>
-#include <rte_version.h>
 #include <rte_log.h>
 #include <rte_alarm.h>
 #include <rte_memory.h>
 #include <rte_flow.h>
 #include <rte_kvargs.h>
 #include <rte_interrupts.h>
+#include <rte_branch_prediction.h>
 
 /* Generated configuration header. */
 #include "mlx4_autoconf.h"
@@ -4649,10 +4649,6 @@ mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 	return -1;
 }
 
-static int
-mlx4_ibv_device_to_pci_addr(const struct ibv_device *device,
-			    struct rte_pci_addr *pci_addr);
-
 /**
  * DPDK callback to change the MTU.
  *
@@ -4998,10 +4994,6 @@ mlx4_dev_filter_ctrl(struct rte_eth_dev *dev,
 			return -EINVAL;
 		*(const void **)arg = &mlx4_flow_ops;
 		return 0;
-	case RTE_ETH_FILTER_FDIR:
-		DEBUG("%p: filter type FDIR is not supported by this PMD",
-		      (void *)dev);
-		break;
 	default:
 		ERROR("%p: filter type (%d) not supported",
 		      (void *)dev, filter_type);
@@ -5024,22 +5016,15 @@ static const struct eth_dev_ops mlx4_dev_ops = {
 	.link_update = mlx4_link_update,
 	.stats_get = mlx4_stats_get,
 	.stats_reset = mlx4_stats_reset,
-	.queue_stats_mapping_set = NULL,
 	.dev_infos_get = mlx4_dev_infos_get,
 	.dev_supported_ptypes_get = mlx4_dev_supported_ptypes_get,
 	.vlan_filter_set = mlx4_vlan_filter_set,
-	.vlan_tpid_set = NULL,
-	.vlan_strip_queue_set = NULL,
-	.vlan_offload_set = NULL,
 	.rx_queue_setup = mlx4_rx_queue_setup,
 	.tx_queue_setup = mlx4_tx_queue_setup,
 	.rx_queue_release = mlx4_rx_queue_release,
 	.tx_queue_release = mlx4_tx_queue_release,
-	.dev_led_on = NULL,
-	.dev_led_off = NULL,
 	.flow_ctrl_get = mlx4_dev_get_flow_ctrl,
 	.flow_ctrl_set = mlx4_dev_set_flow_ctrl,
-	.priority_flow_ctrl_set = NULL,
 	.mac_addr_remove = mlx4_mac_addr_remove,
 	.mac_addr_add = mlx4_mac_addr_add,
 	.mac_addr_set = mlx4_mac_addr_set,
drivers/net/mlx4/mlx4.h +0 -12
index a12d1fa..702f9c9 100644
@@ -34,7 +34,6 @@
 #ifndef RTE_PMD_MLX4_H_
 #define RTE_PMD_MLX4_H_
 
-#include <stddef.h>
 #include <stdint.h>
 #include <limits.h>
 
@@ -150,17 +149,6 @@ enum {
 /* Number of elements in array. */
 #define elemof(a) (sizeof(a) / sizeof((a)[0]))
 
-/* Cast pointer p to structure member m to its parent structure of type t. */
-#define containerof(p, t, m) ((t *)((uint8_t *)(p) - offsetof(t, m)))
-
-/* Branch prediction helpers. */
-#ifndef likely
-#define likely(c) __builtin_expect(!!(c), 1)
-#endif
-#ifndef unlikely
-#define unlikely(c) __builtin_expect(!!(c), 0)
-#endif
-
 /* Debugging */
 #ifndef NDEBUG
 #include <stdio.h>
Signature · 1 line
2.1.4
#62 lore raw

PATCH v2 7/51 net/mlx4: remove soft counters compilation option

In reply to Adrien Mazarguil

Software counters are mandatory since hardware counters are not implemented.

---
 config/common_base        |  1 -
 doc/guides/nics/mlx4.rst  |  6 ------
 drivers/net/mlx4/Makefile |  4 ----
 drivers/net/mlx4/mlx4.c   | 37 -------------------------------------
 drivers/net/mlx4/mlx4.h   | 12 ------------
 5 files changed, 60 deletions(-)
config/common_base +0 -1
index 5e97a08..c7ffb6b 100644
@@ -217,7 +217,6 @@ CONFIG_RTE_LIBRTE_MLX4_DEBUG_BROKEN_VERBS=n
 CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N=4
 CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE=0
 CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
-CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS=1
 
 #
 # Compile burst-oriented Mellanox ConnectX-4 & ConnectX-5 (MLX5) PMD
doc/guides/nics/mlx4.rst +0 -6
index bba1034..eba81ba 100644
@@ -97,7 +97,6 @@ Limitations
 - RSS RETA cannot be configured
 - RSS always includes L3 (IPv4/IPv6) and L4 (UDP/TCP). They cannot be
   dissociated.
-- Hardware counters are not implemented (they are software counters).
 
 Configuration
 -------------
@@ -145,11 +144,6 @@ These options can be modified in the ``.config`` file.
 
   This value is always 1 for RX queues since they use a single MP.
 
-- ``CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS`` (default **1**)
-
-  Toggle software counters. No counters are available if this option is
-  disabled since hardware counters are not supported.
-
 Environment variables
 ~~~~~~~~~~~~~~~~~~~~~
 
drivers/net/mlx4/Makefile +0 -4
index 07a66c4..147e541 100644
@@ -80,10 +80,6 @@ ifdef CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE
 CFLAGS += -DMLX4_PMD_TX_MP_CACHE=$(CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE)
 endif
 
-ifdef CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS
-CFLAGS += -DMLX4_PMD_SOFT_COUNTERS=$(CONFIG_RTE_LIBRTE_MLX4_SOFT_COUNTERS)
-endif
-
 ifeq ($(CONFIG_RTE_LIBRTE_MLX4_DEBUG_BROKEN_VERBS),y)
 CFLAGS += -DMLX4_PMD_DEBUG_BROKEN_VERBS
 endif
drivers/net/mlx4/mlx4.c +0 -37
index cb07a53..2e8de92 100644
@@ -34,7 +34,6 @@
 /*
  * Known limitations:
  * - RSS hash key and options cannot be modified.
- * - Hardware counters aren't implemented.
  */
 
 /* System headers. */
@@ -1372,9 +1371,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		struct txq_elt *elt_next = &(*txq->elts)[elts_head_next];
 		struct txq_elt *elt = &(*txq->elts)[elts_head];
 		unsigned int segs = NB_SEGS(buf);
-#ifdef MLX4_PMD_SOFT_COUNTERS
 		unsigned int sent_size = 0;
-#endif
 		uint32_t send_flags = 0;
 
 		/* Clean up old buffer. */
@@ -1452,9 +1449,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 					 send_flags);
 			if (unlikely(err))
 				goto stop;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 			sent_size += length;
-#endif
 		} else {
 #if MLX4_PMD_SGE_WR_N > 1
 			struct ibv_sge sges[MLX4_PMD_SGE_WR_N];
@@ -1473,9 +1468,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 				 send_flags);
 			if (unlikely(err))
 				goto stop;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 			sent_size += ret.length;
-#endif
 #else /* MLX4_PMD_SGE_WR_N > 1 */
 			DEBUG("%p: TX scattered buffers support not"
 			      " compiled in", (void *)txq);
@@ -1483,19 +1476,15 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 #endif /* MLX4_PMD_SGE_WR_N > 1 */
 		}
 		elts_head = elts_head_next;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 		/* Increment sent bytes counter. */
 		txq->stats.obytes += sent_size;
-#endif
 	}
 stop:
 	/* Take a shortcut if nothing must be sent. */
 	if (unlikely(i == 0))
 		return 0;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 	/* Increment sent packets counter. */
 	txq->stats.opackets += i;
-#endif
 	/* Ring QP doorbell. */
 	err = txq->if_qp->send_flush(txq->qp);
 	if (unlikely(err)) {
@@ -2786,10 +2775,8 @@ mlx4_rx_burst_sp(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 				      " completion status (%d): %s",
 				      (void *)rxq, wc.wr_id, wc.status,
 				      ibv_wc_status_str(wc.status));
-#ifdef MLX4_PMD_SOFT_COUNTERS
 				/* Increment dropped packets counter. */
 				++rxq->stats.idropped;
-#endif
 				/* Link completed WRs together for repost. */
 				*next = wr;
 				next = &wr->next;
@@ -2901,10 +2888,8 @@ mlx4_rx_burst_sp(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		/* Return packet. */
 		*(pkts++) = pkt_buf;
 		++pkts_ret;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 		/* Increase bytes counter. */
 		rxq->stats.ibytes += pkt_buf_len;
-#endif
 repost:
 		if (++elts_head >= elts_n)
 			elts_head = 0;
@@ -2924,10 +2909,8 @@ mlx4_rx_burst_sp(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		abort();
 	}
 	rxq->elts_head = elts_head;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 	/* Increase packets counter. */
 	rxq->stats.ipackets += pkts_ret;
-#endif
 	return pkts_ret;
 }
 
@@ -3008,10 +2991,8 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 				      " completion status (%d): %s",
 				      (void *)rxq, wc.wr_id, wc.status,
 				      ibv_wc_status_str(wc.status));
-#ifdef MLX4_PMD_SOFT_COUNTERS
 				/* Increment dropped packets counter. */
 				++rxq->stats.idropped;
-#endif
 				/* Add SGE to array for repost. */
 				sges[i] = elt->sge;
 				goto repost;
@@ -3062,10 +3043,8 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		/* Return packet. */
 		*(pkts++) = seg;
 		++pkts_ret;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 		/* Increase bytes counter. */
 		rxq->stats.ibytes += len;
-#endif
 repost:
 		if (++elts_head >= elts_n)
 			elts_head = 0;
@@ -3083,10 +3062,8 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		abort();
 	}
 	rxq->elts_head = elts_head;
-#ifdef MLX4_PMD_SOFT_COUNTERS
 	/* Increase packets counter. */
 	rxq->stats.ipackets += pkts_ret;
-#endif
 	return pkts_ret;
 }
 
@@ -4270,17 +4247,13 @@ mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 			continue;
 		idx = rxq->stats.idx;
 		if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-#ifdef MLX4_PMD_SOFT_COUNTERS
 			tmp.q_ipackets[idx] += rxq->stats.ipackets;
 			tmp.q_ibytes[idx] += rxq->stats.ibytes;
-#endif
 			tmp.q_errors[idx] += (rxq->stats.idropped +
 					      rxq->stats.rx_nombuf);
 		}
-#ifdef MLX4_PMD_SOFT_COUNTERS
 		tmp.ipackets += rxq->stats.ipackets;
 		tmp.ibytes += rxq->stats.ibytes;
-#endif
 		tmp.ierrors += rxq->stats.idropped;
 		tmp.rx_nombuf += rxq->stats.rx_nombuf;
 	}
@@ -4291,21 +4264,14 @@ mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 			continue;
 		idx = txq->stats.idx;
 		if (idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-#ifdef MLX4_PMD_SOFT_COUNTERS
 			tmp.q_opackets[idx] += txq->stats.opackets;
 			tmp.q_obytes[idx] += txq->stats.obytes;
-#endif
 			tmp.q_errors[idx] += txq->stats.odropped;
 		}
-#ifdef MLX4_PMD_SOFT_COUNTERS
 		tmp.opackets += txq->stats.opackets;
 		tmp.obytes += txq->stats.obytes;
-#endif
 		tmp.oerrors += txq->stats.odropped;
 	}
-#ifndef MLX4_PMD_SOFT_COUNTERS
-	/* FIXME: retrieve and add hardware counters. */
-#endif
 	*stats = tmp;
 	priv_unlock(priv);
 }
@@ -4340,9 +4306,6 @@ mlx4_stats_reset(struct rte_eth_dev *dev)
 		(*priv->txqs)[i]->stats =
 			(struct mlx4_txq_stats){ .idx = idx };
 	}
-#ifndef MLX4_PMD_SOFT_COUNTERS
-	/* FIXME: reset hardware counters. */
-#endif
 	priv_unlock(priv);
 }
 
drivers/net/mlx4/mlx4.h +0 -12
index 702f9c9..97e042e 100644
@@ -101,14 +101,6 @@
 #define MLX4_PMD_TX_MP_CACHE 8
 #endif
 
-/*
- * If defined, only use software counters. The PMD will never ask the hardware
- * for these, and many of them won't be available.
- */
-#ifndef MLX4_PMD_SOFT_COUNTERS
-#define MLX4_PMD_SOFT_COUNTERS 1
-#endif
-
 /* Alarm timeout. */
 #define MLX4_ALARM_TIMEOUT_US 100000
 
@@ -186,10 +178,8 @@ enum {
 
 struct mlx4_rxq_stats {
 	unsigned int idx; /**< Mapping index. */
-#ifdef MLX4_PMD_SOFT_COUNTERS
 	uint64_t ipackets; /**< Total of successfully received packets. */
 	uint64_t ibytes; /**< Total of successfully received bytes. */
-#endif
 	uint64_t idropped; /**< Total of packets dropped when RX ring full. */
 	uint64_t rx_nombuf; /**< Total of RX mbuf allocation failures. */
 };
@@ -252,10 +242,8 @@ struct txq_elt {
 
 struct mlx4_txq_stats {
 	unsigned int idx; /**< Mapping index. */
-#ifdef MLX4_PMD_SOFT_COUNTERS
 	uint64_t opackets; /**< Total of successfully sent packets. */
 	uint64_t obytes;   /**< Total of successfully sent bytes. */
-#endif
 	uint64_t odropped; /**< Total of packets not sent when TX ring full. */
 };
 
Signature · 1 line
2.1.4
#63 lore raw

PATCH v2 8/51 net/mlx4: remove scatter mode compilation option

In reply to Adrien Mazarguil

This option both sets the maximum number of segments for Rx/Tx packets and whether scattered mode is supported at all. This commit removes the latter as well as configuration file exposure since the most appropriate value should be decided at run-time.

---
 config/common_base        |  1 -
 doc/guides/nics/mlx4.rst  |  7 -------
 drivers/net/mlx4/Makefile |  4 ----
 drivers/net/mlx4/mlx4.c   | 10 ----------
 drivers/net/mlx4/mlx4.h   |  2 --
 5 files changed, 24 deletions(-)
config/common_base +0 -1
index c7ffb6b..f966fd1 100644
@@ -214,7 +214,6 @@ CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
 CONFIG_RTE_LIBRTE_MLX4_PMD=n
 CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
 CONFIG_RTE_LIBRTE_MLX4_DEBUG_BROKEN_VERBS=n
-CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N=4
 CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE=0
 CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
 
doc/guides/nics/mlx4.rst +0 -7
index eba81ba..8c656d3 100644
@@ -124,13 +124,6 @@ These options can be modified in the ``.config`` file.
   to abort with harmless debugging messages as a workaround.
   Relevant only when CONFIG_RTE_LIBRTE_MLX4_DEBUG is enabled.
 
-- ``CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N`` (default **4**)
-
-  Number of scatter/gather elements (SGEs) per work request (WR). Lowering
-  this number improves performance but also limits the ability to receive
-  scattered packets (packets that do not fit a single mbuf). The default
-  value is a safe tradeoff.
-
 - ``CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE`` (default **0**)
 
   Amount of data to be inlined during TX operations. Improves latency but
drivers/net/mlx4/Makefile +0 -4
index 147e541..f9257fc 100644
@@ -68,10 +68,6 @@ else
 CFLAGS += -DNDEBUG -UPEDANTIC
 endif
 
-ifdef CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N
-CFLAGS += -DMLX4_PMD_SGE_WR_N=$(CONFIG_RTE_LIBRTE_MLX4_SGE_WR_N)
-endif
-
 ifdef CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE
 CFLAGS += -DMLX4_PMD_MAX_INLINE=$(CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE)
 endif
drivers/net/mlx4/mlx4.c +0 -10
index 2e8de92..0bbcb7b 100644
@@ -1176,8 +1176,6 @@ txq_mp2mr_iter(struct rte_mempool *mp, void *arg)
 	txq_mp2mr(txq, mp);
 }
 
-#if MLX4_PMD_SGE_WR_N > 1
-
 /**
  * Copy scattered mbuf contents to a single linear buffer.
  *
@@ -1324,8 +1322,6 @@ tx_burst_sg(struct txq *txq, unsigned int segs, struct txq_elt *elt,
 	};
 }
 
-#endif /* MLX4_PMD_SGE_WR_N > 1 */
-
 /**
  * DPDK callback for TX.
  *
@@ -1451,7 +1447,6 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 				goto stop;
 			sent_size += length;
 		} else {
-#if MLX4_PMD_SGE_WR_N > 1
 			struct ibv_sge sges[MLX4_PMD_SGE_WR_N];
 			struct tx_burst_sg_ret ret;
 
@@ -1469,11 +1464,6 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			if (unlikely(err))
 				goto stop;
 			sent_size += ret.length;
-#else /* MLX4_PMD_SGE_WR_N > 1 */
-			DEBUG("%p: TX scattered buffers support not"
-			      " compiled in", (void *)txq);
-			goto stop;
-#endif /* MLX4_PMD_SGE_WR_N > 1 */
 		}
 		elts_head = elts_head_next;
 		/* Increment sent bytes counter. */
drivers/net/mlx4/mlx4.h +0 -2
index 97e042e..5c2005d 100644
@@ -81,9 +81,7 @@
 #define MLX4_PMD_TX_PER_COMP_REQ 64
 
 /* Maximum number of Scatter/Gather Elements per Work Request. */
-#ifndef MLX4_PMD_SGE_WR_N
 #define MLX4_PMD_SGE_WR_N 4
-#endif
 
 /* Maximum size for inline data. */
 #ifndef MLX4_PMD_MAX_INLINE
Signature · 1 line
2.1.4
#64 lore raw

PATCH v2 9/51 net/mlx4: remove Tx inline compilation option

In reply to Adrien Mazarguil

This should be a run-time parameter.

---
 config/common_base        | 1 -
 drivers/net/mlx4/Makefile | 4 ----
 drivers/net/mlx4/mlx4.c   | 6 ------
 drivers/net/mlx4/mlx4.h   | 4 ----
 4 files changed, 15 deletions(-)
config/common_base +0 -1
index f966fd1..edc563a 100644
@@ -214,7 +214,6 @@ CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
 CONFIG_RTE_LIBRTE_MLX4_PMD=n
 CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
 CONFIG_RTE_LIBRTE_MLX4_DEBUG_BROKEN_VERBS=n
-CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE=0
 CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
 
 #
drivers/net/mlx4/Makefile +0 -4
index f9257fc..bd713e2 100644
@@ -68,10 +68,6 @@ else
 CFLAGS += -DNDEBUG -UPEDANTIC
 endif
 
-ifdef CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE
-CFLAGS += -DMLX4_PMD_MAX_INLINE=$(CONFIG_RTE_LIBRTE_MLX4_MAX_INLINE)
-endif
-
 ifdef CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE
 CFLAGS += -DMLX4_PMD_TX_MP_CACHE=$(CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE)
 endif
drivers/net/mlx4/mlx4.c +0 -6
index 0bbcb7b..394b87c 100644
@@ -1428,7 +1428,6 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 					      (uintptr_t)addr);
 			RTE_MBUF_PREFETCH_TO_FREE(elt_next->buf);
 			/* Put packet into send queue. */
-#if MLX4_PMD_MAX_INLINE > 0
 			if (length <= txq->max_inline)
 				err = txq->if_qp->send_pending_inline
 					(txq->qp,
@@ -1436,7 +1435,6 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 					 length,
 					 send_flags);
 			else
-#endif
 				err = txq->if_qp->send_pending
 					(txq->qp,
 					 addr,
@@ -1578,9 +1576,7 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 					  MLX4_PMD_SGE_WR_N) ?
 					 priv->device_attr.max_sge :
 					 MLX4_PMD_SGE_WR_N),
-#if MLX4_PMD_MAX_INLINE > 0
 			.max_inline_data = MLX4_PMD_MAX_INLINE,
-#endif
 		},
 		.qp_type = IBV_QPT_RAW_PACKET,
 		/* Do *NOT* enable this, completions events are managed per
@@ -1598,10 +1594,8 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		      (void *)dev, strerror(ret));
 		goto error;
 	}
-#if MLX4_PMD_MAX_INLINE > 0
 	/* ibv_create_qp() updates this value. */
 	tmpl.max_inline = attr.init.cap.max_inline_data;
-#endif
 	attr.mod = (struct ibv_exp_qp_attr){
 		/* Move the QP to this state. */
 		.qp_state = IBV_QPS_INIT,
drivers/net/mlx4/mlx4.h +0 -4
index 5c2005d..256e644 100644
@@ -84,9 +84,7 @@
 #define MLX4_PMD_SGE_WR_N 4
 
 /* Maximum size for inline data. */
-#ifndef MLX4_PMD_MAX_INLINE
 #define MLX4_PMD_MAX_INLINE 0
-#endif
 
 /*
  * Maximum number of cached Memory Pools (MPs) per TX queue. Each RTE MP
@@ -267,9 +265,7 @@ struct txq {
 	struct ibv_qp *qp; /* Queue Pair. */
 	struct ibv_exp_qp_burst_family *if_qp; /* QP burst interface. */
 	struct ibv_exp_cq_family *if_cq; /* CQ interface. */
-#if MLX4_PMD_MAX_INLINE > 0
 	uint32_t max_inline; /* Max inline send size <= MLX4_PMD_MAX_INLINE. */
-#endif
 	unsigned int elts_n; /* (*elts)[] length. */
 	struct txq_elt (*elts)[]; /* TX elements. */
 	unsigned int elts_head; /* Current index in (*elts)[]. */
Signature · 1 line
2.1.4
#65 lore raw

PATCH v2 10/51 net/mlx4: remove allmulti and promisc support

In reply to Adrien Mazarguil

This is done in preparation for a major refactoring.

---
 doc/guides/nics/features/mlx4.ini |   2 -
 doc/guides/nics/mlx4.rst          |   2 -
 drivers/net/mlx4/mlx4.c           | 311 ---------------------------------
 drivers/net/mlx4/mlx4.h           |   4 -
 4 files changed, 319 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -2
index f6efd21..344731f 100644
@@ -13,8 +13,6 @@ Queue start/stop     = Y
 MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
-Promiscuous mode     = Y
-Allmulticast mode    = Y
 Unicast MAC filter   = Y
 Multicast MAC filter = Y
 RSS hash             = Y
doc/guides/nics/mlx4.rst +0 -2
index 8c656d3..b6aaee2 100644
@@ -82,8 +82,6 @@ Features
   configured RX queues must be a power of two.
 - VLAN filtering is supported.
 - Link state information is provided.
-- Promiscuous mode is supported.
-- All multicast mode is supported.
 - Multiple MAC addresses (unicast, multicast) can be configured.
 - Scattered packets are supported for TX and RX.
 - Inner L3/L4 (IP, TCP and UDP) TX/RX checksum offloading and validation.
drivers/net/mlx4/mlx4.c +0 -311

380 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +0 -4
index 256e644..d4b3a5f 100644
@@ -210,8 +210,6 @@ struct rxq {
 	 */
 	BITFIELD_DECLARE(mac_configured, uint32_t, MLX4_MAX_MAC_ADDRESSES);
 	struct ibv_flow *mac_flow[MLX4_MAX_MAC_ADDRESSES][MLX4_MAX_VLAN_IDS];
-	struct ibv_flow *promisc_flow; /* Promiscuous flow. */
-	struct ibv_flow *allmulti_flow; /* Multicast flow. */
 	unsigned int port_id; /* Port ID for incoming packets. */
 	unsigned int elts_n; /* (*elts)[] length. */
 	unsigned int elts_head; /* Current index in (*elts)[]. */
@@ -303,8 +301,6 @@ struct priv {
 	uint16_t mtu; /* Configured MTU. */
 	uint8_t port; /* Physical port number. */
 	unsigned int started:1; /* Device started, flows enabled. */
-	unsigned int promisc:1; /* Device in promiscuous mode. */
-	unsigned int allmulti:1; /* Device receives all multicast packets. */
 	unsigned int hw_qpg:1; /* QP groups are supported. */
 	unsigned int hw_tss:1; /* TSS is supported. */
 	unsigned int hw_rss:1; /* RSS is supported. */
Signature · 1 line
2.1.4
#66 lore raw

PATCH v2 11/51 net/mlx4: remove VLAN filter support

In reply to Adrien Mazarguil

This is done in preparation for a major refactoring.

---
 doc/guides/nics/features/mlx4.ini |   1 -
 doc/guides/nics/mlx4.rst          |   1 -
 drivers/net/mlx4/mlx4.c           | 206 +++------------------------------
 drivers/net/mlx4/mlx4.h           |  13 +--
 4 files changed, 17 insertions(+), 204 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -1
index 344731f..bfa6948 100644
@@ -17,7 +17,6 @@ Unicast MAC filter   = Y
 Multicast MAC filter = Y
 RSS hash             = Y
 SR-IOV               = Y
-VLAN filter          = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
 Inner L3 checksum    = Y
doc/guides/nics/mlx4.rst +0 -1
index b6aaee2..0f340c5 100644
@@ -80,7 +80,6 @@ Features
 - Multi arch support: x86_64 and POWER8.
 - RSS, also known as RCA, is supported. In this mode the number of
   configured RX queues must be a power of two.
-- VLAN filtering is supported.
 - Link state information is provided.
 - Multiple MAC addresses (unicast, multicast) can be configured.
 - Scattered packets are supported for TX and RX.
drivers/net/mlx4/mlx4.c +16 -190

295 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +1 -12
index d4b3a5f..d26d826 100644
@@ -74,9 +74,6 @@
  */
 #define MLX4_MAX_MAC_ADDRESSES 128
 
-/* Maximum number of simultaneous VLAN filters supported. See above. */
-#define MLX4_MAX_VLAN_IDS 127
-
 /* Request send completion once in every 64 sends, might be less. */
 #define MLX4_PMD_TX_PER_COMP_REQ 64
 
@@ -205,11 +202,8 @@ struct rxq {
 	struct ibv_exp_qp_burst_family *if_qp; /* QP burst interface. */
 	struct ibv_exp_cq_family *if_cq; /* CQ interface. */
 	struct ibv_comp_channel *channel;
-	/*
-	 * Each VLAN ID requires a separate flow steering rule.
-	 */
 	BITFIELD_DECLARE(mac_configured, uint32_t, MLX4_MAX_MAC_ADDRESSES);
-	struct ibv_flow *mac_flow[MLX4_MAX_MAC_ADDRESSES][MLX4_MAX_VLAN_IDS];
+	struct ibv_flow *mac_flow[MLX4_MAX_MAC_ADDRESSES];
 	unsigned int port_id; /* Port ID for incoming packets. */
 	unsigned int elts_n; /* (*elts)[] length. */
 	unsigned int elts_head; /* Current index in (*elts)[]. */
@@ -292,11 +286,6 @@ struct priv {
 	 */
 	struct ether_addr mac[MLX4_MAX_MAC_ADDRESSES];
 	BITFIELD_DECLARE(mac_configured, uint32_t, MLX4_MAX_MAC_ADDRESSES);
-	/* VLAN filters. */
-	struct {
-		unsigned int enabled:1; /* If enabled. */
-		unsigned int id:12; /* VLAN ID (0-4095). */
-	} vlan_filter[MLX4_MAX_VLAN_IDS]; /* VLAN filters table. */
 	/* Device properties. */
 	uint16_t mtu; /* Configured MTU. */
 	uint8_t port; /* Physical port number. */
Signature · 1 line
2.1.4
#67 lore raw

PATCH v2 12/51 net/mlx4: remove MAC address configuration support

In reply to Adrien Mazarguil

Only the default port MAC address remains and is not configurable. This is done in preparation for a major refactoring.

---
 doc/guides/nics/features/mlx4.ini |   2 -
 doc/guides/nics/mlx4.rst          |   1 -
 drivers/net/mlx4/mlx4.c           | 322 ++++-----------------------------
 drivers/net/mlx4/mlx4.h           |  41 +----
 4 files changed, 39 insertions(+), 327 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -2
index bfa6948..3acf8d3 100644
@@ -13,8 +13,6 @@ Queue start/stop     = Y
 MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
-Unicast MAC filter   = Y
-Multicast MAC filter = Y
 RSS hash             = Y
 SR-IOV               = Y
 L3 checksum offload  = Y
doc/guides/nics/mlx4.rst +0 -1
index 0f340c5..d3d51f7 100644
@@ -81,7 +81,6 @@ Features
 - RSS, also known as RCA, is supported. In this mode the number of
   configured RX queues must be a power of two.
 - Link state information is provided.
-- Multiple MAC addresses (unicast, multicast) can be configured.
 - Scattered packets are supported for TX and RX.
 - Inner L3/L4 (IP, TCP and UDP) TX/RX checksum offloading and validation.
 - Outer L3 (IP) TX/RX checksum offloading and validation for VXLAN frames.
drivers/net/mlx4/mlx4.c +37 -285

506 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +2 -39

71 lines not on this page · raw message

Signature · 1 line
2.1.4
#68 lore raw

PATCH v2 13/51 net/mlx4: drop MAC flows affecting all Rx queues

In reply to Adrien Mazarguil

Configuring several Rx queues enables RSS, which causes an additional special parent queue to be created to manage them.

MAC flows are associated with the queue supposed to receive packets; either the parent one in case of RSS or the single orphan otherwise.

For historical reasons the current implementation supports another scenario with multiple orphans, in which case MAC flows are configured on all of them. This is harmless but useless since it cannot happen.

Removing this feature allows dissociating the remaining MAC flow from Rx queues and store it inside the private structure where it belongs.

---
 drivers/net/mlx4/mlx4.c | 215 +++++++++++--------------------------------
 drivers/net/mlx4/mlx4.h |   2 +-
 2 files changed, 57 insertions(+), 160 deletions(-)
drivers/net/mlx4/mlx4.c +56 -159
index 8ca5698..05923e9 100644
@@ -515,6 +515,9 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 static void
 rxq_cleanup(struct rxq *rxq);
 
+static void
+priv_mac_addr_del(struct priv *priv);
+
 /**
  * Create RSS parent queue.
  *
@@ -641,6 +644,7 @@ dev_configure(struct rte_eth_dev *dev)
 		for (i = 0; (i != priv->rxqs_n); ++i)
 			if ((*priv->rxqs)[i] != NULL)
 				return EINVAL;
+		priv_mac_addr_del(priv);
 		priv_parent_list_cleanup(priv);
 		priv->rss = 0;
 		priv->rxqs_n = 0;
@@ -2065,46 +2069,57 @@ rxq_free_elts(struct rxq *rxq)
 }
 
 /**
- * Unregister a MAC address from a Rx queue.
+ * Unregister a MAC address.
  *
- * @param rxq
- *   Pointer to RX queue structure.
+ * @param priv
+ *   Pointer to private structure.
  */
 static void
-rxq_mac_addr_del(struct rxq *rxq)
+priv_mac_addr_del(struct priv *priv)
 {
 #ifndef NDEBUG
-	struct priv *priv = rxq->priv;
-	const uint8_t (*mac)[ETHER_ADDR_LEN] =
-		(const uint8_t (*)[ETHER_ADDR_LEN])
-		priv->mac.addr_bytes;
+	uint8_t (*mac)[ETHER_ADDR_LEN] = &priv->mac.addr_bytes;
 #endif
-	if (!rxq->mac_flow)
+
+	if (!priv->mac_flow)
 		return;
 	DEBUG("%p: removing MAC address %02x:%02x:%02x:%02x:%02x:%02x",
-	      (void *)rxq,
+	      (void *)priv,
 	      (*mac)[0], (*mac)[1], (*mac)[2], (*mac)[3], (*mac)[4], (*mac)[5]);
-	claim_zero(ibv_destroy_flow(rxq->mac_flow));
-	rxq->mac_flow = NULL;
+	claim_zero(ibv_destroy_flow(priv->mac_flow));
+	priv->mac_flow = NULL;
 }
 
 /**
- * Register a MAC address in a Rx queue.
+ * Register a MAC address.
  *
- * @param rxq
- *   Pointer to RX queue structure.
+ * In RSS mode, the MAC address is registered in the parent queue,
+ * otherwise it is registered in queue 0.
+ *
+ * @param priv
+ *   Pointer to private structure.
  *
  * @return
  *   0 on success, errno value on failure.
  */
 static int
-rxq_mac_addr_add(struct rxq *rxq)
+priv_mac_addr_add(struct priv *priv)
 {
+	uint8_t (*mac)[ETHER_ADDR_LEN] = &priv->mac.addr_bytes;
+	struct rxq *rxq;
 	struct ibv_flow *flow;
-	struct priv *priv = rxq->priv;
-	const uint8_t (*mac)[ETHER_ADDR_LEN] =
-			(const uint8_t (*)[ETHER_ADDR_LEN])
-			priv->mac.addr_bytes;
+
+	/* If device isn't started, this is all we need to do. */
+	if (!priv->started)
+		return 0;
+	if (priv->isolated)
+		return 0;
+	if (priv->rss)
+		rxq = LIST_FIRST(&priv->parents);
+	else if (*priv->rxqs && (*priv->rxqs)[0])
+		rxq = (*priv->rxqs)[0];
+	else
+		return 0;
 
 	/* Allocate flow specification on the stack. */
 	struct __attribute__((packed)) {
@@ -2114,8 +2129,8 @@ rxq_mac_addr_add(struct rxq *rxq)
 	struct ibv_flow_attr *attr = &data.attr;
 	struct ibv_flow_spec_eth *spec = &data.spec;
 
-	if (rxq->mac_flow)
-		rxq_mac_addr_del(rxq);
+	if (priv->mac_flow)
+		priv_mac_addr_del(priv);
 	/*
 	 * No padding must be inserted by the compiler between attr and spec.
 	 * This layout is expected by libibverbs.
@@ -2142,7 +2157,7 @@ rxq_mac_addr_add(struct rxq *rxq)
 		}
 	};
 	DEBUG("%p: adding MAC address %02x:%02x:%02x:%02x:%02x:%02x",
-	      (void *)rxq,
+	      (void *)priv,
 	      (*mac)[0], (*mac)[1], (*mac)[2], (*mac)[3], (*mac)[4], (*mac)[5]);
 	/* Create related flow. */
 	errno = 0;
@@ -2156,60 +2171,8 @@ rxq_mac_addr_add(struct rxq *rxq)
 			return errno;
 		return EINVAL;
 	}
-	assert(rxq->mac_flow == NULL);
-	rxq->mac_flow = flow;
-	return 0;
-}
-
-/**
- * Register a MAC address.
- *
- * In RSS mode, the MAC address is registered in the parent queue,
- * otherwise it is registered in each queue directly.
- *
- * @param priv
- *   Pointer to private structure.
- * @param mac
- *   MAC address to register.
- *
- * @return
- *   0 on success, errno value on failure.
- */
-static int
-priv_mac_addr_add(struct priv *priv, const uint8_t (*mac)[ETHER_ADDR_LEN])
-{
-	unsigned int i;
-	int ret;
-
-	priv->mac = (struct ether_addr){
-		{
-			(*mac)[0], (*mac)[1], (*mac)[2],
-			(*mac)[3], (*mac)[4], (*mac)[5]
-		}
-	};
-	/* If device isn't started, this is all we need to do. */
-	if (!priv->started) {
-		goto end;
-	}
-	if (priv->rss) {
-		ret = rxq_mac_addr_add(LIST_FIRST(&priv->parents));
-		if (ret)
-			return ret;
-		goto end;
-	}
-	for (i = 0; (i != priv->rxqs_n); ++i) {
-		if ((*priv->rxqs)[i] == NULL)
-			continue;
-		ret = rxq_mac_addr_add((*priv->rxqs)[i]);
-		if (!ret)
-			continue;
-		/* Failure, rollback. */
-		while (i != 0)
-			if ((*priv->rxqs)[(--i)] != NULL)
-				rxq_mac_addr_del((*priv->rxqs)[i]);
-		return ret;
-	}
-end:
+	assert(priv->mac_flow == NULL);
+	priv->mac_flow = flow;
 	return 0;
 }
 
@@ -2253,9 +2216,6 @@ rxq_cleanup(struct rxq *rxq)
 						rxq->if_cq,
 						&params));
 	}
-	if (rxq->qp != NULL && !rxq->priv->isolated) {
-		rxq_mac_addr_del(rxq);
-	}
 	if (rxq->qp != NULL)
 		claim_zero(ibv_destroy_qp(rxq->qp));
 	if (rxq->cq != NULL)
@@ -2894,12 +2854,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 		DEBUG("%p: nothing to do", (void *)dev);
 		return 0;
 	}
-	/* Remove attached flows if RSS is disabled (no parent queue). */
-	if (!priv->rss && !priv->isolated) {
-		rxq_mac_addr_del(&tmpl);
-		/* Update original queue in case of failure. */
-		rxq->mac_flow = NULL;
-	}
 	/* From now on, any failure will render the queue unusable.
 	 * Reinitialize QP. */
 	if (!tmpl.qp)
@@ -2933,12 +2887,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 		assert(err > 0);
 		return err;
 	}
-	/* Reconfigure flows. Do not care for errors. */
-	if (!priv->rss && !priv->isolated) {
-		rxq_mac_addr_add(&tmpl);
-		/* Update original queue in case of failure. */
-		rxq->mac_flow = NULL;
-	}
 	/* Allocate pool. */
 	pool = rte_malloc(__func__, (mbuf_n * sizeof(*pool)), 0);
 	if (pool == NULL) {
@@ -3081,15 +3029,6 @@ rxq_create_qp(struct rxq *rxq,
 		      strerror(ret));
 		return ret;
 	}
-	if (!priv->isolated && (parent || !priv->rss)) {
-		/* Configure MAC and broadcast addresses. */
-		ret = rxq_mac_addr_add(rxq);
-		if (ret) {
-			ERROR("QP flow attachment failed: %s",
-			      strerror(ret));
-			return ret;
-		}
-	}
 	if (!parent) {
 		ret = ibv_post_recv(rxq->qp,
 				    (rxq->sp ?
@@ -3359,6 +3298,8 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 			return -EEXIST;
 		}
 		(*priv->rxqs)[idx] = NULL;
+		if (idx == 0)
+			priv_mac_addr_del(priv);
 		rxq_cleanup(rxq);
 	} else {
 		rxq = rte_calloc_socket("RXQ", 1, sizeof(*rxq), 0, socket);
@@ -3418,6 +3359,8 @@ mlx4_rx_queue_release(void *dpdk_rxq)
 			DEBUG("%p: removing RX queue %p from list",
 			      (void *)priv->dev, (void *)rxq);
 			(*priv->rxqs)[i] = NULL;
+			if (i == 0)
+				priv_mac_addr_del(priv);
 			break;
 		}
 	rxq_cleanup(rxq);
@@ -3449,9 +3392,6 @@ static int
 mlx4_dev_start(struct rte_eth_dev *dev)
 {
 	struct priv *priv = dev->data->dev_private;
-	unsigned int i = 0;
-	unsigned int r;
-	struct rxq *rxq;
 	int ret;
 
 	priv_lock(priv);
@@ -3461,28 +3401,9 @@ mlx4_dev_start(struct rte_eth_dev *dev)
 	}
 	DEBUG("%p: attaching configured flows to all RX queues", (void *)dev);
 	priv->started = 1;
-	if (priv->isolated) {
-		rxq = NULL;
-		r = 1;
-	} else if (priv->rss) {
-		rxq = LIST_FIRST(&priv->parents);
-		r = 1;
-	} else {
-		rxq = (*priv->rxqs)[0];
-		r = priv->rxqs_n;
-	}
-	/* Iterate only once when RSS is enabled. */
-	do {
-		/* Ignore nonexistent RX queues. */
-		if (rxq == NULL)
-			continue;
-		ret = rxq_mac_addr_add(rxq);
-		if (!ret)
-			continue;
-		WARN("%p: QP flow attachment failed: %s",
-		     (void *)dev, strerror(ret));
+	ret = priv_mac_addr_add(priv);
+	if (ret)
 		goto err;
-	} while ((--r) && ((rxq = (*priv->rxqs)[++i]), i));
 	ret = priv_dev_link_interrupt_handler_install(priv, dev);
 	if (ret) {
 		ERROR("%p: LSC handler install failed",
@@ -3511,12 +3432,7 @@ mlx4_dev_start(struct rte_eth_dev *dev)
 	return 0;
 err:
 	/* Rollback. */
-	while (i != 0) {
-		rxq = (*priv->rxqs)[i--];
-		if (rxq != NULL) {
-			rxq_mac_addr_del(rxq);
-		}
-	}
+	priv_mac_addr_del(priv);
 	priv->started = 0;
 	priv_unlock(priv);
 	return -ret;
@@ -3534,9 +3450,6 @@ static void
 mlx4_dev_stop(struct rte_eth_dev *dev)
 {
 	struct priv *priv = dev->data->dev_private;
-	unsigned int i = 0;
-	unsigned int r;
-	struct rxq *rxq;
 
 	priv_lock(priv);
 	if (!priv->started) {
@@ -3545,24 +3458,8 @@ mlx4_dev_stop(struct rte_eth_dev *dev)
 	}
 	DEBUG("%p: detaching flows from all RX queues", (void *)dev);
 	priv->started = 0;
-	if (priv->isolated) {
-		rxq = NULL;
-		r = 1;
-	} else if (priv->rss) {
-		rxq = LIST_FIRST(&priv->parents);
-		r = 1;
-	} else {
-		rxq = (*priv->rxqs)[0];
-		r = priv->rxqs_n;
-	}
 	mlx4_priv_flow_stop(priv);
-	/* Iterate only once when RSS is enabled. */
-	do {
-		/* Ignore nonexistent RX queues. */
-		if (rxq == NULL)
-			continue;
-		rxq_mac_addr_del(rxq);
-	} while ((--r) && ((rxq = (*priv->rxqs)[++i]), i));
+	priv_mac_addr_del(priv);
 	priv_unlock(priv);
 }
 
@@ -3647,6 +3544,7 @@ mlx4_dev_close(struct rte_eth_dev *dev)
 	DEBUG("%p: closing device \"%s\"",
 	      (void *)dev,
 	      ((priv->ctx != NULL) ? priv->ctx->device->name : ""));
+	priv_mac_addr_del(priv);
 	/* Prevent crashes when queues are still in use. This is unfortunately
 	 * still required for DPDK 1.3 because some programs (such as testpmd)
 	 * never release them before closing the device. */
@@ -4036,6 +3934,8 @@ mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	} else
 		DEBUG("adapter port %u MTU set to %u", priv->port, mtu);
 	priv->mtu = mtu;
+	/* Remove MAC flow. */
+	priv_mac_addr_del(priv);
 	/* Temporarily replace RX handler with a fake one, assuming it has not
 	 * been copied elsewhere. */
 	dev->rx_pkt_burst = removed_rx_burst;
@@ -4064,11 +3964,6 @@ mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 				rx_func = mlx4_rx_burst_sp;
 			break;
 		}
-		/* Reenable non-RSS queue attributes. No need to check
-		 * for errors at this stage. */
-		if (!priv->rss && !priv->isolated) {
-			rxq_mac_addr_add(rxq);
-		}
 		/* Scattered burst function takes priority. */
 		if (rxq->sp)
 			rx_func = mlx4_rx_burst_sp;
@@ -4076,6 +3971,8 @@ mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	/* Burst functions can now be called again. */
 	rte_wmb();
 	dev->rx_pkt_burst = rx_func;
+	/* Restore MAC flow. */
+	ret = priv_mac_addr_add(priv);
 out:
 	priv_unlock(priv);
 	assert(ret >= 0);
@@ -5131,9 +5028,9 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		     mac.addr_bytes[2], mac.addr_bytes[3],
 		     mac.addr_bytes[4], mac.addr_bytes[5]);
 		/* Register MAC address. */
-		claim_zero(priv_mac_addr_add(priv,
-					     (const uint8_t (*)[ETHER_ADDR_LEN])
-					     mac.addr_bytes));
+		priv->mac = mac;
+		if (priv_mac_addr_add(priv))
+			goto port_error;
 #ifndef NDEBUG
 		{
 			char ifname[IF_NAMESIZE];
drivers/net/mlx4/mlx4.h +1 -1
index d00e77f..af70076 100644
@@ -172,7 +172,6 @@ struct rxq {
 	struct ibv_exp_qp_burst_family *if_qp; /* QP burst interface. */
 	struct ibv_exp_cq_family *if_cq; /* CQ interface. */
 	struct ibv_comp_channel *channel;
-	struct ibv_flow *mac_flow; /* Flow associated with MAC address. */
 	unsigned int port_id; /* Port ID for incoming packets. */
 	unsigned int elts_n; /* (*elts)[] length. */
 	unsigned int elts_head; /* Current index in (*elts)[]. */
@@ -249,6 +248,7 @@ struct priv {
 	struct ibv_device_attr device_attr; /* Device properties. */
 	struct ibv_pd *pd; /* Protection Domain. */
 	struct ether_addr mac; /* MAC address. */
+	struct ibv_flow *mac_flow; /* Flow associated with MAC address. */
 	/* Device properties. */
 	uint16_t mtu; /* Configured MTU. */
 	uint8_t port; /* Physical port number. */
Signature · 1 line
2.1.4
#69 lore raw

PATCH v2 14/51 net/mlx4: revert flow API RSS support

In reply to Adrien Mazarguil

This reverts commit d7769c7c08cc08a9d1bc4e40b95524d9697707d9.

Existing RSS features rely on experimental Verbs provided by Mellanox OFED.

In order to replace this dependency with standard distribution packages, RSS support must be temporarily removed to be re-implemented using a different API.

Removing support for the RSS flow rule action is the first step toward this goal.

---
 drivers/net/mlx4/mlx4.c      |   6 +-
 drivers/net/mlx4/mlx4.h      |   5 -
 drivers/net/mlx4/mlx4_flow.c | 206 +++-----------------------------------
 drivers/net/mlx4/mlx4_flow.h |   3 +-
 4 files changed, 20 insertions(+), 200 deletions(-)
drivers/net/mlx4/mlx4.c +4 -2
index 05923e9..02605c9 100644
@@ -533,7 +533,7 @@ priv_mac_addr_del(struct priv *priv);
  * @return
  *   Pointer to a parent rxq structure, NULL on failure.
  */
-struct rxq *
+static struct rxq *
 priv_parent_create(struct priv *priv,
 		   uint16_t queues[],
 		   uint16_t children_n)
@@ -670,8 +670,10 @@ dev_configure(struct rte_eth_dev *dev)
 	priv->rss = 1;
 	tmp = priv->rxqs_n;
 	priv->rxqs_n = rxqs_n;
-	if (priv->isolated)
+	if (priv->isolated) {
+		priv->rss = 0;
 		return 0;
+	}
 	if (priv_parent_create(priv, NULL, priv->rxqs_n))
 		return 0;
 	/* Failure, rollback. */
drivers/net/mlx4/mlx4.h +0 -5
index af70076..b76bf48 100644
@@ -291,9 +291,4 @@ rxq_create_qp(struct rxq *rxq,
 void
 rxq_parent_cleanup(struct rxq *parent);
 
-struct rxq *
-priv_parent_create(struct priv *priv,
-		   uint16_t queues[],
-		   uint16_t children_n);
-
 #endif /* RTE_PMD_MLX4_H_ */
drivers/net/mlx4/mlx4_flow.c +15 -191

255 lines not on this page · raw message

drivers/net/mlx4/mlx4_flow.h +1 -2
index 4654dc2..17e5f6e 100644
@@ -98,8 +98,7 @@ mlx4_flow_isolate(struct rte_eth_dev *dev,
 struct mlx4_flow_action {
 	uint32_t drop:1; /**< Target is a drop queue. */
 	uint32_t queue:1; /**< Target is a receive queue. */
-	uint16_t queues[RTE_MAX_QUEUES_PER_PORT]; /**< Queue indices to use. */
-	uint16_t queues_n; /**< Number of entries in queue[] */
+	uint32_t queue_id; /**< Identifier of the queue. */
 };
 
 int mlx4_priv_flow_start(struct priv *priv);
Signature · 1 line
2.1.4
#70 lore raw

PATCH v2 15/51 net/mlx4: revert RSS parent queue refactoring

In reply to Adrien Mazarguil

This reverts commit ff00a0dc5600dbb0a29e4aa7fa4b078f98c7a360.

Support for several RSS parent queues was necessary to implement the RSS flow rule action, dropped in a prior commit.

---
 drivers/net/mlx4/mlx4.c      | 332 +++++++++++---------------------------
 drivers/net/mlx4/mlx4.h      |  17 +-
 drivers/net/mlx4/mlx4_flow.c |  15 --
 3 files changed, 97 insertions(+), 267 deletions(-)
drivers/net/mlx4/mlx4.c +96 -236
index 02605c9..44a2093 100644
@@ -507,10 +507,8 @@ txq_cleanup(struct txq *txq);
 
 static int
 rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
-	  unsigned int socket, int inactive,
-	  const struct rte_eth_rxconf *conf,
-	  struct rte_mempool *mp, int children_n,
-	  struct rxq *rxq_parent);
+	  unsigned int socket, int inactive, const struct rte_eth_rxconf *conf,
+	  struct rte_mempool *mp);
 
 static void
 rxq_cleanup(struct rxq *rxq);
@@ -519,84 +517,6 @@ static void
 priv_mac_addr_del(struct priv *priv);
 
 /**
- * Create RSS parent queue.
- *
- * The new parent is inserted in front of the list in the private structure.
- *
- * @param priv
- *   Pointer to private structure.
- * @param queues
- *   Queues indices array, if NULL use all Rx queues.
- * @param children_n
- *   The number of entries in queues[].
- *
- * @return
- *   Pointer to a parent rxq structure, NULL on failure.
- */
-static struct rxq *
-priv_parent_create(struct priv *priv,
-		   uint16_t queues[],
-		   uint16_t children_n)
-{
-	int ret;
-	uint16_t i;
-	struct rxq *parent;
-
-	parent = rte_zmalloc("parent queue",
-			     sizeof(*parent),
-			     RTE_CACHE_LINE_SIZE);
-	if (!parent) {
-		ERROR("cannot allocate memory for RSS parent queue");
-		return NULL;
-	}
-	ret = rxq_setup(priv->dev, parent, 0, 0, 0,
-			NULL, NULL, children_n, NULL);
-	if (ret) {
-		rte_free(parent);
-		return NULL;
-	}
-	parent->rss.queues_n = children_n;
-	if (queues) {
-		for (i = 0; i < children_n; ++i)
-			parent->rss.queues[i] = queues[i];
-	} else {
-		/* the default RSS ring case */
-		assert(priv->rxqs_n == children_n);
-		for (i = 0; i < priv->rxqs_n; ++i)
-			parent->rss.queues[i] = i;
-	}
-	LIST_INSERT_HEAD(&priv->parents, parent, next);
-	return parent;
-}
-
-/**
- * Clean up RX queue parent structure.
- *
- * @param parent
- *   RX queue parent structure.
- */
-void
-rxq_parent_cleanup(struct rxq *parent)
-{
-	LIST_REMOVE(parent, next);
-	rxq_cleanup(parent);
-	rte_free(parent);
-}
-
-/**
- * Clean up parent structures from the parent list.
- *
- * @param priv
- *   Pointer to private structure.
- */
-static void
-priv_parent_list_cleanup(struct priv *priv)
-{
-	while (!LIST_EMPTY(&priv->parents))
-		rxq_parent_cleanup(LIST_FIRST(&priv->parents));
-}
-
-/**
  * Ethernet device configuration.
  *
  * Prepare the driver for a given number of TX and RX queues.
@@ -615,6 +535,7 @@ dev_configure(struct rte_eth_dev *dev)
 	unsigned int rxqs_n = dev->data->nb_rx_queues;
 	unsigned int txqs_n = dev->data->nb_tx_queues;
 	unsigned int tmp;
+	int ret;
 
 	priv->rxqs = (void *)dev->data->rx_queues;
 	priv->txqs = (void *)dev->data->tx_queues;
@@ -645,7 +566,7 @@ dev_configure(struct rte_eth_dev *dev)
 			if ((*priv->rxqs)[i] != NULL)
 				return EINVAL;
 		priv_mac_addr_del(priv);
-		priv_parent_list_cleanup(priv);
+		rxq_cleanup(&priv->rxq_parent);
 		priv->rss = 0;
 		priv->rxqs_n = 0;
 	}
@@ -670,16 +591,14 @@ dev_configure(struct rte_eth_dev *dev)
 	priv->rss = 1;
 	tmp = priv->rxqs_n;
 	priv->rxqs_n = rxqs_n;
-	if (priv->isolated) {
-		priv->rss = 0;
-		return 0;
-	}
-	if (priv_parent_create(priv, NULL, priv->rxqs_n))
+	ret = rxq_setup(dev, &priv->rxq_parent, 0, 0, 0, NULL, NULL);
+	if (!ret)
 		return 0;
 	/* Failure, rollback. */
 	priv->rss = 0;
 	priv->rxqs_n = tmp;
-	return ENOMEM;
+	assert(ret > 0);
+	return ret;
 }
 
 /**
@@ -2117,7 +2036,7 @@ priv_mac_addr_add(struct priv *priv)
 	if (priv->isolated)
 		return 0;
 	if (priv->rss)
-		rxq = LIST_FIRST(&priv->parents);
+		rxq = &priv->rxq_parent;
 	else if (*priv->rxqs && (*priv->rxqs)[0])
 		rxq = (*priv->rxqs)[0];
 	else
@@ -2743,18 +2662,15 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
  *   Completion queue to associate with QP.
  * @param desc
  *   Number of descriptors in QP (hint only).
- * @param children_n
- *   If nonzero, a number of children for parent QP and zero for a child.
- * @param rxq_parent
- *   Pointer for a parent in a child case, NULL otherwise.
+ * @param parent
+ *   If nonzero, create a parent QP, otherwise a child.
  *
  * @return
  *   QP pointer or NULL in case of error.
  */
 static struct ibv_qp *
 rxq_setup_qp_rss(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
-		 int children_n, struct ibv_exp_res_domain *rd,
-		 struct rxq *rxq_parent)
+		 int parent, struct ibv_exp_res_domain *rd)
 {
 	struct ibv_exp_qp_init_attr attr = {
 		/* CQ to be associated with the send queue. */
@@ -2782,16 +2698,16 @@ rxq_setup_qp_rss(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
 
 	attr.max_inl_recv = priv->inl_recv_size,
 	attr.comp_mask |= IBV_EXP_QP_INIT_ATTR_INL_RECV;
-	if (children_n > 0) {
+	if (parent) {
 		attr.qpg.qpg_type = IBV_EXP_QPG_PARENT;
 		/* TSS isn't necessary. */
 		attr.qpg.parent_attrib.tss_child_count = 0;
 		attr.qpg.parent_attrib.rss_child_count =
-			rte_align32pow2(children_n + 1) >> 1;
+			rte_align32pow2(priv->rxqs_n + 1) >> 1;
 		DEBUG("initializing parent RSS queue");
 	} else {
 		attr.qpg.qpg_type = IBV_EXP_QPG_CHILD_RX;
-		attr.qpg.qpg_parent = rxq_parent->qp;
+		attr.qpg.qpg_parent = priv->rxq_parent.qp;
 		DEBUG("initializing child RSS queue");
 	}
 	return ibv_exp_create_qp(priv->ctx, &attr);
@@ -2825,7 +2741,13 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 	struct ibv_recv_wr *bad_wr;
 	unsigned int mb_len;
 	int err;
+	int parent = (rxq == &priv->rxq_parent);
 
+	if (parent) {
+		ERROR("%p: cannot rehash parent queue %p",
+		      (void *)dev, (void *)rxq);
+		return EINVAL;
+	}
 	mb_len = rte_pktmbuf_data_room_size(rxq->mp);
 	DEBUG("%p: rehashing queue %p", (void *)dev, (void *)rxq);
 	/* Number of descriptors and mbufs currently allocated. */
@@ -2858,8 +2780,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 	}
 	/* From now on, any failure will render the queue unusable.
 	 * Reinitialize QP. */
-	if (!tmpl.qp)
-		goto skip_init;
 	mod = (struct ibv_exp_qp_attr){ .qp_state = IBV_QPS_RESET };
 	err = ibv_exp_modify_qp(tmpl.qp, &mod, IBV_EXP_QP_STATE);
 	if (err) {
@@ -2867,6 +2787,12 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 		assert(err > 0);
 		return err;
 	}
+	err = ibv_resize_cq(tmpl.cq, desc_n);
+	if (err) {
+		ERROR("%p: cannot resize CQ: %s", (void *)dev, strerror(err));
+		assert(err > 0);
+		return err;
+	}
 	mod = (struct ibv_exp_qp_attr){
 		/* Move the QP to this state. */
 		.qp_state = IBV_QPS_INIT,
@@ -2875,6 +2801,7 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 	};
 	err = ibv_exp_modify_qp(tmpl.qp, &mod,
 				(IBV_EXP_QP_STATE |
+				 (parent ? IBV_EXP_QP_GROUP_RSS : 0) |
 				 IBV_EXP_QP_PORT));
 	if (err) {
 		ERROR("%p: QP state to IBV_QPS_INIT failed: %s",
@@ -2882,13 +2809,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 		assert(err > 0);
 		return err;
 	};
-skip_init:
-	err = ibv_resize_cq(tmpl.cq, desc_n);
-	if (err) {
-		ERROR("%p: cannot resize CQ: %s", (void *)dev, strerror(err));
-		assert(err > 0);
-		return err;
-	}
 	/* Allocate pool. */
 	pool = rte_malloc(__func__, (mbuf_n * sizeof(*pool)), 0);
 	if (pool == NULL) {
@@ -2942,8 +2862,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 	rxq->elts_n = 0;
 	rte_free(rxq->elts.sp);
 	rxq->elts.sp = NULL;
-	if (!tmpl.qp)
-		goto skip_rtr;
 	/* Post WRs. */
 	err = ibv_post_recv(tmpl.qp,
 			    (tmpl.sp ?
@@ -2971,103 +2889,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)
 }
 
 /**
- * Create verbs QP resources associated with a rxq.
- *
- * @param rxq
- *   Pointer to RX queue structure.
- * @param desc
- *   Number of descriptors to configure in queue.
- * @param inactive
- *   If true, the queue is disabled because its index is higher or
- *   equal to the real number of queues, which must be a power of 2.
- * @param children_n
- *   The number of children in a parent case, zero for a child.
- * @param rxq_parent
- *   The pointer to a parent RX structure for a child in RSS case,
- *   NULL for parent.
- *
- * @return
- *   0 on success, errno value on failure.
- */
-int
-rxq_create_qp(struct rxq *rxq,
-	      uint16_t desc,
-	      int inactive,
-	      int children_n,
-	      struct rxq *rxq_parent)
-{
-	int ret;
-	struct ibv_exp_qp_attr mod;
-	struct ibv_exp_query_intf_params params;
-	enum ibv_exp_query_intf_status status;
-	struct ibv_recv_wr *bad_wr;
-	int parent = (children_n > 0);
-	struct priv *priv = rxq->priv;
-
-	if (priv->rss && !inactive && (rxq_parent || parent))
-		rxq->qp = rxq_setup_qp_rss(priv, rxq->cq, desc,
-					   children_n, rxq->rd,
-					   rxq_parent);
-	else
-		rxq->qp = rxq_setup_qp(priv, rxq->cq, desc, rxq->rd);
-	if (rxq->qp == NULL) {
-		ret = (errno ? errno : EINVAL);
-		ERROR("QP creation failure: %s",
-		      strerror(ret));
-		return ret;
-	}
-	mod = (struct ibv_exp_qp_attr){
-		/* Move the QP to this state. */
-		.qp_state = IBV_QPS_INIT,
-		/* Primary port number. */
-		.port_num = priv->port
-	};
-	ret = ibv_exp_modify_qp(rxq->qp, &mod,
-				(IBV_EXP_QP_STATE |
-				 (parent ? IBV_EXP_QP_GROUP_RSS : 0) |
-				 IBV_EXP_QP_PORT));
-	if (ret) {
-		ERROR("QP state to IBV_QPS_INIT failed: %s",
-		      strerror(ret));
-		return ret;
-	}
-	if (!parent) {
-		ret = ibv_post_recv(rxq->qp,
-				    (rxq->sp ?
-				     &(*rxq->elts.sp)[0].wr :
-				     &(*rxq->elts.no_sp)[0].wr),
-				    &bad_wr);
-		if (ret) {
-			ERROR("ibv_post_recv() failed for WR %p: %s",
-			      (void *)bad_wr,
-			      strerror(ret));
-			return ret;
-		}
-	}
-	mod = (struct ibv_exp_qp_attr){
-		.qp_state = IBV_QPS_RTR
-	};
-	ret = ibv_exp_modify_qp(rxq->qp, &mod, IBV_EXP_QP_STATE);
-	if (ret) {
-		ERROR("QP state to IBV_QPS_RTR failed: %s",
-		      strerror(ret));
-		return ret;
-	}
-	params = (struct ibv_exp_query_intf_params){
-		.intf_scope = IBV_EXP_INTF_GLOBAL,
-		.intf = IBV_EXP_INTF_QP_BURST,
-		.obj = rxq->qp,
-	};
-	rxq->if_qp = ibv_exp_query_intf(priv->ctx, &params, &status);
-	if (rxq->if_qp == NULL) {
-		ERROR("QP interface family query failed with status %d",
-		      status);
-		return errno;
-	}
-	return 0;
-}
-
-/**
  * Configure a RX queue.
  *
  * @param dev
@@ -3085,21 +2906,14 @@ rxq_create_qp(struct rxq *rxq,
  *   Thresholds parameters.
  * @param mp
  *   Memory pool for buffer allocations.
- * @param children_n
- *   The number of children in a parent case, zero for a child.
- * @param rxq_parent
- *   The pointer to a parent RX structure (or NULL) in a child case,
- *   NULL for parent.
  *
  * @return
  *   0 on success, errno value on failure.
  */
 static int
 rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
-	  unsigned int socket, int inactive,
-	  const struct rte_eth_rxconf *conf,
-	  struct rte_mempool *mp, int children_n,
-	  struct rxq *rxq_parent)
+	  unsigned int socket, int inactive, const struct rte_eth_rxconf *conf,
+	  struct rte_mempool *mp)
 {
 	struct priv *priv = dev->data->dev_private;
 	struct rxq tmpl = {
@@ -3107,15 +2921,17 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 		.mp = mp,
 		.socket = socket
 	};
+	struct ibv_exp_qp_attr mod;
 	union {
 		struct ibv_exp_query_intf_params params;
 		struct ibv_exp_cq_init_attr cq;
 		struct ibv_exp_res_domain_init_attr rd;
 	} attr;
 	enum ibv_exp_query_intf_status status;
+	struct ibv_recv_wr *bad_wr;
 	unsigned int mb_len;
 	int ret = 0;
-	int parent = (children_n > 0);
+	int parent = (rxq == &priv->rxq_parent);
 
 	(void)conf; /* Thresholds configuration (ignored). */
 	/*
@@ -3206,6 +3022,32 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	      priv->device_attr.max_qp_wr);
 	DEBUG("priv->device_attr.max_sge is %d",
 	      priv->device_attr.max_sge);
+	if (priv->rss && !inactive)
+		tmpl.qp = rxq_setup_qp_rss(priv, tmpl.cq, desc, parent,
+					   tmpl.rd);
+	else
+		tmpl.qp = rxq_setup_qp(priv, tmpl.cq, desc, tmpl.rd);
+	if (tmpl.qp == NULL) {
+		ret = (errno ? errno : EINVAL);
+		ERROR("%p: QP creation failure: %s",
+		      (void *)dev, strerror(ret));
+		goto error;
+	}
+	mod = (struct ibv_exp_qp_attr){
+		/* Move the QP to this state. */
+		.qp_state = IBV_QPS_INIT,
+		/* Primary port number. */
+		.port_num = priv->port
+	};
+	ret = ibv_exp_modify_qp(tmpl.qp, &mod,
+				(IBV_EXP_QP_STATE |
+				 (parent ? IBV_EXP_QP_GROUP_RSS : 0) |
+				 IBV_EXP_QP_PORT));
+	if (ret) {
+		ERROR("%p: QP state to IBV_QPS_INIT failed: %s",
+		      (void *)dev, strerror(ret));
+		goto error;
+	}
 	/* Allocate descriptors for RX queues, except for the RSS parent. */
 	if (parent)
 		goto skip_alloc;
@@ -3216,14 +3058,29 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	if (ret) {
 		ERROR("%p: RXQ allocation failed: %s",
 		      (void *)dev, strerror(ret));
-		return ret;
+		goto error;
+	}
+	ret = ibv_post_recv(tmpl.qp,
+			    (tmpl.sp ?
+			     &(*tmpl.elts.sp)[0].wr :
+			     &(*tmpl.elts.no_sp)[0].wr),
+			    &bad_wr);
+	if (ret) {
+		ERROR("%p: ibv_post_recv() failed for WR %p: %s",
+		      (void *)dev,
+		      (void *)bad_wr,
+		      strerror(ret));
+		goto error;
 	}
 skip_alloc:
-	if (parent || rxq_parent || !priv->rss) {
-		ret = rxq_create_qp(&tmpl, desc, inactive,
-				    children_n, rxq_parent);
-		if (ret)
-			goto error;
+	mod = (struct ibv_exp_qp_attr){
+		.qp_state = IBV_QPS_RTR
+	};
+	ret = ibv_exp_modify_qp(tmpl.qp, &mod, IBV_EXP_QP_STATE);
+	if (ret) {
+		ERROR("%p: QP state to IBV_QPS_RTR failed: %s",
+		      (void *)dev, strerror(ret));
+		goto error;
 	}
 	/* Save port ID. */
 	tmpl.port_id = dev->data->port_id;
@@ -3235,11 +3092,21 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	};
 	tmpl.if_cq = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
 	if (tmpl.if_cq == NULL) {
-		ret = EINVAL;
 		ERROR("%p: CQ interface family query failed with status %d",
 		      (void *)dev, status);
 		goto error;
 	}
+	attr.params = (struct ibv_exp_query_intf_params){
+		.intf_scope = IBV_EXP_INTF_GLOBAL,
+		.intf = IBV_EXP_INTF_QP_BURST,
+		.obj = tmpl.qp,
+	};
+	tmpl.if_qp = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
+	if (tmpl.if_qp == NULL) {
+		ERROR("%p: QP interface family query failed with status %d",
+		      (void *)dev, status);
+		goto error;
+	}
 	/* Clean up rxq in case we're reinitializing it. */
 	DEBUG("%p: cleaning-up old rxq just in case", (void *)rxq);
 	rxq_cleanup(rxq);
@@ -3277,7 +3144,6 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		    unsigned int socket, const struct rte_eth_rxconf *conf,
 		    struct rte_mempool *mp)
 {
-	struct rxq *parent;
 	struct priv *priv = dev->data->dev_private;
 	struct rxq *rxq = (*priv->rxqs)[idx];
 	int inactive = 0;
@@ -3312,16 +3178,9 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 			return -ENOMEM;
 		}
 	}
-	if (priv->rss && !priv->isolated) {
-		/* The list consists of the single default one. */
-		parent = LIST_FIRST(&priv->parents);
-		if (idx >= rte_align32pow2(priv->rxqs_n + 1) >> 1)
-			inactive = 1;
-	} else {
-		parent = NULL;
-	}
-	ret = rxq_setup(dev, rxq, desc, socket,
-			inactive, conf, mp, 0, parent);
+	if (idx >= rte_align32pow2(priv->rxqs_n + 1) >> 1)
+		inactive = 1;
+	ret = rxq_setup(dev, rxq, desc, socket, inactive, conf, mp);
 	if (ret)
 		rte_free(rxq);
 	else {
@@ -3356,6 +3215,7 @@ mlx4_rx_queue_release(void *dpdk_rxq)
 		return;
 	priv = rxq->priv;
 	priv_lock(priv);
+	assert(rxq != &priv->rxq_parent);
 	for (i = 0; (i != priv->rxqs_n); ++i)
 		if ((*priv->rxqs)[i] == rxq) {
 			DEBUG("%p: removing RX queue %p from list",
@@ -3581,7 +3441,7 @@ mlx4_dev_close(struct rte_eth_dev *dev)
 		priv->txqs = NULL;
 	}
 	if (priv->rss)
-		priv_parent_list_cleanup(priv);
+		rxq_cleanup(&priv->rxq_parent);
 	if (priv->pd != NULL) {
 		assert(priv->ctx != NULL);
 		claim_zero(ibv_dealloc_pd(priv->pd));
drivers/net/mlx4/mlx4.h +1 -16
index b76bf48..b7177d4 100644
@@ -163,7 +163,6 @@ struct rxq_elt {
 
 /* RX queue descriptor. */
 struct rxq {
-	LIST_ENTRY(rxq) next; /* Used by parent queue only */
 	struct priv *priv; /* Back pointer to private data. */
 	struct rte_mempool *mp; /* Memory Pool for allocations. */
 	struct ibv_mr *mr; /* Memory Region (for mp). */
@@ -185,10 +184,6 @@ struct rxq {
 	struct mlx4_rxq_stats stats; /* RX queue counters. */
 	unsigned int socket; /* CPU socket ID for allocations. */
 	struct ibv_exp_res_domain *rd; /* Resource Domain. */
-	struct {
-		uint16_t queues_n;
-		uint16_t queues[RTE_MAX_QUEUES_PER_PORT];
-	} rss;
 };
 
 /* TX element. */
@@ -265,6 +260,7 @@ struct priv {
 	unsigned int inl_recv_size; /* Inline recv size */
 	unsigned int max_rss_tbl_sz; /* Maximum number of RSS queues. */
 	/* RX/TX queues. */
+	struct rxq rxq_parent; /* Parent queue when RSS is enabled. */
 	unsigned int rxqs_n; /* RX queues array size. */
 	unsigned int txqs_n; /* TX queues array size. */
 	struct rxq *(*rxqs)[]; /* RX queues. */
@@ -274,21 +270,10 @@ struct priv {
 	struct rte_flow_drop *flow_drop_queue; /* Flow drop queue. */
 	LIST_HEAD(mlx4_flows, rte_flow) flows;
 	struct rte_intr_conf intr_conf; /* Active interrupt configuration. */
-	LIST_HEAD(mlx4_parents, rxq) parents;
 	rte_spinlock_t lock; /* Lock for control functions. */
 };
 
 void priv_lock(struct priv *priv);
 void priv_unlock(struct priv *priv);
 
-int
-rxq_create_qp(struct rxq *rxq,
-	      uint16_t desc,
-	      int inactive,
-	      int children_n,
-	      struct rxq *rxq_parent);
-
-void
-rxq_parent_cleanup(struct rxq *parent);
-
 #endif /* RTE_PMD_MLX4_H_ */
drivers/net/mlx4/mlx4_flow.c +0 -15
index 827115e..2c5dc3c 100644
@@ -828,23 +828,8 @@ priv_flow_create_action_queue(struct priv *priv,
 	if (action->drop) {
 		qp = priv->flow_drop_queue ? priv->flow_drop_queue->qp : NULL;
 	} else {
-		int ret;
 		struct rxq *rxq = (*priv->rxqs)[action->queue_id];
 
-		if (!rxq->qp) {
-			assert(priv->isolated);
-			ret = rxq_create_qp(rxq, rxq->elts_n,
-					    0, 0, NULL);
-			if (ret) {
-				rte_flow_error_set(
-					error,
-					ENOMEM,
-					RTE_FLOW_ERROR_TYPE_HANDLE,
-					NULL,
-					"flow rule creation failure");
-				goto error;
-			}
-		}
 		qp = rxq->qp;
 		rte_flow->qp = qp;
 	}
Signature · 1 line
2.1.4
#71 lore raw

PATCH v2 16/51 net/mlx4: drop RSS support

In reply to Adrien Mazarguil

The Verbs RSS API used in this PMD is now obsolete. It is superseded by an enhanced API with fewer constraints already used in the mlx5 PMD.

Drop RSS support in preparation for a major refactoring. The ability to configure several Rx queues is retained, these can be targeted directly by creating specific flow rules.

There is no need for "ignored" Rx queues anymore since their number is no longer limited to powers of two.

---
 doc/guides/nics/features/mlx4.ini |   1 -
 doc/guides/nics/mlx4.rst          |  13 --
 drivers/net/mlx4/mlx4.c           | 212 +++------------------------------
 drivers/net/mlx4/mlx4.h           |   6 -
 4 files changed, 14 insertions(+), 218 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -1
index 3acf8d3..aa1ad21 100644
@@ -13,7 +13,6 @@ Queue start/stop     = Y
 MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
-RSS hash             = Y
 SR-IOV               = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
doc/guides/nics/mlx4.rst +0 -13
index d3d51f7..9ab9a05 100644
@@ -78,22 +78,12 @@ Features
 --------
 
 - Multi arch support: x86_64 and POWER8.
-- RSS, also known as RCA, is supported. In this mode the number of
-  configured RX queues must be a power of two.
 - Link state information is provided.
 - Scattered packets are supported for TX and RX.
 - Inner L3/L4 (IP, TCP and UDP) TX/RX checksum offloading and validation.
 - Outer L3 (IP) TX/RX checksum offloading and validation for VXLAN frames.
 - RX interrupts.
 
-Limitations
------------
-
-- RSS hash key cannot be modified.
-- RSS RETA cannot be configured
-- RSS always includes L3 (IPv4/IPv6) and L4 (UDP/TCP). They cannot be
-  dissociated.
-
 Configuration
 -------------
 
@@ -145,9 +135,6 @@ Environment variables
 Run-time configuration
 ~~~~~~~~~~~~~~~~~~~~~~
 
-- The only constraint when RSS mode is requested is to make sure the number
-  of RX queues is a power of two. This is a hardware requirement.
-
 - librte_pmd_mlx4 brings kernel network interfaces up during initialization
   because it is affected by their state. Forcing them down prevents packets
   reception.
drivers/net/mlx4/mlx4.c +14 -198

362 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +0 -6
index b7177d4..8a16b1e 100644
@@ -248,19 +248,13 @@ struct priv {
 	uint16_t mtu; /* Configured MTU. */
 	uint8_t port; /* Physical port number. */
 	unsigned int started:1; /* Device started, flows enabled. */
-	unsigned int hw_qpg:1; /* QP groups are supported. */
-	unsigned int hw_tss:1; /* TSS is supported. */
-	unsigned int hw_rss:1; /* RSS is supported. */
 	unsigned int hw_csum:1; /* Checksum offload is supported. */
 	unsigned int hw_csum_l2tun:1; /* Same for L2 tunnels. */
-	unsigned int rss:1; /* RSS is enabled. */
 	unsigned int vf:1; /* This is a VF device. */
 	unsigned int pending_alarm:1; /* An alarm is pending. */
 	unsigned int isolated:1; /* Toggle isolated mode. */
 	unsigned int inl_recv_size; /* Inline recv size */
-	unsigned int max_rss_tbl_sz; /* Maximum number of RSS queues. */
 	/* RX/TX queues. */
-	struct rxq rxq_parent; /* Parent queue when RSS is enabled. */
 	unsigned int rxqs_n; /* RX queues array size. */
 	unsigned int txqs_n; /* TX queues array size. */
 	struct rxq *(*rxqs)[]; /* RX queues. */
Signature · 1 line
2.1.4
#72 lore raw

PATCH v2 17/51 net/mlx4: drop checksum offloads support

In reply to Adrien Mazarguil

The Verbs API used to implement Tx and Rx checksum offloads is deprecated. Support for these will be added back after refactoring the PMD.

---
 doc/guides/nics/features/mlx4.ini |  4 --
 doc/guides/nics/mlx4.rst          |  2 -
 drivers/net/mlx4/mlx4.c           | 91 ++--------------------------------
 drivers/net/mlx4/mlx4.h           |  4 --
 4 files changed, 4 insertions(+), 97 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -4
index aa1ad21..08a2e17 100644
@@ -14,10 +14,6 @@ MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
 SR-IOV               = Y
-L3 checksum offload  = Y
-L4 checksum offload  = Y
-Inner L3 checksum    = Y
-Inner L4 checksum    = Y
 Packet type parsing  = Y
 Basic stats          = Y
 Stats per queue      = Y
doc/guides/nics/mlx4.rst +0 -2
index 9ab9a05..754b2d0 100644
@@ -80,8 +80,6 @@ Features
 - Multi arch support: x86_64 and POWER8.
 - Link state information is provided.
 - Scattered packets are supported for TX and RX.
-- Inner L3/L4 (IP, TCP and UDP) TX/RX checksum offloading and validation.
-- Outer L3 (IP) TX/RX checksum offloading and validation for VXLAN frames.
 - RX interrupts.
 
 Configuration
drivers/net/mlx4/mlx4.c +4 -87

139 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +0 -4
index 8a16b1e..d1104c3 100644
@@ -179,8 +179,6 @@ struct rxq {
 		struct rxq_elt (*no_sp)[]; /* RX elements. */
 	} elts;
 	unsigned int sp:1; /* Use scattered RX elements. */
-	unsigned int csum:1; /* Enable checksum offloading. */
-	unsigned int csum_l2tun:1; /* Same for L2 tunnels. */
 	struct mlx4_rxq_stats stats; /* RX queue counters. */
 	unsigned int socket; /* CPU socket ID for allocations. */
 	struct ibv_exp_res_domain *rd; /* Resource Domain. */
@@ -248,8 +246,6 @@ struct priv {
 	uint16_t mtu; /* Configured MTU. */
 	uint8_t port; /* Physical port number. */
 	unsigned int started:1; /* Device started, flows enabled. */
-	unsigned int hw_csum:1; /* Checksum offload is supported. */
-	unsigned int hw_csum_l2tun:1; /* Same for L2 tunnels. */
 	unsigned int vf:1; /* This is a VF device. */
 	unsigned int pending_alarm:1; /* An alarm is pending. */
 	unsigned int isolated:1; /* Toggle isolated mode. */
Signature · 1 line
2.1.4
#73 lore raw

PATCH v2 18/51 net/mlx4: drop packet type recognition support

In reply to Adrien Mazarguil

The Verbs API used to implement packet type recognition is deprecated. Support will be added back after refactoring the PMD.

---
 doc/guides/nics/features/mlx4.ini |  1 -
 drivers/net/mlx4/mlx4.c           | 70 +---------------------------------
 2 files changed, 2 insertions(+), 69 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -1
index 08a2e17..27c7ae3 100644
@@ -14,7 +14,6 @@ MTU update           = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
 SR-IOV               = Y
-Packet type parsing  = Y
 Basic stats          = Y
 Stats per queue      = Y
 Other kdrv           = Y
drivers/net/mlx4/mlx4.c +2 -68

106 lines not on this page · raw message

Signature · 1 line
2.1.4
#74 lore raw

PATCH v2 19/51 net/mlx4: drop scatter/gather support

In reply to Adrien Mazarguil

The Verbs API used to implement Tx and Rx burst functions is deprecated. Drop scatter/gather support to ease refactoring while maintaining basic single-segment Rx/Tx functionality in the meantime.

---
 doc/guides/nics/features/mlx4.ini |   1 -
 doc/guides/nics/mlx4.rst          |   1 -
 drivers/net/mlx4/mlx4.c           | 860 +--------------------------------
 drivers/net/mlx4/mlx4.h           |  28 +-
 4 files changed, 26 insertions(+), 864 deletions(-)
doc/guides/nics/features/mlx4.ini +0 -1
index 27c7ae3..0812a30 100644
@@ -12,7 +12,6 @@ Rx interrupt         = Y
 Queue start/stop     = Y
 MTU update           = Y
 Jumbo frame          = Y
-Scattered Rx         = Y
 SR-IOV               = Y
 Basic stats          = Y
 Stats per queue      = Y
doc/guides/nics/mlx4.rst +0 -1
index 754b2d0..5c3fb76 100644
@@ -79,7 +79,6 @@ Features
 
 - Multi arch support: x86_64 and POWER8.
 - Link state information is provided.
-- Scattered packets are supported for TX and RX.
 - RX interrupts.
 
 Configuration
drivers/net/mlx4/mlx4.c +25 -835

1,073 lines not on this page · raw message

drivers/net/mlx4/mlx4.h +1 -27
index d1104c3..cc36d29 100644
@@ -66,9 +66,6 @@
 /* Request send completion once in every 64 sends, might be less. */
 #define MLX4_PMD_TX_PER_COMP_REQ 64
 
-/* Maximum number of Scatter/Gather Elements per Work Request. */
-#define MLX4_PMD_SGE_WR_N 4
-
 /* Maximum size for inline data. */
 #define MLX4_PMD_MAX_INLINE 0
 
@@ -147,13 +144,6 @@ struct mlx4_rxq_stats {
 	uint64_t rx_nombuf; /**< Total of RX mbuf allocation failures. */
 };
 
-/* RX element (scattered packets). */
-struct rxq_elt_sp {
-	struct ibv_recv_wr wr; /* Work Request. */
-	struct ibv_sge sges[MLX4_PMD_SGE_WR_N]; /* Scatter/Gather Elements. */
-	struct rte_mbuf *bufs[MLX4_PMD_SGE_WR_N]; /* SGEs buffers. */
-};
-
 /* RX element. */
 struct rxq_elt {
 	struct ibv_recv_wr wr; /* Work Request. */
@@ -174,11 +164,7 @@ struct rxq {
 	unsigned int port_id; /* Port ID for incoming packets. */
 	unsigned int elts_n; /* (*elts)[] length. */
 	unsigned int elts_head; /* Current index in (*elts)[]. */
-	union {
-		struct rxq_elt_sp (*sp)[]; /* Scattered RX elements. */
-		struct rxq_elt (*no_sp)[]; /* RX elements. */
-	} elts;
-	unsigned int sp:1; /* Use scattered RX elements. */
+	struct rxq_elt (*elts)[]; /* Rx elements. */
 	struct mlx4_rxq_stats stats; /* RX queue counters. */
 	unsigned int socket; /* CPU socket ID for allocations. */
 	struct ibv_exp_res_domain *rd; /* Resource Domain. */
@@ -196,16 +182,6 @@ struct mlx4_txq_stats {
 	uint64_t odropped; /**< Total of packets not sent when TX ring full. */
 };
 
-/*
- * Linear buffer type. It is used when transmitting buffers with too many
- * segments that do not fit the hardware queue (see max_send_sge).
- * Extra segments are copied (linearized) in such buffers, replacing the
- * last SGE during TX.
- * The size is arbitrary but large enough to hold a jumbo frame with
- * 8 segments considering mbuf.buf_len is about 2048 bytes.
- */
-typedef uint8_t linear_t[16384];
-
 /* TX queue descriptor. */
 struct txq {
 	struct priv *priv; /* Back pointer to private data. */
@@ -227,8 +203,6 @@ struct txq {
 	unsigned int elts_comp_cd; /* Countdown for next completion request. */
 	unsigned int elts_comp_cd_init; /* Initial value for countdown. */
 	struct mlx4_txq_stats stats; /* TX queue counters. */
-	linear_t (*elts_linear)[]; /* Linearized buffers. */
-	struct ibv_mr *mr_linear; /* Memory Region for linearized buffers. */
 	unsigned int socket; /* CPU socket ID for allocations. */
 	struct ibv_exp_res_domain *rd; /* Resource Domain. */
 };
Signature · 1 line
2.1.4
#75 lore raw

PATCH v2 20/51 net/mlx4: drop inline receive support

In reply to Adrien Mazarguil

The Verbs API used to implement inline receive is deprecated. Support will be added back after refactoring the PMD.

---
 drivers/net/mlx4/mlx4.c | 52 --------------------------------------------
 drivers/net/mlx4/mlx4.h |  1 -
 2 files changed, 53 deletions(-)
drivers/net/mlx4/mlx4.c +0 -52
index 0a71e2c..30c70ee 100644
@@ -1914,8 +1914,6 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
 		.res_domain = rd,
 	};
 
-	attr.max_inl_recv = priv->inl_recv_size,
-	attr.comp_mask |= IBV_EXP_QP_INIT_ATTR_INL_RECV;
 	return ibv_exp_create_qp(priv->ctx, &attr);
 }
 
@@ -2977,25 +2975,6 @@ priv_get_mac(struct priv *priv, uint8_t (*mac)[ETHER_ADDR_LEN])
 	return 0;
 }
 
-/**
- * Retrieve integer value from environment variable.
- *
- * @param[in] name
- *   Environment variable name.
- *
- * @return
- *   Integer value, 0 if the variable is not set.
- */
-static int
-mlx4_getenv_int(const char *name)
-{
-	const char *val = getenv(name);
-
-	if (val == NULL)
-		return 0;
-	return atoi(val);
-}
-
 static void
 mlx4_dev_link_status_handler(void *);
 static void
@@ -3644,13 +3623,11 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		struct ibv_pd *pd = NULL;
 		struct priv *priv = NULL;
 		struct rte_eth_dev *eth_dev = NULL;
-		struct ibv_exp_device_attr exp_device_attr;
 		struct ether_addr mac;
 
 		/* If port is not enabled, skip. */
 		if (!(conf.ports.enabled & (1 << i)))
 			continue;
-		exp_device_attr.comp_mask = IBV_EXP_DEVICE_ATTR_EXP_CAP_FLAGS;
 
 		DEBUG("using port %u", port);
 
@@ -3703,35 +3680,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		priv->port = port;
 		priv->pd = pd;
 		priv->mtu = ETHER_MTU;
-		if (ibv_exp_query_device(ctx, &exp_device_attr)) {
-			ERROR("ibv_exp_query_device() failed");
-			err = ENODEV;
-			goto port_error;
-		}
-
-		priv->inl_recv_size = mlx4_getenv_int("MLX4_INLINE_RECV_SIZE");
-
-		if (priv->inl_recv_size) {
-			exp_device_attr.comp_mask =
-				IBV_EXP_DEVICE_ATTR_INLINE_RECV_SZ;
-			if (ibv_exp_query_device(ctx, &exp_device_attr)) {
-				INFO("Couldn't query device for inline-receive"
-				     " capabilities.");
-				priv->inl_recv_size = 0;
-			} else {
-				if ((unsigned)exp_device_attr.inline_recv_sz <
-				    priv->inl_recv_size) {
-					INFO("Max inline-receive (%d) <"
-					     " requested inline-receive (%u)",
-					     exp_device_attr.inline_recv_sz,
-					     priv->inl_recv_size);
-					priv->inl_recv_size =
-						exp_device_attr.inline_recv_sz;
-				}
-			}
-			INFO("Set inline receive size to %u",
-			     priv->inl_recv_size);
-		}
 
 		priv->vf = vf;
 		/* Configure the first MAC address by default. */
drivers/net/mlx4/mlx4.h +0 -1
index cc36d29..9cbde1d 100644
@@ -223,7 +223,6 @@ struct priv {
 	unsigned int vf:1; /* This is a VF device. */
 	unsigned int pending_alarm:1; /* An alarm is pending. */
 	unsigned int isolated:1; /* Toggle isolated mode. */
-	unsigned int inl_recv_size; /* Inline recv size */
 	/* RX/TX queues. */
 	unsigned int rxqs_n; /* RX queues array size. */
 	unsigned int txqs_n; /* TX queues array size. */
Signature · 1 line
2.1.4
#76 lore raw

PATCH v2 21/51 net/mlx4: use standard QP attributes

In reply to Adrien Mazarguil

The Verbs API used to set QP attributes is deprecated. Revert to the standard API since it actually supports the remaining ones.

---
 drivers/net/mlx4/mlx4.c | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)
drivers/net/mlx4/mlx4.c +11 -14
index 30c70ee..682307f 100644
@@ -1178,7 +1178,7 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		struct ibv_exp_qp_init_attr init;
 		struct ibv_exp_res_domain_init_attr rd;
 		struct ibv_exp_cq_init_attr cq;
-		struct ibv_exp_qp_attr mod;
+		struct ibv_qp_attr mod;
 	} attr;
 	enum ibv_exp_query_intf_status status;
 	int ret = 0;
@@ -1251,14 +1251,13 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 	}
 	/* ibv_create_qp() updates this value. */
 	tmpl.max_inline = attr.init.cap.max_inline_data;
-	attr.mod = (struct ibv_exp_qp_attr){
+	attr.mod = (struct ibv_qp_attr){
 		/* Move the QP to this state. */
 		.qp_state = IBV_QPS_INIT,
 		/* Primary port number. */
 		.port_num = priv->port
 	};
-	ret = ibv_exp_modify_qp(tmpl.qp, &attr.mod,
-				(IBV_EXP_QP_STATE | IBV_EXP_QP_PORT));
+	ret = ibv_modify_qp(tmpl.qp, &attr.mod, IBV_QP_STATE | IBV_QP_PORT);
 	if (ret) {
 		ERROR("%p: QP state to IBV_QPS_INIT failed: %s",
 		      (void *)dev, strerror(ret));
@@ -1270,17 +1269,17 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		      (void *)dev, strerror(ret));
 		goto error;
 	}
-	attr.mod = (struct ibv_exp_qp_attr){
+	attr.mod = (struct ibv_qp_attr){
 		.qp_state = IBV_QPS_RTR
 	};
-	ret = ibv_exp_modify_qp(tmpl.qp, &attr.mod, IBV_EXP_QP_STATE);
+	ret = ibv_modify_qp(tmpl.qp, &attr.mod, IBV_QP_STATE);
 	if (ret) {
 		ERROR("%p: QP state to IBV_QPS_RTR failed: %s",
 		      (void *)dev, strerror(ret));
 		goto error;
 	}
 	attr.mod.qp_state = IBV_QPS_RTS;
-	ret = ibv_exp_modify_qp(tmpl.qp, &attr.mod, IBV_EXP_QP_STATE);
+	ret = ibv_modify_qp(tmpl.qp, &attr.mod, IBV_QP_STATE);
 	if (ret) {
 		ERROR("%p: QP state to IBV_QPS_RTS failed: %s",
 		      (void *)dev, strerror(ret));
@@ -1947,7 +1946,7 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 		.mp = mp,
 		.socket = socket
 	};
-	struct ibv_exp_qp_attr mod;
+	struct ibv_qp_attr mod;
 	union {
 		struct ibv_exp_query_intf_params params;
 		struct ibv_exp_cq_init_attr cq;
@@ -2035,15 +2034,13 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 		      (void *)dev, strerror(ret));
 		goto error;
 	}
-	mod = (struct ibv_exp_qp_attr){
+	mod = (struct ibv_qp_attr){
 		/* Move the QP to this state. */
 		.qp_state = IBV_QPS_INIT,
 		/* Primary port number. */
 		.port_num = priv->port
 	};
-	ret = ibv_exp_modify_qp(tmpl.qp, &mod,
-				IBV_EXP_QP_STATE |
-				IBV_EXP_QP_PORT);
+	ret = ibv_modify_qp(tmpl.qp, &mod, IBV_QP_STATE | IBV_QP_PORT);
 	if (ret) {
 		ERROR("%p: QP state to IBV_QPS_INIT failed: %s",
 		      (void *)dev, strerror(ret));
@@ -2063,10 +2060,10 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 		      strerror(ret));
 		goto error;
 	}
-	mod = (struct ibv_exp_qp_attr){
+	mod = (struct ibv_qp_attr){
 		.qp_state = IBV_QPS_RTR
 	};
-	ret = ibv_exp_modify_qp(tmpl.qp, &mod, IBV_EXP_QP_STATE);
+	ret = ibv_modify_qp(tmpl.qp, &mod, IBV_QP_STATE);
 	if (ret) {
 		ERROR("%p: QP state to IBV_QPS_RTR failed: %s",
 		      (void *)dev, strerror(ret));
Signature · 1 line
2.1.4
#77 lore raw

PATCH v2 22/51 net/mlx4: revert resource domain support

In reply to Adrien Mazarguil

This reverts commit 3e49c148b715c3c0a12c1200295bb9b312f7028e.

Resource domains are not part of the standard Verbs interface. The performance improvement they bring will be restored later through a different data path implementation.

This commit makes the PMD not rely on the non-standard QP allocation interface.

---
 drivers/net/mlx4/mlx4.c      | 88 ++++-----------------------------------
 drivers/net/mlx4/mlx4.h      |  2 -
 drivers/net/mlx4/mlx4_flow.c | 30 +++++--------
 3 files changed, 20 insertions(+), 100 deletions(-)
drivers/net/mlx4/mlx4.c +9 -79
index 682307f..7dbed93 100644
@@ -697,17 +697,6 @@ txq_cleanup(struct txq *txq)
 		claim_zero(ibv_destroy_qp(txq->qp));
 	if (txq->cq != NULL)
 		claim_zero(ibv_destroy_cq(txq->cq));
-	if (txq->rd != NULL) {
-		struct ibv_exp_destroy_res_domain_attr attr = {
-			.comp_mask = 0,
-		};
-
-		assert(txq->priv != NULL);
-		assert(txq->priv->ctx != NULL);
-		claim_zero(ibv_exp_destroy_res_domain(txq->priv->ctx,
-						      txq->rd,
-						      &attr));
-	}
 	for (i = 0; (i != elemof(txq->mp2mr)); ++i) {
 		if (txq->mp2mr[i].mp == NULL)
 			break;
@@ -1175,9 +1164,7 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 	};
 	union {
 		struct ibv_exp_query_intf_params params;
-		struct ibv_exp_qp_init_attr init;
-		struct ibv_exp_res_domain_init_attr rd;
-		struct ibv_exp_cq_init_attr cq;
+		struct ibv_qp_init_attr init;
 		struct ibv_qp_attr mod;
 	} attr;
 	enum ibv_exp_query_intf_status status;
@@ -1191,24 +1178,7 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		return EINVAL;
 	}
 	/* MRs will be registered in mp2mr[] later. */
-	attr.rd = (struct ibv_exp_res_domain_init_attr){
-		.comp_mask = (IBV_EXP_RES_DOMAIN_THREAD_MODEL |
-			      IBV_EXP_RES_DOMAIN_MSG_MODEL),
-		.thread_model = IBV_EXP_THREAD_SINGLE,
-		.msg_model = IBV_EXP_MSG_HIGH_BW,
-	};
-	tmpl.rd = ibv_exp_create_res_domain(priv->ctx, &attr.rd);
-	if (tmpl.rd == NULL) {
-		ret = ENOMEM;
-		ERROR("%p: RD creation failure: %s",
-		      (void *)dev, strerror(ret));
-		goto error;
-	}
-	attr.cq = (struct ibv_exp_cq_init_attr){
-		.comp_mask = IBV_EXP_CQ_INIT_ATTR_RES_DOMAIN,
-		.res_domain = tmpl.rd,
-	};
-	tmpl.cq = ibv_exp_create_cq(priv->ctx, desc, NULL, NULL, 0, &attr.cq);
+	tmpl.cq = ibv_create_cq(priv->ctx, desc, NULL, NULL, 0);
 	if (tmpl.cq == NULL) {
 		ret = ENOMEM;
 		ERROR("%p: CQ creation failure: %s",
@@ -1219,7 +1189,7 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 	      priv->device_attr.max_qp_wr);
 	DEBUG("priv->device_attr.max_sge is %d",
 	      priv->device_attr.max_sge);
-	attr.init = (struct ibv_exp_qp_init_attr){
+	attr.init = (struct ibv_qp_init_attr){
 		/* CQ to be associated with the send queue. */
 		.send_cq = tmpl.cq,
 		/* CQ to be associated with the receive queue. */
@@ -1237,12 +1207,8 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		/* Do *NOT* enable this, completions events are managed per
 		 * TX burst. */
 		.sq_sig_all = 0,
-		.pd = priv->pd,
-		.res_domain = tmpl.rd,
-		.comp_mask = (IBV_EXP_QP_INIT_ATTR_PD |
-			      IBV_EXP_QP_INIT_ATTR_RES_DOMAIN),
 	};
-	tmpl.qp = ibv_exp_create_qp(priv->ctx, &attr.init);
+	tmpl.qp = ibv_create_qp(priv->pd, &attr.init);
 	if (tmpl.qp == NULL) {
 		ret = (errno ? errno : EINVAL);
 		ERROR("%p: QP creation failure: %s",
@@ -1710,17 +1676,6 @@ rxq_cleanup(struct rxq *rxq)
 		claim_zero(ibv_destroy_cq(rxq->cq));
 	if (rxq->channel != NULL)
 		claim_zero(ibv_destroy_comp_channel(rxq->channel));
-	if (rxq->rd != NULL) {
-		struct ibv_exp_destroy_res_domain_attr attr = {
-			.comp_mask = 0,
-		};
-
-		assert(rxq->priv != NULL);
-		assert(rxq->priv->ctx != NULL);
-		claim_zero(ibv_exp_destroy_res_domain(rxq->priv->ctx,
-						      rxq->rd,
-						      &attr));
-	}
 	if (rxq->mr != NULL)
 		claim_zero(ibv_dereg_mr(rxq->mr));
 	memset(rxq, 0, sizeof(*rxq));
@@ -1890,10 +1845,9 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
  *   QP pointer or NULL in case of error.
  */
 static struct ibv_qp *
-rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
-	     struct ibv_exp_res_domain *rd)
+rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc)
 {
-	struct ibv_exp_qp_init_attr attr = {
+	struct ibv_qp_init_attr attr = {
 		/* CQ to be associated with the send queue. */
 		.send_cq = cq,
 		/* CQ to be associated with the receive queue. */
@@ -1907,13 +1861,9 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,
 			.max_recv_sge = 1,
 		},
 		.qp_type = IBV_QPT_RAW_PACKET,
-		.comp_mask = (IBV_EXP_QP_INIT_ATTR_PD |
-			      IBV_EXP_QP_INIT_ATTR_RES_DOMAIN),
-		.pd = priv->pd,
-		.res_domain = rd,
 	};
 
-	return ibv_exp_create_qp(priv->ctx, &attr);
+	return ibv_create_qp(priv->pd, &attr);
 }
 
 /**
@@ -1949,8 +1899,6 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	struct ibv_qp_attr mod;
 	union {
 		struct ibv_exp_query_intf_params params;
-		struct ibv_exp_cq_init_attr cq;
-		struct ibv_exp_res_domain_init_attr rd;
 	} attr;
 	enum ibv_exp_query_intf_status status;
 	struct ibv_recv_wr *bad_wr;
@@ -1988,19 +1936,6 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 		      (void *)dev, strerror(ret));
 		goto error;
 	}
-	attr.rd = (struct ibv_exp_res_domain_init_attr){
-		.comp_mask = (IBV_EXP_RES_DOMAIN_THREAD_MODEL |
-			      IBV_EXP_RES_DOMAIN_MSG_MODEL),
-		.thread_model = IBV_EXP_THREAD_SINGLE,
-		.msg_model = IBV_EXP_MSG_HIGH_BW,
-	};
-	tmpl.rd = ibv_exp_create_res_domain(priv->ctx, &attr.rd);
-	if (tmpl.rd == NULL) {
-		ret = ENOMEM;
-		ERROR("%p: RD creation failure: %s",
-		      (void *)dev, strerror(ret));
-		goto error;
-	}
 	if (dev->data->dev_conf.intr_conf.rxq) {
 		tmpl.channel = ibv_create_comp_channel(priv->ctx);
 		if (tmpl.channel == NULL) {
@@ -2011,12 +1946,7 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 			goto error;
 		}
 	}
-	attr.cq = (struct ibv_exp_cq_init_attr){
-		.comp_mask = IBV_EXP_CQ_INIT_ATTR_RES_DOMAIN,
-		.res_domain = tmpl.rd,
-	};
-	tmpl.cq = ibv_exp_create_cq(priv->ctx, desc, NULL, tmpl.channel, 0,
-				    &attr.cq);
+	tmpl.cq = ibv_create_cq(priv->ctx, desc, NULL, tmpl.channel, 0);
 	if (tmpl.cq == NULL) {
 		ret = ENOMEM;
 		ERROR("%p: CQ creation failure: %s",
@@ -2027,7 +1957,7 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	      priv->device_attr.max_qp_wr);
 	DEBUG("priv->device_attr.max_sge is %d",
 	      priv->device_attr.max_sge);
-	tmpl.qp = rxq_setup_qp(priv, tmpl.cq, desc, tmpl.rd);
+	tmpl.qp = rxq_setup_qp(priv, tmpl.cq, desc);
 	if (tmpl.qp == NULL) {
 		ret = (errno ? errno : EINVAL);
 		ERROR("%p: QP creation failure: %s",
drivers/net/mlx4/mlx4.h +0 -2
index 9cbde1d..edec40c 100644
@@ -167,7 +167,6 @@ struct rxq {
 	struct rxq_elt (*elts)[]; /* Rx elements. */
 	struct mlx4_rxq_stats stats; /* RX queue counters. */
 	unsigned int socket; /* CPU socket ID for allocations. */
-	struct ibv_exp_res_domain *rd; /* Resource Domain. */
 };
 
 /* TX element. */
@@ -204,7 +203,6 @@ struct txq {
 	unsigned int elts_comp_cd_init; /* Initial value for countdown. */
 	struct mlx4_txq_stats stats; /* TX queue counters. */
 	unsigned int socket; /* CPU socket ID for allocations. */
-	struct ibv_exp_res_domain *rd; /* Resource Domain. */
 };
 
 struct rte_flow;
drivers/net/mlx4/mlx4_flow.c +11 -19
index 2c5dc3c..58d4698 100644
@@ -752,29 +752,21 @@ mlx4_flow_create_drop_queue(struct priv *priv)
 		ERROR("Cannot allocate memory for drop struct");
 		goto err;
 	}
-	cq = ibv_exp_create_cq(priv->ctx, 1, NULL, NULL, 0,
-			      &(struct ibv_exp_cq_init_attr){
-					.comp_mask = 0,
-			      });
+	cq = ibv_create_cq(priv->ctx, 1, NULL, NULL, 0);
 	if (!cq) {
 		ERROR("Cannot create drop CQ");
 		goto err_create_cq;
 	}
-	qp = ibv_exp_create_qp(priv->ctx,
-			      &(struct ibv_exp_qp_init_attr){
-					.send_cq = cq,
-					.recv_cq = cq,
-					.cap = {
-						.max_recv_wr = 1,
-						.max_recv_sge = 1,
-					},
-					.qp_type = IBV_QPT_RAW_PACKET,
-					.comp_mask =
-						IBV_EXP_QP_INIT_ATTR_PD |
-						IBV_EXP_QP_INIT_ATTR_PORT,
-					.pd = priv->pd,
-					.port_num = priv->port,
-			      });
+	qp = ibv_create_qp(priv->pd,
+			   &(struct ibv_qp_init_attr){
+				.send_cq = cq,
+				.recv_cq = cq,
+				.cap = {
+					.max_recv_wr = 1,
+					.max_recv_sge = 1,
+				},
+				.qp_type = IBV_QPT_RAW_PACKET,
+			   });
 	if (!qp) {
 		ERROR("Cannot create drop QP");
 		goto err_create_qp;
Signature · 1 line
2.1.4
#78 lore raw

PATCH v2 23/51 net/mlx4: revert multicast echo prevention

In reply to Adrien Mazarguil

This reverts commit 8b3ffe95e75d6d305992505005cbb95969874a15.

Multicast loopback prevention is not part of the standard Verbs interface. Remove it temporarily.

---
 drivers/net/mlx4/Makefile | 6 +-----
 drivers/net/mlx4/mlx4.c   | 7 -------
 2 files changed, 1 insertion(+), 12 deletions(-)
drivers/net/mlx4/Makefile +1 -5
index bd713e2..20692f0 100644
@@ -91,11 +91,7 @@ mlx4_autoconf.h.new: FORCE
 
 mlx4_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 	$Q $(RM) -f -- '$@'
-	$Q sh -- '$<' '$@' \
-		HAVE_EXP_QP_BURST_CREATE_DISABLE_ETH_LOOPBACK \
-		infiniband/verbs.h \
-		enum IBV_EXP_QP_BURST_CREATE_DISABLE_ETH_LOOPBACK \
-		$(AUTOCONF_OUTPUT)
+	$Q : > '$@'
 
 # Create mlx4_autoconf.h or update it in case it differs from the new one.
 
drivers/net/mlx4/mlx4.c +0 -7
index 7dbed93..5abfb37 100644
@@ -1266,13 +1266,6 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		.intf_scope = IBV_EXP_INTF_GLOBAL,
 		.intf = IBV_EXP_INTF_QP_BURST,
 		.obj = tmpl.qp,
-#ifdef HAVE_EXP_QP_BURST_CREATE_DISABLE_ETH_LOOPBACK
-		/* MC loopback must be disabled when not using a VF. */
-		.family_flags =
-			(!priv->vf ?
-			 IBV_EXP_QP_BURST_CREATE_DISABLE_ETH_LOOPBACK :
-			 0),
-#endif
 	};
 	tmpl.if_qp = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
 	if (tmpl.if_qp == NULL) {
Signature · 1 line
2.1.4
#79 lore raw

PATCH v2 24/51 net/mlx4: revert fast Verbs interface for Tx

In reply to Adrien Mazarguil

This reverts commit 9980f81dc2623291b89cf1c281a6a9f116fd2394.

"Fast Verbs" is a nonstandard experimental interface that must be reverted for compatibility reasons. Its replacement is slower but temporary, performance will be restored by a subsequent commit through an enhanced data path implementation. This one focuses on maintaining basic functionality in the meantime.

---
 drivers/net/mlx4/mlx4.c | 120 ++++++++++++++++++-------------------------
 drivers/net/mlx4/mlx4.h |   4 +-
 2 files changed, 52 insertions(+), 72 deletions(-)
drivers/net/mlx4/mlx4.c +50 -70
index 5abfb37..4432952 100644
@@ -666,33 +666,10 @@ txq_free_elts(struct txq *txq)
 static void
 txq_cleanup(struct txq *txq)
 {
-	struct ibv_exp_release_intf_params params;
 	size_t i;
 
 	DEBUG("cleaning up %p", (void *)txq);
 	txq_free_elts(txq);
-	if (txq->if_qp != NULL) {
-		assert(txq->priv != NULL);
-		assert(txq->priv->ctx != NULL);
-		assert(txq->qp != NULL);
-		params = (struct ibv_exp_release_intf_params){
-			.comp_mask = 0,
-		};
-		claim_zero(ibv_exp_release_intf(txq->priv->ctx,
-						txq->if_qp,
-						&params));
-	}
-	if (txq->if_cq != NULL) {
-		assert(txq->priv != NULL);
-		assert(txq->priv->ctx != NULL);
-		assert(txq->cq != NULL);
-		params = (struct ibv_exp_release_intf_params){
-			.comp_mask = 0,
-		};
-		claim_zero(ibv_exp_release_intf(txq->priv->ctx,
-						txq->if_cq,
-						&params));
-	}
 	if (txq->qp != NULL)
 		claim_zero(ibv_destroy_qp(txq->qp));
 	if (txq->cq != NULL)
@@ -726,11 +703,12 @@ txq_complete(struct txq *txq)
 	unsigned int elts_comp = txq->elts_comp;
 	unsigned int elts_tail = txq->elts_tail;
 	const unsigned int elts_n = txq->elts_n;
+	struct ibv_wc wcs[elts_comp];
 	int wcs_n;
 
 	if (unlikely(elts_comp == 0))
 		return 0;
-	wcs_n = txq->if_cq->poll_cnt(txq->cq, elts_comp);
+	wcs_n = ibv_poll_cq(txq->cq, elts_comp, wcs);
 	if (unlikely(wcs_n == 0))
 		return 0;
 	if (unlikely(wcs_n < 0)) {
@@ -1014,6 +992,9 @@ static uint16_t
 mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 {
 	struct txq *txq = (struct txq *)dpdk_txq;
+	struct ibv_send_wr *wr_head = NULL;
+	struct ibv_send_wr **wr_next = &wr_head;
+	struct ibv_send_wr *wr_bad = NULL;
 	unsigned int elts_head = txq->elts_head;
 	const unsigned int elts_n = txq->elts_n;
 	unsigned int elts_comp_cd = txq->elts_comp_cd;
@@ -1041,6 +1022,7 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			(((elts_head + 1) == elts_n) ? 0 : elts_head + 1);
 		struct txq_elt *elt_next = &(*txq->elts)[elts_head_next];
 		struct txq_elt *elt = &(*txq->elts)[elts_head];
+		struct ibv_send_wr *wr = &elt->wr;
 		unsigned int segs = NB_SEGS(buf);
 		unsigned int sent_size = 0;
 		uint32_t send_flags = 0;
@@ -1065,9 +1047,10 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		if (unlikely(--elts_comp_cd == 0)) {
 			elts_comp_cd = txq->elts_comp_cd_init;
 			++elts_comp;
-			send_flags |= IBV_EXP_QP_BURST_SIGNALED;
+			send_flags |= IBV_SEND_SIGNALED;
 		}
 		if (likely(segs == 1)) {
+			struct ibv_sge *sge = &elt->sge;
 			uintptr_t addr;
 			uint32_t length;
 			uint32_t lkey;
@@ -1091,30 +1074,26 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 				rte_prefetch0((volatile void *)
 					      (uintptr_t)addr);
 			RTE_MBUF_PREFETCH_TO_FREE(elt_next->buf);
-			/* Put packet into send queue. */
-			if (length <= txq->max_inline)
-				err = txq->if_qp->send_pending_inline
-					(txq->qp,
-					 (void *)addr,
-					 length,
-					 send_flags);
-			else
-				err = txq->if_qp->send_pending
-					(txq->qp,
-					 addr,
-					 length,
-					 lkey,
-					 send_flags);
-			if (unlikely(err))
-				goto stop;
+			sge->addr = addr;
+			sge->length = length;
+			sge->lkey = lkey;
 			sent_size += length;
 		} else {
 			err = -1;
 			goto stop;
 		}
+		if (sent_size <= txq->max_inline)
+			send_flags |= IBV_SEND_INLINE;
 		elts_head = elts_head_next;
 		/* Increment sent bytes counter. */
 		txq->stats.obytes += sent_size;
+		/* Set up WR. */
+		wr->sg_list = &elt->sge;
+		wr->num_sge = segs;
+		wr->opcode = IBV_WR_SEND;
+		wr->send_flags = send_flags;
+		*wr_next = wr;
+		wr_next = &wr->next;
 	}
 stop:
 	/* Take a shortcut if nothing must be sent. */
@@ -1123,12 +1102,37 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
 	/* Increment sent packets counter. */
 	txq->stats.opackets += i;
 	/* Ring QP doorbell. */
-	err = txq->if_qp->send_flush(txq->qp);
+	*wr_next = NULL;
+	assert(wr_head);
+	err = ibv_post_send(txq->qp, wr_head, &wr_bad);
 	if (unlikely(err)) {
-		/* A nonzero value is not supposed to be returned.
-		 * Nothing can be done about it. */
-		DEBUG("%p: send_flush() failed with error %d",
-		      (void *)txq, err);
+		uint64_t obytes = 0;
+		uint64_t opackets = 0;
+
+		/* Rewind bad WRs. */
+		while (wr_bad != NULL) {
+			int j;
+
+			/* Force completion request if one was lost. */
+			if (wr_bad->send_flags & IBV_SEND_SIGNALED) {
+				elts_comp_cd = 1;
+				--elts_comp;
+			}
+			++opackets;
+			for (j = 0; j < wr_bad->num_sge; ++j)
+				obytes += wr_bad->sg_list[j].length;
+			elts_head = (elts_head ? elts_head : elts_n) - 1;
+			wr_bad = wr_bad->next;
+		}
+		txq->stats.opackets -= opackets;
+		txq->stats.obytes -= obytes;
+		i -= opackets;
+		DEBUG("%p: ibv_post_send() failed, %" PRIu64 " packets"
+		      " (%" PRIu64 " bytes) rejected: %s",
+		      (void *)txq,
+		      opackets,
+		      obytes,
+		      (err <= -1) ? "Internal error" : strerror(err));
 	}
 	txq->elts_head = elts_head;
 	txq->elts_comp += elts_comp;
@@ -1163,11 +1167,9 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		.socket = socket
 	};
 	union {
-		struct ibv_exp_query_intf_params params;
 		struct ibv_qp_init_attr init;
 		struct ibv_qp_attr mod;
 	} attr;
-	enum ibv_exp_query_intf_status status;
 	int ret = 0;
 
 	(void)conf; /* Thresholds configuration (ignored). */
@@ -1251,28 +1253,6 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 		      (void *)dev, strerror(ret));
 		goto error;
 	}
-	attr.params = (struct ibv_exp_query_intf_params){
-		.intf_scope = IBV_EXP_INTF_GLOBAL,
-		.intf = IBV_EXP_INTF_CQ,
-		.obj = tmpl.cq,
-	};
-	tmpl.if_cq = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
-	if (tmpl.if_cq == NULL) {
-		ERROR("%p: CQ interface family query failed with status %d",
-		      (void *)dev, status);
-		goto error;
-	}
-	attr.params = (struct ibv_exp_query_intf_params){
-		.intf_scope = IBV_EXP_INTF_GLOBAL,
-		.intf = IBV_EXP_INTF_QP_BURST,
-		.obj = tmpl.qp,
-	};
-	tmpl.if_qp = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
-	if (tmpl.if_qp == NULL) {
-		ERROR("%p: QP interface family query failed with status %d",
-		      (void *)dev, status);
-		goto error;
-	}
 	/* Clean up txq in case we're reinitializing it. */
 	DEBUG("%p: cleaning-up old txq just in case", (void *)txq);
 	txq_cleanup(txq);
drivers/net/mlx4/mlx4.h +2 -2
index edec40c..8a9a678 100644
@@ -171,6 +171,8 @@ struct rxq {
 
 /* TX element. */
 struct txq_elt {
+	struct ibv_send_wr wr; /* Work request. */
+	struct ibv_sge sge; /* Scatter/gather element. */
 	struct rte_mbuf *buf;
 };
 
@@ -191,8 +193,6 @@ struct txq {
 	} mp2mr[MLX4_PMD_TX_MP_CACHE]; /* MP to MR translation table. */
 	struct ibv_cq *cq; /* Completion Queue. */
 	struct ibv_qp *qp; /* Queue Pair. */
-	struct ibv_exp_qp_burst_family *if_qp; /* QP burst interface. */
-	struct ibv_exp_cq_family *if_cq; /* CQ interface. */
 	uint32_t max_inline; /* Max inline send size <= MLX4_PMD_MAX_INLINE. */
 	unsigned int elts_n; /* (*elts)[] length. */
 	struct txq_elt (*elts)[]; /* TX elements. */
Signature · 1 line
2.1.4
#80 lore raw

PATCH v2 25/51 net/mlx4: revert fast Verbs interface for Rx

In reply to Adrien Mazarguil

This reverts commit acac55f164128fc76da8d93cae1e8c1e560e99f6.

"Fast Verbs" is a nonstandard experimental interface that must be reverted for compatibility reasons. Its replacement is slower but temporary, performance will be restored by a subsequent commit through an enhanced data path implementation. This one focuses on maintaining basic functionality in the meantime.

---
 drivers/net/mlx4/mlx4.c | 127 +++++++++++--------------------------------
 drivers/net/mlx4/mlx4.h |   2 -
 2 files changed, 33 insertions(+), 96 deletions(-)
drivers/net/mlx4/mlx4.c +33 -94
index 4432952..79fb666 100644
@@ -1617,32 +1617,8 @@ priv_mac_addr_add(struct priv *priv)
 static void
 rxq_cleanup(struct rxq *rxq)
 {
-	struct ibv_exp_release_intf_params params;
-
 	DEBUG("cleaning up %p", (void *)rxq);
 	rxq_free_elts(rxq);
-	if (rxq->if_qp != NULL) {
-		assert(rxq->priv != NULL);
-		assert(rxq->priv->ctx != NULL);
-		assert(rxq->qp != NULL);
-		params = (struct ibv_exp_release_intf_params){
-			.comp_mask = 0,
-		};
-		claim_zero(ibv_exp_release_intf(rxq->priv->ctx,
-						rxq->if_qp,
-						&params));
-	}
-	if (rxq->if_cq != NULL) {
-		assert(rxq->priv != NULL);
-		assert(rxq->priv->ctx != NULL);
-		assert(rxq->cq != NULL);
-		params = (struct ibv_exp_release_intf_params){
-			.comp_mask = 0,
-		};
-		claim_zero(ibv_exp_release_intf(rxq->priv->ctx,
-						rxq->if_cq,
-						&params));
-	}
 	if (rxq->qp != NULL)
 		claim_zero(ibv_destroy_qp(rxq->qp));
 	if (rxq->cq != NULL)
@@ -1676,23 +1652,37 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 	struct rxq_elt (*elts)[rxq->elts_n] = rxq->elts;
 	const unsigned int elts_n = rxq->elts_n;
 	unsigned int elts_head = rxq->elts_head;
-	struct ibv_sge sges[pkts_n];
+	struct ibv_wc wcs[pkts_n];
+	struct ibv_recv_wr *wr_head = NULL;
+	struct ibv_recv_wr **wr_next = &wr_head;
+	struct ibv_recv_wr *wr_bad = NULL;
 	unsigned int i;
 	unsigned int pkts_ret = 0;
 	int ret;
 
-	for (i = 0; (i != pkts_n); ++i) {
+	ret = ibv_poll_cq(rxq->cq, pkts_n, wcs);
+	if (unlikely(ret == 0))
+		return 0;
+	if (unlikely(ret < 0)) {
+		DEBUG("rxq=%p, ibv_poll_cq() failed (wc_n=%d)",
+		      (void *)rxq, ret);
+		return 0;
+	}
+	assert(ret <= (int)pkts_n);
+	/* For each work completion. */
+	for (i = 0; i != (unsigned int)ret; ++i) {
+		struct ibv_wc *wc = &wcs[i];
 		struct rxq_elt *elt = &(*elts)[elts_head];
 		struct ibv_recv_wr *wr = &elt->wr;
 		uint64_t wr_id = wr->wr_id;
-		unsigned int len;
+		uint32_t len = wc->byte_len;
 		struct rte_mbuf *seg = (void *)((uintptr_t)elt->sge.addr -
 			WR_ID(wr_id).offset);
 		struct rte_mbuf *rep;
-		uint32_t flags;
 
 		/* Sanity checks. */
 		assert(WR_ID(wr_id).id < rxq->elts_n);
+		assert(wr_id == wc->wr_id);
 		assert(wr->sg_list == &elt->sge);
 		assert(wr->num_sge == 1);
 		assert(elts_head < rxq->elts_n);
@@ -1703,41 +1693,19 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		 */
 		rte_mbuf_prefetch_part1(seg);
 		rte_mbuf_prefetch_part2(seg);
-		ret = rxq->if_cq->poll_length_flags(rxq->cq, NULL, NULL,
-						    &flags);
-		if (unlikely(ret < 0)) {
-			struct ibv_wc wc;
-			int wcs_n;
-
-			DEBUG("rxq=%p, poll_length() failed (ret=%d)",
-			      (void *)rxq, ret);
-			/* ibv_poll_cq() must be used in case of failure. */
-			wcs_n = ibv_poll_cq(rxq->cq, 1, &wc);
-			if (unlikely(wcs_n == 0))
-				break;
-			if (unlikely(wcs_n < 0)) {
-				DEBUG("rxq=%p, ibv_poll_cq() failed (wcs_n=%d)",
-				      (void *)rxq, wcs_n);
-				break;
-			}
-			assert(wcs_n == 1);
-			if (unlikely(wc.status != IBV_WC_SUCCESS)) {
-				/* Whatever, just repost the offending WR. */
-				DEBUG("rxq=%p, wr_id=%" PRIu64 ": bad work"
-				      " completion status (%d): %s",
-				      (void *)rxq, wc.wr_id, wc.status,
-				      ibv_wc_status_str(wc.status));
-				/* Increment dropped packets counter. */
-				++rxq->stats.idropped;
-				/* Add SGE to array for repost. */
-				sges[i] = elt->sge;
-				goto repost;
-			}
-			ret = wc.byte_len;
+		/* Link completed WRs together for repost. */
+		*wr_next = wr;
+		wr_next = &wr->next;
+		if (unlikely(wc->status != IBV_WC_SUCCESS)) {
+			/* Whatever, just repost the offending WR. */
+			DEBUG("rxq=%p, wr_id=%" PRIu64 ": bad work completion"
+			      " status (%d): %s",
+			      (void *)rxq, wr_id, wc->status,
+			      ibv_wc_status_str(wc->status));
+			/* Increment dropped packets counter. */
+			++rxq->stats.idropped;
+			goto repost;
 		}
-		if (ret == 0)
-			break;
-		len = ret;
 		rep = rte_mbuf_raw_alloc(rxq->mp);
 		if (unlikely(rep == NULL)) {
 			/*
@@ -1750,8 +1718,6 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			/* Increase out of memory counters. */
 			++rxq->stats.rx_nombuf;
 			++rxq->priv->dev->data->rx_mbuf_alloc_failed;
-			/* Add SGE to array for repost. */
-			sges[i] = elt->sge;
 			goto repost;
 		}
 
@@ -1763,9 +1729,6 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			 (uintptr_t)rep);
 		assert(WR_ID(wr->wr_id).id == WR_ID(wr_id).id);
 
-		/* Add SGE to array for repost. */
-		sges[i] = elt->sge;
-
 		/* Update seg information. */
 		SET_DATA_OFF(seg, RTE_PKTMBUF_HEADROOM);
 		NB_SEGS(seg) = 1;
@@ -1789,7 +1752,9 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 	if (unlikely(i == 0))
 		return 0;
 	/* Repost WRs. */
-	ret = rxq->if_qp->recv_burst(rxq->qp, sges, i);
+	*wr_next = NULL;
+	assert(wr_head);
+	ret = ibv_post_recv(rxq->qp, wr_head, &wr_bad);
 	if (unlikely(ret)) {
 		/* Inability to repost WRs is fatal. */
 		DEBUG("%p: recv_burst(): failed (ret=%d)",
@@ -1870,10 +1835,6 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 		.socket = socket
 	};
 	struct ibv_qp_attr mod;
-	union {
-		struct ibv_exp_query_intf_params params;
-	} attr;
-	enum ibv_exp_query_intf_status status;
 	struct ibv_recv_wr *bad_wr;
 	unsigned int mb_len;
 	int ret = 0;
@@ -1975,28 +1936,6 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,
 	/* Save port ID. */
 	tmpl.port_id = dev->data->port_id;
 	DEBUG("%p: RTE port ID: %u", (void *)rxq, tmpl.port_id);
-	attr.params = (struct ibv_exp_query_intf_params){
-		.intf_scope = IBV_EXP_INTF_GLOBAL,
-		.intf = IBV_EXP_INTF_CQ,
-		.obj = tmpl.cq,
-	};
-	tmpl.if_cq = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
-	if (tmpl.if_cq == NULL) {
-		ERROR("%p: CQ interface family query failed with status %d",
-		      (void *)dev, status);
-		goto error;
-	}
-	attr.params = (struct ibv_exp_query_intf_params){
-		.intf_scope = IBV_EXP_INTF_GLOBAL,
-		.intf = IBV_EXP_INTF_QP_BURST,
-		.obj = tmpl.qp,
-	};
-	tmpl.if_qp = ibv_exp_query_intf(priv->ctx, &attr.params, &status);
-	if (tmpl.if_qp == NULL) {
-		ERROR("%p: QP interface family query failed with status %d",
-		      (void *)dev, status);
-		goto error;
-	}
 	/* Clean up rxq in case we're reinitializing it. */
 	DEBUG("%p: cleaning-up old rxq just in case", (void *)rxq);
 	rxq_cleanup(rxq);
drivers/net/mlx4/mlx4.h +0 -2
index 8a9a678..772784f 100644
@@ -158,8 +158,6 @@ struct rxq {
 	struct ibv_mr *mr; /* Memory Region (for mp). */
 	struct ibv_cq *cq; /* Completion Queue. */
 	struct ibv_qp *qp; /* Queue Pair. */
-	struct ibv_exp_qp_burst_family *if_qp; /* QP burst interface. */
-	struct ibv_exp_cq_family *if_cq; /* CQ interface. */
 	struct ibv_comp_channel *channel;
 	unsigned int port_id; /* Port ID for incoming packets. */
 	unsigned int elts_n; /* (*elts)[] length. */
Signature · 1 line
2.1.4
#81 lore raw

PATCH v2 26/51 net/mlx4: simplify Rx buffer handling

In reply to Adrien Mazarguil

Thanks to the fact the PMD temporarily uses a slower interface for Rx, removing the WR ID hack to instead store mbuf pointers directly makes the code simpler at no extra cost.

---
 drivers/net/mlx4/mlx4.c | 79 ++++++--------------------------------------
 drivers/net/mlx4/mlx4.h |  2 +-
 2 files changed, 12 insertions(+), 69 deletions(-)
drivers/net/mlx4/mlx4.c +11 -68
index 79fb666..1208e7a 100644
@@ -84,17 +84,6 @@
 #define NB_SEGS(m) ((m)->nb_segs)
 #define PORT(m) ((m)->port)
 
-/* Work Request ID data type (64 bit). */
-typedef union {
-	struct {
-		uint32_t id;
-		uint16_t offset;
-	} data;
-	uint64_t raw;
-} wr_id_t;
-
-#define WR_ID(o) (((wr_id_t *)&(o))->data)
-
 /** Configuration structure for device arguments. */
 struct mlx4_conf {
 	struct {
@@ -1403,13 +1392,7 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n)
 			ret = ENOMEM;
 			goto error;
 		}
-		/* Configure WR. Work request ID contains its own index in
-		 * the elts array and the offset between SGE buffer header and
-		 * its data. */
-		WR_ID(wr->wr_id).id = i;
-		WR_ID(wr->wr_id).offset =
-			(((uintptr_t)buf->buf_addr + RTE_PKTMBUF_HEADROOM) -
-			 (uintptr_t)buf);
+		elt->buf = buf;
 		wr->next = &(*elts)[(i + 1)].wr;
 		wr->sg_list = sge;
 		wr->num_sge = 1;
@@ -1427,18 +1410,6 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n)
 		sge->lkey = rxq->mr->lkey;
 		/* Redundant check for tailroom. */
 		assert(sge->length == rte_pktmbuf_tailroom(buf));
-		/* Make sure elts index and SGE mbuf pointer can be deduced
-		 * from WR ID. */
-		if ((WR_ID(wr->wr_id).id != i) ||
-		    ((void *)((uintptr_t)sge->addr -
-			WR_ID(wr->wr_id).offset) != buf)) {
-			ERROR("%p: cannot store index and offset in WR ID",
-			      (void *)rxq);
-			sge->addr = 0;
-			rte_pktmbuf_free(buf);
-			ret = EOVERFLOW;
-			goto error;
-		}
 	}
 	/* The last WR pointer must be NULL. */
 	(*elts)[(i - 1)].wr.next = NULL;
@@ -1451,17 +1422,8 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n)
 	return 0;
 error:
 	if (elts != NULL) {
-		for (i = 0; (i != elemof(*elts)); ++i) {
-			struct rxq_elt *elt = &(*elts)[i];
-			struct rte_mbuf *buf;
-
-			if (elt->sge.addr == 0)
-				continue;
-			assert(WR_ID(elt->wr.wr_id).id == i);
-			buf = (void *)((uintptr_t)elt->sge.addr -
-				WR_ID(elt->wr.wr_id).offset);
-			rte_pktmbuf_free_seg(buf);
-		}
+		for (i = 0; (i != elemof(*elts)); ++i)
+			rte_pktmbuf_free_seg((*elts)[i].buf);
 		rte_free(elts);
 	}
 	DEBUG("%p: failed, freed everything", (void *)rxq);
@@ -1487,17 +1449,8 @@ rxq_free_elts(struct rxq *rxq)
 	rxq->elts = NULL;
 	if (elts == NULL)
 		return;
-	for (i = 0; (i != elemof(*elts)); ++i) {
-		struct rxq_elt *elt = &(*elts)[i];
-		struct rte_mbuf *buf;
-
-		if (elt->sge.addr == 0)
-			continue;
-		assert(WR_ID(elt->wr.wr_id).id == i);
-		buf = (void *)((uintptr_t)elt->sge.addr -
-			WR_ID(elt->wr.wr_id).offset);
-		rte_pktmbuf_free_seg(buf);
-	}
+	for (i = 0; (i != elemof(*elts)); ++i)
+		rte_pktmbuf_free_seg((*elts)[i].buf);
 	rte_free(elts);
 }
 
@@ -1674,15 +1627,11 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		struct ibv_wc *wc = &wcs[i];
 		struct rxq_elt *elt = &(*elts)[elts_head];
 		struct ibv_recv_wr *wr = &elt->wr;
-		uint64_t wr_id = wr->wr_id;
 		uint32_t len = wc->byte_len;
-		struct rte_mbuf *seg = (void *)((uintptr_t)elt->sge.addr -
-			WR_ID(wr_id).offset);
+		struct rte_mbuf *seg = elt->buf;
 		struct rte_mbuf *rep;
 
 		/* Sanity checks. */
-		assert(WR_ID(wr_id).id < rxq->elts_n);
-		assert(wr_id == wc->wr_id);
 		assert(wr->sg_list == &elt->sge);
 		assert(wr->num_sge == 1);
 		assert(elts_head < rxq->elts_n);
@@ -1698,9 +1647,8 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		wr_next = &wr->next;
 		if (unlikely(wc->status != IBV_WC_SUCCESS)) {
 			/* Whatever, just repost the offending WR. */
-			DEBUG("rxq=%p, wr_id=%" PRIu64 ": bad work completion"
-			      " status (%d): %s",
-			      (void *)rxq, wr_id, wc->status,
+			DEBUG("rxq=%p: bad work completion status (%d): %s",
+			      (void *)rxq, wc->status,
 			      ibv_wc_status_str(wc->status));
 			/* Increment dropped packets counter. */
 			++rxq->stats.idropped;
@@ -1712,9 +1660,8 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 			 * Unable to allocate a replacement mbuf,
 			 * repost WR.
 			 */
-			DEBUG("rxq=%p, wr_id=%" PRIu32 ":"
-			      " can't allocate a new mbuf",
-			      (void *)rxq, WR_ID(wr_id).id);
+			DEBUG("rxq=%p: can't allocate a new mbuf",
+			      (void *)rxq);
 			/* Increase out of memory counters. */
 			++rxq->stats.rx_nombuf;
 			++rxq->priv->dev->data->rx_mbuf_alloc_failed;
@@ -1724,10 +1671,7 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
 		/* Reconfigure sge to use rep instead of seg. */
 		elt->sge.addr = (uintptr_t)rep->buf_addr + RTE_PKTMBUF_HEADROOM;
 		assert(elt->sge.lkey == rxq->mr->lkey);
-		WR_ID(wr->wr_id).offset =
-			(((uintptr_t)rep->buf_addr + RTE_PKTMBUF_HEADROOM) -
-			 (uintptr_t)rep);
-		assert(WR_ID(wr->wr_id).id == WR_ID(wr_id).id);
+		elt->buf = rep;
 
 		/* Update seg information. */
 		SET_DATA_OFF(seg, RTE_PKTMBUF_HEADROOM);
@@ -3659,7 +3603,6 @@ RTE_INIT(rte_mlx4_pmd_init);
 static void
 rte_mlx4_pmd_init(void)
 {
-	RTE_BUILD_BUG_ON(sizeof(wr_id_t) != sizeof(uint64_t));
 	/*
 	 * RDMAV_HUGEPAGES_SAFE tells ibv_fork_init() we intend to use
 	 * huge pages. Calling ibv_fork_init() during init allows
drivers/net/mlx4/mlx4.h +1 -1
index 772784f..c619c87 100644
@@ -148,7 +148,7 @@ struct mlx4_rxq_stats {
 struct rxq_elt {
 	struct ibv_recv_wr wr; /* Work Request. */
 	struct ibv_sge sge; /* Scatter/Gather Element. */
-	/* mbuf pointer is derived from WR_ID(wr.wr_id).offset. */
+	struct rte_mbuf *buf; /**< Buffer. */
 };
 
 /* RX queue descriptor. */
Signature · 1 line
2.1.4
#82 lore raw

PATCH v2 27/51 net/mlx4: simplify link update function

In reply to Adrien Mazarguil

Returning a different value when the current link status differs from the previous one was probably useful at some point in the past but is now meaningless; this value is ignored both internally (mlx4 PMD) and externally (ethdev wrapper).

---
 drivers/net/mlx4/mlx4.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)
drivers/net/mlx4/mlx4.c +2 -7
index 1208e7a..9694170 100644
@@ -2476,13 +2476,8 @@ mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 				ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
 	dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
 			ETH_LINK_SPEED_FIXED);
-	if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
-		/* Link status changed. */
-		dev->data->dev_link = dev_link;
-		return 0;
-	}
-	/* Link status is still the same. */
-	return -1;
+	dev->data->dev_link = dev_link;
+	return 0;
 }
 
 /**
Signature · 1 line
2.1.4