DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Prudvi Deti <prudvi.deti@intel.com>
To: dev@dpdk.org
Cc: bruce.richardson@intel.com, orika@nvidia.com,
	nirint.shah@intel.com, prudvi.deti@intel.com
Subject: [RFC 1/7] regex/hs: add driver skeleton and build integration
Date: Fri, 28 Aug 2026 11:05:50 +0530	[thread overview]
Message-ID: <20260828053629.1224611-2-prudvi.deti@intel.com> (raw)
In-Reply-To: <20260828053629.1224611-1-prudvi.deti@intel.com>

Add a new software regex Poll Mode Driver based on Intel Hyperscan.
This patch provides the minimal vdev skeleton: probe, remove, device
registration, and info_get.

Build is gated by meson dependency check on libhs via pkg-config.
Only supported on 64-bit platforms.

Includes documentation, MAINTAINERS entry, feature matrix, and
release notes.

Signed-off-by: Prudvi Deti <prudvi.deti@intel.com>
---
 .mailmap                               |   1 +
 MAINTAINERS                            |   6 +
 doc/guides/regexdevs/features/hs.ini   |   8 ++
 doc/guides/regexdevs/hs.rst            | 143 +++++++++++++++++++
 doc/guides/regexdevs/index.rst         |   1 +
 doc/guides/rel_notes/release_26_11.rst |   7 +
 drivers/regex/hs/hs_regex.c            | 186 +++++++++++++++++++++++++
 drivers/regex/hs/hs_regex.h            |  69 +++++++++
 drivers/regex/hs/meson.build           |  19 +++
 drivers/regex/meson.build              |   1 +
 10 files changed, 441 insertions(+)
 create mode 100644 doc/guides/regexdevs/features/hs.ini
 create mode 100644 doc/guides/regexdevs/hs.rst
 create mode 100644 drivers/regex/hs/hs_regex.c
 create mode 100644 drivers/regex/hs/hs_regex.h
 create mode 100644 drivers/regex/hs/meson.build

diff --git a/.mailmap b/.mailmap
index fcb3d1b..8a8a6e4 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1336,6 +1336,7 @@ Pravin Pathak <pravin.pathak.dev@gmail.com> <pravin.pathak@intel.com>
 Prince Takkar <ptakkar@marvell.com>
 Priyalee Kushwaha <priyalee.kushwaha@intel.com>
 Priyanka Jain <priyanka.jain@nxp.com>
+Prudvi Deti <prudvi.deti@intel.com>
 Przemek Kitszel <przemyslaw.kitszel@intel.com>
 Przemyslaw Ciesielski <przemyslaw.ciesielski@intel.com>
 Przemyslaw Czesnowicz <przemyslaw.czesnowicz@intel.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index e99a65d..e29af50 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1433,6 +1433,12 @@ F: drivers/regex/cn9k/
 F: doc/guides/regexdevs/cn9k.rst
 F: doc/guides/regexdevs/features/cn9k.ini
 
+Intel Hyperscan
+M: Prudvi Deti <prudvi.deti@intel.com>
+F: drivers/regex/hs/
+F: doc/guides/regexdevs/hs.rst
+F: doc/guides/regexdevs/features/hs.ini
+
 NVIDIA mlx5
 M: Ori Kam <orika@nvidia.com>
 F: drivers/regex/mlx5/
