net/mlx4: trim and refactor entire PMD
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
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 2/48 net/mlx4: remove limitation on number of instances
In reply to Adrien MazarguilThe 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
@@ -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
PATCH 3/48 net/mlx4: check max number of ports dynamically
In reply to Adrien MazarguilUse maximum number reported by hardware capabilities as replacement for the static check on MLX4_PMD_MAX_PHYS_PORTS.
--- 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
@@ -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
@@ -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
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
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
PATCH 4/48 net/mlx4: remove useless compilation checks
In reply to Adrien MazarguilVerbs 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
@@ -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
@@ -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
@@ -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
@@ -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
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.
Signed-off-by Adrien Mazarguil <[email protected]>
<...>
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.
Signed-off-by Adrien Mazarguil <[email protected]><...>
Signature · 2 lines
Adrien Mazarguil 6WIND
PATCH 5/48 net/mlx4: remove secondary process support
In reply to Adrien MazarguilCurrent 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
@@ -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
@@ -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
PATCH 6/48 net/mlx4: remove useless code
In reply to Adrien MazarguilLess 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
@@ -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
@@ -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
PATCH 7/48 net/mlx4: remove soft counters compilation option
In reply to Adrien MazarguilSoftware 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 8/48 net/mlx4: remove scatter mode compilation option
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 9/48 net/mlx4: remove Tx inline compilation option
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 10/48 net/mlx4: remove allmulti and promisc support
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
PATCH 11/48 net/mlx4: remove VLAN filter support
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
PATCH 12/48 net/mlx4: remove MAC address configuration support
In reply to Adrien MazarguilOnly 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
@@ -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
@@ -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
PATCH 13/48 net/mlx4: drop MAC flows affecting all Rx queues
In reply to Adrien MazarguilConfiguring 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
@@ -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, ¶ms)); } -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
@@ -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
PATCH 14/48 net/mlx4: revert flow API RSS support
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
PATCH 15/48 net/mlx4: revert RSS parent queue refactoring
In reply to Adrien MazarguilThis 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
@@ -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, ¶ms, &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
@@ -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
@@ -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
PATCH 16/48 net/mlx4: drop RSS support
In reply to Adrien MazarguilThe 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
@@ -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
@@ -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
@@ -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
PATCH 17/48 net/mlx4: drop checksum offloads support
In reply to Adrien MazarguilThe 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
@@ -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
@@ -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
@@ -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
PATCH 18/48 net/mlx4: drop packet type recognition support
In reply to Adrien MazarguilThe 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
@@ -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
PATCH 19/48 net/mlx4: drop scatter/gather support
In reply to Adrien MazarguilThe 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
@@ -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
@@ -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
@@ -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
PATCH 20/48 net/mlx4: drop inline receive support
In reply to Adrien MazarguilThe 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
@@ -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
@@ -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
PATCH 21/48 net/mlx4: use standard QP attributes
In reply to Adrien MazarguilThe 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
@@ -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
PATCH 22/48 net/mlx4: revert resource domain support
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
PATCH 23/48 net/mlx4: revert multicast echo prevention
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
PATCH 24/48 net/mlx4: revert fast Verbs interface for Tx
In reply to Adrien MazarguilThis 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
@@ -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, - ¶ms)); - } -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, - ¶ms)); - }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
@@ -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
PATCH 25/48 net/mlx4: revert fast Verbs interface for Rx
In reply to Adrien MazarguilThis 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
@@ -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, - ¶ms)); - } -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, - ¶ms)); - }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
@@ -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
PATCH 26/48 net/mlx4: simplify link update function
In reply to Adrien MazarguilReturning 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
@@ -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 Ð_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
PATCH 27/48 net/mlx4: standardize on negative errno values
In reply to Adrien MazarguilDue 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
@@ -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 *)ðpause;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
PATCH 28/48 net/mlx4: clean up coding style inconsistencies
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
PATCH 29/48 net/mlx4: remove control path locks
In reply to Adrien MazarguilConcurrent 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
@@ -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 *)ðpause; -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
@@ -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
@@ -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
PATCH 30/48 net/mlx4: remove unnecessary wrapper functions
In reply to Adrien MazarguilWrapper 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
@@ -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
PATCH 31/48 net/mlx4: remove mbuf macro definitions
In reply to Adrien MazarguilThese 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
@@ -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
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
@@ -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
@@ -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
PATCH 33/48 net/mlx4: separate debugging macros
In reply to Adrien MazarguilThe 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
@@ -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
@@ -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
PATCH 34/48 net/mlx4: use a single interrupt handle
In reply to Adrien MazarguilThe 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
@@ -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
@@ -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
PATCH 35/48 net/mlx4: rename alarm field
In reply to Adrien MazarguilMake 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
@@ -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
@@ -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
PATCH 36/48 net/mlx4: refactor interrupt FD settings
In reply to Adrien MazarguilFile 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
@@ -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
@@ -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
@@ -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
PATCH 37/48 net/mlx4: clean up interrupt functions prototypes
In reply to Adrien MazarguilThe 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
@@ -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
PATCH 38/48 net/mlx4: compact interrupt functions
In reply to Adrien MazarguilLink 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
@@ -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
@@ -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
PATCH 39/48 net/mlx4: separate interrupt handling
In reply to Adrien MazarguilPrivate 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
@@ -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
@@ -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
PATCH 40/48 net/mlx4: separate Rx/Tx definitions
In reply to Adrien MazarguilExcept 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
@@ -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
@@ -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
@@ -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
PATCH 41/48 net/mlx4: separate Rx/Tx functions
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
PATCH 42/48 net/mlx4: separate device control functions
In reply to Adrien MazarguilPrivate 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
@@ -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
@@ -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
@@ -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
PATCH 43/48 net/mlx4: separate Tx configuration functions
In reply to Adrien MazarguilPrivate 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
@@ -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
@@ -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
PATCH 44/48 net/mlx4: separate Rx configuration functions
In reply to Adrien MazarguilPrivate 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
@@ -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
@@ -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
PATCH 45/48 net/mlx4: group flow API handlers in common file
In reply to Adrien MazarguilOnly 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
@@ -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
@@ -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
PATCH 46/48 net/mlx4: rename private functions in flow API
In reply to Adrien MazarguilWhile 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
@@ -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
@@ -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
@@ -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
PATCH 47/48 net/mlx4: separate memory management functions
In reply to Adrien MazarguilNo 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
@@ -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
@@ -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
PATCH 48/48 net/mlx4: clean up includes and comments
In reply to Adrien MazarguilAdd 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
@@ -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
@@ -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
@@ -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
@@ -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
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.
<...>
v2 cover net/mlx4: trim and refactor entire PMD
In reply to Adrien MazarguilThe 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
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v2 2/51 net/mlx4: remove limitation on number of instances
In reply to Adrien MazarguilThe 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
@@ -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
PATCH v2 3/51 net/mlx4: check max number of ports dynamically
In reply to Adrien MazarguilUse maximum number reported by hardware capabilities as replacement for the static check on MLX4_PMD_MAX_PHYS_PORTS.
--- 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
@@ -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
@@ -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
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]>Signed-off-by Adrien Mazarguil <[email protected]>
PATCH v2 4/51 net/mlx4: remove useless compilation checks
In reply to Adrien MazarguilVerbs 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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v2 5/51 net/mlx4: remove secondary process support
In reply to Adrien MazarguilCurrent 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
@@ -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
@@ -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
PATCH v2 6/51 net/mlx4: remove useless code
In reply to Adrien MazarguilLess 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
@@ -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
@@ -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
PATCH v2 7/51 net/mlx4: remove soft counters compilation option
In reply to Adrien MazarguilSoftware 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v2 8/51 net/mlx4: remove scatter mode compilation option
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v2 9/51 net/mlx4: remove Tx inline compilation option
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v2 10/51 net/mlx4: remove allmulti and promisc support
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
PATCH v2 11/51 net/mlx4: remove VLAN filter support
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
PATCH v2 12/51 net/mlx4: remove MAC address configuration support
In reply to Adrien MazarguilOnly 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
@@ -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
@@ -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
PATCH v2 13/51 net/mlx4: drop MAC flows affecting all Rx queues
In reply to Adrien MazarguilConfiguring 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
@@ -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, ¶ms)); } -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
@@ -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
PATCH v2 14/51 net/mlx4: revert flow API RSS support
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
PATCH v2 15/51 net/mlx4: revert RSS parent queue refactoring
In reply to Adrien MazarguilThis 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
@@ -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, ¶ms, &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
@@ -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
@@ -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
PATCH v2 16/51 net/mlx4: drop RSS support
In reply to Adrien MazarguilThe 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
@@ -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
@@ -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
@@ -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
PATCH v2 17/51 net/mlx4: drop checksum offloads support
In reply to Adrien MazarguilThe 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
@@ -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
@@ -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
@@ -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
PATCH v2 18/51 net/mlx4: drop packet type recognition support
In reply to Adrien MazarguilThe 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
@@ -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
PATCH v2 19/51 net/mlx4: drop scatter/gather support
In reply to Adrien MazarguilThe 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
@@ -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
@@ -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
@@ -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
PATCH v2 20/51 net/mlx4: drop inline receive support
In reply to Adrien MazarguilThe 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
@@ -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
@@ -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
PATCH v2 21/51 net/mlx4: use standard QP attributes
In reply to Adrien MazarguilThe 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
@@ -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
PATCH v2 22/51 net/mlx4: revert resource domain support
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
@@ -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
PATCH v2 23/51 net/mlx4: revert multicast echo prevention
In reply to Adrien MazarguilThis 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
@@ -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
@@ -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
PATCH v2 24/51 net/mlx4: revert fast Verbs interface for Tx
In reply to Adrien MazarguilThis 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
@@ -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, - ¶ms)); - } -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, - ¶ms)); - }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
@@ -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
PATCH v2 25/51 net/mlx4: revert fast Verbs interface for Rx
In reply to Adrien MazarguilThis 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
@@ -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, - ¶ms)); - } -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, - ¶ms)); - }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
@@ -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
PATCH v2 26/51 net/mlx4: simplify Rx buffer handling
In reply to Adrien MazarguilThanks 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
@@ -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
@@ -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
PATCH v2 27/51 net/mlx4: simplify link update function
In reply to Adrien MazarguilReturning 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
@@ -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 Ð_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