2020-07-20 06:26:05 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
* Copyright 2020 Mellanox Technologies, Ltd
|
|
|
|
*/
|
|
|
|
|
2020-07-20 06:26:07 +00:00
|
|
|
#include <rte_malloc.h>
|
|
|
|
#include <rte_log.h>
|
|
|
|
#include <rte_errno.h>
|
|
|
|
#include <rte_pci.h>
|
|
|
|
#include <rte_regexdev.h>
|
|
|
|
#include <rte_regexdev_core.h>
|
|
|
|
#include <rte_regexdev_driver.h>
|
2022-07-28 15:26:30 +00:00
|
|
|
#include <bus_pci_driver.h>
|
2020-07-20 06:26:07 +00:00
|
|
|
|
2021-05-04 17:54:56 +00:00
|
|
|
#include <mlx5_common.h>
|
2021-07-12 07:06:42 +00:00
|
|
|
#include <mlx5_common_mr.h>
|
2020-07-20 06:26:07 +00:00
|
|
|
#include <mlx5_glue.h>
|
|
|
|
#include <mlx5_devx_cmds.h>
|
|
|
|
#include <mlx5_prm.h>
|
|
|
|
|
2020-07-20 06:26:05 +00:00
|
|
|
#include "mlx5_regex.h"
|
2020-07-20 06:26:06 +00:00
|
|
|
#include "mlx5_regex_utils.h"
|
|
|
|
|
2020-08-05 14:51:01 +00:00
|
|
|
#define MLX5_REGEX_DRIVER_NAME regex_mlx5
|
|
|
|
|
2020-07-20 06:26:06 +00:00
|
|
|
int mlx5_regex_logtype;
|
|
|
|
|
2020-07-20 06:26:08 +00:00
|
|
|
const struct rte_regexdev_ops mlx5_regexdev_ops = {
|
|
|
|
.dev_info_get = mlx5_regex_info_get,
|
2020-07-20 06:26:10 +00:00
|
|
|
.dev_configure = mlx5_regex_configure,
|
2020-07-20 06:26:11 +00:00
|
|
|
.dev_db_import = mlx5_regex_rules_db_import,
|
2020-07-20 06:26:12 +00:00
|
|
|
.dev_qp_setup = mlx5_regex_qp_setup,
|
2020-07-20 06:26:17 +00:00
|
|
|
.dev_start = mlx5_regex_start,
|
|
|
|
.dev_stop = mlx5_regex_stop,
|
|
|
|
.dev_close = mlx5_regex_close,
|
2020-07-20 06:26:08 +00:00
|
|
|
};
|
2020-07-20 06:26:07 +00:00
|
|
|
|
2020-07-20 06:26:17 +00:00
|
|
|
int
|
2021-10-19 20:56:02 +00:00
|
|
|
mlx5_regex_start(struct rte_regexdev *dev)
|
2020-07-20 06:26:17 +00:00
|
|
|
{
|
2021-10-19 20:56:02 +00:00
|
|
|
struct mlx5_regex_priv *priv = dev->data->dev_private;
|
|
|
|
|
|
|
|
return mlx5_dev_mempool_subscribe(priv->cdev);
|
2020-07-20 06:26:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
mlx5_regex_stop(struct rte_regexdev *dev __rte_unused)
|
|
|
|
{
|
2021-10-22 15:45:52 +00:00
|
|
|
struct mlx5_regex_priv *priv = dev->data->dev_private;
|
|
|
|
|
|
|
|
mlx5_regex_clean_ctrl(dev);
|
|
|
|
rte_free(priv->qps);
|
|
|
|
priv->qps = NULL;
|
|
|
|
|
2020-07-20 06:26:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
mlx5_regex_close(struct rte_regexdev *dev __rte_unused)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-07-20 06:26:07 +00:00
|
|
|
static void
|
2021-07-21 14:37:37 +00:00
|
|
|
mlx5_regex_get_name(char *name, struct rte_device *dev)
|
2020-07-20 06:26:07 +00:00
|
|
|
{
|
2021-07-21 14:37:37 +00:00
|
|
|
sprintf(name, "mlx5_regex_%s", dev->name);
|
2020-07-20 06:26:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2022-02-14 09:35:11 +00:00
|
|
|
mlx5_regex_dev_probe(struct mlx5_common_device *cdev,
|
|
|
|
struct mlx5_kvargs_ctrl *mkvlist __rte_unused)
|
2020-07-20 06:26:07 +00:00
|
|
|
{
|
|
|
|
struct mlx5_regex_priv *priv = NULL;
|
2021-10-19 20:55:55 +00:00
|
|
|
struct mlx5_hca_attr *attr = &cdev->config.hca_attr;
|
2020-07-20 06:26:07 +00:00
|
|
|
char name[RTE_REGEXDEV_NAME_MAX_LEN];
|
2021-11-03 18:35:13 +00:00
|
|
|
int ret;
|
2020-07-20 06:26:07 +00:00
|
|
|
|
2021-10-22 15:45:51 +00:00
|
|
|
if ((!attr->regexp_params && !attr->mmo_regex_sq_en && !attr->mmo_regex_qp_en)
|
2021-10-19 20:55:55 +00:00
|
|
|
|| attr->regexp_num_of_engines == 0) {
|
2020-07-20 06:26:07 +00:00
|
|
|
DRV_LOG(ERR, "Not enough capabilities to support RegEx, maybe "
|
|
|
|
"old FW/OFED version?");
|
|
|
|
rte_errno = ENOTSUP;
|
2021-10-19 20:55:52 +00:00
|
|
|
return -rte_errno;
|
2020-07-20 06:26:07 +00:00
|
|
|
}
|
|
|
|
priv = rte_zmalloc("mlx5 regex device private", sizeof(*priv),
|
|
|
|
RTE_CACHE_LINE_SIZE);
|
|
|
|
if (!priv) {
|
|
|
|
DRV_LOG(ERR, "Failed to allocate private memory.");
|
|
|
|
rte_errno = ENOMEM;
|
2021-10-19 20:55:52 +00:00
|
|
|
return -rte_errno;
|
2020-07-20 06:26:07 +00:00
|
|
|
}
|
2021-10-19 20:55:55 +00:00
|
|
|
priv->mmo_regex_qp_cap = attr->mmo_regex_qp_en;
|
|
|
|
priv->mmo_regex_sq_cap = attr->mmo_regex_sq_en;
|
2021-10-19 20:55:52 +00:00
|
|
|
priv->cdev = cdev;
|
2020-07-20 06:26:11 +00:00
|
|
|
priv->nb_engines = 2; /* attr.regexp_num_of_engines */
|
2021-10-22 15:45:51 +00:00
|
|
|
if (attr->regexp_version == MLX5_RXP_BF2_IDENTIFIER)
|
2021-01-07 16:57:08 +00:00
|
|
|
priv->is_bf2 = 1;
|
2020-07-20 06:26:11 +00:00
|
|
|
/* Default RXP programming mode to Shared. */
|
|
|
|
priv->prog_mode = MLX5_RXP_SHARED_PROG_MODE;
|
2021-10-19 20:55:46 +00:00
|
|
|
mlx5_regex_get_name(name, cdev->dev);
|
2020-07-20 06:26:07 +00:00
|
|
|
priv->regexdev = rte_regexdev_register(name);
|
|
|
|
if (priv->regexdev == NULL) {
|
|
|
|
DRV_LOG(ERR, "Failed to register RegEx device.");
|
|
|
|
rte_errno = rte_errno ? rte_errno : EINVAL;
|
2021-10-19 20:55:52 +00:00
|
|
|
goto dev_error;
|
2020-07-20 06:26:07 +00:00
|
|
|
}
|
2021-11-03 18:35:13 +00:00
|
|
|
ret = mlx5_devx_uar_prepare(cdev, &priv->uar);
|
|
|
|
if (ret)
|
2020-07-20 06:26:11 +00:00
|
|
|
goto error;
|
2020-07-20 06:26:07 +00:00
|
|
|
priv->regexdev->dev_ops = &mlx5_regexdev_ops;
|
2020-07-20 06:26:15 +00:00
|
|
|
priv->regexdev->enqueue = mlx5_regexdev_enqueue;
|
regex/mlx5: add data path scattered mbuf process
UMR (User-Mode Memory Registration) WQE can present data buffers
scattered within multiple mbufs with single indirect mkey. Take
advantage of the UMR WQE, scattered mbuf in one operation can be
presented to an indirect mkey. The RegEx which only accepts one
mkey can now process the whole scattered mbuf in one operation.
The maximum scattered mbuf can be supported in one UMR WQE is now
defined as 64. The mbufs from multiple operations can be combined
into one UMR WQE as well if there is enough space in the KLM array,
since the operations can address their own mbuf's content by the
mkey's address and length. However, one operation's scattered mbuf's
can't be placed in two different UMR WQE's KLM array, if the UMR
WQE's KLM does not has enough free space for one operation, the
extra UMR WQE will be engaged.
In case the UMR WQE's indirect mkey will be over wrapped by the SQ's
WQE move, the mkey's index used by the UMR WQE should be the index
of last the RegEX WQE in the operations. As one operation consumes
one WQE set, build the RegEx WQE by reverse helps address the mkey
more efficiently. Once the operations in one burst consumes multiple
mkeys, when the mkey KLM array is full, the reverse WQE set index
will always be the last of the new mkey's for the new UMR WQE.
In GGA mode, the SQ WQE's memory layout becomes UMR/NOP and RegEx
WQE by interleave. The UMR and RegEx WQE can be called as WQE set.
The SQ's pi and ci will also be increased as WQE set not as WQE.
For operations don't have scattered mbuf, uses the mbuf's mkey directly,
the WQE set combination is NOP + RegEx.
For operations have scattered mbuf but share the UMR WQE with others,
the WQE set combination is NOP + RegEx.
For operations complete the UMR WQE, the WQE set combination is UMR +
RegEx.
Signed-off-by: John Hurley <jhurley@nvidia.com>
Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
2021-04-07 07:21:39 +00:00
|
|
|
#ifdef HAVE_MLX5_UMR_IMKEY
|
2021-10-19 20:55:55 +00:00
|
|
|
if (!attr->umr_indirect_mkey_disabled &&
|
|
|
|
!attr->umr_modify_entity_size_disabled)
|
regex/mlx5: add data path scattered mbuf process
UMR (User-Mode Memory Registration) WQE can present data buffers
scattered within multiple mbufs with single indirect mkey. Take
advantage of the UMR WQE, scattered mbuf in one operation can be
presented to an indirect mkey. The RegEx which only accepts one
mkey can now process the whole scattered mbuf in one operation.
The maximum scattered mbuf can be supported in one UMR WQE is now
defined as 64. The mbufs from multiple operations can be combined
into one UMR WQE as well if there is enough space in the KLM array,
since the operations can address their own mbuf's content by the
mkey's address and length. However, one operation's scattered mbuf's
can't be placed in two different UMR WQE's KLM array, if the UMR
WQE's KLM does not has enough free space for one operation, the
extra UMR WQE will be engaged.
In case the UMR WQE's indirect mkey will be over wrapped by the SQ's
WQE move, the mkey's index used by the UMR WQE should be the index
of last the RegEX WQE in the operations. As one operation consumes
one WQE set, build the RegEx WQE by reverse helps address the mkey
more efficiently. Once the operations in one burst consumes multiple
mkeys, when the mkey KLM array is full, the reverse WQE set index
will always be the last of the new mkey's for the new UMR WQE.
In GGA mode, the SQ WQE's memory layout becomes UMR/NOP and RegEx
WQE by interleave. The UMR and RegEx WQE can be called as WQE set.
The SQ's pi and ci will also be increased as WQE set not as WQE.
For operations don't have scattered mbuf, uses the mbuf's mkey directly,
the WQE set combination is NOP + RegEx.
For operations have scattered mbuf but share the UMR WQE with others,
the WQE set combination is NOP + RegEx.
For operations complete the UMR WQE, the WQE set combination is UMR +
RegEx.
Signed-off-by: John Hurley <jhurley@nvidia.com>
Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
2021-04-07 07:21:39 +00:00
|
|
|
priv->has_umr = 1;
|
|
|
|
if (priv->has_umr)
|
|
|
|
priv->regexdev->enqueue = mlx5_regexdev_enqueue_gga;
|
|
|
|
#endif
|
2020-07-20 06:26:16 +00:00
|
|
|
priv->regexdev->dequeue = mlx5_regexdev_dequeue;
|
2021-10-19 20:55:46 +00:00
|
|
|
priv->regexdev->device = cdev->dev;
|
2020-07-20 06:26:07 +00:00
|
|
|
priv->regexdev->data->dev_private = priv;
|
2020-07-20 06:26:10 +00:00
|
|
|
priv->regexdev->state = RTE_REGEXDEV_READY;
|
regex/mlx5: add data path scattered mbuf process
UMR (User-Mode Memory Registration) WQE can present data buffers
scattered within multiple mbufs with single indirect mkey. Take
advantage of the UMR WQE, scattered mbuf in one operation can be
presented to an indirect mkey. The RegEx which only accepts one
mkey can now process the whole scattered mbuf in one operation.
The maximum scattered mbuf can be supported in one UMR WQE is now
defined as 64. The mbufs from multiple operations can be combined
into one UMR WQE as well if there is enough space in the KLM array,
since the operations can address their own mbuf's content by the
mkey's address and length. However, one operation's scattered mbuf's
can't be placed in two different UMR WQE's KLM array, if the UMR
WQE's KLM does not has enough free space for one operation, the
extra UMR WQE will be engaged.
In case the UMR WQE's indirect mkey will be over wrapped by the SQ's
WQE move, the mkey's index used by the UMR WQE should be the index
of last the RegEX WQE in the operations. As one operation consumes
one WQE set, build the RegEx WQE by reverse helps address the mkey
more efficiently. Once the operations in one burst consumes multiple
mkeys, when the mkey KLM array is full, the reverse WQE set index
will always be the last of the new mkey's for the new UMR WQE.
In GGA mode, the SQ WQE's memory layout becomes UMR/NOP and RegEx
WQE by interleave. The UMR and RegEx WQE can be called as WQE set.
The SQ's pi and ci will also be increased as WQE set not as WQE.
For operations don't have scattered mbuf, uses the mbuf's mkey directly,
the WQE set combination is NOP + RegEx.
For operations have scattered mbuf but share the UMR WQE with others,
the WQE set combination is NOP + RegEx.
For operations complete the UMR WQE, the WQE set combination is UMR +
RegEx.
Signed-off-by: John Hurley <jhurley@nvidia.com>
Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
2021-04-07 07:21:39 +00:00
|
|
|
DRV_LOG(INFO, "RegEx GGA is %s.",
|
|
|
|
priv->has_umr ? "supported" : "unsupported");
|
2020-07-20 06:26:07 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
2020-07-20 06:26:11 +00:00
|
|
|
if (priv->regexdev)
|
|
|
|
rte_regexdev_unregister(priv->regexdev);
|
2020-07-27 17:47:10 +00:00
|
|
|
dev_error:
|
2022-02-09 19:17:15 +00:00
|
|
|
rte_free(priv);
|
2020-07-20 06:26:07 +00:00
|
|
|
return -rte_errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2021-10-19 20:55:46 +00:00
|
|
|
mlx5_regex_dev_remove(struct mlx5_common_device *cdev)
|
2020-07-20 06:26:07 +00:00
|
|
|
{
|
|
|
|
char name[RTE_REGEXDEV_NAME_MAX_LEN];
|
|
|
|
struct rte_regexdev *dev;
|
|
|
|
struct mlx5_regex_priv *priv = NULL;
|
|
|
|
|
2021-10-19 20:55:46 +00:00
|
|
|
mlx5_regex_get_name(name, cdev->dev);
|
2020-07-20 06:26:07 +00:00
|
|
|
dev = rte_regexdev_get_device_by_name(name);
|
|
|
|
if (!dev)
|
|
|
|
return 0;
|
|
|
|
priv = dev->data->dev_private;
|
|
|
|
if (priv) {
|
2021-11-03 18:35:13 +00:00
|
|
|
mlx5_devx_uar_release(&priv->uar);
|
2020-07-20 06:26:11 +00:00
|
|
|
if (priv->regexdev)
|
|
|
|
rte_regexdev_unregister(priv->regexdev);
|
2020-07-20 06:26:07 +00:00
|
|
|
rte_free(priv);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct rte_pci_id mlx5_regex_pci_id_map[] = {
|
|
|
|
{
|
|
|
|
RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
|
|
|
|
PCI_DEVICE_ID_MELLANOX_CONNECTX6DXBF)
|
|
|
|
},
|
2020-10-26 11:41:47 +00:00
|
|
|
{
|
|
|
|
RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
|
|
|
|
PCI_DEVICE_ID_MELLANOX_CONNECTX7BF)
|
|
|
|
},
|
2020-07-20 06:26:07 +00:00
|
|
|
{
|
|
|
|
.vendor_id = 0
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-07-21 14:37:37 +00:00
|
|
|
static struct mlx5_class_driver mlx5_regex_driver = {
|
|
|
|
.drv_class = MLX5_CLASS_REGEX,
|
|
|
|
.name = RTE_STR(MLX5_REGEX_DRIVER_NAME),
|
|
|
|
.id_table = mlx5_regex_pci_id_map,
|
|
|
|
.probe = mlx5_regex_dev_probe,
|
|
|
|
.remove = mlx5_regex_dev_remove,
|
2020-07-20 06:26:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
RTE_INIT(rte_mlx5_regex_init)
|
|
|
|
{
|
2020-07-27 17:47:11 +00:00
|
|
|
mlx5_common_init();
|
2020-07-20 06:26:07 +00:00
|
|
|
if (mlx5_glue)
|
2021-07-21 14:37:37 +00:00
|
|
|
mlx5_class_driver_register(&mlx5_regex_driver);
|
2020-07-20 06:26:07 +00:00
|
|
|
}
|
|
|
|
|
log: register with standardized names
Let's try to enforce the convention where most drivers use a pmd. logtype
with their class reflected in it, and libraries use a lib. logtype.
Introduce two new macros:
- RTE_LOG_REGISTER_DEFAULT can be used when a single logtype is
used in a component. It is associated to the default name provided
by the build system,
- RTE_LOG_REGISTER_SUFFIX can be used when multiple logtypes are used,
and then the passed name is appended to the default name,
RTE_LOG_REGISTER is left untouched for existing external users
and for components that do not comply with the convention.
There is a new Meson variable log_prefix to adapt the default name
for baseband (pmd.bb.), bus (no pmd.) and mempool (no pmd.) classes.
Note: achieved with below commands + reverted change on net/bonding +
edits on crypto/virtio, compress/mlx5, regex/mlx5
$ git grep -l RTE_LOG_REGISTER drivers/ |
while read file; do
pattern=${file##drivers/};
class=${pattern%%/*};
pattern=${pattern#$class/};
drv=${pattern%%/*};
case "$class" in
baseband) pattern=pmd.bb.$drv;;
bus) pattern=bus.$drv;;
mempool) pattern=mempool.$drv;;
*) pattern=pmd.$class.$drv;;
esac
sed -i -e 's/RTE_LOG_REGISTER(\(.*\), '$pattern',/RTE_LOG_REGISTER_DEFAULT(\1,/' $file;
sed -i -e 's/RTE_LOG_REGISTER(\(.*\), '$pattern'\.\(.*\),/RTE_LOG_REGISTER_SUFFIX(\1, \2,/' $file;
done
$ git grep -l RTE_LOG_REGISTER lib/ |
while read file; do
pattern=${file##lib/};
pattern=lib.${pattern%%/*};
sed -i -e 's/RTE_LOG_REGISTER(\(.*\), '$pattern',/RTE_LOG_REGISTER_DEFAULT(\1,/' $file;
sed -i -e 's/RTE_LOG_REGISTER(\(.*\), '$pattern'\.\(.*\),/RTE_LOG_REGISTER_SUFFIX(\1, \2,/' $file;
done
Signed-off-by: David Marchand <david.marchand@redhat.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
2021-04-26 12:51:08 +00:00
|
|
|
RTE_LOG_REGISTER_DEFAULT(mlx5_regex_logtype, NOTICE)
|
2020-08-05 14:51:01 +00:00
|
|
|
RTE_PMD_EXPORT_NAME(MLX5_REGEX_DRIVER_NAME, __COUNTER__);
|
|
|
|
RTE_PMD_REGISTER_PCI_TABLE(MLX5_REGEX_DRIVER_NAME, mlx5_regex_pci_id_map);
|
|
|
|
RTE_PMD_REGISTER_KMOD_DEP(MLX5_REGEX_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
|