From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR03-AM5-obe.outbound.protection.outlook.com (mail-eopbgr30086.outbound.protection.outlook.com [40.107.3.86]) by dpdk.org (Postfix) with ESMTP id F198C324D for ; Fri, 29 Mar 2019 00:27:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector1-arm-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Ml/hi3vRn+Yck121zBiF/KZpGEsOtugjwbdDSGsF2w0=; b=flG6JoUJcQUOX0toqz/1U/oOhcDI2HBLhlMVv/cAq2A9yURPbINxigzoWQvEaxThl0LAIZefiszo4Uj9kogatUVBzECvpovr4MfLFtQY9otUVfkdhW3riOMrqVIi6Imjv8M98RGX42MRB+kCvqnx0TNT/aVltapGPySctZfWYMk= Received: from VE1PR08MB5149.eurprd08.prod.outlook.com (20.179.30.152) by VE1PR08MB5168.eurprd08.prod.outlook.com (20.179.30.218) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1750.15; Thu, 28 Mar 2019 23:27:00 +0000 Received: from VE1PR08MB5149.eurprd08.prod.outlook.com ([fe80::e0ae:ecad:ec5:8177]) by VE1PR08MB5149.eurprd08.prod.outlook.com ([fe80::e0ae:ecad:ec5:8177%2]) with mapi id 15.20.1750.017; Thu, 28 Mar 2019 23:27:00 +0000 From: Honnappa Nagarahalli To: Gage Eads , "dev@dpdk.org" CC: "olivier.matz@6wind.com" , "arybchenko@solarflare.com" , "bruce.richardson@intel.com" , "konstantin.ananyev@intel.com" , "Gavin Hu (Arm Technology China)" , nd , "thomas@monjalon.net" , nd Thread-Topic: [PATCH v3 5/8] stack: add lock-free stack implementation Thread-Index: AQHU1CtXemjpCfhXh0aG8vUsBJcLcaYgpWeQ Date: Thu, 28 Mar 2019 23:27:00 +0000 Message-ID: References: <20190305164256.2367-1-gage.eads@intel.com> <20190306144559.391-1-gage.eads@intel.com> <20190306144559.391-6-gage.eads@intel.com> In-Reply-To: <20190306144559.391-6-gage.eads@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=Honnappa.Nagarahalli@arm.com; x-originating-ip: [217.140.111.135] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 27288d61-9a34-49b7-2c76-08d6b3d4e0da x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(5600127)(711020)(4605104)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060)(7193020); SRVR:VE1PR08MB5168; x-ms-traffictypediagnostic: VE1PR08MB5168: x-ld-processed: f34e5979-57d9-4aaa-ad4d-b122a662184d,ExtAddr nodisclaimer: True x-microsoft-antispam-prvs: x-forefront-prvs: 0990C54589 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(39860400002)(366004)(346002)(136003)(376002)(396003)(199004)(189003)(86362001)(486006)(71190400001)(7696005)(53936002)(8936002)(25786009)(2501003)(14454004)(8676002)(81156014)(6506007)(76176011)(81166006)(316002)(110136005)(54906003)(6246003)(5660300002)(4326008)(55016002)(478600001)(72206003)(229853002)(99286004)(68736007)(105586002)(6436002)(106356001)(74316002)(305945005)(9686003)(14444005)(33656002)(256004)(2906002)(3846002)(7736002)(66066001)(97736004)(186003)(6116002)(26005)(52536014)(71200400001)(102836004)(11346002)(446003)(476003); DIR:OUT; SFP:1101; SCL:1; SRVR:VE1PR08MB5168; H:VE1PR08MB5149.eurprd08.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: cyF5hxThOae0um4roVlUyU9xRlwn1I+UnFt4dTdot3Wkwi/iPpivPh3jxly/m/Sg3bLMzA6hSslIhYPv3LyrdRxL/3Jq2ofEUK8iyNmUh6NS1paWhVuv2OKl8yR0rtWVeqiNmji8bLkueoKOwC/BOfjnokPdSt5N8sLXgLGupL6FGDlrryCrTbXtJQ8/cUoO1VcyGDsphB/5ZY7lNywZvxHYf5tQ2p8s/tr5r1RsxL6z3bTpzM94dE/YdvTgkXBf2tDS+FelehsqLWX6Sm8XwHbh27/4SrG2r07U5+aF4JBP4/56UMn3TX5XPBqVeDKkvjx0ksUEOjPX4ze0358wpOSTTHrgFyi9Tg2JO+1KTUk3ka6mZjgPV/XVVH2eJsiIiAtK1Ban6zQzi0x68npEu3cxdwVr8oUpalUAdV0JtcE= Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-Network-Message-Id: 27288d61-9a34-49b7-2c76-08d6b3d4e0da X-MS-Exchange-CrossTenant-originalarrivaltime: 28 Mar 2019 23:27:00.5226 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1PR08MB5168 Subject: Re: [dpdk-dev] [PATCH v3 5/8] stack: add lock-free stack implementation 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, 28 Mar 2019 23:27:02 -0000 > diff --git a/lib/librte_stack/rte_stack.c b/lib/librte_stack/rte_stack.c = index > 96dffdf44..8f0361ea1 100644 > --- a/lib/librte_stack/rte_stack.c > +++ b/lib/librte_stack/rte_stack.c > @@ -63,9 +81,16 @@ rte_stack_create(const char *name, unsigned int > count, int socket_id, > unsigned int sz; > int ret; >=20 > - RTE_SET_USED(flags); > +#ifdef RTE_ARCH_X86_64 > + RTE_BUILD_BUG_ON(sizeof(struct rte_stack_lf_head) !=3D 16); This check should be independent of the platform. #else > + if (flags & RTE_STACK_F_LF) { > + STACK_LOG_ERR("Lock-free stack is not supported on your > platform\n"); > + return NULL; > + } > +#endif >=20 > - sz =3D rte_stack_get_memsize(count); > + sz =3D rte_stack_get_memsize(count, flags); >=20 > ret =3D snprintf(mz_name, sizeof(mz_name), "%s%s", > RTE_STACK_MZ_PREFIX, name); > @@ -94,7 +119,7 @@ rte_stack_create(const char *name, unsigned int > count, int socket_id, >=20 > s =3D mz->addr; >=20 > - rte_stack_init(s); > + rte_stack_init(s, count, flags); >=20 > /* Store the name for later lookups */ > ret =3D snprintf(s->name, sizeof(s->name), "%s", name); diff --git > a/lib/librte_stack/rte_stack.h b/lib/librte_stack/rte_stack.h index > 7a633deb5..b484313bb 100644 > --- a/lib/librte_stack/rte_stack.h > +++ b/lib/librte_stack/rte_stack.h > @@ -30,6 +30,35 @@ extern "C" { > +/** > + * @internal Push several objects on the lock-free stack (MT-safe). > + * > + * @param s > + * A pointer to the stack structure. > + * @param obj_table > + * A pointer to a table of void * pointers (objects). > + * @param n > + * The number of objects to push on the stack from the obj_table. > + * @return > + * Actual number of objects enqueued. > + */ > +static __rte_always_inline unsigned int __rte_experimental This is an internal function. Is '__rte_experimental' tag required? (applie= s to other instances in this patch) > +rte_stack_lf_push(struct rte_stack *s, void * const *obj_table, > +unsigned int n) { > + struct rte_stack_lf_elem *tmp, *first, *last =3D NULL; > + unsigned int i; > + > + if (unlikely(n =3D=3D 0)) > + return 0; > + > + /* Pop n free elements */ > + first =3D __rte_stack_lf_pop(&s->stack_lf.free, n, NULL, &last); > + if (unlikely(first =3D=3D NULL)) > + return 0; > + > + /* Construct the list elements */ > + for (tmp =3D first, i =3D 0; i < n; i++, tmp =3D tmp->next) > + tmp->data =3D obj_table[n - i - 1]; > + > + /* Push them to the used list */ > + __rte_stack_lf_push(&s->stack_lf.used, first, last, n); > + > + return n; > +} > + =20 >=20 > /** > @@ -225,7 +339,10 @@ rte_stack_free_count(struct rte_stack *s) > * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA > * constraint for the reserved zone. > * @param flags > - * Reserved for future use. > + * An OR of the following: > + * - RTE_STACK_F_LF: If this flag is set, the stack uses lock-free > + * variants of the push and pop functions. Otherwise, it achieves > + * thread-safety using a lock. > * @return > * On success, the pointer to the new allocated stack. NULL on error w= ith > * rte_errno set appropriately. Possible errno values include: > diff --git a/lib/librte_stack/rte_stack_generic.h > b/lib/librte_stack/rte_stack_generic.h > new file mode 100644 > index 000000000..5e4cbc38e > --- /dev/null > +++ b/lib/librte_stack/rte_stack_generic.h The name "...stack_generic.h" is confusing. It is implementing LF algorithm= . IMO, the code should be re-organized differently. rte_stack.h, rte_stack.c - Contain the APIs (calling std or LF based on the= flag) and top level structure definition rte_stack_std.c, rte_stack_std.h - Contain the standard implementation rte_stack_lf.c, rte_stack_lf.h - Contain the LF implementation rte_stack_lf_c11.h - Contain the LF C11 implementation > @@ -0,0 +1,151 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2019 Intel Corporation > + */ > + > +#ifndef _RTE_STACK_GENERIC_H_ > +#define _RTE_STACK_GENERIC_H_ > + > +#include > +#include > + > + > +static __rte_always_inline struct rte_stack_lf_elem * > +__rte_stack_lf_pop(struct rte_stack_lf_list *list, > + unsigned int num, > + void **obj_table, > + struct rte_stack_lf_elem **last) > +{ > +#ifndef RTE_ARCH_X86_64 > + RTE_SET_USED(obj_table); > + RTE_SET_USED(last); > + RTE_SET_USED(list); > + RTE_SET_USED(num); > + > + return NULL; > +#else > + struct rte_stack_lf_head old_head; > + int success; > + > + /* Reserve num elements, if available */ > + while (1) { > + uint64_t len =3D rte_atomic64_read(&list->len); > + > + /* Does the list contain enough elements? */ > + if (unlikely(len < num)) > + return NULL; > + > + if (rte_atomic64_cmpset((volatile uint64_t *)&list->len, > + len, len - num)) > + break; > + } > + > + old_head =3D list->head; > + > + /* Pop num elements */ > + do { > + struct rte_stack_lf_head new_head; > + struct rte_stack_lf_elem *tmp; > + unsigned int i; > + > + rte_prefetch0(old_head.top); > + > + tmp =3D old_head.top; > + > + /* Traverse the list to find the new head. A next pointer will > + * either point to another element or NULL; if a thread > + * encounters a pointer that has already been popped, the > CAS > + * will fail. > + */ > + for (i =3D 0; i < num && tmp !=3D NULL; i++) { > + rte_prefetch0(tmp->next); > + if (obj_table) > + obj_table[i] =3D tmp->data; > + if (last) > + *last =3D tmp; > + tmp =3D tmp->next; > + } > + > + /* If NULL was encountered, the list was modified while > + * traversing it. Retry. > + */ > + if (i !=3D num) > + continue; > + > + new_head.top =3D tmp; > + new_head.cnt =3D old_head.cnt + 1; > + > + /* old_head is updated on failure */ > + success =3D rte_atomic128_cmp_exchange( > + (rte_int128_t *)&list->head, > + (rte_int128_t *)&old_head, > + (rte_int128_t *)&new_head, > + 1, __ATOMIC_ACQUIRE, > + __ATOMIC_ACQUIRE); Just wondering if 'rte_atomic128_cmp_exchange' for x86 should have compile= r barriers based on the memory order passed? C++11 memory model is getting mixed with barrier based model. I think this = is something that needs to be discussed at a wider level. > + } while (success =3D=3D 0); > + > + return old_head.top; > +#endif > +} > + > +#endif /* _RTE_STACK_GENERIC_H_ */ > -- > 2.13.6 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by dpdk.space (Postfix) with ESMTP id 30C59A0679 for ; Fri, 29 Mar 2019 00:27:07 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 02BF8326D; Fri, 29 Mar 2019 00:27:06 +0100 (CET) Received: from EUR03-AM5-obe.outbound.protection.outlook.com (mail-eopbgr30086.outbound.protection.outlook.com [40.107.3.86]) by dpdk.org (Postfix) with ESMTP id F198C324D for ; Fri, 29 Mar 2019 00:27:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector1-arm-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Ml/hi3vRn+Yck121zBiF/KZpGEsOtugjwbdDSGsF2w0=; b=flG6JoUJcQUOX0toqz/1U/oOhcDI2HBLhlMVv/cAq2A9yURPbINxigzoWQvEaxThl0LAIZefiszo4Uj9kogatUVBzECvpovr4MfLFtQY9otUVfkdhW3riOMrqVIi6Imjv8M98RGX42MRB+kCvqnx0TNT/aVltapGPySctZfWYMk= Received: from VE1PR08MB5149.eurprd08.prod.outlook.com (20.179.30.152) by VE1PR08MB5168.eurprd08.prod.outlook.com (20.179.30.218) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1750.15; Thu, 28 Mar 2019 23:27:00 +0000 Received: from VE1PR08MB5149.eurprd08.prod.outlook.com ([fe80::e0ae:ecad:ec5:8177]) by VE1PR08MB5149.eurprd08.prod.outlook.com ([fe80::e0ae:ecad:ec5:8177%2]) with mapi id 15.20.1750.017; Thu, 28 Mar 2019 23:27:00 +0000 From: Honnappa Nagarahalli To: Gage Eads , "dev@dpdk.org" CC: "olivier.matz@6wind.com" , "arybchenko@solarflare.com" , "bruce.richardson@intel.com" , "konstantin.ananyev@intel.com" , "Gavin Hu (Arm Technology China)" , nd , "thomas@monjalon.net" , nd Thread-Topic: [PATCH v3 5/8] stack: add lock-free stack implementation Thread-Index: AQHU1CtXemjpCfhXh0aG8vUsBJcLcaYgpWeQ Date: Thu, 28 Mar 2019 23:27:00 +0000 Message-ID: References: <20190305164256.2367-1-gage.eads@intel.com> <20190306144559.391-1-gage.eads@intel.com> <20190306144559.391-6-gage.eads@intel.com> In-Reply-To: <20190306144559.391-6-gage.eads@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=Honnappa.Nagarahalli@arm.com; x-originating-ip: [217.140.111.135] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 27288d61-9a34-49b7-2c76-08d6b3d4e0da x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(5600127)(711020)(4605104)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060)(7193020); SRVR:VE1PR08MB5168; x-ms-traffictypediagnostic: VE1PR08MB5168: x-ld-processed: f34e5979-57d9-4aaa-ad4d-b122a662184d,ExtAddr nodisclaimer: True x-microsoft-antispam-prvs: x-forefront-prvs: 0990C54589 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(39860400002)(366004)(346002)(136003)(376002)(396003)(199004)(189003)(86362001)(486006)(71190400001)(7696005)(53936002)(8936002)(25786009)(2501003)(14454004)(8676002)(81156014)(6506007)(76176011)(81166006)(316002)(110136005)(54906003)(6246003)(5660300002)(4326008)(55016002)(478600001)(72206003)(229853002)(99286004)(68736007)(105586002)(6436002)(106356001)(74316002)(305945005)(9686003)(14444005)(33656002)(256004)(2906002)(3846002)(7736002)(66066001)(97736004)(186003)(6116002)(26005)(52536014)(71200400001)(102836004)(11346002)(446003)(476003); DIR:OUT; SFP:1101; SCL:1; SRVR:VE1PR08MB5168; H:VE1PR08MB5149.eurprd08.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: cyF5hxThOae0um4roVlUyU9xRlwn1I+UnFt4dTdot3Wkwi/iPpivPh3jxly/m/Sg3bLMzA6hSslIhYPv3LyrdRxL/3Jq2ofEUK8iyNmUh6NS1paWhVuv2OKl8yR0rtWVeqiNmji8bLkueoKOwC/BOfjnokPdSt5N8sLXgLGupL6FGDlrryCrTbXtJQ8/cUoO1VcyGDsphB/5ZY7lNywZvxHYf5tQ2p8s/tr5r1RsxL6z3bTpzM94dE/YdvTgkXBf2tDS+FelehsqLWX6Sm8XwHbh27/4SrG2r07U5+aF4JBP4/56UMn3TX5XPBqVeDKkvjx0ksUEOjPX4ze0358wpOSTTHrgFyi9Tg2JO+1KTUk3ka6mZjgPV/XVVH2eJsiIiAtK1Ban6zQzi0x68npEu3cxdwVr8oUpalUAdV0JtcE= Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-Network-Message-Id: 27288d61-9a34-49b7-2c76-08d6b3d4e0da X-MS-Exchange-CrossTenant-originalarrivaltime: 28 Mar 2019 23:27:00.5226 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1PR08MB5168 Subject: Re: [dpdk-dev] [PATCH v3 5/8] stack: add lock-free stack implementation 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" Message-ID: <20190328232700.THm4e5wbOnRud6fFSeitYf3c_14FE0r03d6an8jyUwM@z> > diff --git a/lib/librte_stack/rte_stack.c b/lib/librte_stack/rte_stack.c = index > 96dffdf44..8f0361ea1 100644 > --- a/lib/librte_stack/rte_stack.c > +++ b/lib/librte_stack/rte_stack.c > @@ -63,9 +81,16 @@ rte_stack_create(const char *name, unsigned int > count, int socket_id, > unsigned int sz; > int ret; >=20 > - RTE_SET_USED(flags); > +#ifdef RTE_ARCH_X86_64 > + RTE_BUILD_BUG_ON(sizeof(struct rte_stack_lf_head) !=3D 16); This check should be independent of the platform. #else > + if (flags & RTE_STACK_F_LF) { > + STACK_LOG_ERR("Lock-free stack is not supported on your > platform\n"); > + return NULL; > + } > +#endif >=20 > - sz =3D rte_stack_get_memsize(count); > + sz =3D rte_stack_get_memsize(count, flags); >=20 > ret =3D snprintf(mz_name, sizeof(mz_name), "%s%s", > RTE_STACK_MZ_PREFIX, name); > @@ -94,7 +119,7 @@ rte_stack_create(const char *name, unsigned int > count, int socket_id, >=20 > s =3D mz->addr; >=20 > - rte_stack_init(s); > + rte_stack_init(s, count, flags); >=20 > /* Store the name for later lookups */ > ret =3D snprintf(s->name, sizeof(s->name), "%s", name); diff --git > a/lib/librte_stack/rte_stack.h b/lib/librte_stack/rte_stack.h index > 7a633deb5..b484313bb 100644 > --- a/lib/librte_stack/rte_stack.h > +++ b/lib/librte_stack/rte_stack.h > @@ -30,6 +30,35 @@ extern "C" { > +/** > + * @internal Push several objects on the lock-free stack (MT-safe). > + * > + * @param s > + * A pointer to the stack structure. > + * @param obj_table > + * A pointer to a table of void * pointers (objects). > + * @param n > + * The number of objects to push on the stack from the obj_table. > + * @return > + * Actual number of objects enqueued. > + */ > +static __rte_always_inline unsigned int __rte_experimental This is an internal function. Is '__rte_experimental' tag required? (applie= s to other instances in this patch) > +rte_stack_lf_push(struct rte_stack *s, void * const *obj_table, > +unsigned int n) { > + struct rte_stack_lf_elem *tmp, *first, *last =3D NULL; > + unsigned int i; > + > + if (unlikely(n =3D=3D 0)) > + return 0; > + > + /* Pop n free elements */ > + first =3D __rte_stack_lf_pop(&s->stack_lf.free, n, NULL, &last); > + if (unlikely(first =3D=3D NULL)) > + return 0; > + > + /* Construct the list elements */ > + for (tmp =3D first, i =3D 0; i < n; i++, tmp =3D tmp->next) > + tmp->data =3D obj_table[n - i - 1]; > + > + /* Push them to the used list */ > + __rte_stack_lf_push(&s->stack_lf.used, first, last, n); > + > + return n; > +} > + =20 >=20 > /** > @@ -225,7 +339,10 @@ rte_stack_free_count(struct rte_stack *s) > * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA > * constraint for the reserved zone. > * @param flags > - * Reserved for future use. > + * An OR of the following: > + * - RTE_STACK_F_LF: If this flag is set, the stack uses lock-free > + * variants of the push and pop functions. Otherwise, it achieves > + * thread-safety using a lock. > * @return > * On success, the pointer to the new allocated stack. NULL on error w= ith > * rte_errno set appropriately. Possible errno values include: > diff --git a/lib/librte_stack/rte_stack_generic.h > b/lib/librte_stack/rte_stack_generic.h > new file mode 100644 > index 000000000..5e4cbc38e > --- /dev/null > +++ b/lib/librte_stack/rte_stack_generic.h The name "...stack_generic.h" is confusing. It is implementing LF algorithm= . IMO, the code should be re-organized differently. rte_stack.h, rte_stack.c - Contain the APIs (calling std or LF based on the= flag) and top level structure definition rte_stack_std.c, rte_stack_std.h - Contain the standard implementation rte_stack_lf.c, rte_stack_lf.h - Contain the LF implementation rte_stack_lf_c11.h - Contain the LF C11 implementation > @@ -0,0 +1,151 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2019 Intel Corporation > + */ > + > +#ifndef _RTE_STACK_GENERIC_H_ > +#define _RTE_STACK_GENERIC_H_ > + > +#include > +#include > + > + > +static __rte_always_inline struct rte_stack_lf_elem * > +__rte_stack_lf_pop(struct rte_stack_lf_list *list, > + unsigned int num, > + void **obj_table, > + struct rte_stack_lf_elem **last) > +{ > +#ifndef RTE_ARCH_X86_64 > + RTE_SET_USED(obj_table); > + RTE_SET_USED(last); > + RTE_SET_USED(list); > + RTE_SET_USED(num); > + > + return NULL; > +#else > + struct rte_stack_lf_head old_head; > + int success; > + > + /* Reserve num elements, if available */ > + while (1) { > + uint64_t len =3D rte_atomic64_read(&list->len); > + > + /* Does the list contain enough elements? */ > + if (unlikely(len < num)) > + return NULL; > + > + if (rte_atomic64_cmpset((volatile uint64_t *)&list->len, > + len, len - num)) > + break; > + } > + > + old_head =3D list->head; > + > + /* Pop num elements */ > + do { > + struct rte_stack_lf_head new_head; > + struct rte_stack_lf_elem *tmp; > + unsigned int i; > + > + rte_prefetch0(old_head.top); > + > + tmp =3D old_head.top; > + > + /* Traverse the list to find the new head. A next pointer will > + * either point to another element or NULL; if a thread > + * encounters a pointer that has already been popped, the > CAS > + * will fail. > + */ > + for (i =3D 0; i < num && tmp !=3D NULL; i++) { > + rte_prefetch0(tmp->next); > + if (obj_table) > + obj_table[i] =3D tmp->data; > + if (last) > + *last =3D tmp; > + tmp =3D tmp->next; > + } > + > + /* If NULL was encountered, the list was modified while > + * traversing it. Retry. > + */ > + if (i !=3D num) > + continue; > + > + new_head.top =3D tmp; > + new_head.cnt =3D old_head.cnt + 1; > + > + /* old_head is updated on failure */ > + success =3D rte_atomic128_cmp_exchange( > + (rte_int128_t *)&list->head, > + (rte_int128_t *)&old_head, > + (rte_int128_t *)&new_head, > + 1, __ATOMIC_ACQUIRE, > + __ATOMIC_ACQUIRE); Just wondering if 'rte_atomic128_cmp_exchange' for x86 should have compile= r barriers based on the memory order passed? C++11 memory model is getting mixed with barrier based model. I think this = is something that needs to be discussed at a wider level. > + } while (success =3D=3D 0); > + > + return old_head.top; > +#endif > +} > + > +#endif /* _RTE_STACK_GENERIC_H_ */ > -- > 2.13.6