[v1,4/4] regexdev: implement regex rte level functions

Message ID 1585464438-111285-5-git-send-email-orika@mellanox.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series add RegEx class |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/travis-robot success Travis build: passed
ci/Intel-compilation success Compilation OK

Commit Message

Ori Kam March 29, 2020, 6:47 a.m. UTC
  This commit implements all the RegEx public API.

Signed-off-by: Ori Kam <orika@mellanox.com>
---
 lib/librte_regexdev/rte_regexdev.c | 298 +++++++++++++++++++++++++++++++++++++
 1 file changed, 298 insertions(+)
  

Comments

Pavan Nikhilesh Bhagavatula April 4, 2020, 2:27 p.m. UTC | #1
>This commit implements all the RegEx public API.
>
>Signed-off-by: Ori Kam <orika@mellanox.com>
>---
> lib/librte_regexdev/rte_regexdev.c | 298
>+++++++++++++++++++++++++++++++++++++
> 1 file changed, 298 insertions(+)
>
>diff --git a/lib/librte_regexdev/rte_regexdev.c
>b/lib/librte_regexdev/rte_regexdev.c
>index 4396bb5..72f18fb 100644
>--- a/lib/librte_regexdev/rte_regexdev.c
>+++ b/lib/librte_regexdev/rte_regexdev.c
>@@ -76,3 +76,301 @@
> {
> 	regex_devices[dev->dev_id] = NULL;
> }
>+

<snip>

>+
>+int
>+rte_regexdev_info_get(uint8_t dev_id, struct rte_regexdev_info
>*dev_info)
>+{
>+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
>+		return -EINVAL;

We should use macro for this similar to ethdev/eventdev across the file.

RTE_ETH_VALID_PORTID_OR_ERR_RET
RTE_FUNC_PTR_OR_ERR_RET


>+	if (regex_devices[dev_id] == NULL)
>+		return -EINVAL;
>+	if (dev_info == NULL)
>+		return -EINVAL;
>+	if (regex_devices[dev_id]->dev_ops->dev_info_get == NULL)
>+		return -ENOTSUP;
>+	return regex_devices[dev_id]->dev_ops->dev_info_get
>+		(regex_devices[dev_id], dev_info);
>+}
>+
>+int
>+rte_regexdev_configure(uint8_t dev_id, const struct
>rte_regexdev_config *cfg)
>+{
>+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
>+		return -EINVAL;
>+	if (regex_devices[dev_id] == NULL)
>+		return -EINVAL;
>+	if (cfg == NULL)
>+		return -EINVAL;

Please handle re-configure cases, add error checks for cfg passed based on dev info.

>+	if (regex_devices[dev_id]->dev_ops->dev_configure == NULL)
>+		return -ENOTSUP;
>+	return regex_devices[dev_id]->dev_ops->dev_configure
>+		(regex_devices[dev_id], cfg);
>+}
>+

<Snip>

>+
>+uint16_t
>+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
>+			   struct rte_regex_ops **ops, uint16_t nb_ops)
>+{
>+	return regex_devices[dev_id]-
>>enqueue(regex_devices[dev_id], qp_id,
>+					      ops, nb_ops);
>+}

Move these functions to .h in-lining them.
Also, please add debug checks @see rte_eth_rx_burst/rte_eth_tx_burst.

>+
>+uint16_t
>+rte_regexdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id,
>+			   struct rte_regex_ops **ops, uint16_t nb_ops)
>+{
>+	return regex_devices[dev_id]-
>>dequeue(regex_devices[dev_id], qp_id,
>+					      ops, nb_ops);
>+}
>--
>1.8.3.1
  
Ori Kam April 5, 2020, 3:04 p.m. UTC | #2
Hi Pavan,

Thanks for the review, PSB

Thanks,
Ori

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Pavan Nikhilesh Bhagavatula
> 
> >This commit implements all the RegEx public API.
> >
> >Signed-off-by: Ori Kam <orika@mellanox.com>
> >---
> > lib/librte_regexdev/rte_regexdev.c | 298
> >+++++++++++++++++++++++++++++++++++++
> > 1 file changed, 298 insertions(+)
> >
> >diff --git a/lib/librte_regexdev/rte_regexdev.c
> >b/lib/librte_regexdev/rte_regexdev.c
> >index 4396bb5..72f18fb 100644
> >--- a/lib/librte_regexdev/rte_regexdev.c
> >+++ b/lib/librte_regexdev/rte_regexdev.c
> >@@ -76,3 +76,301 @@
> > {
> > 	regex_devices[dev->dev_id] = NULL;
> > }
> >+
> 
> <snip>
> 
> >+
> >+int
> >+rte_regexdev_info_get(uint8_t dev_id, struct rte_regexdev_info
> >*dev_info)
> >+{
> >+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
> >+		return -EINVAL;
> 
> We should use macro for this similar to ethdev/eventdev across the file.
> 
> RTE_ETH_VALID_PORTID_OR_ERR_RET
> RTE_FUNC_PTR_OR_ERR_RET
> 

O.K will move to macro.

> 
> >+	if (regex_devices[dev_id] == NULL)
> >+		return -EINVAL;
> >+	if (dev_info == NULL)
> >+		return -EINVAL;
> >+	if (regex_devices[dev_id]->dev_ops->dev_info_get == NULL)
> >+		return -ENOTSUP;
> >+	return regex_devices[dev_id]->dev_ops->dev_info_get
> >+		(regex_devices[dev_id], dev_info);
> >+}
> >+
> >+int
> >+rte_regexdev_configure(uint8_t dev_id, const struct
> >rte_regexdev_config *cfg)
> >+{
> >+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
> >+		return -EINVAL;
> >+	if (regex_devices[dev_id] == NULL)
> >+		return -EINVAL;
> >+	if (cfg == NULL)
> >+		return -EINVAL;
> 
> Please handle re-configure cases, add error checks for cfg passed based on dev
> info.
> 

I don't think the checks that you suggest should be done in this level.
The RTE level isn't aware on the specific capabilities of the PMD.
I think it is the responsibility of the PMD to check. 

> >+	if (regex_devices[dev_id]->dev_ops->dev_configure == NULL)
> >+		return -ENOTSUP;
> >+	return regex_devices[dev_id]->dev_ops->dev_configure
> >+		(regex_devices[dev_id], cfg);
> >+}
> >+
> 
> <Snip>
> 
> >+
> >+uint16_t
> >+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
> >+			   struct rte_regex_ops **ops, uint16_t nb_ops)
> >+{
> >+	return regex_devices[dev_id]-
> >>enqueue(regex_devices[dev_id], qp_id,
> >+					      ops, nb_ops);
> >+}
> 
> Move these functions to .h in-lining them.
> Also, please add debug checks @see rte_eth_rx_burst/rte_eth_tx_burst.
> 

