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 026D3A04B6; Mon, 12 Oct 2020 19:06:41 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 5DB361D94C; Mon, 12 Oct 2020 19:06:39 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id E95CD1D942 for ; Mon, 12 Oct 2020 19:06:37 +0200 (CEST) IronPort-SDR: j5NlN9GuvrkSZUDbGhhi/cXAlL+n2nGKYpLWpRU5cMra5LgJr6aWyY4kVDJrgyxS7LC6uXPSpC vTTsahKslr4A== X-IronPort-AV: E=McAfee;i="6000,8403,9772"; a="165832533" X-IronPort-AV: E=Sophos;i="5.77,367,1596524400"; d="scan'208";a="165832533" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Oct 2020 10:06:34 -0700 IronPort-SDR: TqR8/s0lEG64OyEVRaofwRzdDa0HQY5+u1qKdGla2CeTkVtGVFV8l7Pu0wxFaJ3d8cEzfacFaj bHLz+uXofmwA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,367,1596524400"; d="scan'208";a="313507844" Received: from orsmsx601.amr.corp.intel.com ([10.22.229.14]) by orsmga003.jf.intel.com with ESMTP; 12 Oct 2020 10:06:33 -0700 Received: from orsmsx612.amr.corp.intel.com (10.22.229.25) by ORSMSX601.amr.corp.intel.com (10.22.229.14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Mon, 12 Oct 2020 10:06:33 -0700 Received: from orsmsx601.amr.corp.intel.com (10.22.229.14) by ORSMSX612.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Mon, 12 Oct 2020 10:06:33 -0700 Received: from ORSEDG602.ED.cps.intel.com (10.7.248.7) by orsmsx601.amr.corp.intel.com (10.22.229.14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5 via Frontend Transport; Mon, 12 Oct 2020 10:06:33 -0700 Received: from NAM04-CO1-obe.outbound.protection.outlook.com (104.47.45.50) by edgegateway.intel.com (134.134.137.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.1713.5; Mon, 12 Oct 2020 10:06:31 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=RFjNH3/kWa7t8oqtIZ/Dd34qaCKhflt1cyTkCzTuPxamptCfNtZWHC2ZkFTadGc245bg9kBmjBROSee+UinyBccrZJQBbUHfFrhARaiRYLSuxbbyvHzSW5kBEc2We6oFGcvAi99ev1Ta6hQ21n57JBInG8Ztbrusq+b1XLXRGBLIUrv9ugcIe0uMGBTe//8mXjQ2IkD6VlfCYZSJXCebEtxePsM1IAHrU/4tQjPe6Z4Pl1JdKdZYMjqR51k3c0ixtLEf0tWxFjcyvKYxBPH+qHR2JtS/DnhmMoOu4KznEGAvrZ1VvIFPvQ8Ja0fV9oyeswmdiyzWdDh8flSgQPWdrw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=p9a4xPfX4QKj9ULbcFJUffHD92pxPUe8vb77mrqjmNc=; b=i1/YXcqQFU5QygD576Y4ojFCLadndSQnyMTRlA5vCLoPp2Dg1sHvSFXZIxtWlgFdXOaSOrfKvweur0FZIvbKOtHUB3jWOr6JwSPR/PplRJf8bV6TTYqZUS3HpTqcOir/zLzR6FnLdNIqSAr6dxJ9COGWXQlnt8zvAzosdn/etAR7SuFjl7WITmtYhf9ulyxOqqHd4I1+BAIFQDxxJG+irOMOd0sIwvOVwrOtlUf4bqdTSV6fZj4bjoEmJp6DFcIxSoG48NZtxSCJSOIo59NNbt8xP3v/rmwxOmq8ED4W9nvsmBzCNru98+leZWLxnG2h14i6K+AOhF7AqYMNw9/wlQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=p9a4xPfX4QKj9ULbcFJUffHD92pxPUe8vb77mrqjmNc=; b=VVTuzWk++ylZ3/vkKZdOz8uBe5neT7UVuCYVZbXBCxFKbOcqxUwQLR8kPu5Uvb1mrFHfne0n1umc13C1KCuHfE/l9BgNzaHQKZjbo/qcVnE2uH4w2kTrtOKW69fPrb5mbGsElgtbBrtiqUZDjRVAOKR/8ygKEYi8mzl/5q3ckJg= Received: from BYAPR11MB3301.namprd11.prod.outlook.com (2603:10b6:a03:7f::26) by BYAPR11MB3606.namprd11.prod.outlook.com (2603:10b6:a03:b5::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3455.26; Mon, 12 Oct 2020 17:06:30 +0000 Received: from BYAPR11MB3301.namprd11.prod.outlook.com ([fe80::f5a4:3f6b:ade3:296b]) by BYAPR11MB3301.namprd11.prod.outlook.com ([fe80::f5a4:3f6b:ade3:296b%3]) with mapi id 15.20.3455.029; Mon, 12 Oct 2020 17:06:30 +0000 From: "Ananyev, Konstantin" To: Honnappa Nagarahalli , Olivier Matz CC: "dev@dpdk.org" , "david.marchand@redhat.com" , nd , nd Thread-Topic: [RFC v2 1/1] lib/ring: add scatter gather APIs Thread-Index: AQHWm+TAMRnLEGUYBEqkMDYffUIcWqmLz6WAgAJgIYCAALV2AIAABhsggAD7PICABFJqEA== Date: Mon, 12 Oct 2020 17:06:30 +0000 Message-ID: References: <20200224203931.21256-1-honnappa.nagarahalli@arm.com> <20201006132905.46205-1-honnappa.nagarahalli@arm.com> <20201006132905.46205-2-honnappa.nagarahalli@arm.com> <20201007082739.GL21395@platinum> <20201009073342.GZ21395@platinum> In-Reply-To: Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-reaction: no-action dlp-version: 11.5.1.3 authentication-results: arm.com; dkim=none (message not signed) header.d=none;arm.com; dmarc=none action=none header.from=intel.com; x-originating-ip: [46.7.39.127] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 2f6f9248-f8a3-4509-466a-08d86ed129e1 x-ms-traffictypediagnostic: BYAPR11MB3606: x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:9508; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 9lXrHzdQdzGlgIhPAiAgCllpQWgZ9NXu7ojiAHTcCE661/MP3Y3nTCc+XuDSdDRCvvz+vEZ5Jxv1VG924p5f9OKFeIq6R752oEqx6ITgjrAW9sIlxjFY491RSq4XTpkSNW10hm3jdSFwoqtolrvJtrLZLZgFeRyZ5VZoaU2/O20mRkZAcWdvcUJDGpjAkpRRrIsf3D0XFcBCzitxgCOomf/wytuHs/R7JAXl1MVuaUQ/9sZroECzCA1wK0EVFj++BJPmnfVpVu7rdg9KqAmMHH8y4SiA79OB9U6H+nekbLSvrH6i0JnXxfXCmElfRK85Ya2qiTp6FosOYw7GQX7OX/wfO8Af8SH8v828+Sgt+aw= x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BYAPR11MB3301.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(39860400002)(366004)(136003)(346002)(396003)(376002)(54906003)(8936002)(8676002)(66946007)(4326008)(186003)(71200400001)(110136005)(66556008)(66476007)(66446008)(478600001)(76116006)(2906002)(33656002)(64756008)(52536014)(5660300002)(86362001)(966005)(316002)(30864003)(9686003)(6506007)(55016002)(83380400001)(7696005)(26005); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata: dbWKUle0j73BmiPlYDZhO9F8RrA1OMt2R+AU6AaUR0A+dRAvPNCKfkSEDOabloWYbM9/TFMlqqHvd5IQYmHFAh7zbf5tPMmOW440azWQ84LIXGIttufMbr/IWqhloPhMfQS5SiM/D6QXtf3gKtb95ti2ev0jV55D4ScyUTsP5CgnnqHW2hV1l0zZ2nbLceosQB1JHbvbWHc/OnagV5rmwCRshBCdYOwt3tysTwuYq1cp4ZFj3Z/Qidt8s6/TMD3A9UoH8GbiYEr/U4fcjKKQvPO6yjmFAGHbXYrsF6VqlWVp//XjeYA0QfsclurTdv3EzhJyTwKYP8mA7vZJX1ulaJV1OxGgksjplFKPqKZv6mmcTfCt5TguBMpc3QCrGmHvTJckZQT0gldyjP37PmfzEzK6ZhTcxDhU9Ep9hTNsn4qlvlInK9PtL1/zYHw5sRPRyeY0Bp/LcmS8i5mz45BgWt/clBbzizdliZeLwxNMMoPG3p/NNjsbIq+N1hik2jUulA0te7FyVC7Kq8SveCYd35D0CyUzkSZGZp2+y+OvVtkyPzN2ZlP+tMVNBGrIp7Ft0O0LWfQkcYX4yBPgm5YQeIJaMcxL1FYS9S9H/afQuhpCKT7HFJYhLChtDHG2nOvhTxpx6yglwQnI1kxNYms7xQ== x-ms-exchange-transport-forked: True Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: BYAPR11MB3301.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2f6f9248-f8a3-4509-466a-08d86ed129e1 X-MS-Exchange-CrossTenant-originalarrivaltime: 12 Oct 2020 17:06:30.1225 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: yCUydewRrqLfwcTNBF13Q21wuZBrICE30nTiwuxB2q7cVPxeOWlUMsrTQHh3OEOZJNKOiOtud38EbDpXr3S+7QUGGvaOSk8K9RGOz2Xn7cQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR11MB3606 X-OriginatorOrg: intel.com Subject: Re: [dpdk-dev] [RFC v2 1/1] lib/ring: add scatter gather APIs 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" =20 > >=20 > > > > > Hi Honnappa, > > > > > > > > > > From a quick walkthrough, I have some questions/comments, please > > > > > see below. > > > > Hi Olivier, appreciate your input. > > > > > > > > > > > > > > On Tue, Oct 06, 2020 at 08:29:05AM -0500, Honnappa Nagarahalli wr= ote: > > > > > > Add scatter gather APIs to avoid intermediate memcpy. Use cases > > > > > > that involve copying large amount of data to/from the ring can > > > > > > benefit from these APIs. > > > > > > > > > > > > Signed-off-by: Honnappa Nagarahalli > > > > > > > > > > > > --- > > > > > > lib/librte_ring/meson.build | 3 +- > > > > > > lib/librte_ring/rte_ring_elem.h | 1 + > > > > > > lib/librte_ring/rte_ring_peek_sg.h | 552 > > > > > > +++++++++++++++++++++++++++++ > > > > > > 3 files changed, 555 insertions(+), 1 deletion(-) create mode > > > > > > 100644 lib/librte_ring/rte_ring_peek_sg.h > > > > > > > > > > > > diff --git a/lib/librte_ring/meson.build > > > > > > b/lib/librte_ring/meson.build index 31c0b4649..377694713 100644 > > > > > > --- a/lib/librte_ring/meson.build > > > > > > +++ b/lib/librte_ring/meson.build > > > > > > @@ -12,4 +12,5 @@ headers =3D files('rte_ring.h', > > > > > > 'rte_ring_peek.h', > > > > > > 'rte_ring_peek_c11_mem.h', > > > > > > 'rte_ring_rts.h', > > > > > > - 'rte_ring_rts_c11_mem.h') > > > > > > + 'rte_ring_rts_c11_mem.h', > > > > > > + 'rte_ring_peek_sg.h') > > > > > > diff --git a/lib/librte_ring/rte_ring_elem.h > > > > > > b/lib/librte_ring/rte_ring_elem.h index 938b398fc..7d3933f15 > > > > > > 100644 > > > > > > --- a/lib/librte_ring/rte_ring_elem.h > > > > > > +++ b/lib/librte_ring/rte_ring_elem.h > > > > > > @@ -1079,6 +1079,7 @@ rte_ring_dequeue_burst_elem(struct > > > > > > rte_ring *r, void *obj_table, > > > > > > > > > > > > #ifdef ALLOW_EXPERIMENTAL_API > > > > > > #include > > > > > > +#include > > > > > > #endif > > > > > > > > > > > > #include > > > > > > diff --git a/lib/librte_ring/rte_ring_peek_sg.h > > > > > > b/lib/librte_ring/rte_ring_peek_sg.h > > > > > > new file mode 100644 > > > > > > index 000000000..97d5764a6 > > > > > > --- /dev/null > > > > > > +++ b/lib/librte_ring/rte_ring_peek_sg.h > > > > > > @@ -0,0 +1,552 @@ > > > > > > +/* SPDX-License-Identifier: BSD-3-Clause > > > > > > + * > > > > > > + * Copyright (c) 2020 Arm > > > > > > + * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org > > > > > > + * All rights reserved. > > > > > > + * Derived from FreeBSD's bufring.h > > > > > > + * Used as BSD-3 Licensed with permission from Kip Macy. > > > > > > + */ > > > > > > + > > > > > > +#ifndef _RTE_RING_PEEK_SG_H_ > > > > > > +#define _RTE_RING_PEEK_SG_H_ > > > > > > + > > > > > > +/** > > > > > > + * @file > > > > > > + * @b EXPERIMENTAL: this API may change without prior notice > > > > > > + * It is not recommended to include this file directly. > > > > > > + * Please include instead. > > > > > > + * > > > > > > + * Ring Peek Scatter Gather APIs > > > > > > > > > > I am not fully convinced by the API name. To me, "scatter/gather" > > > > > is associated to iovecs, like for instance in [1]. The wikipedia > > > > > definition [2] may be closer though. > > > > > > > > > > [1] > > > > > > > https://www.gnu.org/software/libc/manual/html_node/Scatter_002dGat > > > > > he > > > > > r.html > > > > > [2] > > > > > https://en.wikipedia.org/wiki/Gather-scatter_(vector_addressing) > > > > The way I understand scatter-gather is, the data to be sent to > > > > something (like a device) is coming from multiple sources. It would > > > > require > > > copying to put the data together to be contiguous. If the device > > > supports scatter-gather, such copying is not required. The device can > > collect data from multiple locations and make it contiguous. > > > > > > > > In the case I was looking at, one part of the data was coming from > > > > the user of the API and another was generated by the API itself. If > > > these two pieces of information have to be enqueued as a single objec= t > > > on the ring, I had to create an intermediate copy. But by exposing th= e ring > > memory to the user, the intermediate copy is avoided. Hence I called it > > scatter-gather. > > > > > > > > > > > > > > What about "zero-copy"? > > > > I think no-copy (nc for short) or user-copy (uc for short) would > > > > convey the meaning better. These would indicate that the rte_ring > > > > APIs are > > > not copying the objects and it is left to the user to do the actual c= opy. +1 for _ZC_ in naming. _NC_ is probably ok too, but sounds really strange to me. > > > > > > > > > > > > > > Also, the "peek" term looks also a bit confusing to me, but it > > > > > existed before your patch. I understand it for dequeue, but not f= or > > enqueue. > > > > I kept 'peek' there because the API still offers the 'peek' API > > > > capabilities. I am also not sure on what 'peek' means for enqueue > > > > API. The > > > enqueue 'peek' API was provided to be symmetric with dequeue peek API= . > > > > > > > > > > > > > > Or, what about replacing the existing experimental peek API by th= is one? > > > > > They look quite similar to me. > > > > I agree, scatter gather APIs provide the peek capability and the no= -copy > > benefits. > > > > Konstantin, any opinions here? I am still not very comfortable with API that allows users to access elems locations directly. I do understand that it could be beneficial in so= me special cases (you provided some good examples below), so I don't object to have it as addon. But I still think it shouldn't be the _only_ API.=20 > > > > Sorry, didn't have time yet, to look at this RFC properly. > > Will try to do it next week, as I understand that's for 21.02 anyway? > This is committed for 20.11. We should be able to get into RC2. Sounds really tight..., but ok, let's see how it goes. =20 > > > > > > > > > > > > > + * Introduction of rte_ring with scatter gather serialized > > > > > > + producer/consumer > > > > > > + * (HTS sync mode) makes it possible to split public > > > > > > + enqueue/dequeue API > > > > > > + * into 3 phases: > > > > > > + * - enqueue/dequeue start > > > > > > + * - copy data to/from the ring > > > > > > + * - enqueue/dequeue finish > > > > > > + * Along with the advantages of the peek APIs, these APIs > > > > > > + provide the ability > > > > > > + * to avoid copying of the data to temporary area. > > > > > > + * > > > > > > + * Note that right now this new API is available only for two = sync > > modes: > > > > > > + * 1) Single Producer/Single Consumer (RTE_RING_SYNC_ST) > > > > > > + * 2) Serialized Producer/Serialized Consumer > > (RTE_RING_SYNC_MT_HTS). > > > > > > + * It is a user responsibility to create/init ring with > > > > > > + appropriate sync > > > > > > + * modes selected. > > > > > > + * > > > > > > + * Example usage: > > > > > > + * // read 1 elem from the ring: > > > > > > > > > > Comment should be "prepare enqueuing 32 objects" > > > > > > > > > > > + * n =3D rte_ring_enqueue_sg_bulk_start(ring, 32, &sgd, NULL); > > > > > > + * if (n !=3D 0) { > > > > > > + * //Copy objects in the ring > > > > > > + * memcpy (sgd->ptr1, obj, sgd->n1 * sizeof(uintptr_t)); > > > > > > + * if (n !=3D sgd->n1) > > > > > > + * //Second memcpy because of wrapround > > > > > > + * n2 =3D n - sgd->n1; > > > > > > + * memcpy (sgd->ptr2, obj[n2], n2 * sizeof(uintptr_t)); > > > > > > > > > > Missing { } > > > > > > > > > > > + * rte_ring_dequeue_sg_finish(ring, n); > > > > > > > > > > Should be enqueue > > > > > > > > > Thanks, will correct them. > > > > > > > > > > + * } > > > > > > + * > > > > > > + * Note that between _start_ and _finish_ none other thread ca= n > > > > > > + proceed > > > > > > + * with enqueue(/dequeue) operation till _finish_ completes. > > > > > > + */ > > > > > > + > > > > > > +#ifdef __cplusplus > > > > > > +extern "C" { > > > > > > +#endif > > > > > > + > > > > > > +#include > > > > > > + > > > > > > +/* Rock that needs to be passed between reserve and commit API= s > > > > > > +*/ struct rte_ring_sg_data { > > > > > > + /* Pointer to the first space in the ring */ > > > > > > + void **ptr1; > > > > > > + /* Pointer to the second space in the ring if there is wrap- > > around */ > > > > > > + void **ptr2; > > > > > > + /* Number of elements in the first pointer. If this is equal = to > > > > > > + * the number of elements requested, then ptr2 is NULL. > > > > > > + * Otherwise, subtracting n1 from number of elements > > requested > > > > > > + * will give the number of elements available at ptr2. > > > > > > + */ > > > > > > + unsigned int n1; > > > > > > +}; > > > > > > > > > > Would it be possible to simply return the offset instead of this = structure? > > > > > The wrap could be managed by a __rte_ring_enqueue_elems() > > function. > > > > Trying to use __rte_ring_enqueue_elems() will force temporary copy. > > See below. > > > > > > > > > > > > > > I mean something like this: > > > > > > > > > > uint32_t start; > > > > > n =3D rte_ring_enqueue_sg_bulk_start(ring, 32, &start, NULL); > > > > > if (n !=3D 0) { > > > > > /* Copy objects in the ring. */ > > > > > __rte_ring_enqueue_elems(ring, start, obj, sizeof(uintptr_t), > > > > > n); > > > > For ex: 'obj' here is temporary copy. > > > > > > > > > rte_ring_enqueue_sg_finish(ring, n); > > > > > } > > > > > > > > > > It would require to slightly change __rte_ring_enqueue_elems() to > > > > > support to be called with prod_head >=3D size, and wrap in that c= ase. > > > > > > > > > The alternate solution I can think of requires 3 things 1) the base > > > > address of the ring 2) Index to where to copy 3) the mask. With > > > > these 3 > > > things one could write the code like below: > > > > for (i =3D 0; i < n; i++) { > > > > ring_addr[(index + i) & mask] =3D obj[i]; // ANDing with mask will= take > > care of wrap-around. > > > > } > > > > > > > > However, I think this does not allow for passing the address in the > > > > ring to another function/API to copy the data (It is possible, but > > > > the user > > > has to calculate the actual address, worry about the wrap-around, sec= ond > > pointer etc). > > > > > > > > The current approach hides some details and provides flexibility to= the > > application to use the pointer the way it wants. > > > > > > I agree that doing the access + masking manually looks too complex. > > > > > > However I'm not sure to get why using __rte_ring_enqueue_elems() > > would > > > result in an additional copy. I suppose the object that you want to > > > enqueue is already stored somewhere? > I think this is the key. The object is not stored any where (yet), it is = getting generated. When it is generated, it should get stored directly into > the ring. I have provided some examples below. >=20 > > > > > > For instance, let's say you have 10 objects to enqueue, located at > > > different places: > > > > > > void *obj_0_to_3 =3D ; > > > void *obj_4_to_7 =3D ...; > > > void *obj_8_to_9 =3D ...; > > > uint32_t start; > > > n =3D rte_ring_enqueue_sg_bulk_start(ring, 10, &start, NULL); > > > if (n !=3D 0) { > > > __rte_ring_enqueue_elems(ring, start, obj_0_to_3, > > > sizeof(uintptr_t), 4); > > > __rte_ring_enqueue_elems(ring, start + 4, obj_4_to_7, > > > sizeof(uintptr_t), 4); > > > __rte_ring_enqueue_elems(ring, start + 8, obj_8_to_9, > > > sizeof(uintptr_t), 2); > > > rte_ring_enqueue_sg_finish(ring, 10); > > > } > > > > > > > > > As I understand, It is not about different objects stored in different = places, it > > is about: > > a) object is relatively big (16B+ ?) > > b) You compose objects from values stored in few different places. > > > > Let say you have: > > struct elem_obj {uint64_t a; uint32_t b, c;}; > > > > And then you'd like to copy 'a' value from one location, 'b' from secon= d, and > > 'c' from third one. > > > > Konstantin > > > I think there are multiple use cases. Some I have in mind are: >=20 > 1) > Code without this patch: >=20 > struct rte_mbuf *pkts_burst[32]; >=20 > /* Create ring with sync type RTE_RING_SYNC_ST or RTE_RING_SYNC_MT_HTS */ >=20 > /* Pkt I/O core polls packets from the NIC, pkts_burst is the temporary s= tore */ > nb_rx =3D rte_eth_rx_burst(portid, queueid, pkts_burst, 32); > /* Provide packets to the packet processing cores */ > rte_ring_enqueue_burst(ring, pkts_burst, 32, &free_space); >=20 > Code with the patch: >=20 > /* Create ring with sync type RTE_RING_SYNC_ST or RTE_RING_SYNC_MT_HTS */ >=20 > /* Reserve space on the ring */ > n =3D rte_ring_enqueue_sg_burst_start(ring, 32, &sgd, NULL); > /* Pkt I/O core polls packets from the NIC */ > if (n =3D=3D 32) > nb_rx =3D rte_eth_rx_burst(portid, queueid, sgd->ptr1, 32); > else > nb_rx =3D rte_eth_rx_burst(portid, queueid, sgd->ptr1, sgd->n1); > /* Provide packets to the packet processing cores */ > /* Temporary storage 'pkts_burst' is not required */ > rte_ring_enqueue_sg_finish(ring, nb_rx); >=20 >=20 > 2) This is same/similar to what Konstantin mentioned >=20 > Code without this patch: >=20 > struct elem_obj {uint64_t a; uint32_t b, c;}; > struct elem_obj obj; >=20 > /* Create ring with sync type RTE_RING_SYNC_ST or RTE_RING_SYNC_MT_HTS */ >=20 > obj.a =3D rte_get_a(); > obj.b =3D rte_get_b(); > obj.c =3D rte_get_c(); > /* obj is the temporary storage and results in memcpy in the following ca= ll */ > rte_ring_enqueue_elem(ring, sizeof(struct elem_obj), 1, &obj, NULL); >=20 > Code with the patch: >=20 > struct elem_obj *obj; > /* Reserve space on the ring */ > n =3D rte_ring_enqueue_sg_bulk_elem_start(ring, sizeof(elem_obj), 1, &sgd= , NULL); >=20 > obj =3D (struct elem_obj *)sgd->ptr1; > obj.a =3D rte_get_a(); > obj.b =3D rte_get_b(); > obj.c =3D rte_get_c(); > /* obj is not a temporary storage */ > rte_ring_enqueue_sg_elem_finish(ring, n);