From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id E366C4323F; Mon, 30 Oct 2023 13:31:16 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AFA0D40285; Mon, 30 Oct 2023 13:31:16 +0100 (CET) Received: from mail-oo1-f43.google.com (mail-oo1-f43.google.com [209.85.161.43]) by mails.dpdk.org (Postfix) with ESMTP id 5F48E4026F for ; Mon, 30 Oct 2023 13:31:15 +0100 (CET) Received: by mail-oo1-f43.google.com with SMTP id 006d021491bc7-5841a3ffd50so631503eaf.1 for ; Mon, 30 Oct 2023 05:31:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1698669074; x=1699273874; darn=dpdk.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=V5D+3IfhqddcJeJBDnnsrDNPW/py6gR94cvkgGH3snY=; b=HnQ8vnG+1CEyS3+yAumfPUorf81wTAuZXH/5EU9iCUkjimP7Qc5VxdxEzhrdg5upTu 2YydODL0TTzMKu7RA1mWcrpEAnV8f7NhhYTKaoR7MkdaFZaEj6k6vv98Et0cmjWsWBvm 6uWDibdoqQdYLpIRtI0aEK1GV8TEYkb2UF15Tu+sKEHa3azPaC0cmfBKVJ/JGOjR3lLG 04jD7d7UxoMLi2l6XaREK6h0JbVN2PtcuyaWj11aGjgzxG6Wmid5DLYQhjxjQs2PEBtO gzBSRuAp5Sg5/9kY1dkPA6UM7A8Z3uC2BJRlLKJNrU0/4PVKexvjEaVHvfG+rMqadm02 bRjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698669074; x=1699273874; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=V5D+3IfhqddcJeJBDnnsrDNPW/py6gR94cvkgGH3snY=; b=sxH+8T6VRoaUOMNqVXv8xUHbKhafZjHVkZgV7z0TaLoCNTdCRt5sdJvXresHofbVLk 47y64KMxDghrlsk/erEwwYBWqV15jfI7J2052r+ZZZmeyK+fdSRS4729ZDiz8Bdosm5E dY/FsvFkOgZhykWHOENOr5o5YDpo65Mky33czFeAE6Z3ztStuan5fT1Gqa9gPxpqHofp 9gGtNxa16fSxpBQ0MIz/IuXwYglsgDhH0MpX0I8ycs8QjkBe4L0vjmeCjHl9che9cuAd pJ21yM2nSLmbiHajVNy3Xj4eDYlgkOhLApbij4vlk3XzU9EAHdyA5fEeKT9pknEJbVdu 5aOA== X-Gm-Message-State: AOJu0YxNBJ5EBWOnA/a6tLIVyolfk9DTrS2Jj9/fNKVHEt7ELRDMVOww VyqUqU0ICzVrXUf42pfEl41TdT0jnjZZ/MIg64BRNA== X-Google-Smtp-Source: AGHT+IE8SYYr0z7KqhXQX24lLpETIVNcTeugmT/fSejQ20AhKbAEHW6Qh7nakSvYhEZfSWlT5lVCQWSC+XKcIdTrqcA= X-Received: by 2002:a05:6358:3493:b0:169:4b1f:a82d with SMTP id w19-20020a056358349300b001694b1fa82dmr11325770rwd.3.1698669074407; Mon, 30 Oct 2023 05:31:14 -0700 (PDT) MIME-Version: 1.0 References: <20230912090415.48709-1-changfengnan@bytedance.com> <20231022232234.42168129@sovereign> <20231025090357.60c1f56e@hermes.local> In-Reply-To: <20231025090357.60c1f56e@hermes.local> From: Fengnan Chang Date: Mon, 30 Oct 2023 20:31:03 +0800 Message-ID: Subject: Re: [External] Re: [PATCH] eal: fix modify data area after memset To: Stephen Hemminger Cc: Dmitry Kozlyuk , anatoly.burakov@intel.com, dev@dpdk.org, xuemingl@mellanox.com Content-Type: multipart/alternative; boundary="000000000000c5ce6e0608ee3691" X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --000000000000c5ce6e0608ee3691 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Thanks for your response, It's my fault, I got mixed up=EF=BC=8C this problem only can reproduce after apply https://patches.dpdk.org/project/dpdk/patch/20230831111937.60975-1-changfen= gnan@bytedance.com/ , I'll reorganize this to previous patch. So sorry for waste your time. Stephen Hemminger =E4=BA=8E2023=E5=B9=B410=E6= =9C=8826=E6=97=A5=E5=91=A8=E5=9B=9B 00:04=E5=86=99=E9=81=93=EF=BC=9A > On Mon, 23 Oct 2023 17:07:21 +0800 > Fengnan Chang wrote: > > > Dmitry Kozlyuk =E4=BA=8E2023=E5=B9=B410=E6= =9C=8823=E6=97=A5=E5=91=A8=E4=B8=80 04:22=E5=86=99=E9=81=93=EF=BC=9A > > > > > > 2023-09-22 16:12 (UTC+0800), Fengnan Chang: > > > > ping > > > > > > > > Fengnan Chang =E4=BA=8E2023=E5=B9=B49= =E6=9C=8812=E6=97=A5=E5=91=A8=E4=BA=8C 17:05=E5=86=99=E9=81=93=EF=BC=9A > > > > > > > > > > Let's look at this path: > > > > > malloc_elem_free > > > > > ->malloc_elem_join_adjacent_free > > > > > ->join_elem(elem, elem->next) > > > > > > > > > > 0. cur elem's pad > 0 > > > > > 1. data area memset in malloc_elem_free first. > > > > > 2. next elem is free, try to join cur elem and next. > > > > > 3. in join_elem, try to modify inner->size, this address had > > > > > memset in step 1, it casue the content of addrees become non-zero= . > > > > > > > > > > If user call rte_zmalloc, and pick this elem, it can't get all > > > > > zero'd memory. > > > > > > malloc_elem_join_adjacent_free() always calls memset() after > join_elem(), > > > for the next and the previous element respectively. > > when try to call join_elem() for the next element in > > malloc_elem_join_adjacent_free(), > > the memset is try to memset *next* element, but join_elem() is update > > *current* element's > > content, which shoudn't happen, it's two different element. > > > > > How to reproduce this bug? > > when I test this patch, > > > https://patches.dpdk.org/project/dpdk/patch/20230831111937.60975-1-changf= engnan@bytedance.com/ > > I have a case try to alloc 64/128/192 size object and free with 16 > threads, > > after every > > alloc I'll check wheather all content is 0 or not. > > It's not easy to reproduce, you can have a try, it's easier to find > > this problem in code level. > > I tried to make a test that would reproduce the problem but it did not. > > diff --git a/app/test/test_malloc.c b/app/test/test_malloc.c > index cd579c503cf5..cfd45d6a28eb 100644 > --- a/app/test/test_malloc.c > +++ b/app/test/test_malloc.c > @@ -28,6 +28,7 @@ > #include > > #define N 10000 > +#define BINS 100 > > static int > is_mem_on_socket(int32_t socket); > @@ -69,13 +70,24 @@ is_aligned(void *p, int align) > return 1; > } > > +static bool is_all_zero(uint8_t *mem, size_t sz) > +{ > + size_t i; > + > + for (i =3D 0; i < sz; i++) > + if (mem[i] !=3D 0) > + return false; > + > + return true; > +} > + > static int > test_align_overlap_per_lcore(__rte_unused void *arg) > { > const unsigned align1 =3D 8, > align2 =3D 64, > align3 =3D 2048; > - unsigned i,j; > + unsigned int i; > void *p1 =3D NULL, *p2 =3D NULL, *p3 =3D NULL; > int ret =3D 0; > > @@ -86,11 +98,12 @@ test_align_overlap_per_lcore(__rte_unused void *arg) > ret =3D -1; > break; > } > - for(j =3D 0; j < 1000 ; j++) { > - if( *(char *)p1 !=3D 0) { > - printf("rte_zmalloc didn't zero the > allocated memory\n"); > - ret =3D -1; > - } > + > + if (!is_all_zero(p1, 1000)) { > + printf("rte_zmalloc didn't zero the allocated > memory\n"); > + ret =3D -1; > + rte_free(p1); > + break; > } > p2 =3D rte_malloc("dummy", 1000, align2); > if (!p2){ > @@ -140,6 +153,66 @@ test_align_overlap_per_lcore(__rte_unused void *arg) > return ret; > } > > +/* > + * Allocate random size chunks and make sure that they are > + * always zero. > + */ > +static int > +test_zmalloc(__rte_unused void *arg) > +{ > + unsigned int i, n; > + void *slots[BINS] =3D { }; > + void *p1; > + size_t sz; > + > + /* Allocate many variable size chunks */ > + for (i =3D 0; i < BINS; i++) { > + sz =3D rte_rand_max(1024) + 1; > + p1 =3D rte_zmalloc("slots", sz, 0); > + if (p1 =3D=3D NULL) { > + printf("rte_zmalloc(%zu) returned NULL (i=3D%u)\n= ", > sz, i); > + goto fail; > + } > + slots[i] =3D p1; > + if (!is_all_zero(p1, sz)) > + goto fail; > + } > + > + /* Drop one chunk per iteration */ > + for (n =3D BINS; n > 0; n--) { > + /* Swap in a new block into a slot */ > + for (i =3D 0; i < N; i++) { > + unsigned int bin =3D rte_rand_max(n); > + > + sz =3D rte_rand_max(1024) + 1; > + p1 =3D rte_zmalloc("swap", sz, 0); > + if (!p1){ > + printf("rte_zmalloc(%zu) returned NULL > (i=3D%u)\n", sz, i); > + goto fail; > + } > + > + if (!is_all_zero(p1, sz)) { > + printf("rte_zmalloc didn't zero the > allocated memory\n"); > + goto fail; > + } > + > + rte_free(slots[bin]); > + slots[bin] =3D p1; > + } > + > + /* Drop last bin */ > + rte_free(slots[n]); > + slots[n] =3D NULL; > + } > + > + return 0; > +fail: > + for (i =3D 0; i < BINS; i++) > + rte_free(slots[i]); > + > + return -1; > +} > + > static int > test_reordered_free_per_lcore(__rte_unused void *arg) > { > @@ -1020,6 +1091,21 @@ test_malloc(void) > } > else printf("test_realloc() passed\n"); > > + /*----------------------------*/ > + RTE_LCORE_FOREACH_WORKER(lcore_id) { > + rte_eal_remote_launch(test_zmalloc, NULL, lcore_id); > + } > + > + RTE_LCORE_FOREACH_WORKER(lcore_id) { > + if (rte_eal_wait_lcore(lcore_id) < 0) > + ret =3D -1; > + } > + if (ret < 0){ > + printf("test_zmalloc() failed\n"); > + return ret; > + } > + else printf("test_zmalloc() passed\n"); > + > /*----------------------------*/ > RTE_LCORE_FOREACH_WORKER(lcore_id) { > rte_eal_remote_launch(test_align_overlap_per_lcore, NULL, > lcore_id); > --000000000000c5ce6e0608ee3691 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Thanks for your response, It's my fault,=C2=A0 I= =C2=A0got mixed up=EF=BC=8C
I'll reorganize this to previo= us patch.
So sorry for waste your time.=C2=A0