O.K will update.

> >+
> >+uint16_t
> >+rte_regexdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id,
> >+			   struct rte_regex_ops **ops, uint16_t nb_ops)
> >+{
> >+	return regex_devices[dev_id]-
> >>dequeue(regex_devices[dev_id], qp_id,
> >+					      ops, nb_ops);
> >+}
> >--
> >1.8.3.1
  
Pavan Nikhilesh Bhagavatula April 5, 2020, 4:48 p.m. UTC | #3
>> >+
>> >+int
>> >+rte_regexdev_configure(uint8_t dev_id, const struct
>> >rte_regexdev_config *cfg)
>> >+{
>> >+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
>> >+		return -EINVAL;
>> >+	if (regex_devices[dev_id] == NULL)
>> >+		return -EINVAL;
>> >+	if (cfg == NULL)
>> >+		return -EINVAL;
>>
>> Please handle re-configure cases, add error checks for cfg passed
>based on dev
>> info.
>>
>
>I don't think the checks that you suggest should be done in this level.
>The RTE level isn't aware on the specific capabilities of the PMD.

PMD capabilities are standardized through dev_info.
All the PMD capabilities needs to be exposed to RTE level through dev_info else 
how would an application using rte_regexdev would know the capabilities of the driver.

>I think it is the responsibility of the PMD to check.

The checks would be same for all the pmds which would just be unnecessary code repetition.
Instead RTE layer should probe dev_info and compare against dev_configure.

>
>> >+	if (regex_devices[dev_id]->dev_ops->dev_configure == NULL)
>> >+		return -ENOTSUP;
>> >+	return regex_devices[dev_id]->dev_ops->dev_configure
>> >+		(regex_devices[dev_id], cfg);
>> >+}
>> >+
>>
>> <Snip>
>>
>> >+
>> >+uint16_t
>> >+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
>> >+			   struct rte_regex_ops **ops, uint16_t nb_ops)
>> >+{
>> >+	return regex_devices[dev_id]-
>> >>enqueue(regex_devices[dev_id], qp_id,
>> >+					      ops, nb_ops);
>> >+}
>>
>> Move these functions to .h in-lining them.
>> Also, please add debug checks @see
>rte_eth_rx_burst/rte_eth_tx_burst.
>>
>
>O.K will update.
>
>> >+
>> >+uint16_t
>> >+rte_regexdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id,
>> >+			   struct rte_regex_ops **ops, uint16_t nb_ops)
>> >+{
>> >+	return regex_devices[dev_id]-
>> >>dequeue(regex_devices[dev_id], qp_id,
>> >+					      ops, nb_ops);
>> >+}
>> >--
>> >1.8.3.1
  
Ori Kam April 5, 2020, 7:46 p.m. UTC | #4
Hi Pavan,

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Pavan Nikhilesh Bhagavatula
> 
> >> >+
> >> >+int
> >> >+rte_regexdev_configure(uint8_t dev_id, const struct
> >> >rte_regexdev_config *cfg)
> >> >+{
> >> >+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
> >> >+		return -EINVAL;
> >> >+	if (regex_devices[dev_id] == NULL)
> >> >+		return -EINVAL;
> >> >+	if (cfg == NULL)
> >> >+		return -EINVAL;
> >>
> >> Please handle re-configure cases, add error checks for cfg passed
> >based on dev
> >> info.
> >>
> >
> >I don't think the checks that you suggest should be done in this level.
> >The RTE level isn't aware on the specific capabilities of the PMD.
> 
> PMD capabilities are standardized through dev_info.
> All the PMD capabilities needs to be exposed to RTE level through dev_info else
> how would an application using rte_regexdev would know the capabilities of
> the driver.
> 

The capabilities are exposed to the application using rte_regexdev_info_get.

> >I think it is the responsibility of the PMD to check.
> 
> The checks would be same for all the pmds which would just be unnecessary
> code repetition.
> Instead RTE layer should probe dev_info and compare against dev_configure.
> 

I accept your comment I will add the missing checks, and re-configuration cases.

> >
> >> >+	if (regex_devices[dev_id]->dev_ops->dev_configure == NULL)
> >> >+		return -ENOTSUP;
> >> >+	return regex_devices[dev_id]->dev_ops->dev_configure
> >> >+		(regex_devices[dev_id], cfg);
> >> >+}
> >> >+
> >>
> >> <Snip>
> >>
> >> >+
> >> >+uint16_t
> >> >+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
> >> >+			   struct rte_regex_ops **ops, uint16_t nb_ops)
> >> >+{
> >> >+	return regex_devices[dev_id]-
> >> >>enqueue(regex_devices[dev_id], qp_id,
> >> >+					      ops, nb_ops);
> >> >+}
> >>
> >> Move these functions to .h in-lining them.
> >> Also, please add debug checks @see
> >rte_eth_rx_burst/rte_eth_tx_burst.
> >>
> >
> >O.K will update.
> >
> >> >+
> >> >+uint16_t
> >> >+rte_regexdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id,
> >> >+			   struct rte_regex_ops **ops, uint16_t nb_ops)
> >> >+{
> >> >+	return regex_devices[dev_id]-
> >> >>dequeue(regex_devices[dev_id], qp_id,
> >> >+					      ops, nb_ops);
> >> >+}
> >> >--
> >> >1.8.3.1
  
