From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2CC17457E1 for ; Fri, 16 Aug 2024 09:12:40 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A29864025D; Fri, 16 Aug 2024 09:12:39 +0200 (CEST) Received: from mail-qv1-f51.google.com (mail-qv1-f51.google.com [209.85.219.51]) by mails.dpdk.org (Postfix) with ESMTP id 0FA43400EF for ; Fri, 16 Aug 2024 09:12:38 +0200 (CEST) Received: by mail-qv1-f51.google.com with SMTP id 6a1803df08f44-6bf7f4a133aso1988296d6.2 for ; Fri, 16 Aug 2024 00:12:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723792357; x=1724397157; darn=dpdk.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=VBT4G5XcUzo7lKJgQ5WmwvXHPAYaZn9wGMJ0c69oLZY=; b=FTCmp72vWjehyvKKysxOOX9jnKVGMC/PjZjqZYMrNSGCcMyEGUaCvzs2Mzx3hlH0bN f62hPDrtDtkTldrJLo9ZfPFCcoJKUOPLccZGkysQ49MboVjIr0CtD3C2s0X+lboRNKZP PZOUDmakvT9G3JkjSyI+yP23PETW+SPPTOgqBwPP5DzppOe3g0CComyJb8dftm+A6uhh w5gJdB8MTL7BpOq8fhTfSG4KfqHyGlWaS3oAUgJyPRtyc8e+0gRIvhjknYRHCwFhVHsE sxLDj9uvQHi0zzT/0LG2xYp3rump2ksmtqsPk7byMtvSvUZfY/luJccBdzJyWRdpm89x rcDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723792357; x=1724397157; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=VBT4G5XcUzo7lKJgQ5WmwvXHPAYaZn9wGMJ0c69oLZY=; b=QrNw3SelEyBfQJVos2TFh5SFdFAvubPuffRLCRs3oYE8gnKh8EzNORnXcbLv7WsFSc pYrUQeYI0VCDc1M1dNHGix0/K4Y+KbYmdTZRWR+8dQNasVmJuSdEDIEMQlgeDcWWS5Vp O7w5PgNrpIQXNlmOc/1jQGNJKe68B1mOAKVnr9A5c6qlfWVD7RbxuQAyVHpleIUic2TB wWk3Ve76hCxJ2kCktOo0wc/I2r2hDvjKSbtk9tfg8yc156in2Ovxy8drG3YhuOIbcPC1 8aEu8XE2nvfSPhuWb18WKxcMHPgGSVR6tjzw1uT/B1L3u7yA50UhqEdoi0q0/VwqHPXb IrYg== X-Gm-Message-State: AOJu0Ywcovv29F/2GxsyaRp+NhL3FlYfQ/tkZjry77id8HeQOWq97X5p Jsp3TqazRMh3E7wFmLJ4Vice/WVmkYCVCTEA+rapTYH8Q+oqNX6t8izy/E2WR67oCO71ciB7t8n DlNL0+D0VlfSZA4ddL+VYKGBAZFRzHQi6 X-Google-Smtp-Source: AGHT+IGw8pRTPuCRyCFteTW87Hg4yM9eVhpr7sf3SetHMRO4ptyfF5JUCLVtretDzNOwhgnKnglrBzV28jGe/AxYwqQ= X-Received: by 2002:a05:6214:4a07:b0:6bf:745e:d48e with SMTP id 6a1803df08f44-6bf7ce67f9dmr24987706d6.51.1723792357086; Fri, 16 Aug 2024 00:12:37 -0700 (PDT) MIME-Version: 1.0 References: <20240812075216.534be9db@hermes.local> <20240814075902.187cda3f@hermes.local> In-Reply-To: From: Lokesh Chakka Date: Fri, 16 Aug 2024 12:42:26 +0530 Message-ID: Subject: Re: reuse the packets after tx burst To: Stephen Hemminger Cc: users Content-Type: multipart/alternative; boundary="0000000000001c5c81061fc7afee" X-BeenThere: users@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK usage discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: users-bounces@dpdk.org --0000000000001c5c81061fc7afee Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Please ignore the type. It Solved *OUR* problem. Thanks & Regards -- Lokesh Chakka. On Thu, Aug 15, 2024 at 9:48=E2=80=AFPM Lokesh Chakka wrote: > Hi Stephen, > > Thank you for the information. > It solved your problem. > > Regards. > Lokesh. > > > On Wed, 14 Aug, 2024, 20:29 Stephen Hemminger, > wrote: > >> On Wed, 14 Aug 2024 17:57:40 +0530 >> Lokesh Chakka wrote: >> >> > hi stephen, >> > >> > Thanks for your response. However it seems the solution is not working= . >> The >> > following is the modified snippet.... >> > >> > while( condition ) >> > { >> > for( pkt_count=3D0; pkt_count> > { >> > rte_mbuf_refcnt_set( mbuf[pkt_count], 2 );// setting to two = - >> > first and second iteration >> > } >> > for( pkt_count=3D0; pkt_count<5; pkt_count++ ) >> > { >> > fprintf( stderr, "%s %d %u\n", __func__, __LINE__, >> > rte_mbuf_refcnt_read( mbuf[pkt_count] ) );//able to print two- first a= nd >> > second iteration >> > } >> > if( rte_eth_tx_burst( port_id, 0, mbuf, num_of_pkts_per_queue ) != =3D >> > num_of_pkts_per_queue ) >> > { >> > fprintf( stderr, "%s %d %d %s\n", __func__, __LINE__, >> rte_errno, >> > rte_strerror(rte_errno) );//failing second time >> > rte_exit( EXIT_FAILURE, "%s %d rte_eth_tx_burst port id: >> %u\n", >> > __func__, __LINE__, port_id ); >> > } >> > fprintf( stderr, "%s %d port: %u sent %u packets\n", __func__, >> > __LINE__, port_id, num_of_pkts_per_queue );//able to send once - first >> > iteration only >> > for( pkt_count=3D0; pkt_count<5; pkt_count++ ) >> > { >> > fprintf( stderr, "%s %d %u\n", __func__, __LINE__, >> > rte_mbuf_refcnt_read( mbuf[pkt_count] ) );//refcnt is printing one >> > } >> > } >> > >> > There seems to be some more gap in my understanding. Could you please >> help >> > understand the issue? >> > >> > Thanks & Regards >> > -- >> > Lokesh Chakka. >> > >> > >> > On Mon, Aug 12, 2024 at 8:22=E2=80=AFPM Stephen Hemminger < >> > stephen@networkplumber.org> wrote: >> > >> > > On Mon, 12 Aug 2024 15:55:50 +0530 >> > > Lokesh Chakka wrote: >> > > >> > > > hello, >> > > > >> > > > Here is a small piece of code : >> > > > >> > > > while( condition ) >> > > > { >> > > > >> > > > if( rte_eth_tx_burst( port_id, 0, mbuf, num_of_pkts_per_queu= e >> ) !=3D >> > > > num_of_pkts_per_queue ) >> > > > { >> > > > fprintf( stderr, "%d %s\n", rte_errno, >> > > rte_strerror(rte_errno) ); >> > > > rte_exit( EXIT_FAILURE, "%s %d rte_eth_tx_burst port >> id: >> > > %u\n", >> > > > __func__, __LINE__, port_id );//second iteration failing. >> > > > } >> > > > fprintf( stderr, "%s %d port: %u packet: %c sent %u >> packets\n", >> > > > __func__, __LINE__, port_id, argv[3][0], num_of_pkts_per_queue >> > > > );//printing once >> > > > for( pkt_count=3D0; pkt_count> pkt_count++ ) >> > > > {//want to send same data again...!!! >> > > > mbuf[pkt_count]->pkt_len =3D mbuf[pkt_count]->data_l= en >> =3D >> > > dev_info.max_mtu; >> > > > >> > > > } >> > > > >> > > > } >> > > > >> > > > Can someone help me understand how to reuse the packets again to >> send the >> > > > same data ? >> > > > >> > > >> > > When packet is passed to tx_burst, the ownership of that mbuf is >> passed >> > > to the driver. The driver will free it after it is sent. >> > > >> > > One option would be to increase the reference count on the packet >> before >> > > sending. >> > > Using rte_mbuf_refcnt_update() function to add one to refcount. >> > > Then the driver will decrement refcount and the refcount will still >> be one >> > > (not freed). >> > > >> > > Assume this is some kind of packet generator. >> > > >> >> >> Don't use refcnt_set(), you want to add an additional refcount not force >> it to two. >> The device driver may hold onto the mbuf for a while after it was passed >> to tx_burst >> so can't assume a value of two. >> >> If the number actually queued is less that the number requested, that >> means the device >> transmit queue is now full. Need to handle that case. >> >> Something like this might get you started: >> >> >> volatile running =3D true; >> >> void flood(uint16_t port_id, struct rte_mbufs *mbufs[], uint16_t num_pkt= s) >> { >> >> while (running) { >> /* Add additional reference to retain the packets */ >> for (uint16_t i =3D 0; i < num_pkts; i++) >> rte_mbuf_refcnt_update(mbufs[i], 1); >> >> uint16_t sent =3D rte_eth_tx_burst(port_id, queue_id, >> mbufs, num_pkts); >> >> if (sent < num_pkts) { >> /* device transmit queue was full, drop our >> reference */ >> for (uint16_t i =3D sent; i < num_pkts; i++) >> rte_pktmbuf_free(mbufs[i]); >> } >> } >> >> /* Don't leak original version */ >> rte_pktmbuf_free_bulk(mbufs, num_pkts); >> >> } >> >> >> --0000000000001c5c81061fc7afee Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Please ignore the type.
It Solved *OUR* pro= blem.


Thanks &a= mp; Regards
--
Lokesh Chakka.


On Thu, Aug 15, 2024 at 9:48=E2=80=AFPM= Lokesh Chakka <lvenkat= akumarchakka@gmail.com> wrote:
Hi Stephen,
<= br>
Thank you for the information.
It solved your problem.

Regards.
Lokesh.


On Wed, 14 Aug, 2024, 20:2= 9 Stephen Hemminger, <stephen@networkplumber.org> wrote:
On Wed, 14 Aug 2024 17:57:40 +0530<= br> Lokesh Chakka <lvenkatakumarchakka@gmail.com> wrote:
> hi stephen,
>
> Thanks for your response. However it seems the solution is not working= . The
> following is the modified snippet....
>
> while( condition )
> {
>=C2=A0 =C2=A0 =C2=A0 for( pkt_count=3D0; pkt_count<num_of_pkts_per_q= ueue; pkt_count++ )
>=C2=A0 =C2=A0 =C2=A0 {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_mbuf_refcnt_set( mbuf[pkt_= count], 2 );// setting to two -
> first and second iteration
>=C2=A0 =C2=A0 =C2=A0 }
>=C2=A0 =C2=A0 =C2=A0 for( pkt_count=3D0; pkt_count<5; pkt_count++ )<= br> >=C2=A0 =C2=A0 =C2=A0 {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf( stderr, "%s %d %= u\n", __func__, __LINE__,
> rte_mbuf_refcnt_read( mbuf[pkt_count] ) );//able to print two- first a= nd
> second iteration
>=C2=A0 =C2=A0 =C2=A0 }
>=C2=A0 =C2=A0 =C2=A0 if( rte_eth_tx_burst( port_id, 0, mbuf, num_of_pkt= s_per_queue ) !=3D
> num_of_pkts_per_queue )
>=C2=A0 =C2=A0 =C2=A0 {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf( stderr, "%s %d %= d %s\n", __func__, __LINE__, rte_errno,
> rte_strerror(rte_errno) );//failing second time
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_exit( EXIT_FAILURE, "= %s %d rte_eth_tx_burst port id: %u\n",
> __func__, __LINE__, port_id );
>=C2=A0 =C2=A0 =C2=A0 }
>=C2=A0 =C2=A0 =C2=A0 fprintf( stderr, "%s %d port: %u sent %u pack= ets\n", __func__,
> __LINE__, port_id, num_of_pkts_per_queue );//able to send once - first=
> iteration only
>=C2=A0 =C2=A0 =C2=A0 for( pkt_count=3D0; pkt_count<5; pkt_count++ )<= br> >=C2=A0 =C2=A0 =C2=A0 {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf( stderr, "%s %d %= u\n", __func__, __LINE__,
> rte_mbuf_refcnt_read( mbuf[pkt_count] ) );//refcnt is printing one
>=C2=A0 =C2=A0 =C2=A0 }
> }
>
> There seems to be some more gap in my understanding. Could you please = help
> understand the issue?
>
> Thanks & Regards
> --
> Lokesh Chakka.
>
>
> On Mon, Aug 12, 2024 at 8:22=E2=80=AFPM Stephen Hemminger <
> stephen@networkplumber.org> wrote:=C2=A0
>
> > On Mon, 12 Aug 2024 15:55:50 +0530
> > Lokesh Chakka <lvenkatakumarchakka@gmail.com>= ; wrote:
> >=C2=A0
> > > hello,
> > >
> > > Here is a small piece of code :
> > >
> > > while( condition )
> > > {
> > >
> > >=C2=A0 =C2=A0 =C2=A0 =C2=A0if( rte_eth_tx_burst( port_id, 0, = mbuf, num_of_pkts_per_queue ) !=3D
> > > num_of_pkts_per_queue )
> > >=C2=A0 =C2=A0 =C2=A0 =C2=A0{
> > >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprint= f( stderr, "%d %s\n", rte_errno,=C2=A0
> > rte_strerror(rte_errno) );=C2=A0
> > >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_ex= it( EXIT_FAILURE, "%s %d rte_eth_tx_burst port id:=C2=A0
> > %u\n",=C2=A0
> > > __func__, __LINE__, port_id );//second iteration failing. > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0}
> > >=C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf( stderr, "%s %d port:= %u packet: %c sent %u packets\n",
> > > __func__, __LINE__, port_id, argv[3][0], num_of_pkts_per_que= ue
> > > );//printing once
> > >=C2=A0 =C2=A0 =C2=A0 =C2=A0for( pkt_count=3D0; pkt_count<n= um_of_pkts_per_queue; pkt_count++ )
> > >=C2=A0 =C2=A0 =C2=A0 =C2=A0{//want to send same data again...= !!!
> > >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0mbuf[p= kt_count]->pkt_len =3D mbuf[pkt_count]->data_len =3D=C2=A0
> > dev_info.max_mtu;=C2=A0
> > >
> > >=C2=A0 =C2=A0 =C2=A0 =C2=A0}
> > >
> > > }
> > >
> > > Can someone help me understand how to reuse the packets agai= n to send the
> > > same data ?
> > >=C2=A0
> >
> > When packet is passed to tx_burst, the ownership of that mbuf is = passed
> > to the driver. The driver will free it after it is sent.
> >
> > One option would be to increase the reference count on the packet= before
> > sending.
> > Using rte_mbuf_refcnt_update() function to add one to refcount. > > Then the driver will decrement refcount and the refcount will sti= ll be one
> > (not freed).
> >
> > Assume this is some kind of packet generator.
> >=C2=A0


Don't use refcnt_set(), you want to add an additional refcount not forc= e it to two.
The device driver may hold onto the mbuf for a while after it was passed to= tx_burst
so can't assume a value of two.

If the number actually queued is less that the number requested, that means= the device
transmit queue is now full. Need to handle that case.

Something like this might get you started:


volatile running =3D true;

void flood(uint16_t port_id, struct rte_mbufs *mbufs[], uint16_t num_pkts)<= br> {

=C2=A0 =C2=A0 =C2=A0 =C2=A0 while (running) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Add additional r= eference to retain the packets */
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for (uint16_t i =3D= 0; i < num_pkts; i++)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 rte_mbuf_refcnt_update(mbufs[i], 1);

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 uint16_t sent =3D r= te_eth_tx_burst(port_id, queue_id, mbufs, num_pkts);

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (sent < num_p= kts) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 /* device transmit queue was full, drop our reference */
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 for (uint16_t i =3D sent; i < num_pkts; i++)
=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=A0 =C2=A0 =C2=A0 rte_pktmbuf_free(mbufs[i]);
=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=A0 =C2=A0 =C2=A0 /* Don't leak original version */
=C2=A0 =C2=A0 =C2=A0 =C2=A0 rte_pktmbuf_free_bulk(mbufs, num_pkts);

}


--0000000000001c5c81061fc7afee--