diff --git a/doc/guides/regexdevs/features/hs.ini b/doc/guides/regexdevs/features/hs.ini
new file mode 100644
index 0000000..58cf4a2
--- /dev/null
+++ b/doc/guides/regexdevs/features/hs.ini
@@ -0,0 +1,8 @@
+;
+; Supported features of the 'hs' RegEx driver.
+;
+; Refer to default.ini for the full list of available driver features.
+;
+[Features]
+Run time compilation        = Y
+x86                         = Y
diff --git a/doc/guides/regexdevs/hs.rst b/doc/guides/regexdevs/hs.rst
new file mode 100644
index 0000000..e94466a
--- /dev/null
+++ b/doc/guides/regexdevs/hs.rst
@@ -0,0 +1,143 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2026 Intel Corporation
+
+Hyperscan RegEx PMD
+===================
+
+The Hyperscan RegEx PMD (**librte_regex_hs**) provides a poll mode
+regexdev driver backed by Intel's
+`Hyperscan <https://github.com/intel/hyperscan>`_ regular expression
+library. It is a software-only virtual device (vdev) PMD that
+implements the ``rte_regexdev`` API using Hyperscan block mode scanning.
+
+Features
+--------
+
+- Software-only virtual device (no hardware dependency)
+- Runtime pattern compilation via ``hs_compile_ext_multi()``
+- Serialized database import/export
+- Per-queue-pair scratch space for lock-free parallel scanning
+- Up to 64 queue pairs, each with up to 32768 descriptors
+- Up to 1,000,000 rules per device, with O(1) duplicate rule_id
+  detection backed by ``rte_hash``
+- Per-rule extended match parameters (minimum/maximum start offset)
+- Per-queue-pair statistics via xstats
+
+In the RegEx driver feature matrix, this PMD reports:
+
+- ``Run time compilation``
+- ``x86``
+
+Supported Regex Rule Flags (Hyperscan Mapping)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Standard DPDK flags (advertised via ``info->rule_flags``):
+
+- ``RTE_REGEX_PCRE_RULE_ALLOW_EMPTY_F`` (maps to ``HS_FLAG_ALLOWEMPTY``)
+- ``RTE_REGEX_PCRE_RULE_CASELESS_F``    (maps to ``HS_FLAG_CASELESS``)
+- ``RTE_REGEX_PCRE_RULE_DOTALL_F``      (maps to ``HS_FLAG_DOTALL``)
+- ``RTE_REGEX_PCRE_RULE_MULTILINE_F``   (maps to ``HS_FLAG_MULTILINE``)
+- ``RTE_REGEX_PCRE_RULE_UCP_F``         (maps to ``HS_FLAG_UCP``)
+- ``RTE_REGEX_PCRE_RULE_UTF_F``         (maps to ``HS_FLAG_UTF8``)
+
+PMD-private flags (accepted in ``rule_flags`` but not advertised;
+defined in ``drivers/regex/hs/hs_regex.h``):
+
+- ``HS_REGEX_RULE_SINGLEMATCH_F``  (bit 32, maps to ``HS_FLAG_SINGLEMATCH``)
+- ``HS_REGEX_RULE_PREFILTER_F``    (bit 33, maps to ``HS_FLAG_PREFILTER``)
+- ``HS_REGEX_RULE_SOM_LEFTMOST_F`` (bit 34, maps to ``HS_FLAG_SOM_LEFTMOST``)
+- ``HS_REGEX_RULE_COMBINATION_F``  (bit 35, maps to ``HS_FLAG_COMBINATION``)
+- ``HS_REGEX_RULE_QUIET_F``        (bit 36, maps to ``HS_FLAG_QUIET``)
+
+Unknown flag bits are rejected with an error during ``rule_db_update``.
+
+Extended Match Parameters
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Per-rule minimum and maximum start offset constraints (Hyperscan
+``hs_expr_ext_t``) can be encoded in the upper bits of ``rule_flags``:
+
+- Bits 37-49 (13 bits, mask ``0x1FFF``): maximum start offset,
+  mapped to ``HS_EXT_FLAG_MAX_OFFSET``.
+- Bits 50-63 (14 bits, mask ``0x3FFF``): minimum start offset,
+  mapped to ``HS_EXT_FLAG_MIN_OFFSET``.
+
+A value of 0 leaves the corresponding constraint disabled. These
+constraints are applied via ``hs_compile_ext_multi()`` during
+``rule_db_compile_activate``.
+
+Prerequisites
+-------------
+
+The Hyperscan library must be installed and discoverable via
+``pkg-config``.  On Ubuntu/Debian::
+
+    sudo apt install libhyperscan-dev
+
+On Fedora/RHEL::
+
+    sudo dnf install hyperscan-devel
+
+The PMD is built automatically when ``libhs`` is found by the meson
+build system.  It is only supported on 64-bit platforms.
+
+Device Setup
+------------
+
+The Hyperscan PMD is a virtual device.  Create it with the EAL
+``--vdev`` option::
+
+    dpdk-app --vdev regex_hs -- ...
+
+Or programmatically with ``rte_vdev_init()``::
+
+    rte_vdev_init("regex_hs", NULL);
+
+Device Lifecycle
+~~~~~~~~~~~~~~~~
+
+.. code-block:: c
+
+    rte_regexdev_configure(dev, &cfg);
+    rte_regexdev_queue_pair_setup(dev, qp_id, &qp_conf);
+    rte_regexdev_rule_db_update(dev, rules, nb_rules);
+    rte_regexdev_rule_db_compile_activate(dev);
+    rte_regexdev_start(dev);
+
+    /* data path */
+    rte_regexdev_enqueue_burst(dev, qp, ops, n);
+    rte_regexdev_dequeue_burst(dev, qp, results, n);
+
+    rte_regexdev_stop(dev);
+    rte_regexdev_close(dev);
+
+Alternatively, a pre-compiled serialized database can be loaded
+during ``rte_regexdev_configure()`` via ``cfg.rule_db`` and
+``cfg.rule_db_len``, or at any time via ``rte_regexdev_rule_db_import()``.
+
+Statistics
+~~~~~~~~~~
+
+Extended statistics are reported per queue pair, with names of the
+form ``qp<N>_enqueued``, ``qp<N>_dequeued``, and ``qp<N>_matches``.
+All counters can be reset in bulk or selectively by stat id via
+``rte_regexdev_xstats_reset()``.
+
+Limitations
+-----------
+
+- Scanning is synchronous: ``enqueue_burst`` blocks until
+  ``hs_scan()`` completes for each operation.
+- Multi-segment mbufs are linearized (``rte_pktmbuf_linearize()``)
+  before scanning; linearization failure marks the op with
+  ``RTE_REGEX_OPS_RSP_RESOURCE_LIMIT_REACHED_F``.
+- Multi-process mode is not supported.
+- Each queue pair must be used by exactly one lcore
+  (single-producer/single-consumer model).
+
+Debugging Options
+-----------------
+
+Enable PMD debug logging with::
+
+    --log-level='pmd.regex.hs,8'
diff --git a/doc/guides/regexdevs/index.rst b/doc/guides/regexdevs/index.rst
index 4f928f9..bf4ca10 100644
--- a/doc/guides/regexdevs/index.rst
+++ b/doc/guides/regexdevs/index.rst
@@ -13,4 +13,5 @@ which can be used from an application through RegEx API.
 
    features_overview
    cn9k