On Mon, 23 Oct 2023 17:07:21 +0800
Fengnan Chang <
changfengnan@bytedance.com> wrote:

> Dmitry Kozlyuk <dmitry.kozliuk@gmail.com> =E4=BA=8E2023=E5=B9=B410=E6=9C= =8823=E6=97=A5=E5=91=A8=E4=B8=80 04:22=E5=86=99=E9=81=93=EF=BC=9A
> >
> > 2023-09-22 16:12 (UTC+0800), Fengnan Chang:=C2=A0
> > > ping
> > >
> > > Fengnan Chang <changfengnan@bytedance.com> =E4=BA=8E2023=E5= =B9=B49=E6=9C=8812=E6=97=A5=E5=91=A8=E4=BA=8C 17:05=E5=86=99=E9=81=93=EF=BC= =9A=C2=A0
> > > >
> > > > Let's look at this path:
> > > > malloc_elem_free=C2=A0
> > > >=C2=A0 =C2=A0 ->malloc_elem_join_adjacent_free
> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0->join_elem(elem, elem->= ;next)=C2=A0
> > > >
> > > > 0. cur elem's pad > 0
> > > > 1. data area memset in malloc_elem_free first.
> > > > 2. next elem is free, try to join cur elem and next. > > > > 3. in join_elem, try to modify inner->size, this add= ress had
> > > > memset in step 1, it casue the content of addrees becom= e non-zero.
> > > >
> > > > If user call rte_zmalloc, and pick this elem, it can= 9;t get all
> > > > zero'd memory.=C2=A0
> >
> > malloc_elem_join_adjacent_free() always calls memset() after join= _elem(),
> > for the next and the previous element respectively.=C2=A0
> when try to call join_elem() for the next element in
> malloc_elem_join_adjacent_free(),
> the memset is try to memset *next* element, but join_elem() is update<= br> > *current* element's
> content, which shoudn't happen, it's two different element. >
> > How to reproduce this bug?=C2=A0
> when I test this patch,
> h= ttps://patches.dpdk.org/project/dpdk/patch/20230831111937.60975-1-changfeng= nan@bytedance.com/
> I have a case try to alloc 64/128/192 size object and free with 16 thr= eads,
> after every
> alloc I'll check wheather all content is 0 or not.
> It's not easy to reproduce, you can have a try, it's easier to= find
> this problem in code level.

I tried to make a test that would reproduce the problem but it did not.

diff --git a/app/test/test_malloc.c b/app/test/test_malloc.c
index cd579c503cf5..cfd45d6a28eb 100644
--- a/app/test/test_malloc.c
+++ b/app/test/test_malloc.c
@@ -28,6 +28,7 @@
=C2=A0#include <rte_string_fns.h>

=C2=A0#define N 10000
+#define BINS 100

=C2=A0static int
=C2=A0is_mem_on_socket(int32_t socket);
@@ -69,13 +70,24 @@ is_aligned(void *p, int align)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return 1;
=C2=A0}

+static bool is_all_zero(uint8_t *mem, size_t sz)
+{
+=C2=A0 =C2=A0 =C2=A0 =C2=A0size_t i;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < sz; i++)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (mem[i] !=3D 0)<= br> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0return false;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return true;
+}
+
=C2=A0static int
=C2=A0test_align_overlap_per_lcore(__rte_unused void *arg)
=C2=A0{
=C2=A0 =C2=A0 =C2=A0 =C2=A0 const unsigned align1 =3D 8,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 align2 =3D 64,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 align3 =3D 2048;
-=C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned i,j;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int i;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 void *p1 =3D NULL, *p2 =3D NULL, *p3 =3D NULL;<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 int ret =3D 0;

@@ -86,11 +98,12 @@ test_align_overlap_per_lcore(__rte_unused void *arg) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 ret =3D -1;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 break;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for(j =3D 0; j <= 1000 ; j++) {
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0if( *(char *)p1 !=3D 0) {
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("rte_zmalloc didn't z= ero the allocated memory\n");
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D -1;
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (!is_all_zero(p1= , 1000)) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0printf("rte_zmalloc didn't zero the allocated memory\n&q= uot;);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0ret =3D -1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0rte_free(p1);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0break;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 p2 =3D rte_malloc(&= quot;dummy", 1000, align2);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!p2){
@@ -140,6 +153,66 @@ test_align_overlap_per_lcore(__rte_unused void *arg) =C2=A0 =C2=A0 =C2=A0 =C2=A0 return ret;
=C2=A0}

+/*
+ * Allocate random size chunks and make sure that they are
+ * always zero.
+ */
+static int
+test_zmalloc(__rte_unused void *arg)
+{
+=C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int i, n;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0void *slots[BINS] =3D { };
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0void *p1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0size_t sz;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Allocate many variable size chunks */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < BINS; i++) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sz =3D rte_rand_max= (1024) + 1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0p1 =3D rte_zmalloc(= "slots", sz, 0);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (p1 =3D=3D NULL)= {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0printf("rte_zmalloc(%zu) returned NULL (i=3D%u)\n", sz,= i);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0goto fail;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0slots[i] =3D p1; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (!is_all_zero(p1= , sz))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0goto fail;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Drop one chunk per iteration */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0for (n =3D BINS; n > 0; n--) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Swap in a new bl= ock into a slot */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for (i =3D 0; i <= ; N; i++) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0unsigned int bin =3D rte_rand_max(n);
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0sz =3D rte_rand_max(1024) + 1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0p1 =3D rte_zmalloc("swap", sz, 0);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0if (!p1){
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("rte_zmalloc(%zu) returne= d NULL (i=3D%u)\n", sz, i);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto fail;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0if (!is_all_zero(p1, sz)) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("rte_zmalloc didn't z= ero the allocated memory\n");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto fail;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0rte_free(slots[bin]);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0slots[bin] =3D p1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Drop last bin */=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_free(slots[n]);=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0slots[n] =3D NULL;<= br> +=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;
+fail:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < BINS; i++)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_free(slots[i]);=
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;
+}
+
=C2=A0static int
=C2=A0test_reordered_free_per_lcore(__rte_unused void *arg)
=C2=A0{
@@ -1020,6 +1091,21 @@ test_malloc(void)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 =C2=A0 =C2=A0 else printf("test_realloc() passed\n"= );

+=C2=A0 =C2=A0 =C2=A0 =C2=A0/*----------------------------*/
+=C2=A0 =C2=A0 =C2=A0 =C2=A0RTE_LCORE_FOREACH_WORKER(lcore_id) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_eal_remote_laun= ch(test_zmalloc, NULL, lcore_id);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0RTE_LCORE_FOREACH_WORKER(lcore_id) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (rte_eal_wait_lc= ore(lcore_id) < 0)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0ret =3D -1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret < 0){
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("test_z= malloc() failed\n");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return ret;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0else printf("test_zmalloc() passed\n"= );
+
=C2=A0 =C2=A0 =C2=A0 =C2=A0 /*----------------------------*/
=C2=A0 =C2=A0 =C2=A0 =C2=A0 RTE_LCORE_FOREACH_WORKER(lcore_id) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 rte_eal_remote_laun= ch(test_align_overlap_per_lcore, NULL, lcore_id);
--000000000000c5ce6e0608ee3691--