Thomas Monjalon April 6, 2020, 11:16 a.m. UTC | #5
05/04/2020 17:04, Ori Kam:
> From: Pavan Nikhilesh Bhagavatula
> > >+uint16_t
> > >+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
> > >+			   struct rte_regex_ops **ops, uint16_t nb_ops)
> > >+{
> > >+	return regex_devices[dev_id]-
> > >>enqueue(regex_devices[dev_id], qp_id,
> > >+					      ops, nb_ops);
> > >+}
> > 
> > Move these functions to .h in-lining them.
> > Also, please add debug checks @see rte_eth_rx_burst/rte_eth_tx_burst.
> 
> O.K will update.

In general, inlining is a pain for ABI compatibility.
Please inline only if the gain is very significant.
  
Pavan Nikhilesh Bhagavatula April 6, 2020, 12:33 p.m. UTC | #6
>> From: Pavan Nikhilesh Bhagavatula
>> > >+uint16_t
>> > >+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
>> > >+			   struct rte_regex_ops **ops, uint16_t nb_ops)
>> > >+{
>> > >+	return regex_devices[dev_id]-
>> > >>enqueue(regex_devices[dev_id], qp_id,
>> > >+					      ops, nb_ops);
>> > >+}
>> >
>> > Move these functions to .h in-lining them.
>> > Also, please add debug checks @see
>rte_eth_rx_burst/rte_eth_tx_burst.
>>
>> O.K will update.
>
>In general, inlining is a pain for ABI compatibility.
>Please inline only if the gain is very significant.
>

The performance gain mostly comes from hoisting `regex_devices[dev_id]` load above the 
poll loop. 
Since, the performance measurement application is still in pipeline and regexdev would be 
experimental for next couple of releases I suggest inlining it now and worrying about ABI when
experimental tag needs to be removed.

We can follow the same path as done by ethdev [https://www.mail-archive.com/dev@dpdk.org/msg142392.html]
  
Thomas Monjalon April 6, 2020, 1:14 p.m. UTC | #7
06/04/2020 14:33, Pavan Nikhilesh Bhagavatula:
> >> From: Pavan Nikhilesh Bhagavatula
> >> > >+uint16_t
> >> > >+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
> >> > >+			   struct rte_regex_ops **ops, uint16_t nb_ops)
> >> > >+{
> >> > >+	return regex_devices[dev_id]-
> >> > >>enqueue(regex_devices[dev_id], qp_id,
> >> > >+					      ops, nb_ops);
> >> > >+}
> >> >
> >> > Move these functions to .h in-lining them.
> >> > Also, please add debug checks @see
> >rte_eth_rx_burst/rte_eth_tx_burst.
> >>
> >> O.K will update.
> >
> >In general, inlining is a pain for ABI compatibility.
> >Please inline only if the gain is very significant.
> >
> 
> The performance gain mostly comes from hoisting `regex_devices[dev_id]` load above the 
> poll loop. 
> Since, the performance measurement application is still in pipeline and regexdev would be 
> experimental for next couple of releases I suggest inlining it now and worrying about ABI when
> experimental tag needs to be removed.

No, we must worry about ABI from the beginning.

> We can follow the same path as done by ethdev [https://www.mail-archive.com/dev@dpdk.org/msg142392.html]

ethdev is not an argument.
  
Jerin Jacob April 6, 2020, 1:20 p.m. UTC | #8
On Mon, Apr 6, 2020 at 6:44 PM Thomas Monjalon <thomas@monjalon.net> wrote:
>
> 06/04/2020 14:33, Pavan Nikhilesh Bhagavatula:
> > >> From: Pavan Nikhilesh Bhagavatula
> > >> > >+uint16_t
> > >> > >+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
> > >> > >+                          struct rte_regex_ops **ops, uint16_t nb_ops)
> > >> > >+{
> > >> > >+       return regex_devices[dev_id]-
> > >> > >>enqueue(regex_devices[dev_id], qp_id,
> > >> > >+                                             ops, nb_ops);
> > >> > >+}
> > >> >
> > >> > Move these functions to .h in-lining them.
> > >> > Also, please add debug checks @see
> > >rte_eth_rx_burst/rte_eth_tx_burst.
> > >>
> > >> O.K will update.
> > >
> > >In general, inlining is a pain for ABI compatibility.
> > >Please inline only if the gain is very significant.
> > >
> >
> > The performance gain mostly comes from hoisting `regex_devices[dev_id]` load above the
> > poll loop.
> > Since, the performance measurement application is still in pipeline and regexdev would be
> > experimental for next couple of releases I suggest inlining it now and worrying about ABI when
> > experimental tag needs to be removed.
>
> No, we must worry about ABI from the beginning.

