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 92969457D8 for ; Thu, 15 Aug 2024 18:18:23 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 577E54275C; Thu, 15 Aug 2024 18:18:23 +0200 (CEST) Received: from mail-qv1-f46.google.com (mail-qv1-f46.google.com [209.85.219.46]) by mails.dpdk.org (Postfix) with ESMTP id 859D740647 for ; Thu, 15 Aug 2024 18:18:22 +0200 (CEST) Received: by mail-qv1-f46.google.com with SMTP id 6a1803df08f44-6bf7ba05f75so1666706d6.0 for ; Thu, 15 Aug 2024 09:18:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723738702; x=1724343502; 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=8N+0bHmaktqeJiZ9nYTGxOpv/9ttE90rFzaHIrr7MhQ=; b=kxEKeUQqxtpXpDKff0Y8jPDVk9CgXhsXO7HPOY9eleuOMIkZhB2dpyuU+22o3G2QFX +879wuyq7cAJb5ouZtFBNofEUKRrzX20BgvaaXWk+DiAcFDS2UHtAzNlTSYd1MNoPEDP qpn1wnX738HF3ItI6gOdKz/EzxP/Oj8v65cstoCEIGnhtvyFrGdA7XXQJjKASmV5SO/8 xbVkTiGApsxY6INcnCvTCNBP44dMVo/wQn/BLasuJRjJUIpOnHbKjXk22l+R/01HXPjm RWw5nXxVEbdNBoZ2fIOOQi+5djdBXWnjir0Xtupc4AVWoBbOcIHape+9YAEkJ41fBKMP EW/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723738702; x=1724343502; 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=8N+0bHmaktqeJiZ9nYTGxOpv/9ttE90rFzaHIrr7MhQ=; b=cTXQh1qL32hiz9aI2pV8i9ylIY3nRUa9f08nX0pJiqw1cPqvJiA7p8XBWMMkaud8me klPR/P8+oJTcdQKU3LYS47aCQq03WeyEFpQalK4vGrzxshZ8+uwDYMS+MO0AZjyrMM30 xra0gLCCkLZ+9b3BYowYbIloXfsPIjDLRHAauMl7UEnv8heDEgap4zfCLOULj21OsgyF AxKCR71PVeltVlpyTgeGl3NWOSBwTqkI6uUzR7fT6mb9QqKN4udCNPDkQO3pf7wY0dIN 9uPDXsUHtnF+VZ0bM4mdK0sFG8m9Ct4DfYr4JeS3k/MIY7yEbStxGoDOfMOGhyruSvKR OArQ== X-Gm-Message-State: AOJu0YwhKPhQ2Tv7PCA7lvWlVE99BeGpsV9Riauh97VECfQ88+NIBf0J fAVvVXbAJCvs4yanPkfcVB5gbJLj7XLvygf4xm0+JZTwHi7xzmqP1X03p4mONXIyhR2+/qjMm81 0ClpfwaeTo+XUUfq0aBEuVdlIVew= X-Google-Smtp-Source: AGHT+IHKQUaqfvF9WAjoxBQSBqRt9zUIXQhx1vVLzSvonMVlIuCEP4sdc53U7PowyOmC9i52Y8CowMbDppGrdFNPjKQ= X-Received: by 2002:a05:6214:2508:b0:6b5:d73d:9196 with SMTP id 6a1803df08f44-6bf6de4d1c6mr81084146d6.22.1723738701545; Thu, 15 Aug 2024 09:18:21 -0700 (PDT) MIME-Version: 1.0 References: <20240812075216.534be9db@hermes.local> <20240814075902.187cda3f@hermes.local> In-Reply-To: <20240814075902.187cda3f@hermes.local> From: Lokesh Chakka Date: Thu, 15 Aug 2024 21:48:10 +0530 Message-ID: Subject: Re: reuse the packets after tx burst To: Stephen Hemminger Cc: users Content-Type: multipart/alternative; boundary="000000000000fdc995061fbb308e" 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 --000000000000fdc995061fbb308e Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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 an= d > > 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_queue > ) !=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 ) > > > > {//want to send same data again...!!! > > > > mbuf[pkt_count]->pkt_len =3D mbuf[pkt_count]->data_le= n > =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 pass= ed > > > 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 b= e > 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_pkts= ) > { > > 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, mbu= fs, > 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); > > } > > > --000000000000fdc995061fbb308e Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Stephen,

Thank you for the information.
It solved your p= roblem.

Regards.
Lokesh.


On Wed, 14 Aug, 2024, 20:29 Stephen Hemminger, &= lt;stephen@networkplumber.org= > wrote:
On Wed, 14 Aug 2024= 17:57:40 +0530
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);

}


--000000000000fdc995061fbb308e--