Ady Agbarih 9fa82d287f regex/mlx5: move RXP to CrSpace
Add patch for programming the regex database through ROF file,
using the firmware instead of manually through the software.
No need to setup the DB anymore, the regex-daemon is responsible
for that always.
In the new flow the regex driver only has to program ROF rules
by using set params DevX cmd, requires ROF mkey creation.
The rules file has to be read into 4KB aligned memory.

Signed-off-by: Ady Agbarih <adypodoman@gmail.com>
Acked-by: Ori Kam <orika@nvidia.com>
2021-11-03 23:14:48 +01:00

174 lines
4.5 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright 2020 Mellanox Technologies, Ltd
*/
#include <rte_log.h>
#include <rte_errno.h>
#include <rte_malloc.h>
#include <rte_regexdev.h>
#include <rte_regexdev_core.h>
#include <rte_regexdev_driver.h>
#include <sys/mman.h>
#include <mlx5_glue.h>
#include <mlx5_devx_cmds.h>
#include <mlx5_prm.h>
#include <mlx5_common_os.h>
#include "mlx5_regex.h"
#include "mlx5_regex_utils.h"
#include "mlx5_rxp_csrs.h"
#include "mlx5_rxp.h"
#define MLX5_REGEX_MAX_MATCHES MLX5_RXP_MAX_MATCHES
#define MLX5_REGEX_MAX_PAYLOAD_SIZE MLX5_RXP_MAX_JOB_LENGTH
#define MLX5_REGEX_MAX_RULES_PER_GROUP UINT32_MAX
#define MLX5_REGEX_MAX_GROUPS MLX5_RXP_MAX_SUBSETS
#define MLX5_REGEX_RXP_ROF2_LINE_LEN 34
/* Private Declarations */
static int
rxp_create_mkey(struct mlx5_regex_priv *priv, void *ptr, size_t size,
uint32_t access, struct mlx5_regex_mkey *mkey);
static inline void
rxp_destroy_mkey(struct mlx5_regex_mkey *mkey);
int
mlx5_regex_info_get(struct rte_regexdev *dev __rte_unused,
struct rte_regexdev_info *info)
{
info->max_matches = MLX5_REGEX_MAX_MATCHES;
info->max_payload_size = MLX5_REGEX_MAX_PAYLOAD_SIZE;
info->max_rules_per_group = MLX5_REGEX_MAX_RULES_PER_GROUP;
info->max_groups = MLX5_REGEX_MAX_GROUPS;
info->regexdev_capa = RTE_REGEXDEV_SUPP_PCRE_GREEDY_F |
RTE_REGEXDEV_CAPA_QUEUE_PAIR_OOS_F;
info->rule_flags = 0;
info->max_queue_pairs = UINT16_MAX;
return 0;
}
static int
rxp_create_mkey(struct mlx5_regex_priv *priv, void *ptr, size_t size,
uint32_t access, struct mlx5_regex_mkey *mkey)
{
struct mlx5_devx_mkey_attr mkey_attr;
/* Register the memory. */
mkey->umem = mlx5_glue->devx_umem_reg(priv->cdev->ctx, ptr, size, access);
if (!mkey->umem) {
DRV_LOG(ERR, "Failed to register memory!");
return -ENODEV;
}
/* Create mkey */
mkey_attr = (struct mlx5_devx_mkey_attr) {
.addr = (uintptr_t)ptr,
.size = (uint32_t)size,
.umem_id = mlx5_os_get_umem_id(mkey->umem),
.pg_access = 1,
.umr_en = 0,
};
#ifdef HAVE_IBV_FLOW_DV_SUPPORT
mkey_attr.pd = priv->cdev->pdn;
#endif
mkey->mkey = mlx5_devx_cmd_mkey_create(priv->cdev->ctx, &mkey_attr);
if (!mkey->mkey) {
DRV_LOG(ERR, "Failed to create direct mkey!");
return -ENODEV;
}
return 0;
}
static inline void
rxp_destroy_mkey(struct mlx5_regex_mkey *mkey)
{
if (mkey->mkey)
claim_zero(mlx5_devx_cmd_destroy(mkey->mkey));
if (mkey->umem)
claim_zero(mlx5_glue->devx_umem_dereg(mkey->umem));
}
int
mlx5_regex_rules_db_import(struct rte_regexdev *dev,
const char *rule_db, uint32_t rule_db_len)
{
struct mlx5_regex_priv *priv = dev->data->dev_private;
struct mlx5_regex_mkey mkey;
uint32_t id;
int ret;
void *ptr;
if (priv->prog_mode == MLX5_RXP_MODE_NOT_DEFINED) {
DRV_LOG(ERR, "RXP programming mode not set!");
return -1;
}
if (rule_db == NULL) {
DRV_LOG(ERR, "Database empty!");
return -ENODEV;
}
if (rule_db_len == 0)
return -EINVAL;
/* copy rules - rules have to be 4KB aligned. */
ptr = rte_malloc("", rule_db_len, 1 << 12);
if (!ptr) {
DRV_LOG(ERR, "Failed to allocate rules file memory.");
return -ENOMEM;
}
rte_memcpy(ptr, rule_db, rule_db_len);
/* Register umem and create rof mkey. */
ret = rxp_create_mkey(priv, ptr, rule_db_len, /*access=*/7, &mkey);
if (ret < 0)
return ret;
for (id = 0; id < priv->nb_engines; id++) {
ret = mlx5_devx_regex_rules_program(priv->cdev->ctx, id,
mkey.mkey->id, rule_db_len, (uintptr_t)ptr);
if (ret < 0) {
DRV_LOG(ERR, "Failed to program rxp rules.");
ret = -ENODEV;
break;
}
ret = 0;
}
rxp_destroy_mkey(&mkey);
rte_free(ptr);
return ret;
}
int
mlx5_regex_configure(struct rte_regexdev *dev,
const struct rte_regexdev_config *cfg)
{
struct mlx5_regex_priv *priv = dev->data->dev_private;
int ret;
if (priv->prog_mode == MLX5_RXP_MODE_NOT_DEFINED)
return -1;
priv->nb_queues = cfg->nb_queue_pairs;
dev->data->dev_conf.nb_queue_pairs = priv->nb_queues;
priv->qps = rte_zmalloc(NULL, sizeof(struct mlx5_regex_qp) *
priv->nb_queues, 0);
if (!priv->nb_queues) {
DRV_LOG(ERR, "can't allocate qps memory");
rte_errno = ENOMEM;
return -rte_errno;
}
priv->nb_max_matches = cfg->nb_max_matches;
if (cfg->rule_db != NULL) {
ret = mlx5_regex_rules_db_import(dev, cfg->rule_db,
cfg->rule_db_len);
if (ret < 0) {
DRV_LOG(ERR, "Failed to program rxp rules.");
rte_errno = ENODEV;
goto configure_error;
}
} else
DRV_LOG(DEBUG, "Regex config without rules programming!");
return 0;
configure_error:
if (priv->qps)
rte_free(priv->qps);
return -rte_errno;
}