I think, we need to have the performance number first before we decide
one or another.


>
> > We can follow the same path as done by ethdev [https://www.mail-archive.com/dev@dpdk.org/msg142392.html]
>
> ethdev is not an argument.

Actually this thread explains how to make it inline without exposing
the internal structure unlike existing ethdev. The effort
is stalled due to PMD changes required. In this case, regexdev is new
so it is the correct time to add such code.




>
>
>
  
Pavan Nikhilesh Bhagavatula April 6, 2020, 1:22 p.m. UTC | #9
>06/04/2020 14:33, Pavan Nikhilesh Bhagavatula:
>> >> From: Pavan Nikhilesh Bhagavatula
>> >> > >+uint16_t
>> >> > >+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t
>qp_id,
>> >> > >+			   struct rte_regex_ops **ops, uint16_t
>nb_ops)
>> >> > >+{
>> >> > >+	return regex_devices[dev_id]-
>> >> > >>enqueue(regex_devices[dev_id], qp_id,
>> >> > >+					      ops, nb_ops);
>> >> > >+}
>> >> >
>> >> > Move these functions to .h in-lining them.
>> >> > Also, please add debug checks @see
>> >rte_eth_rx_burst/rte_eth_tx_burst.
>> >>
>> >> O.K will update.
>> >
>> >In general, inlining is a pain for ABI compatibility.
>> >Please inline only if the gain is very significant.
>> >
>>
>> The performance gain mostly comes from hoisting
>`regex_devices[dev_id]` load above the
>> poll loop.
>> Since, the performance measurement application is still in pipeline
>and regexdev would be
>> experimental for next couple of releases I suggest inlining it now and
>worrying about ABI when
>> experimental tag needs to be removed.
>
>No, we must worry about ABI from the beginning.

I though performance was the primary objective :-).

>
>> We can follow the same path as done by ethdev
>[https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mail-
>2Darchive.com_dev-
>40dpdk.org_msg142392.html&d=DwICAg&c=nKjWec2b6R0mOyPaz7xtf
>Q&r=E3SgYMjtKCMVsB-fmvgGV3o-
>g_fjLhk5Pupi9ijohpc&m=7Gqb6WKmZV5uY3xa7FRVrRVDz8Usrsd-
>rDjIKr6CUQQ&s=sQo2Kx9fzTNXwiQ2Fzki3s5GSuiiAEzz2VtN68_KKXo&e=
>]
>
>ethdev is not an argument.

What about ring? [http://mails.dpdk.org/archives/dev/2020-April/161506.html]

Why do we need to prove the same performance advantage using in-lining for datapath 
critical functions again and again?

>
>
  
Thomas Monjalon April 6, 2020, 1:36 p.m. UTC | #10
06/04/2020 15:22, Pavan Nikhilesh Bhagavatula:
> >06/04/2020 14:33, Pavan Nikhilesh Bhagavatula:
> >> >> From: Pavan Nikhilesh Bhagavatula
> >> >> > >+uint16_t
> >> >> > >+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t
> >qp_id,
> >> >> > >+			   struct rte_regex_ops **ops, uint16_t
> >nb_ops)
> >> >> > >+{
> >> >> > >+	return regex_devices[dev_id]-
> >> >> > >>enqueue(regex_devices[dev_id], qp_id,
> >> >> > >+					      ops, nb_ops);
> >> >> > >+}
> >> >> >
> >> >> > Move these functions to .h in-lining them.
> >> >> > Also, please add debug checks @see
> >> >rte_eth_rx_burst/rte_eth_tx_burst.
> >> >>
> >> >> O.K will update.
> >> >
> >> >In general, inlining is a pain for ABI compatibility.
> >> >Please inline only if the gain is very significant.
> >> >
> >>
> >> The performance gain mostly comes from hoisting
> >`regex_devices[dev_id]` load above the
> >> poll loop.
> >> Since, the performance measurement application is still in pipeline
> >and regexdev would be
> >> experimental for next couple of releases I suggest inlining it now and
> >worrying about ABI when
> >> experimental tag needs to be removed.
> >
> >No, we must worry about ABI from the beginning.
> 
> I though performance was the primary objective :-).

It is.

