From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
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 <dev@dpdk.org>; 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" <konstantin.ananyev@intel.com>
To: Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>, Olivier Matz
 <olivier.matz@6wind.com>
CC: "dev@dpdk.org" <dev@dpdk.org>, "david.marchand@redhat.com"
 <david.marchand@redhat.com>, nd <nd@arm.com>, nd <nd@arm.com>
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: <BYAPR11MB3301191B27890F387D48D34B9A070@BYAPR11MB3301.namprd11.prod.outlook.com>
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>
 <DBAPR08MB5814C9B0AB1E569C3D51CC65980B0@DBAPR08MB5814.eurprd08.prod.outlook.com>
 <20201009073342.GZ21395@platinum>
 <BYAPR11MB33011F4A1B68B713723DF25A9A080@BYAPR11MB3301.namprd11.prod.outlook.com>
 <DBAPR08MB581406C02A163D1F2601841D98080@DBAPR08MB5814.eurprd08.prod.outlook.com>
In-Reply-To: <DBAPR08MB581406C02A163D1F2601841D98080@DBAPR08MB5814.eurprd08.prod.outlook.com>
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: <BYAPR11MB36069FF16E7567B8F51F49139A070@BYAPR11MB3606.namprd11.prod.outlook.com>
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 <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org
Sender: "dev" <dev-bounces@dpdk.org>



=20
> <snip>
>=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
> > > > > > <honnappa.nagarahalli@arm.com>
> > > > > > ---
> > > > > >  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 <rte_ring_peek.h>
> > > > > > +#include <rte_ring_peek_sg.h>
> > > > > >  #endif
> > > > > >
> > > > > >  #include <rte_ring.h>
> > > > > > 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 <rte_ring_elem.h> 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 <rte_ring_peek_c11_mem.h>
> > > > > > +
> > > > > > +/* 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 <place where objects 0 to 3 are stored>;
> > > 	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);