<div dir="ltr"><div>Please ignore the type.</div><div>It Solved *OUR* problem.<br></div><div><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><br><br>Thanks & Regards<br>--<br>Lokesh Chakka.</div></div></div></div></div></div></div></div></div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Aug 15, 2024 at 9:48 PM Lokesh Chakka <<a href="mailto:lvenkatakumarchakka@gmail.com">lvenkatakumarchakka@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div>Hi Stephen,<div dir="auto"><br></div><div dir="auto">Thank you for the information.</div><div dir="auto">It solved your problem.</div><div dir="auto"><br></div><div dir="auto">Regards.</div><div dir="auto">Lokesh.</div><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 14 Aug, 2024, 20:29 Stephen Hemminger, <<a href="mailto:stephen@networkplumber.org" target="_blank">stephen@networkplumber.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wed, 14 Aug 2024 17:57:40 +0530<br>
Lokesh Chakka <<a href="mailto:lvenkatakumarchakka@gmail.com" rel="noreferrer" target="_blank">lvenkatakumarchakka@gmail.com</a>> wrote:<br>
<br>
> hi stephen,<br>
> <br>
> Thanks for your response. However it seems the solution is not working. The<br>
> following is the modified snippet....<br>
> <br>
> while( condition )<br>
> {<br>
> for( pkt_count=0; pkt_count<num_of_pkts_per_queue; pkt_count++ )<br>
> {<br>
> rte_mbuf_refcnt_set( mbuf[pkt_count], 2 );// setting to two -<br>
> first and second iteration<br>
> }<br>
> for( pkt_count=0; pkt_count<5; pkt_count++ )<br>
> {<br>
> fprintf( stderr, "%s %d %u\n", __func__, __LINE__,<br>
> rte_mbuf_refcnt_read( mbuf[pkt_count] ) );//able to print two- first and<br>
> second iteration<br>
> }<br>
> if( rte_eth_tx_burst( port_id, 0, mbuf, num_of_pkts_per_queue ) !=<br>
> num_of_pkts_per_queue )<br>
> {<br>
> fprintf( stderr, "%s %d %d %s\n", __func__, __LINE__, rte_errno,<br>
> rte_strerror(rte_errno) );//failing second time<br>
> rte_exit( EXIT_FAILURE, "%s %d rte_eth_tx_burst port id: %u\n",<br>
> __func__, __LINE__, port_id );<br>
> }<br>
> fprintf( stderr, "%s %d port: %u sent %u packets\n", __func__,<br>
> __LINE__, port_id, num_of_pkts_per_queue );//able to send once - first<br>
> iteration only<br>
> for( pkt_count=0; pkt_count<5; pkt_count++ )<br>
> {<br>
> fprintf( stderr, "%s %d %u\n", __func__, __LINE__,<br>
> rte_mbuf_refcnt_read( mbuf[pkt_count] ) );//refcnt is printing one<br>
> }<br>
> }<br>
> <br>
> There seems to be some more gap in my understanding. Could you please help<br>
> understand the issue?<br>
> <br>
> Thanks & Regards<br>
> --<br>
> Lokesh Chakka.<br>
> <br>
> <br>
> On Mon, Aug 12, 2024 at 8:22 PM Stephen Hemminger <<br>
> <a href="mailto:stephen@networkplumber.org" rel="noreferrer" target="_blank">stephen@networkplumber.org</a>> wrote: <br>
> <br>
> > On Mon, 12 Aug 2024 15:55:50 +0530<br>
> > Lokesh Chakka <<a href="mailto:lvenkatakumarchakka@gmail.com" rel="noreferrer" target="_blank">lvenkatakumarchakka@gmail.com</a>> wrote:<br>
> > <br>
> > > hello,<br>
> > ><br>
> > > Here is a small piece of code :<br>
> > ><br>
> > > while( condition )<br>
> > > {<br>
> > ><br>
> > > if( rte_eth_tx_burst( port_id, 0, mbuf, num_of_pkts_per_queue ) !=<br>
> > > num_of_pkts_per_queue )<br>
> > > {<br>
> > > fprintf( stderr, "%d %s\n", rte_errno, <br>
> > rte_strerror(rte_errno) ); <br>
> > > rte_exit( EXIT_FAILURE, "%s %d rte_eth_tx_burst port id: <br>
> > %u\n", <br>
> > > __func__, __LINE__, port_id );//second iteration failing.<br>
> > > }<br>
> > > fprintf( stderr, "%s %d port: %u packet: %c sent %u packets\n",<br>
> > > __func__, __LINE__, port_id, argv[3][0], num_of_pkts_per_queue<br>
> > > );//printing once<br>
> > > for( pkt_count=0; pkt_count<num_of_pkts_per_queue; pkt_count++ )<br>
> > > {//want to send same data again...!!!<br>
> > > mbuf[pkt_count]->pkt_len = mbuf[pkt_count]->data_len = <br>
> > dev_info.max_mtu; <br>
> > ><br>
> > > }<br>
> > ><br>
> > > }<br>
> > ><br>
> > > Can someone help me understand how to reuse the packets again to send the<br>
> > > same data ?<br>
> > > <br>
> ><br>
> > When packet is passed to tx_burst, the ownership of that mbuf is passed<br>
> > to the driver. The driver will free it after it is sent.<br>
> ><br>
> > One option would be to increase the reference count on the packet before<br>
> > sending.<br>
> > Using rte_mbuf_refcnt_update() function to add one to refcount.<br>
> > Then the driver will decrement refcount and the refcount will still be one<br>
> > (not freed).<br>
> ><br>
> > Assume this is some kind of packet generator.<br>
> > <br>
<br>
<br>
Don't use refcnt_set(), you want to add an additional refcount not force it to two.<br>
The device driver may hold onto the mbuf for a while after it was passed to tx_burst<br>
so can't assume a value of two.<br>
<br>
If the number actually queued is less that the number requested, that means the device<br>
transmit queue is now full. Need to handle that case.<br>
<br>
Something like this might get you started:<br>
<br>
<br>
volatile running = true;<br>
<br>
void flood(uint16_t port_id, struct rte_mbufs *mbufs[], uint16_t num_pkts)<br>
{<br>
<br>
while (running) {<br>
/* Add additional reference to retain the packets */<br>
for (uint16_t i = 0; i < num_pkts; i++)<br>
rte_mbuf_refcnt_update(mbufs[i], 1);<br>
<br>
uint16_t sent = rte_eth_tx_burst(port_id, queue_id, mbufs, num_pkts);<br>
<br>
if (sent < num_pkts) {<br>
/* device transmit queue was full, drop our reference */<br>
for (uint16_t i = sent; i < num_pkts; i++)<br>
rte_pktmbuf_free(mbufs[i]);<br>
}<br>
}<br>
<br>
/* Don't leak original version */<br>
rte_pktmbuf_free_bulk(mbufs, num_pkts);<br>
<br>
}<br>
<br>
<br>
</blockquote></div></div></div>
</blockquote></div>