From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2196DA318B for ; Fri, 18 Oct 2019 06:35:25 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id ED9FA1BEBA; Fri, 18 Oct 2019 06:35:23 +0200 (CEST) Received: from us-smtp-delivery-1.mimecast.com (us-smtp-2.mimecast.com [205.139.110.61]) by dpdk.org (Postfix) with ESMTP id 9DD3229C6 for ; Fri, 18 Oct 2019 06:35:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1571373322; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=F/R5uQfK/By/3JEEku5Mdnm7EskSwLDktUUsql6Tvas=; b=W+A2KIudjud7b+yXLgxRqMK6GsTuPmj6sO1mnnSL5Mz07yLFQUVc8/3tJkM1DfpA04+hGV GKeoDTrzT+BVOu0Rquat7fCYSl970ofHyPRwCm+aFfLjQUl+eoL5S8Yq/AKIMRleclAhmm q2gtQOGxg0UfbzIt9AqaqVXDWguFyJ4= Received: from mail-vk1-f200.google.com (mail-vk1-f200.google.com [209.85.221.200]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-290-L6eaxThdN0SBpdNt0CMbUA-1; Fri, 18 Oct 2019 00:35:20 -0400 Received: by mail-vk1-f200.google.com with SMTP id d64so1878153vke.6 for ; Thu, 17 Oct 2019 21:35:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=F/R5uQfK/By/3JEEku5Mdnm7EskSwLDktUUsql6Tvas=; b=XuW1KgCsR+tUL0tCy9eMK/9lFJjLd3Pa0ePWkQAUYaDIqTMNWGHD56yy/xWym9Tb07 V7wB/pfQX3Rcvnxyzl05trr2MZV9nA2k77fO+DFntQizq+RmrO6YoVinNRUrhSfDvcnc 5Xm+dGigHZM/VcjfKDfXG3ugvJS6mE4dGb2LoGaZ70bcHOcfGYDEpPYRLGHbdv7ZqT6l FPYDiUuI+NQjAmT2DAMxiXaWZuqZlVCoH0EeFYf1gR0kjn43rxZBLak3gua9RS0F31Mg uCaWTDc6Q7N2Ty8NQT0gOhwfvCV94Pm39Z4gVDOS22AvL2R6iTfXNAoQ2lYs2lkIo8oz WVCg== X-Gm-Message-State: APjAAAUsIYVJgHV7QmkVXkhC2cLoccKSzX7k0emn1Wsk0Pi+ZYBOcvx/ 3E8TgDKDudS5WogLdUrHk22pOmPcvt4rAzgHaAF15m5FDRsuEe8mgVFXx2wg+KEYxkYjkXdEpzl n3VMDekskK3yHOJ70i04= X-Received: by 2002:a67:fc49:: with SMTP id p9mr4140524vsq.198.1571373320218; Thu, 17 Oct 2019 21:35:20 -0700 (PDT) X-Google-Smtp-Source: APXvYqyjvLkivOTMh/e1l7qmJA3jXstcgkM6Caa7Gdm5c+4uerJqtDKBWOZDEq9f9Er/IH2WVdAbjrKk9ovEco4opMA= X-Received: by 2002:a67:fc49:: with SMTP id p9mr4140510vsq.198.1571373319806; Thu, 17 Oct 2019 21:35:19 -0700 (PDT) MIME-Version: 1.0 References: <20191017222105.105667-1-drc@linux.vnet.ibm.com> <20191017223903.70437-1-drc@linux.vnet.ibm.com> In-Reply-To: <20191017223903.70437-1-drc@linux.vnet.ibm.com> From: David Marchand Date: Fri, 18 Oct 2019 06:35:08 +0200 Message-ID: To: David Christensen Cc: dev X-MC-Unique: L6eaxThdN0SBpdNt0CMbUA-1 X-Mimecast-Spam-Score: 0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [dpdk-dev] [PATCH v2] app/test: add tests for atomic exchanges 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" On Fri, Oct 18, 2019 at 12:39 AM David Christensen wrote: > > The test works by creating a token comprised of random data > and a CRC8 value, using the rte_atomicXX_exchange to exchange > the new token for a previously generated token, and then > verifying that the exchanged data is intact (i.e. the CRC8 > is still correct for the data). Thanks for working on this, there is a build error reported by the CI, see below. If you have a github account, you can set up travis. Travis will compile your patch through the different targets we have in it + run the unit tests. > > Signed-off-by: David Christensen > --- > app/test/test_atomic.c | 173 ++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 171 insertions(+), 2 deletions(-) > > diff --git a/app/test/test_atomic.c b/app/test/test_atomic.c > index 43be30ec0..4a818b6d5 100644 > --- a/app/test/test_atomic.c > +++ b/app/test/test_atomic.c > @@ -1,10 +1,12 @@ > /* SPDX-License-Identifier: BSD-3-Clause > * Copyright(c) 2010-2014 Intel Corporation > + * Copyright(c) 2019 Arm Limited > */ > > #include > #include > #include > +#include > #include > > #include > @@ -13,6 +15,8 @@ > #include > #include > #include > +#include > +#include > > #include "test.h" > > @@ -20,7 +24,7 @@ > * Atomic Variables > * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > * > - * - The main test function performs three subtests. The first test > + * - The main test function performs four subtests. The first test > * checks that the usual inc/dec/add/sub functions are working > * correctly: > * > @@ -61,11 +65,26 @@ > * atomic_sub(&count, tmp+1); > * > * - At the end of the test, the *count* value must be 0. > + * > + * - Test "atomic exchange" > + * > + * - Create a 64 bit token that can be tested for data integrity > + * > + * - Invoke ``test_atomic_exchange`` on each lcore. Before doing > + * anything else, the cores wait for a synchronization event. > + * Each core then does the follwoing for N iterations: > + * > + * Generate a new token with a data integrity check > + * Exchange the new token for previously generated token > + * Increment a counter if a corrupt token was received > + * > + * - At the end of the test, the number of corrupted tokens must be 0. > + * > */ > > #define NUM_ATOMIC_TYPES 3 > > -#define N 10000 > +#define N 1000000 > > static rte_atomic16_t a16; > static rte_atomic32_t a32; > @@ -216,6 +235,124 @@ test_atomic_dec_and_test(__attribute__((unused)) vo= id *arg) > return 0; > } > > +/* > + * Helper definitions/variables/functions for > + * atomic exchange tests > + */ > +typedef union { > + uint16_t u16; > + uint8_t u8[2]; > +} rte_u16_t; > + > +typedef union { > + uint32_t u32; > + uint16_t u16[2]; > + uint8_t u8[4]; > +} rte_u32_t; > + > +typedef union { > + uint64_t u64; > + uint32_t u32[2]; > + uint16_t u16[4]; > + uint8_t u8[8]; > +} rte_u64_t; > + > +const uint8_t CRC8_POLY =3D 0x91; > +uint8_t crc8_table[256]; > + > +volatile uint16_t token16; > +volatile uint32_t token32; > +volatile uint64_t token64; > + > +static void > +build_crc8_table(void) > +{ > + uint8_t val; > + > + for (int i =3D 0; i < 256; i++) { > + val =3D i; > + for (int j =3D 0; j < 8; j++) { > + if (val & 1) > + val ^=3D CRC8_POLY; > + val >>=3D 1; > + } > + crc8_table[i] =3D val; > + } > +} > + > +static uint8_t > +get_crc8(uint8_t *message, int length) > +{ > + uint8_t crc =3D 0; > + > + for (int i =3D 0; i < length; i++) > + crc =3D crc8_table[crc ^ message[i]]; > + return crc; > +} > + > +/* > + * The atomic exchange test sets up a token in memory and > + * then spins up multiple lcores whose job is to generate > + * new tokens, exchange that new token for the old one held > + * in memory, and then verify that the old token is still > + * valid (i.e. the exchange did not corrupt the token). > + * > + * A token is made up of random data and 8 bits of crc > + * covering that random data. The following is an example > + * of a 64bit token. > + * > + * +------------+------------+ > + * | 63 56 | 55 0 | > + * +------------+------------+ > + * | CRC8 | Data | > + * +------------+------------+ > + */ > +static int > +test_atomic_exchange(__attribute__((unused)) void *arg) > +{ > + rte_u16_t nt16, ot16; /* new token, old token */ > + rte_u32_t nt32, ot32; > + rte_u64_t nt64, ot64; > + > + /* Wait until all of the other threads have been dispatched */ > + while (rte_atomic32_read(&synchro) =3D=3D 0) > + ; > + > + /* > + * Let the battle begin! Every thread attempts to steal the curre= nt > + * token with an atomic exchange operation and install its own ne= wly > + * generated token. If the old token is valid (i.e. it has the > + * appropriate crc32 hash for the data) then the test iteration h= as > + * passed. If the token is invalid, increment the counter. > + */ > + for (int i =3D 0; i < N; i++) { > + > + /* Test 64bit Atomic Exchange */ > + nt64.u64 =3D rte_rand(); > + nt64.u8[7] =3D get_crc8(&nt64.u8[0], sizeof(nt64) - 1); > + ot64.u64 =3D rte_atomic64_exchange(&token64, nt64.u64); > + if (ot64.u8[7] !=3D get_crc8(&ot64.u8[0], sizeof(ot64) - = 1)) > + rte_atomic64_inc(&count); > + > + /* Test 32bit Atomic Exchange */ > + nt32.u32 =3D (uint32_t)rte_rand(); > + nt32.u8[3] =3D get_crc8(&nt32.u8[0], sizeof(nt32) - 1); > + ot32.u32 =3D rte_atomic32_exchange(&token32, nt32.u32); > + if (ot32.u8[3] !=3D get_crc8(&ot32.u8[0], sizeof(ot32) - = 1)) > + rte_atomic64_inc(&count); > + > + /* Test 16bit Atomic Exchange */ > + nt16.u16 =3D (uint16_t)rte_rand(); > + nt16.u8[1] =3D get_crc8(&nt16.u8[0], sizeof(nt16) - 1); > + ot16.u16 =3D rte_atomic16_exchange(&token16, nt16.u16); > + if (ot16.u8[1] !=3D get_crc8(&ot16.u8[0], sizeof(ot16) - = 1)) > + te_atomic64_inc(&count); CC test_atomic.o /home-local/jenkins-local/jenkins-agent/workspace/Apply-Custom-Patch-Set/dp= dk/app/test/test_atomic.c: In function =E2=80=98test_atomic_exchange=E2=80=99: /home-local/jenkins-local/jenkins-agent/workspace/Apply-Custom-Patch-Set/dp= dk/app/test/test_atomic.c:349:4: error: implicit declaration of function =E2=80=98te_atomic64_inc=E2=80=99; = did you mean =E2=80=98rte_atomic64_inc=E2=80=99? [-Werror=3Dimplicit-function-decla= ration] te_atomic64_inc(&count); ^~~~~~~~~~~~~~~ rte_atomic64_inc /home-local/jenkins-local/jenkins-agent/workspace/Apply-Custom-Patch-Set/dp= dk/app/test/test_atomic.c:349:4: error: nested extern declaration of =E2=80=98te_atomic64_inc=E2=80=99 [-Werror=3Dnested-externs] /home-local/jenkins-local/jenkins-agent/workspace/Apply-Custom-Patch-Set/dp= dk/app/test/test_atomic.c: At top level: cc1: error: unrecognized command line option =E2=80=98-Wno-address-of-packed-member=E2=80=99 [-Werror] cc1: all warnings being treated as errors / > + } > + > + return 0; > +} > + > + > static int > test_atomic(void) > { > @@ -340,6 +477,38 @@ test_atomic(void) > return -1; > } > > + /* > + * Test 16/32/64bit atomic exchange. > + */ > + rte_u64_t t; > + > + printf("exchange test\n"); > + > + rte_atomic32_clear(&synchro); > + rte_atomic64_clear(&count); > + > + /* Generate the CRC8 lookup table */ > + build_crc8_table(); > + > + /* Create the initial tokens used by the test */ > + t.u64 =3D rte_rand(); > + token16 =3D (get_crc8(&t.u8[0], sizeof(token16) - 1) << 8) > + | (t.u16[0] & 0x00ff); > + token32 =3D ((uint32_t)get_crc8(&t.u8[0], sizeof(token32) - 1) <<= 24) > + | (t.u32[0] & 0x00ffffff); > + token64 =3D ((uint64_t)get_crc8(&t.u8[0], sizeof(token64) - 1) <<= 56) > + | (t.u64 & 0x00ffffffffffffff); > + > + rte_eal_mp_remote_launch(test_atomic_exchange, NULL, SKIP_MASTER)= ; > + rte_atomic32_set(&synchro, 1); > + rte_eal_mp_wait_lcore(); > + rte_atomic32_clear(&synchro); > + > + if (rte_atomic64_read(&count) > 0) { > + printf("Atomic exchange test failed\n"); > + return -1; > + } > + > return 0; > } > > -- > 2.18.1 > --=20 David Marchand