+   hs
    mlx5
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index c8cc862..31afd5e 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -56,6 +56,13 @@ New Features
      =======================================================
 
 
+* **Added Hyperscan regex PMD.**
+
+  Added a software regex PMD (``regex_hs``) based on Intel Hyperscan
+  library. This virtual device PMD implements the regexdev API using
+  Hyperscan block mode scanning and supports runtime pattern compilation.
+
+
 Removed Items
 -------------
 
diff --git a/drivers/regex/hs/hs_regex.c b/drivers/regex/hs/hs_regex.c
new file mode 100644
index 0000000..393283b
--- /dev/null
+++ b/drivers/regex/hs/hs_regex.c
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2026 Intel Corporation
+ *
+ * Intel Hyperscan PMD for DPDK rte_regexdev
+ *
+ * This Poll Mode Driver wraps Intel Hyperscan behind the standard DPDK
+ * regex device API (rte_regexdev). Applications use the enqueue/dequeue
+ * burst interface with Hyperscan as the matching engine.
+ *
+ * Key design:
+ *   - Synchronous scan in enqueue (hs_scan blocks until done)
+ *   - Per-queue-pair scratch space for lock-free parallel scanning
+ *   - HS_MODE_BLOCK: each buffer scanned independently
+ *   - Runtime compilation via hs_compile_ext_multi()
+ *   - Serialized database import/export via hs_deserialize_database()
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_log.h>
+#include <rte_errno.h>
+#include <bus_vdev_driver.h>
+#include <rte_regexdev.h>
+#include <rte_regexdev_core.h>
+#include <rte_regexdev_driver.h>
+#include <rte_mbuf.h>
+
+#include <hs/hs.h>
+
+#include "hs_regex.h"
+
+RTE_LOG_REGISTER_DEFAULT(hs_regex_logtype, NOTICE);
+#define RTE_LOGTYPE_HS_REGEX hs_regex_logtype
+
+#define HS_LOG(level, ...) \
+	RTE_LOG_LINE(level, HS_REGEX, __VA_ARGS__)
+
+/* Device Info */
+static int
+hs_regex_info_get(struct rte_regexdev *dev __rte_unused,
+		  struct rte_regexdev_info *info)
+{
+	info->driver_name = HS_REGEX_DRIVER_NAME;
+	info->dev = NULL;
+	info->max_matches = UINT16_MAX;
+	info->max_queue_pairs = HS_REGEX_MAX_QUEUE_PAIRS;
+	info->max_payload_size = UINT16_MAX;
+	info->max_rules_per_group = HS_REGEX_MAX_RULES;
+	info->max_groups = HS_REGEX_MAX_GROUPS;
+	info->regexdev_capa = RTE_REGEXDEV_CAPA_RUNTIME_COMPILATION_F;
+	info->rule_flags = RTE_REGEX_PCRE_RULE_CASELESS_F |
+			   RTE_REGEX_PCRE_RULE_DOTALL_F |
+			   RTE_REGEX_PCRE_RULE_MULTILINE_F |
+			   RTE_REGEX_PCRE_RULE_UTF_F;
+
+	return 0;
+}
+
+/* Fast path stubs replaced by real implementations in later patches. */
+
+static uint16_t
+hs_regex_enqueue_burst(struct rte_regexdev *dev __rte_unused,
+		       uint16_t qp_id __rte_unused,
+		       struct rte_regex_ops **ops __rte_unused,
+		       uint16_t nb_ops __rte_unused)
+{
+	return 0;
+}
+
+static uint16_t
+hs_regex_dequeue_burst(struct rte_regexdev *dev __rte_unused,
+		       uint16_t qp_id __rte_unused,
+		       struct rte_regex_ops **ops __rte_unused,
+		       uint16_t nb_ops __rte_unused)
+{
+	return 0;
+}
+
+static const struct rte_regexdev_ops hs_regexdev_ops = {
+	.dev_info_get = hs_regex_info_get,
+};
+
+/* Device Lifecycle */
+
+int
+hs_regex_dev_create(const char *name, struct rte_device *device)
+{
+	struct hs_regex_priv *priv;
+	struct rte_regexdev *dev;
+
+	if (name == NULL || device == NULL)
+		return -EINVAL;
+
+	HS_LOG(INFO, "Creating Hyperscan regex device: %s", name);
+
+	dev = rte_regexdev_register(name);
+	if (!dev) {
+		HS_LOG(ERR, "Failed to register regex device %s", name);
+		return -EINVAL;
+	}
+
+	priv = rte_zmalloc("hs_regex_priv", sizeof(*priv),
+			   RTE_CACHE_LINE_SIZE);
+	if (!priv) {
+		rte_regexdev_unregister(dev);
+		return -ENOMEM;
+	}
+
+	dev->dev_ops = &hs_regexdev_ops;
+	dev->enqueue = hs_regex_enqueue_burst;
+	dev->dequeue = hs_regex_dequeue_burst;
+	dev->device = device;
+	dev->data->dev_private = priv;
+	dev->state = RTE_REGEXDEV_READY;
+
+	HS_LOG(INFO, "Hyperscan regex PMD created (dev_id=%u, hs=%s)",
+	       dev->data->dev_id, hs_version());
+	return dev->data->dev_id;
+}
+
+void
+hs_regex_dev_destroy(const char *name)
+{
+	struct rte_regexdev *dev;
+	struct hs_regex_priv *priv;
+
+	if (name == NULL)
+		return;
+
+	dev = rte_regexdev_get_device_by_name(name);
+	if (!dev)
+		return;
+
+	priv = dev->data->dev_private;
+	if (priv) {
+		rte_free(priv);
+		dev->data->dev_private = NULL;
+	}
+
+	rte_regexdev_unregister(dev);
+	HS_LOG(INFO, "Hyperscan regex PMD destroyed: %s", name);
+}
+
+static int
+hs_regex_probe(struct rte_vdev_device *vdev)
+{
+	const char *name;
+	int ret;
+
+	name = rte_vdev_device_name(vdev);
+	if (name == NULL)
+		return -EINVAL;
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+		HS_LOG(ERR, "Multi-process not supported for %s", name);
+		return -EINVAL;
+	}
+
+	ret = hs_regex_dev_create(name, &vdev->device);
+	return ret < 0 ? ret : 0;
+}
+
+static int
+hs_regex_remove(struct rte_vdev_device *vdev)
+{
+	const char *name;
+
+	name = rte_vdev_device_name(vdev);
+	if (name == NULL)
+		return -EINVAL;
+
+	hs_regex_dev_destroy(name);
+	return 0;
+}
+
+static struct rte_vdev_driver hs_regex_pmd_drv = {
+	.probe = hs_regex_probe,
+	.remove = hs_regex_remove,
+};
+
+RTE_PMD_REGISTER_VDEV(regex_hs, hs_regex_pmd_drv);
+RTE_PMD_REGISTER_PARAM_STRING(regex_hs, "");
diff --git a/drivers/regex/hs/hs_regex.h b/drivers/regex/hs/hs_regex.h
new file mode 100644
index 0000000..be4c2e9
--- /dev/null
+++ b/drivers/regex/hs/hs_regex.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2026 Intel Corporation
+ */
+
+#ifndef HS_REGEX_H
+#define HS_REGEX_H
+
+#include <rte_regexdev.h>
+#include <hs/hs.h>
+
+#define HS_REGEX_DRIVER_NAME "regex_hs"
+#define HS_REGEX_INITIAL_RULES_CAP 64
+#define HS_REGEX_MAX_QUEUE_PAIRS 64
+#define HS_REGEX_MAX_GROUPS 64
+#define HS_REGEX_MAX_RULES 1000000
+#define HS_REGEX_DEFAULT_NB_DESC 1024
+#define HS_REGEX_MAX_NB_DESC 32768
+
+/* Device lifecycle state machine. */
+enum hs_regex_dev_state {
+	HS_REGEX_DEV_CREATED = 0,
+	HS_REGEX_DEV_CONFIGURED,
+	HS_REGEX_DEV_STARTED,
+	HS_REGEX_DEV_STOPPED,
+};
+
+/* Per-rule entry stored before compilation */
+struct hs_regex_rule {
+	char *pattern;
+	uint32_t rule_id;
+	uint16_t group_id;
+	uint64_t rule_flags;
+};
+
+/* Queue pair */
+struct hs_regex_qp {
+	struct rte_regex_ops **ops;
+	uint16_t nb_desc;
+	uint16_t head;
+	uint16_t tail;
+	uint16_t count;
+	hs_scratch_t *scratch;
+	uint64_t qp_enqueued;
+	uint64_t qp_dequeued;
+	uint64_t qp_matches;
+};
+
+/* Per-device private data */
+struct hs_regex_priv {
+	struct hs_regex_rule *rules;
+	uint32_t nb_rules;
+	uint32_t rules_cap;
+
+	hs_database_t *db;
+	int db_compiled;
+
+	struct hs_regex_qp *qps;
+	uint16_t nb_queue_pairs;
+
+	uint16_t max_matches;
+	uint16_t nb_groups;
+
+	enum hs_regex_dev_state dev_state;
+};
+
+int hs_regex_dev_create(const char *name, struct rte_device *device);
+void hs_regex_dev_destroy(const char *name);
+
+#endif /* HS_REGEX_H */
diff --git a/drivers/regex/hs/meson.build b/drivers/regex/hs/meson.build
new file mode 100644
index 0000000..5c855f4
--- /dev/null
+++ b/drivers/regex/hs/meson.build
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2026 Intel Corporation
+
+if not dpdk_conf.get('RTE_ARCH_64')
+    build = false
+    reason = 'only supported on 64-bit platforms'
+    subdir_done()
+endif
+
+hs_dep = dependency('libhs', required: false)
+if not hs_dep.found()
+    build = false
+    reason = 'missing dependency, "libhs"'
+    subdir_done()
+endif
+
+sources = files('hs_regex.c')
+deps += ['bus_vdev', 'hash']
+ext_deps += hs_dep
diff --git a/drivers/regex/meson.build b/drivers/regex/meson.build
index ff2a8fe..d5a378b 100644
--- a/drivers/regex/meson.build
+++ b/drivers/regex/meson.build
@@ -2,6 +2,7 @@
 # Copyright 2020 Mellanox Technologies, Ltd
 
 drivers = [
+        'hs',
         'mlx5',
         'cn9k',
 ]
