From: Marat Khalili <marat.khalili@huawei.com>
To: Stephen Hemminger <stephen@networkplumber.org>,
"dev@dpdk.org" <dev@dpdk.org>
Cc: Konstantin Ananyev <konstantin.ananyev@huawei.com>
Subject: RE: [PATCH v3 6/6] test/bpf: check that bpf_convert can be JIT'd
Date: Tue, 23 Jun 2026 13:57:35 +0000 [thread overview]
Message-ID: <c510bf24a3cd492693fc54f0b558656f@huawei.com> (raw)
In-Reply-To: <20260621162524.82690-7-stephen@networkplumber.org>
Thank you for working on this, please see some comments inline.
> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Sunday 21 June 2026 17:24
> To: dev@dpdk.org
> Cc: Stephen Hemminger <stephen@networkplumber.org>; Konstantin Ananyev <konstantin.ananyev@huawei.com>;
> Marat Khalili <marat.khalili@huawei.com>
> Subject: [PATCH v3 6/6] test/bpf: check that bpf_convert can be JIT'd
>
> Add followup in bpf conversion tests to make sure resulting
> code was also run through JIT and that JIT produces
> same results as non-JIT.
>
> Reduce log output to make it easier to match which
> expression might be causing issues.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> app/test/test_bpf.c | 94 +++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 79 insertions(+), 15 deletions(-)
>
> diff --git a/app/test/test_bpf.c b/app/test/test_bpf.c
> index 3a88434c3c..973dd7d659 100644
> --- a/app/test/test_bpf.c
> +++ b/app/test/test_bpf.c
> @@ -8,6 +8,7 @@
> #include <inttypes.h>
> #include <unistd.h>
>
> +#include <rte_byteorder.h>
> #include <rte_memory.h>
> #include <rte_debug.h>
> #include <rte_hexdump.h>
> @@ -32,6 +33,7 @@ test_bpf(void)
> #include <rte_bpf.h>
> #include <rte_ether.h>
> #include <rte_ip.h>
> +#include <rte_udp.h>
>
>
> /* Tests of most simple BPF programs (no instructions, one instruction etc.) */
> @@ -4529,6 +4531,7 @@ test_bpf_match(pcap_t *pcap, const char *str,
> int ret = -1;
> uint64_t rc;
>
> + printf("%s '%s'\n", __func__, str);
> if (pcap_compile(pcap, &fcode, str, 1, PCAP_NETMASK_UNKNOWN)) {
> printf("%s@%d: pcap_compile(\"%s\") failed: %s;\n",
> __func__, __LINE__, str, pcap_geterr(pcap));
> @@ -4550,6 +4553,24 @@ test_bpf_match(pcap_t *pcap, const char *str,
> }
>
> rc = rte_bpf_exec(bpf, mb);
> +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
We are going to have a few of these lines, I think something like
RTE_BPF_JIT_SUPPORTED is warranted.
> + {
> + struct rte_bpf_jit jit;
> +
> + rte_bpf_get_jit(bpf, &jit);
Out of abundance of caution I would also prefill jit with zeroes and check the
return code here.
> + if (jit.func == NULL) {
> + printf("%s@%d: no JIT generated\n", __func__, __LINE__);
> + goto error;
> + }
> +
> + fflush(stdout);
> + uint64_t rc_jit = jit.func(mb);
> + if (rc_jit != rc) {
> + printf("%s@%d: JIT return code does not match\n", __func__, __LINE__);
> + goto error;
> + }
> + }
> +#endif
> /* The return code from bpf capture filter is non-zero if matched */
> ret = (rc == 0);
> error:
> @@ -4560,23 +4581,16 @@ test_bpf_match(pcap_t *pcap, const char *str,
> return ret;
> }
>
> -/* Basic sanity test can we match a IP packet */
> -static int
> -test_bpf_filter_sanity(pcap_t *pcap)
> +/* Setup mbuf for filter test */
> +static void
> +dummy_ip_prep(void *data, uint16_t plen)
> {
> - const uint32_t plen = 100;
> - struct rte_mbuf mb, *m;
> - uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE];
> struct {
> struct rte_ether_hdr eth_hdr;
> struct rte_ipv4_hdr ip_hdr;
> - } *hdr;
> + struct rte_udp_hdr udp_hdr;
> + } *hdr = data;
>
> - memset(&mb, 0, sizeof(mb));
> - dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen);
> - m = &mb;
> -
> - hdr = rte_pktmbuf_mtod(m, typeof(hdr));
> hdr->eth_hdr = (struct rte_ether_hdr) {
> .dst_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
> .ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4),
> @@ -4589,13 +4603,32 @@ test_bpf_filter_sanity(pcap_t *pcap)
> .src_addr = rte_cpu_to_be_32(RTE_IPV4_LOOPBACK),
> .dst_addr = rte_cpu_to_be_32(RTE_IPV4_BROADCAST),
> };
> + hdr->udp_hdr = (struct rte_udp_hdr) {
> + .src_port = rte_rand_max(UINT16_MAX),
> + .dst_port = rte_cpu_to_be_16(9), /* discard port */
> + .dgram_len = rte_cpu_to_be_16(plen - sizeof(struct rte_ipv4_hdr)),
> + .dgram_cksum = 0,
> + };
> +}
> +
> +
> +/* Basic sanity test can we match a IP packet */
> +static int
> +test_bpf_filter_sanity(pcap_t *pcap)
> +{
> + struct rte_mbuf mb = { 0 };
> + uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE];
> + const uint32_t plen = 100;
> +
> + dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen);
> + dummy_ip_prep(rte_pktmbuf_mtod(&mb, void *), plen);
>
> - if (test_bpf_match(pcap, "ip", m) != 0) {
> + if (test_bpf_match(pcap, "ip", &mb) != 0) {
> printf("%s@%d: filter \"ip\" doesn't match test data\n",
> __func__, __LINE__);
> return -1;
> }
> - if (test_bpf_match(pcap, "not ip", m) == 0) {
> + if (test_bpf_match(pcap, "not ip", &mb) == 0) {
Not a new bug, but this condition should be for non-positive, not just zero.
> printf("%s@%d: filter \"not ip\" does match test data\n",
> __func__, __LINE__);
> return -1;
> @@ -4648,10 +4681,15 @@ static const char * const sample_filters[] = {
> static int
> test_bpf_filter(pcap_t *pcap, const char *s)
> {
> + struct rte_mbuf mb = { 0 };
> + uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE];
> + const uint32_t plen = 100;
> struct bpf_program fcode;
> struct rte_bpf_prm *prm = NULL;
> struct rte_bpf *bpf = NULL;
> + int ret = -1;
>
> + printf("%s '%s'\n", __func__, s);
> if (pcap_compile(pcap, &fcode, s, 1, PCAP_NETMASK_UNKNOWN)) {
> printf("%s@%d: pcap_compile('%s') failed: %s;\n",
> __func__, __LINE__, s, pcap_geterr(pcap));
> @@ -4665,8 +4703,10 @@ test_bpf_filter(pcap_t *pcap, const char *s)
> goto error;
> }
>
> +#ifdef DEBUG
> printf("bpf convert for \"%s\" produced:\n", s);
> rte_bpf_dump(stdout, prm->ins, prm->nb_ins);
> +#endif
>
> bpf = rte_bpf_load(prm);
> if (bpf == NULL) {
> @@ -4675,6 +4715,30 @@ test_bpf_filter(pcap_t *pcap, const char *s)
> goto error;
> }
>
> + dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen);
> + dummy_ip_prep(rte_pktmbuf_mtod(&mb, void *), plen);
> +
> + uint64_t rc = rte_bpf_exec(bpf, &mb);
Would it be hard to check the result against a known correct answer?
> +#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64)
> + {
> + struct rte_bpf_jit jit;
> +
> + rte_bpf_get_jit(bpf, &jit);
Same suggestion regarding zeroing jit and check return code here.
> + if (jit.func == NULL) {
> + printf("%s@%d: no JIT generated\n", __func__, __LINE__);
> + goto error;
> + }
> +
> + fflush(stdout);
> + uint64_t rc_jit = jit.func(&mb);
> + if (rc_jit != rc) {
> + printf("%s@%d: JIT return code does not match\n", __func__, __LINE__);
> + goto error;
> + }
> + }
> +#endif
> + ret = 0;
> +
Are `test_bpf_filter` and `test_bpf_filter_sanity` substantially different any
more, or could they just be merged?
> error:
> if (bpf)
> rte_bpf_destroy(bpf);
> @@ -4685,7 +4749,7 @@ test_bpf_filter(pcap_t *pcap, const char *s)
>
> rte_free(prm);
> pcap_freecode(&fcode);
> - return (bpf == NULL) ? -1 : 0;
> + return ret;
> }
>
> static int
> --
> 2.53.0
next prev parent reply other threads:[~2026-06-23 13:57 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-08 20:28 [PATCH 0/4] bpf/arm64: add BPF_ABS/BPF_IND packet load support Stephen Hemminger
2026-06-08 20:28 ` [PATCH 1/4] bpf/arm64: fix zero-return branch in multi-exit programs Stephen Hemminger
2026-06-17 18:03 ` Marat Khalili
2026-06-08 20:28 ` [PATCH 2/4] test: bpf check that JIT was generated Stephen Hemminger
2026-06-17 18:09 ` Marat Khalili
2026-06-08 20:28 ` [PATCH 3/4] test: bpf check that bpf_convert can be JIT'd Stephen Hemminger
2026-06-17 18:14 ` Marat Khalili
2026-06-08 20:28 ` [PATCH 4/4] bpf/arm64: add BPF_ABS/BPF_IND packet load support Stephen Hemminger
2026-06-17 19:35 ` Marat Khalili
2026-06-17 17:37 ` [PATCH 0/4] " Marat Khalili
2026-06-17 21:17 ` Stephen Hemminger
2026-06-18 20:47 ` [PATCH v2 0/6] bpf: JIT related bug fixes Stephen Hemminger
2026-06-18 20:47 ` [PATCH v2 1/6] bpf/x86: fix JIT encoding of BPF_JSET with immediate Stephen Hemminger
2026-06-19 2:09 ` Stephen Hemminger
2026-06-18 20:47 ` [PATCH v2 2/6] test/bpf: add JSET test with small immediate Stephen Hemminger
2026-06-18 20:47 ` [PATCH v2 3/6] bpf/arm64: fix offset type to allow a negative jump Stephen Hemminger
2026-06-18 20:47 ` [PATCH v2 4/6] test/bpf: check that JIT was generated Stephen Hemminger
2026-06-18 20:47 ` [PATCH v2 5/6] bpf/arm64: add BPF_ABS/BPF_IND packet load support Stephen Hemminger
2026-06-18 20:47 ` [PATCH v2 6/6] test/bpf: check that bpf_convert can be JIT'd Stephen Hemminger
2026-06-21 16:23 ` [PATCH v3 0/6] bpf: JIT related bug fixes Stephen Hemminger
2026-06-21 16:23 ` [PATCH v3 1/6] bpf/x86: fix JIT encoding of BPF_JSET with immediate Stephen Hemminger
2026-06-23 10:11 ` Marat Khalili
2026-06-21 16:23 ` [PATCH v3 2/6] test/bpf: add JSET test with small immediate Stephen Hemminger
2026-06-23 10:16 ` Marat Khalili
2026-06-21 16:23 ` [PATCH v3 3/6] bpf/arm64: fix offset type to allow a negative jump Stephen Hemminger
2026-06-22 16:26 ` Marat Khalili
2026-06-21 16:23 ` [PATCH v3 4/6] test/bpf: check that JIT was generated Stephen Hemminger
2026-06-21 16:23 ` [PATCH v3 5/6] bpf/arm64: add BPF_ABS/BPF_IND packet load support Stephen Hemminger
2026-06-21 16:23 ` [PATCH v3 6/6] test/bpf: check that bpf_convert can be JIT'd Stephen Hemminger
2026-06-23 13:57 ` Marat Khalili [this message]
2026-06-23 15:51 ` 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=c510bf24a3cd492693fc54f0b558656f@huawei.com \
--to=marat.khalili@huawei.com \
--cc=dev@dpdk.org \
--cc=konstantin.ananyev@huawei.com \
--cc=stephen@networkplumber.org \
/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