> >> We can follow the same path as done by ethdev
> >[https://urldefense.proofpoint.com/v2/url?u=https-3A__www.mail-
> >2Darchive.com_dev-
> >40dpdk.org_msg142392.html&d=DwICAg&c=nKjWec2b6R0mOyPaz7xtf
> >Q&r=E3SgYMjtKCMVsB-fmvgGV3o-
> >g_fjLhk5Pupi9ijohpc&m=7Gqb6WKmZV5uY3xa7FRVrRVDz8Usrsd-
> >rDjIKr6CUQQ&s=sQo2Kx9fzTNXwiQ2Fzki3s5GSuiiAEzz2VtN68_KKXo&e=
> >]
> >
> >ethdev is not an argument.
> 
> What about ring? [http://mails.dpdk.org/archives/dev/2020-April/161506.html]
> 
> Why do we need to prove the same performance advantage using in-lining for datapath 
> critical functions again and again?

Because every libraries have not the same usage and load.
We should compare how much cycle is saved with inline vs
how much cycles is, "in average", a regex burst?

If you tell me regex processing is fast, OK, let's inline.
  
Pavan Nikhilesh Bhagavatula April 6, 2020, 1:50 p.m. UTC | #11
>-----Original Message-----
>From: Thomas Monjalon <thomas@monjalon.net>
>Sent: Monday, April 6, 2020 7:07 PM
>To: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>
>Cc: Ori Kam <orika@mellanox.com>; Jerin Jacob Kollanukkaran
><jerinj@marvell.com>; xiang.w.wang@intel.com; dev@dpdk.org;
>Shahaf Shuler <shahafs@mellanox.com>; hemant.agrawal@nxp.com;
>Opher Reviv <opher@mellanox.com>; Alex Rosenbaum
><alexr@mellanox.com>; Dovrat Zifroni <dovrat@marvell.com>; Prasun
>Kapoor <pkapoor@marvell.com>; nipun.gupta@nxp.com;
>bruce.richardson@intel.com; yang.a.hong@intel.com;
>harry.chang@intel.com; gu.jian1@zte.com.cn;
>shanjiangh@chinatelecom.cn; zhangy.yun@chinatelecom.cn;
>lixingfu@huachentel.com; wushuai@inspur.com;
>yuyingxia@yxlink.com; fanchenggang@sunyainfo.com;
>davidfgao@tencent.com; liuzhong1@chinaunicom.cn;
>zhaoyong11@huawei.com; oc@yunify.com; jim@netgate.com;
>hongjun.ni@intel.com; j.bromhead@titan-ic.com; deri@ntop.org;
>fc@napatech.com; arthur.su@lionic.com; david.marchand@redhat.com
>Subject: Re: [EXT] [PATCH v1 4/4] regexdev: implement regex rte level
>functions
>
>06/04/2020 15:22, Pavan Nikhilesh Bhagavatula:
>> >06/04/2020 14:33, Pavan Nikhilesh Bhagavatula:
>> >> >> From: Pavan Nikhilesh Bhagavatula
>> >> >> > >+uint16_t
>> >> >> > >+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t
>> >qp_id,
>> >> >> > >+			   struct rte_regex_ops **ops, uint16_t
>> >nb_ops)
>> >> >> > >+{
>> >> >> > >+	return regex_devices[dev_id]-
>> >> >> > >>enqueue(regex_devices[dev_id], qp_id,
>> >> >> > >+					      ops, nb_ops);
>> >> >> > >+}
>> >> >> >
>> >> >> > Move these functions to .h in-lining them.
>> >> >> > Also, please add debug checks @see
>> >> >rte_eth_rx_burst/rte_eth_tx_burst.
>> >> >>
>> >> >> O.K will update.
>> >> >
>> >> >In general, inlining is a pain for ABI compatibility.
>> >> >Please inline only if the gain is very significant.
>> >> >
>> >>
>> >> The performance gain mostly comes from hoisting
>> >`regex_devices[dev_id]` load above the
>> >> poll loop.
>> >> Since, the performance measurement application is still in pipeline
>> >and regexdev would be
>> >> experimental for next couple of releases I suggest inlining it now
>and
>> >worrying about ABI when
>> >> experimental tag needs to be removed.
>> >
>> >No, we must worry about ABI from the beginning.
>>
>> I though performance was the primary objective :-).
>
>It is.
>
>> >> We can follow the same path as done by ethdev
>> >[https://urldefense.proofpoint.com/v2/url?u=https-
>3A__www.mail-
>> >2Darchive.com_dev-
>>
>>40dpdk.org_msg142392.html&d=DwICAg&c=nKjWec2b6R0mOyPaz7xt
>f
>> >Q&r=E3SgYMjtKCMVsB-fmvgGV3o-
>> >g_fjLhk5Pupi9ijohpc&m=7Gqb6WKmZV5uY3xa7FRVrRVDz8Usrsd-
>>
>>rDjIKr6CUQQ&s=sQo2Kx9fzTNXwiQ2Fzki3s5GSuiiAEzz2VtN68_KKXo&e
>=
>> >]
>> >
>> >ethdev is not an argument.
>>
>> What about ring? [https://urldefense.proofpoint.com/v2/url?u=http-
>3A__mails.dpdk.org_archives_dev_2020-
>2DApril_161506.html&d=DwICAg&c=nKjWec2b6R0mOyPaz7xtfQ&r=E3S
>gYMjtKCMVsB-fmvgGV3o-
>g_fjLhk5Pupi9ijohpc&m=u9gnM_YrOJDusN4yR8YUcUuUkri4tOjnHrQ0A
>Qd5zTw&s=uv6AQA-
>Zu7o6ugyhpGHLxFOk4SfEdkHfFGDmhzANRME&e= ]
>>
>> Why do we need to prove the same performance advantage using in-
>lining for datapath
>> critical functions again and again?
>
>Because every libraries have not the same usage and load.
>We should compare how much cycle is saved with inline vs
>how much cycles is, "in average", a regex burst?
>
>If you tell me regex processing is fast, OK, let's inline.
>

Regex processing speed would still be dependent on underlying device capabilities.

All we are trying to do is reduce the enqueue/dequeue completion time which would 
bring down the overall latency.

Thanks,
Pavan.
  
Thomas Monjalon April 6, 2020, 2 p.m. UTC | #12
06/04/2020 15:50, Pavan Nikhilesh Bhagavatula:
> From: Thomas Monjalon <thomas@monjalon.net>
> >> >06/04/2020 14:33, Pavan Nikhilesh Bhagavatula:
> >> >> >> From: Pavan Nikhilesh Bhagavatula
> >> >> >> > >+uint16_t
> >> >> >> > >+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t
> >> >qp_id,
> >> >> >> > >+			   struct rte_regex_ops **ops, uint16_t
> >> >nb_ops)
> >> >> >> > >+{
> >> >> >> > >+	return regex_devices[dev_id]-
> >> >> >> > >>enqueue(regex_devices[dev_id], qp_id,
> >> >> >> > >+					      ops, nb_ops);
> >> >> >> > >+}
> >> >> >> >
> >> >> >> > Move these functions to .h in-lining them.
> >> >> >> > Also, please add debug checks @see
> >> >> >rte_eth_rx_burst/rte_eth_tx_burst.
> >> >> >>
> >> >> >> O.K will update.
> >> >> >
> >> >> >In general, inlining is a pain for ABI compatibility.
> >> >> >Please inline only if the gain is very significant.
> >> >> >
> >> >>
> >> >> The performance gain mostly comes from hoisting
> >> >`regex_devices[dev_id]` load above the
> >> >> poll loop.
> >> >> Since, the performance measurement application is still in pipeline
> >> >and regexdev would be
> >> >> experimental for next couple of releases I suggest inlining it now
> >and
> >> >worrying about ABI when
> >> >> experimental tag needs to be removed.
> >> >
> >> >No, we must worry about ABI from the beginning.
> >>
> >> I though performance was the primary objective :-).
> >
> >It is.
> >
> >> >> We can follow the same path as done by ethdev
> >> >[https://urldefense.proofpoint.com/v2/url?u=https-
> >3A__www.mail-
> >> >2Darchive.com_dev-
> >>
> >>40dpdk.org_msg142392.html&d=DwICAg&c=nKjWec2b6R0mOyPaz7xt
> >f
> >> >Q&r=E3SgYMjtKCMVsB-fmvgGV3o-
> >> >g_fjLhk5Pupi9ijohpc&m=7Gqb6WKmZV5uY3xa7FRVrRVDz8Usrsd-
> >>
> >>rDjIKr6CUQQ&s=sQo2Kx9fzTNXwiQ2Fzki3s5GSuiiAEzz2VtN68_KKXo&e
> >=
> >> >]
> >> >
> >> >ethdev is not an argument.
> >>
> >> What about ring? [https://urldefense.proofpoint.com/v2/url?u=http-
> >3A__mails.dpdk.org_archives_dev_2020-
> >2DApril_161506.html&d=DwICAg&c=nKjWec2b6R0mOyPaz7xtfQ&r=E3S
> >gYMjtKCMVsB-fmvgGV3o-
> >g_fjLhk5Pupi9ijohpc&m=u9gnM_YrOJDusN4yR8YUcUuUkri4tOjnHrQ0A
> >Qd5zTw&s=uv6AQA-
> >Zu7o6ugyhpGHLxFOk4SfEdkHfFGDmhzANRME&e= ]
> >>
> >> Why do we need to prove the same performance advantage using in-
> >lining for datapath
> >> critical functions again and again?
> >
> >Because every libraries have not the same usage and load.
> >We should compare how much cycle is saved with inline vs
> >how much cycles is, "in average", a regex burst?
> >
> >If you tell me regex processing is fast, OK, let's inline.
> >
> 
> Regex processing speed would still be dependent on underlying device capabilities.
> 
> All we are trying to do is reduce the enqueue/dequeue completion time which would 
> bring down the overall latency.

Take your regex HW and do a simple regex processing burst.
How many cycles it takes to complete?
How many cycles you lose if not inline?
If the ratio is lower than 1/200, I think inline is not a must.

Ori, please consider the same measure for your HW.
  
Ori Kam April 6, 2020, 6:53 p.m. UTC | #13
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> Sent: Monday, April 6, 2020 5:00 PM
> To: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>; Ori Kam
> <orika@mellanox.com>
> Cc: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; xiang.w.wang@intel.com;
> dev@dpdk.org; Shahaf Shuler <shahafs@mellanox.com>;
> hemant.agrawal@nxp.com; Opher Reviv <opher@mellanox.com>; Alex
> Rosenbaum <alexr@mellanox.com>; Dovrat Zifroni <dovrat@marvell.com>;
> Prasun Kapoor <pkapoor@marvell.com>; nipun.gupta@nxp.com;
> bruce.richardson@intel.com; yang.a.hong@intel.com; harry.chang@intel.com;
> gu.jian1@zte.com.cn; shanjiangh@chinatelecom.cn;
> zhangy.yun@chinatelecom.cn; lixingfu@huachentel.com; wushuai@inspur.com;
> yuyingxia@yxlink.com; fanchenggang@sunyainfo.com;
> davidfgao@tencent.com; liuzhong1@chinaunicom.cn;
> zhaoyong11@huawei.com; oc@yunify.com; jim@netgate.com;
> hongjun.ni@intel.com; j.bromhead@titan-ic.com; deri@ntop.org;
> fc@napatech.com; arthur.su@lionic.com; david.marchand@redhat.com
> Subject: Re: [dpdk-dev] [EXT] [PATCH v1 4/4] regexdev: implement regex rte
> level functions
> 
> 06/04/2020 15:50, Pavan Nikhilesh Bhagavatula:
> > From: Thomas Monjalon <thomas@monjalon.net>
> > >> >06/04/2020 14:33, Pavan Nikhilesh Bhagavatula:
> > >> >> >> From: Pavan Nikhilesh Bhagavatula
> > >> >> >> > >+uint16_t
> > >> >> >> > >+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t
> > >> >qp_id,
> > >> >> >> > >+			   struct rte_regex_ops **ops, uint16_t
> > >> >nb_ops)
> > >> >> >> > >+{
> > >> >> >> > >+	return regex_devices[dev_id]-
> > >> >> >> > >>enqueue(regex_devices[dev_id], qp_id,
> > >> >> >> > >+					      ops, nb_ops);
> > >> >> >> > >+}
> > >> >> >> >
> > >> >> >> > Move these functions to .h in-lining them.
> > >> >> >> > Also, please add debug checks @see
> > >> >> >rte_eth_rx_burst/rte_eth_tx_burst.
> > >> >> >>
> > >> >> >> O.K will update.
> > >> >> >
> > >> >> >In general, inlining is a pain for ABI compatibility.
> > >> >> >Please inline only if the gain is very significant.
> > >> >> >
> > >> >>
> > >> >> The performance gain mostly comes from hoisting
> > >> >`regex_devices[dev_id]` load above the
> > >> >> poll loop.
> > >> >> Since, the performance measurement application is still in pipeline
> > >> >and regexdev would be
> > >> >> experimental for next couple of releases I suggest inlining it now
> > >and
> > >> >worrying about ABI when
> > >> >> experimental tag needs to be removed.
> > >> >
> > >> >No, we must worry about ABI from the beginning.
> > >>
> > >> I though performance was the primary objective :-).
> > >
> > >It is.
> > >
> > >> >> We can follow the same path as done by ethdev
> > >>
> >[https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefe
> nse.proofpoint.com%2Fv2%2Furl%3Fu%3Dhttps-
> &amp;data=02%7C01%7Corika%40mellanox.com%7Cc3e07910f52846f64b5008
> d7da32d82e%7Ca652971c7d2e4d9ba6a4d149256f461b%7C0%7C0%7C6372177
> 84252928490&amp;sdata=8Pxq8ciUVW7bMiB1XmQBNm%2Fsmy8m1Wa7yKXK
> JRL4d%2B4%3D&amp;reserved=0
> >
> >3A__https://eur03.safelinks.protection.outlook.com/?url=http%3A%2F%2Fww
> w.mail-
> %2F&amp;data=02%7C01%7Corika%40mellanox.com%7Cc3e07910f52846f64b
> 5008d7da32d82e%7Ca652971c7d2e4d9ba6a4d149256f461b%7C0%7C0%7C637
> 217784252928490&amp;sdata=sTDsN85xShTU7WOLQQ2iF8eh%2FyoVHYwDq%
> 2FTdgdHdlbM%3D&amp;reserved=0
> > >> >2Darchive.com_dev-
> > >>
> > >>40dpdk.org_msg142392.html&d=DwICAg&c=nKjWec2b6R0mOyPaz7xt
> > >f
> > >> >Q&r=E3SgYMjtKCMVsB-fmvgGV3o-
> > >> >g_fjLhk5Pupi9ijohpc&m=7Gqb6WKmZV5uY3xa7FRVrRVDz8Usrsd-
> > >>
> > >>rDjIKr6CUQQ&s=sQo2Kx9fzTNXwiQ2Fzki3s5GSuiiAEzz2VtN68_KKXo&e
> > >=
> > >> >]
> > >> >
> > >> >ethdev is not an argument.
> > >>
> > >> What about ring?
> [https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefens
> e.proofpoint.com%2Fv2%2Furl%3Fu%3Dhttp-
> &amp;data=02%7C01%7Corika%40mellanox.com%7Cc3e07910f52846f64b5008
> d7da32d82e%7Ca652971c7d2e4d9ba6a4d149256f461b%7C0%7C0%7C6372177
> 84252928490&amp;sdata=t2qUIj51WPzqQhJngheYh1s7DWzOxd%2FcAyAQK39C
> HgQ%3D&amp;reserved=0
> > >3A__mails.dpdk.org_archives_dev_2020-
> > >2DApril_161506.html&d=DwICAg&c=nKjWec2b6R0mOyPaz7xtfQ&r=E3S
> > >gYMjtKCMVsB-fmvgGV3o-
> > >g_fjLhk5Pupi9ijohpc&m=u9gnM_YrOJDusN4yR8YUcUuUkri4tOjnHrQ0A
> > >Qd5zTw&s=uv6AQA-
> > >Zu7o6ugyhpGHLxFOk4SfEdkHfFGDmhzANRME&e= ]
> > >>
> > >> Why do we need to prove the same performance advantage using in-
> > >lining for datapath
> > >> critical functions again and again?
> > >
> > >Because every libraries have not the same usage and load.
> > >We should compare how much cycle is saved with inline vs
> > >how much cycles is, "in average", a regex burst?
> > >
> > >If you tell me regex processing is fast, OK, let's inline.
> > >
> >
> > Regex processing speed would still be dependent on underlying device
> capabilities.
> >
> > All we are trying to do is reduce the enqueue/dequeue completion time
> which would
> > bring down the overall latency.
> 
> Take your regex HW and do a simple regex processing burst.
> How many cycles it takes to complete?
> How many cycles you lose if not inline?
> If the ratio is lower than 1/200, I think inline is not a must.
> 
> Ori, please consider the same measure for your HW.
> 
I think that the default for data path should be inline.
In this specific case maybe the benefit is small.
I guess that by definition the RegEx is slower than the net device.
It is much harder to check the performance of RegEx device due to the 
fact that it depends on the data itself and on the rules.

I don't have HW to check the numbers right now. Even if I have them
this is for Mellanox implementation other PMD may have different values.
I suggest that we change to inline, and after getting the HW we will run some tests
and based on them we can decide if the API should be changed.
Please note that the API change will be before the first integration of this patch
so it is not real API change.
  

Patch

diff --git a/lib/librte_regexdev/rte_regexdev.c b/lib/librte_regexdev/rte_regexdev.c
index 4396bb5..72f18fb 100644
--- a/lib/librte_regexdev/rte_regexdev.c
+++ b/lib/librte_regexdev/rte_regexdev.c
@@ -76,3 +76,301 @@ 
 {
 	regex_devices[dev->dev_id] = NULL;
 }