-- 
2.43.0


  reply	other threads:[~2026-08-28  5:37 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-28  5:35 [RFC 0/7] regex/hs: introduce Hyperscan regex PMD Prudvi Deti
2026-08-28  5:35 ` Prudvi Deti [this message]
2026-08-28  5:35 ` [RFC 2/7] regex/hs: add device configure and queue pair setup Prudvi Deti
2026-08-28  5:35 ` [RFC 3/7] regex/hs: add rule database update and compilation Prudvi Deti
2026-08-28  5:35 ` [RFC 4/7] regex/hs: add enqueue and dequeue burst paths Prudvi Deti
2026-08-28  5:35 ` [RFC 5/7] regex/hs: add per-queue-pair extended statistics Prudvi Deti
2026-08-28  5:35 ` [RFC 6/7] regex/hs: add start stop close and device dump Prudvi Deti
2026-08-28  5:35 ` [RFC 7/7] regex/hs: add Hyperscan compile flag support Prudvi Deti
2026-08-28 16:34 ` [RFC 0/7] regex/hs: introduce Hyperscan regex PMD Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260828053629.1224611-2-prudvi.deti@intel.com \
    --to=prudvi.deti@intel.com \
    --cc=bruce.richardson@intel.com \
    --cc=dev@dpdk.org \
    --cc=nirint.shah@intel.com \
    --cc=orika@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox