From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f48.google.com (mail-wm0-f48.google.com [74.125.82.48]) by dpdk.org (Postfix) with ESMTP id E677C3250 for ; Thu, 30 Nov 2017 11:48:05 +0100 (CET) Received: by mail-wm0-f48.google.com with SMTP id f9so11601714wmh.0 for ; Thu, 30 Nov 2017 02:48:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:subject:from:to:cc:date:in-reply-to :references:content-transfer-encoding:mime-version; bh=SC3pb10Hb+tExxWFT/tP/KVlBuwSqGgo5e2Gl1XTe5k=; b=rlLgqtAbOi1HQbEt7pCVcQBAhxdbpsrt/718tPm929MSNMQx8lJVGmjaI8/sFUvpBI 9G17PV055lPwDsuXG1B71EJf71IPnL87zdHT5XBcI1+/BhdnZTF+j9srPsQkASrVmFfg NdLXbKTx/Fhsryu1dJq2d9GqjJ5EWj05zuv6XzSPDJ0qdFgUtRxGlGk3BRyGoQOdEsL0 ZSJwmmqIc3WoJgIVBa1Zlxc+NjIe4/6U8xBnLSr7HfBhvSp9wP59GC9+JiSrgl6qNOb9 CU1p0m89U13ZtOaFxQAmVUhJJJ0Qtx5WTajWQcG4u1s6cEC85N58puylUmKuMbn6f8sD fwfQ== X-Gm-Message-State: AJaThX4vVyLp/ct+3UpKV4zi2bdk9T1UYiOtQEt5a/9A2KqgWz5tVsqS nxJzpCf1XGYmuVxL3x79Nx4= X-Google-Smtp-Source: AGs4zMaYYMiITgK9j1KiZWnSWA8Z7aXGI36K36/O72TtaXGcrZ0+tbzb+Hrw7ymNgwybOi+QScR4PA== X-Received: by 10.28.181.209 with SMTP id e200mr1423601wmf.68.1512038885141; Thu, 30 Nov 2017 02:48:05 -0800 (PST) Received: from localhost ([213.251.34.151]) by smtp.gmail.com with ESMTPSA id r63sm4329340wmg.13.2017.11.30.02.48.04 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 30 Nov 2017 02:48:04 -0800 (PST) Message-ID: <1512038883.10466.1.camel@debian.org> From: Luca Boccassi To: alangordondewar@gmail.com, cristian.dumitrescu@intel.com Cc: dev@dpdk.org, Alan Dewar Date: Thu, 30 Nov 2017 10:48:03 +0000 In-Reply-To: <1512032726-30807-1-git-send-email-alan.dewar@att.com> References: <1512032726-30807-1-git-send-email-alan.dewar@att.com> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Mailer: Evolution 3.22.6-1+deb9u1 Mime-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v2] test: new sched WRR unit-test X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Nov 2017 10:48:06 -0000 On Thu, 2017-11-30 at 09:05 +0000, alangordondewar@gmail.com wrote: > From: Alan Dewar >=20 > New unit-test for the librte_sched WRR weighting code. >=20 > With the standard 17.11 code, the first three sub-tests pass, but > the last three fail due to bugs in the WRR weighting code. >=20 > With v1 of the "sched: fix overflow errors in WRR weighting code" > patch the first five sub-tests pass, and the last sub-test fails > badly. >=20 > With v2 of the "sched: fix overflow errors in WRR weighting code" > patch the first five sub-tests pass, and the last sub-test is a very > near miss (i.e. measured packets counts are one away from the > expected > counts). >=20 > Signed-off-by: Alan Dewar > --- > v2 - add new 255-254-253-1 weightings sub-test >=20 > =C2=A0test/test/Makefile=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0|=C2=A0=C2=A0=C2=A01 + > =C2=A0test/test/test_sched_wrr.c | 491 > +++++++++++++++++++++++++++++++++++++++++++++ > =C2=A02 files changed, 492 insertions(+) > =C2=A0create mode 100644 test/test/test_sched_wrr.c >=20 > diff --git a/test/test/Makefile b/test/test/Makefile > index bb54c98..0ab0ed3 100644 > --- a/test/test/Makefile > +++ b/test/test/Makefile > @@ -173,6 +173,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_NET) +=3D test_crc.c > =C2=A0ifeq ($(CONFIG_RTE_LIBRTE_SCHED),y) > =C2=A0SRCS-y +=3D test_red.c > =C2=A0SRCS-y +=3D test_sched.c > +SRCS-y +=3D test_sched_wrr.c > =C2=A0endif > =C2=A0 > =C2=A0SRCS-$(CONFIG_RTE_LIBRTE_METER) +=3D test_meter.c > diff --git a/test/test/test_sched_wrr.c b/test/test/test_sched_wrr.c > new file mode 100644 > index 0000000..df5a231 > --- /dev/null > +++ b/test/test/test_sched_wrr.c > @@ -0,0 +1,491 @@ > +/*- > + *=C2=A0=C2=A0=C2=A0BSD LICENSE > + * > + *=C2=A0=C2=A0=C2=A0Copyright(c) 2010-2014 Intel Corporation. All rights= reserved. > + *=C2=A0=C2=A0=C2=A0Copyright(c) 2017 ATT Intellectual Property. All rig= hts > reserved. > + *=C2=A0=C2=A0=C2=A0All rights reserved. > + * > + *=C2=A0=C2=A0=C2=A0Redistribution and use in source and binary forms, w= ith or > without > + *=C2=A0=C2=A0=C2=A0modification, are permitted provided that the follow= ing > conditions > + *=C2=A0=C2=A0=C2=A0are met: > + * > + *=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0* Redistributions of source code must re= tain the above > copyright > + *=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0notice, this list of conditi= ons and the following > disclaimer. > + *=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0* Redistributions in binary form must re= produce the above > copyright > + *=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0notice, this list of conditi= ons and the following > disclaimer in > + *=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0the documentation and/or oth= er materials provided with the > + *=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0distribution. > + *=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0* Neither the name of Intel Corporation = nor the names of its > + *=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0contributors may be used to = endorse or promote products > derived > + *=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0from this software without s= pecific prior written > permission. > + * > + *=C2=A0=C2=A0=C2=A0THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS A= ND > CONTRIBUTORS > + *=C2=A0=C2=A0=C2=A0"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLU= DING, BUT > NOT > + *=C2=A0=C2=A0=C2=A0LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILIT= Y AND > FITNESS FOR > + *=C2=A0=C2=A0=C2=A0A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHA= LL THE > COPYRIGHT > + *=C2=A0=C2=A0=C2=A0OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDI= RECT, > INCIDENTAL, > + *=C2=A0=C2=A0=C2=A0SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUD= ING, BUT > NOT > + *=C2=A0=C2=A0=C2=A0LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVI= CES; LOSS > OF USE, > + *=C2=A0=C2=A0=C2=A0DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER = CAUSED AND > ON ANY > + *=C2=A0=C2=A0=C2=A0THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIA= BILITY, OR > TORT > + *=C2=A0=C2=A0=C2=A0(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY W= AY OUT OF > THE USE > + *=C2=A0=C2=A0=C2=A0OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY= OF SUCH > DAMAGE. > + * > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +#include "test.h" > + > +#include > +#include > +#include > +#include > +#include > + > + > +#define SUBPORT=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A00 > +#define PIPE=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A01 > +#define TC=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=A00 > +#define QUEUE=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A03 > + > +static struct rte_sched_subport_params subport_param[] =3D { > + { > + .tb_rate =3D 1250000000, > + .tb_size =3D 1000000, > + > + .tc_rate =3D {1250000000, 1250000000, 1250000000, > 1250000000}, > + .tc_period =3D 10, > + }, > +}; > + > +static struct rte_sched_pipe_params pipe_profile[] =3D { > + { /* Profile #0 */ > + .tb_rate =3D 3051750, > + .tb_size =3D 1000000, > + > + .tc_rate =3D {3051750, 3051750, 3051750, 3051750}, > + .tc_period =3D 160, > + > + .wrr_weights =3D {1, 1, 1, 1, > + 1, 1, 1, 1, > + 1, 1, 1, 1, > + 1, 1, 1, 1}, > + }, > +}; > + > +static struct rte_sched_port_params port_param =3D { > + .socket =3D 0, /* computed */ > + .rate =3D 0, /* computed */ > + .mtu =3D 1522, > + .frame_overhead =3D RTE_SCHED_FRAME_OVERHEAD_DEFAULT, > + .n_subports_per_port =3D 1, > + .n_pipes_per_subport =3D 1024, > + .qsize =3D {32, 32, 32, 32}, > + .pipe_profiles =3D pipe_profile, > + .n_pipe_profiles =3D 1, > +}; > + > +#define NB_MBUF=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0(4 * 32) > +#define MBUF_DATA_SZ=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(2048 + RTE_PKTMBUF_HE= ADROOM) > +#define MEMPOOL_CACHE_SZ 0 > +#define SOCKET=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A00 > + > + > +static struct rte_mempool * > +create_mempool(uint32_t total_packets) > +{ > + struct rte_mempool *mp; > + > + mp =3D rte_mempool_lookup("test_sched wrr"); > + if (!mp) > + mp =3D rte_pktmbuf_pool_create("test_sched wrr", > total_packets, > + MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, SOCKET); > + > + return mp; > +} > + > +static void > +delete_mempool(struct rte_mempool *mp) > +{ > + rte_mempool_free(mp); > +} > + > +static void > +prepare_pkt(struct rte_mbuf *mbuf, uint32_t tc, uint32_t queue) > +{ > + struct ether_hdr *eth_hdr; > + struct vlan_hdr *vlan1, *vlan2; > + struct ipv4_hdr *ip_hdr; > + > + /* Simulate a classifier */ > + eth_hdr =3D rte_pktmbuf_mtod(mbuf, struct ether_hdr *); > + vlan1 =3D (struct vlan_hdr *)(ð_hdr->ether_type); > + vlan2 =3D (struct vlan_hdr *)((uintptr_t)ð_hdr->ether_type > + > + =C2=A0=C2=A0=C2=A0=C2=A0sizeof(struct vlan_hdr)); > + eth_hdr =3D (struct ether_hdr *)((uintptr_t)ð_hdr- > >ether_type + > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A02 * sizeof(struct vlan_hdr= )); > + ip_hdr =3D (struct ipv4_hdr *)((uintptr_t)eth_hdr + > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0sizeof(eth_hdr->ether_type)); > + > + vlan1->vlan_tci =3D rte_cpu_to_be_16(SUBPORT); > + vlan2->vlan_tci =3D rte_cpu_to_be_16(PIPE); > + eth_hdr->ether_type =3D=C2=A0=C2=A0rte_cpu_to_be_16(ETHER_TYPE_IPv4); > + ip_hdr->dst_addr =3D IPv4(0, 0, TC, QUEUE); > + > + > + rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, tc, queue, > + =C2=A0e_RTE_METER_YELLOW); > + > + /* 64 byte packet */ > + mbuf->pkt_len=C2=A0=C2=A0=3D 60; > + mbuf->data_len =3D 60; > +} > + > +/* > + * This function carries out the core of the enqueue/dequeue > testing. > + * This is where we should detect failures if the WRR code is > broken. > + */ > +static int > +test_sched_wrr_enqueue_dequeue(const char *subtest_name, > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0struct rte_mempool *mp, > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0struct rte_sched_port *port= , > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0struct rte_mbuf **in_mbufs, > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0struct rte_mbuf **out_mbufs= , > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0int32_t enqueue_packets, > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0int32_t dequeue_packets, > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0uint32_t *expected_counts) > +{ > + uint32_t wrr_counts[RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS] =3D { > 0 }; > + uint32_t pipe; > + int32_t i; > + int err; > + > + /* > + =C2=A0* Create the packets to be enqueued, spread them evenly > across > + =C2=A0* each of the four WRR queues of the test-TC > + =C2=A0*/ > + for (i =3D 0; i < enqueue_packets; i++) { > + in_mbufs[i] =3D rte_pktmbuf_alloc(mp); > + TEST_ASSERT_NOT_NULL(in_mbufs[i], > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0"%s: Packet allocation failed > on packet " > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0"%d\n", subtest_name, i); > + prepare_pkt(in_mbufs[i], TC, (i & 0x3)); > + } > + > + /* > + =C2=A0* Queue all the enqueue packets, none should be dropped as > the > + =C2=A0* four queues should be long enough. > + =C2=A0*/ > + err =3D rte_sched_port_enqueue(port, in_mbufs, > enqueue_packets); > + TEST_ASSERT_EQUAL(err, enqueue_packets, > + =C2=A0=C2=A0"%s: Enqueue failed, err: %d !=3D %d\n", > + =C2=A0=C2=A0subtest_name, err, enqueue_packets); > + > + /* > + =C2=A0* Dequeue the required number of packets. > + =C2=A0*/ > + err =3D rte_sched_port_dequeue(port, out_mbufs, > dequeue_packets); > + TEST_ASSERT_EQUAL(err, dequeue_packets, > + =C2=A0=C2=A0"%s: Dequeue failed, err: %d !=3D %d\n", > + =C2=A0=C2=A0subtest_name, err, dequeue_packets); > + > + /* > + =C2=A0* Check each packet and count which WRR queue it came from. > + =C2=A0*/ > + for (i =3D 0; i < dequeue_packets; i++) { > + enum rte_meter_color color; > + uint32_t subport, traffic_class, queue; > + > + color =3D rte_sched_port_pkt_read_color(out_mbufs[i]); > + TEST_ASSERT_EQUAL(color, e_RTE_METER_YELLOW, > + =C2=A0=C2=A0"%s: Wrong color\n", > subtest_name); > + > + rte_sched_port_pkt_read_tree_path(out_mbufs[i], > + &subport, &pipe, &traffic_class, > &queue); > + > + TEST_ASSERT_EQUAL(subport, SUBPORT, "%s: Wrong > subport\n", > + =C2=A0=C2=A0subtest_name); > + TEST_ASSERT_EQUAL(pipe, PIPE, "%s: Wrong pipe\n", > subtest_name); > + TEST_ASSERT_EQUAL(traffic_class, TC, > + =C2=A0=C2=A0"%s: Wrong traffic-class\n", > subtest_name); > + wrr_counts[queue]++; > + rte_pktmbuf_free(out_mbufs[i]); > + } > + > + /* > + =C2=A0* Check the number of packets dequeued from each WRR queue > + =C2=A0* against the expected counts. > + =C2=A0*/ > + err =3D 0; > + for (i =3D 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { > + printf("%s - WRR queue %d, dequeued: %u, expected: > %u\n", > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0subtest_name, i, wrr_counts[= i], > expected_counts[i]); > + if (wrr_counts[i] !=3D expected_counts[i]) > + err =3D -1; > + } > + return err; > +} > + > +/* > + * This function does the test config set-up and tear-down. > + * If we see failures in here it is probably due to the test > configuration. > + */ > +static int > +test_sched_wrr_test(const char *subtest_name, uint16_t *tc_qlengths, > + =C2=A0=C2=A0=C2=A0=C2=A0uint8_t *wrr_weights, int32_t enqueue_packets, > + =C2=A0=C2=A0=C2=A0=C2=A0int32_t dequeue_packets, uint32_t > *expected_counts) > +{ > + struct rte_mbuf **in_mbufs; > + struct rte_mbuf **out_mbufs; > + struct rte_mempool *mp =3D NULL; > + struct rte_sched_port *port =3D NULL; > + int32_t total_expected =3D 0; > + uint32_t pipe; > + int32_t i; > + int err; > + > + /* > + =C2=A0* Some inbound argument checking > + =C2=A0*/ > + TEST_ASSERT_EQUAL((tc_qlengths[TC] * 4), enqueue_packets, > + =C2=A0=C2=A0"%s: Queue length/Enqueue packet mismatch > - " > + =C2=A0=C2=A0"%u vs %d\n", > + =C2=A0=C2=A0subtest_name, (tc_qlengths[TC] * 4), > enqueue_packets); > + TEST_ASSERT((dequeue_packets <=3D enqueue_packets), > + =C2=A0=C2=A0=C2=A0=C2=A0"%s: Dequeue packets %d > Enqueue packets %d\n= ", > + =C2=A0=C2=A0=C2=A0=C2=A0subtest_name, dequeue_packets, enqueue_packets= ); > + > + for (i =3D 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) > + total_expected +=3D expected_counts[i]; > + > + TEST_ASSERT((dequeue_packets =3D=3D total_expected), > + =C2=A0=C2=A0=C2=A0=C2=A0"%s: Dequeue packets %d !=3D Total expected %u= \n", > + =C2=A0=C2=A0=C2=A0=C2=A0subtest_name, dequeue_packets, total_expected)= ; > + > + /* > + =C2=A0* Create the mempool and allocate arrays to hold the > rte_mbuf pointers > + =C2=A0*/ > + mp =3D create_mempool(enqueue_packets); > + TEST_ASSERT_NOT_NULL(mp, "%s: Error creating mempool\n", > subtest_name); > + > + in_mbufs =3D malloc(sizeof(struct rte_mbuf *) * > enqueue_packets); > + TEST_ASSERT_NOT_NULL(in_mbufs, "%s: Error creating in_mbuf > array\n", > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0subtest_name); > + > + out_mbufs =3D malloc(sizeof(struct rte_mbuf *) * > dequeue_packets); > + TEST_ASSERT_NOT_NULL(out_mbufs, "%s: Error creating out_mbuf > array\n", > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0subtest_name); > + > + /* > + =C2=A0* Set up the port and pipe profiles with the TC's queue > lengths > + =C2=A0* and the WRR queue weightings > + =C2=A0*/ > + port_param.socket =3D 0; > + port_param.rate =3D (uint64_t) 10000 * 1000 * 1000 / 8; > + for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > + port_param.qsize[i] =3D tc_qlengths[i]; > + > + for (i =3D 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) > + pipe_profile[0].wrr_weights[i] =3D wrr_weights[i]; > + > + port =3D rte_sched_port_config(&port_param); > + TEST_ASSERT_NOT_NULL(port, "%s: Error config sched port\n", > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0subtest_name); > + > + err =3D rte_sched_subport_config(port, SUBPORT, > subport_param); > + TEST_ASSERT_SUCCESS(err, "%s: Error config sched, err=3D%d\n", > + =C2=A0=C2=A0=C2=A0=C2=A0subtest_name, err); > + > + for (pipe =3D 0; pipe < port_param.n_pipes_per_subport; > pipe++) { > + err =3D rte_sched_pipe_config(port, SUBPORT, pipe, 0); > + TEST_ASSERT_SUCCESS(err, > + =C2=A0=C2=A0=C2=A0=C2=A0"%s: Error config sched pipe %u, > err=3D%d\n", > + =C2=A0=C2=A0=C2=A0=C2=A0subtest_name, pipe, err); > + } > + > + /* > + =C2=A0* Enqueue and dequeue packets checking that each WRR queue > dequeued > + =C2=A0* the correct number of packets. > + =C2=A0*/ > + err =3D test_sched_wrr_enqueue_dequeue(subtest_name, mp, port, > in_mbufs, > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0out_mbufs, > enqueue_packets, > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dequeue_packets, > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0expected_counts); > + > + /* > + =C2=A0* Free up allocated resources > + =C2=A0*/ > + free(in_mbufs); > + free(out_mbufs); > + rte_sched_port_free(port); > + delete_mempool(mp); > + > + return err; > +} > + > +static int > +test_sched_wrr_even_weights(void) > +{ > + /* > + =C2=A0* Even weighting - each WRR queue should dequeue the same > number of > + =C2=A0* packets > + =C2=A0*/ > + uint16_t tc_qlengths[] =3D { 64, 64, 64, 64 }; > + uint8_t wrr_weights[] =3D { 1, 1, 1, 1,=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0//= TC-0 > + =C2=A0=C2=A01, 1, 1, 1,=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// TC-1 > + =C2=A0=C2=A01, 1, 1, 1,=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// TC-2 > + =C2=A0=C2=A01, 1, 1, 1 };=C2=A0=C2=A0=C2=A0// TC-3 > + int32_t enqueue_packets =3D 64 * 4; > + int32_t dequeue_packets =3D 32; > + uint32_t expected_counts[] =3D { 8, 8, 8, 8 }; > + > + return test_sched_wrr_test("wrr-even-weights", tc_qlengths, > wrr_weights, > + =C2=A0=C2=A0=C2=A0enqueue_packets, dequeue_packets, > + =C2=A0=C2=A0=C2=A0expected_counts); > +} > + > +static int > +test_sched_wrr_8_4_2_1_weights(void) > +{ > + /* > + =C2=A0* Uneven weightings but with a low LCM of 8 * 4 * 2 * 1 =3D > 64 > + =C2=A0*/ > + uint16_t tc_qlengths[] =3D { 64, 64, 64, 64 }; > + uint8_t wrr_weights[] =3D { 8, 4, 2, 1,=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0//= TC-0 > + =C2=A0=C2=A01, 1, 1, 1, > + =C2=A0=C2=A01, 1, 1, 1, > + =C2=A0=C2=A01, 1, 1, 1 }; > + int32_t enqueue_packets =3D 64 * 4; > + int32_t dequeue_packets =3D 15; > + uint32_t expected_counts[] =3D { 8, 4, 2, 1 }; > + > + return test_sched_wrr_test("wrr-8-4-2-1-weights", > tc_qlengths, > + =C2=A0=C2=A0=C2=A0wrr_weights, enqueue_packets, > + =C2=A0=C2=A0=C2=A0dequeue_packets, > expected_counts); > +} > + > +static int > +test_sched_wrr_1_2_3_4_weights(void) > +{ > + /* > + =C2=A0* Uneven weightings with a low LCM, but weightings in > reverse order > + =C2=A0* from previous test > + =C2=A0*/ > + uint16_t tc_qlengths[] =3D { 64, 64, 64, 64 }; > + uint8_t wrr_weights[] =3D { 1, 2, 3, 4, > + =C2=A0=C2=A01, 1, 1, 1, > + =C2=A0=C2=A01, 1, 1, 1, > + =C2=A0=C2=A01, 1, 1, 1 }; > + int32_t enqueue_packets =3D 64 * 4; > + int32_t dequeue_packets =3D 40; > + uint32_t expected_counts[] =3D { 4, 8, 12, 16 }; > + > + return test_sched_wrr_test("wrr-1-2-3-4-weights", > tc_qlengths, > + =C2=A0=C2=A0=C2=A0wrr_weights, enqueue_packets, > + =C2=A0=C2=A0=C2=A0dequeue_packets, > expected_counts); > +} > + > +static int > +test_sched_wrr_11_7_5_3_weights(void) > +{ > + /* > + =C2=A0* This test generates a LCM of 11 * 7 * 5 * 3 =3D 1155. > + =C2=A0* 1155 / 3 =3D 385 which is more than can be fitted in a > uint8_t > + =C2=A0*/ > + uint16_t tc_qlengths[] =3D { 64, 64, 64, 64 }; > + uint8_t wrr_weights[] =3D { 11, 7, 5, 3, > + =C2=A0=C2=A01, 1, 1, 1, > + =C2=A0=C2=A01, 1, 1, 1, > + =C2=A0=C2=A01, 1, 1, 1 }; > + int32_t enqueue_packets =3D 64 * 4; > + int32_t dequeue_packets =3D 26; > + uint32_t expected_counts[] =3D { 11, 7, 5, 3 }; > + > + return test_sched_wrr_test("wrr-11-7-5-3-weights", > tc_qlengths, > + =C2=A0=C2=A0=C2=A0wrr_weights, enqueue_packets, > + =C2=A0=C2=A0=C2=A0dequeue_packets, > expected_counts); > +} > + > +static int > +test_sched_wrr_100_to_97_weights(void) > +{ > + /* > + =C2=A0* The ratios between the weightings is small how well will > the > + =C2=A0* pseudo floating point wrr_cost perform. > + =C2=A0*/ > + uint16_t tc_qlengths[] =3D { 128, 1, 1, 1 }; > + uint8_t wrr_weights[] =3D { 100, 99, 98, 97, > + =C2=A0=C2=A01, 1, 1, 1, > + =C2=A0=C2=A01, 1, 1, 1, > + =C2=A0=C2=A01, 1, 1, 1 }; > + int32_t enqueue_packets =3D 128 * 4; > + int32_t dequeue_packets =3D 394; > + uint32_t expected_counts[] =3D { 100, 99, 98, 97 }; > + > + return test_sched_wrr_test("wrr-100-to-97-weights", > tc_qlengths, > + =C2=A0=C2=A0=C2=A0wrr_weights, enqueue_packets, > + =C2=A0=C2=A0=C2=A0dequeue_packets, > expected_counts); > +} > + > +static int > +test_sched_wrr_255_254_253_1_weights(void) > +{ > + /* > + =C2=A0* This test generates a LCM of 255 * 254 * 253 * 1 =3D > 16386810 > + =C2=A0* 16386810 / 255 =3D=C2=A0=C2=A0=C2=A0=C2=A064262 =3D=C2=A0=C2=A0= =C2=A00xFB06 > + =C2=A0* 16386810 / 1=C2=A0=C2=A0=C2=A0=3D 16386810 =3D 0xFA0AFF > + =C2=A0* 0xFA0AFF needs to be shifted 16 bits left to fit into a > uint8_t > + =C2=A0* but shifting 0xFB06 16 bits left results in a zero > wrr_cost. > + =C2=A0* > + =C2=A0* This test can fail in two different ways. > + =C2=A0* > + =C2=A0* Very badly when the dequeued packet counts aren't even > close to the > + =C2=A0* expected counts due a bug in a recent WRR patch. > + =C2=A0* > + =C2=A0* A very near miss, when the dequeued packet counts are > just one or > + =C2=A0* two packets away from the expected counts.=C2=A0=C2=A0This happ= ens > because > + =C2=A0* the weights of 255, 254, 254 and 1 get converted into > wrr_costs > + =C2=A0* of 1, 1, 1, 250 respectively.=C2=A0=C2=A0I think that this happ= ens > due to > + =C2=A0* rounding errors in the pseudo floating point code used by > WRR. > + =C2=A0*/ > + uint16_t tc_qlengths[] =3D { 1024, 1, 1, 1 }; > + uint8_t wrr_weights[] =3D { 254, 1, 253, 255, > + =C2=A0=C2=A01, 1, 1, 1, > + =C2=A0=C2=A01, 1, 1, 1, > + =C2=A0=C2=A01, 1, 1, 1 }; > + int32_t enqueue_packets =3D 1024 * 4; > + int32_t dequeue_packets =3D 255 + 254 + 253 + 1; > + uint32_t expected_counts[] =3D { 254, 1, 253, 255 }; > + > + return test_sched_wrr_test("wrr-255-254-253-1-weights", > tc_qlengths, > + =C2=A0=C2=A0=C2=A0wrr_weights, enqueue_packets, > + =C2=A0=C2=A0=C2=A0dequeue_packets, > expected_counts); > +} > + > +/** > + * WRR test main entrance for library sched > + */ > +static int > +test_sched_wrr(void) > +{ > + TEST_ASSERT_SUCCESS(test_sched_wrr_even_weights(), > + =C2=A0=C2=A0=C2=A0=C2=A0"even-weight test failed\n"); > + TEST_ASSERT_SUCCESS(test_sched_wrr_8_4_2_1_weights(), > + =C2=A0=C2=A0=C2=A0=C2=A0"8-4-2-1-weight test failed\n"); > + TEST_ASSERT_SUCCESS(test_sched_wrr_1_2_3_4_weights(), > + =C2=A0=C2=A0=C2=A0=C2=A0"1-2-3-4-weight test failed\n"); > + TEST_ASSERT_SUCCESS(test_sched_wrr_11_7_5_3_weights(), > + =C2=A0=C2=A0=C2=A0=C2=A0"11-7-5-3-weight test failed\n"); > + TEST_ASSERT_SUCCESS(test_sched_wrr_100_to_97_weights(), > + =C2=A0=C2=A0=C2=A0=C2=A0"100-to-97-weight test failed\n"); > + TEST_ASSERT_SUCCESS(test_sched_wrr_255_254_253_1_weights(), > + =C2=A0=C2=A0=C2=A0=C2=A0"255-254-253-1-weight test failed\n"); > + return 0; > +} > + > +REGISTER_TEST_COMMAND(sched_wrr_test, test_sched_wrr); Reviewed-by: Luca Boccassi LGTM --=20 Kind regards, Luca Boccassi