+
+uint8_t
+rte_regexdev_count(void)
+{
+	int i;
+	int count = 0;
+
+	for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
+		if (regex_devices[i] != NULL)
+			count++;
+	}
+	return count;
+}
+
+int
+rte_regexdev_get_dev_id(const char *name)
+{
+	int i;
+	int id = -EINVAL;
+
+	if (name == NULL)
+		return -EINVAL;
+	for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
+		if (regex_devices[i] != NULL)
+			if (strcmp(name, regex_devices[i]->dev_name)) {
+				id = regex_devices[i]->dev_id;
+				break;
+			}
+	}
+	return id;
+}
+
+int
+rte_regexdev_info_get(uint8_t dev_id, struct rte_regexdev_info *dev_info)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (dev_info == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_info_get == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_info_get
+		(regex_devices[dev_id], dev_info);
+}
+
+int
+rte_regexdev_configure(uint8_t dev_id, const struct rte_regexdev_config *cfg)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (cfg == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_configure == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_configure
+		(regex_devices[dev_id], cfg);
+}
+
+int
+rte_regexdev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
+			   const struct rte_regexdev_qp_conf *qp_conf)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_qp_setup == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_qp_setup
+		(regex_devices[dev_id], queue_pair_id, qp_conf);
+}
+
+int
+rte_regexdev_start(uint8_t dev_id)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_start == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_start(regex_devices[dev_id]);
+}
+
+void
+rte_regexdev_stop(uint8_t dev_id)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return;
+	if (regex_devices[dev_id] == NULL)
+		return;
+	regex_devices[dev_id]->dev_ops->dev_stop(regex_devices[dev_id]);
+}
+
+int
+rte_regexdev_close(uint8_t dev_id)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_close == NULL)
+		return -ENOTSUP;
+	regex_devices[dev_id]->dev_ops->dev_close(regex_devices[dev_id]);
+	return 0;
+}
+
+int
+rte_regexdev_attr_get(uint8_t dev_id, enum rte_regexdev_attr_id attr_id,
+		      void *attr_value)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_attr_get == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_attr_get
+		(regex_devices[dev_id], attr_id, attr_value);
+}
+
+int
+rte_regexdev_attr_set(uint8_t dev_id, enum rte_regexdev_attr_id attr_id,
+		      const void *attr_value)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_attr_set == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_attr_set
+		(regex_devices[dev_id], attr_id, attr_value);
+}
+
+int
+rte_regexdev_rule_db_update(uint8_t dev_id,
+			    const struct rte_regexdev_rule *rules,
+			    uint32_t nb_rules)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_rule_db_update == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_rule_db_update
+		(regex_devices[dev_id], rules, nb_rules);
+}
+
+int
+rte_regexdev_rule_db_compile_activate(uint8_t dev_id)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_rule_db_compile_activate ==
+	    NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_rule_db_compile_activate
+		(regex_devices[dev_id]);
+}
+
+int
+rte_regexdev_rule_db_import(uint8_t dev_id, const char *rule_db,
+			    uint32_t rule_db_len)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (rule_db == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_db_import == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_db_import
+		(regex_devices[dev_id], rule_db, rule_db_len);
+}
+
+int
+rte_regexdev_rule_db_export(uint8_t dev_id, char *rule_db)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_db_export == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_db_export
+		(regex_devices[dev_id], rule_db);
+}
+
+int
+rte_regexdev_xstats_names_get(uint8_t dev_id,
+			      struct rte_regexdev_xstats_map *xstats_map)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (xstats_map == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_xstats_names_get == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_xstats_names_get
+		(regex_devices[dev_id], xstats_map);
+}
+
+int
+rte_regexdev_xstats_get(uint8_t dev_id, const uint16_t *ids,
+			uint64_t *values, uint16_t n)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_xstats_get == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_xstats_get
+		(regex_devices[dev_id], ids, values, n);
+}
+
+int
+rte_regexdev_xstats_by_name_get(uint8_t dev_id, const char *name,
+				uint16_t *id, uint64_t *value)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_xstats_by_name_get == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_xstats_by_name_get
+		(regex_devices[dev_id], name, id, value);
+}
+
+int
+rte_regexdev_xstats_reset(uint8_t dev_id, const uint16_t *ids,
+			  uint16_t nb_ids)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_xstats_reset == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_xstats_reset
+		(regex_devices[dev_id], ids, nb_ids);
+}
+
+int
+rte_regexdev_selftest(uint8_t dev_id)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_selftest == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_selftest
+		(regex_devices[dev_id]);
+}
+
+int
+rte_regexdev_dump(uint8_t dev_id, FILE *f)
+{
+	if (dev_id >= RTE_MAX_REGEXDEV_DEVS)
+		return -EINVAL;
+	if (regex_devices[dev_id] == NULL)
+		return -EINVAL;
+	if (f == NULL)
+		return -EINVAL;
+	if (regex_devices[dev_id]->dev_ops->dev_dump == NULL)
+		return -ENOTSUP;
+	return regex_devices[dev_id]->dev_ops->dev_dump
+		(regex_devices[dev_id], f);
+}
+
+uint16_t
+rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
+			   struct rte_regex_ops **ops, uint16_t nb_ops)
+{
+	return regex_devices[dev_id]->enqueue(regex_devices[dev_id], qp_id,
+					      ops, nb_ops);
+}
+
+uint16_t
+rte_regexdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id,
+			   struct rte_regex_ops **ops, uint16_t nb_ops)
+{
+	return regex_devices[dev_id]->dequeue(regex_devices[dev_id], qp_id,
+					      ops, nb_ops);
+}