DPDK patches and discussions
 help / color / mirror / Atom feed
From: Marat Khalili <marat.khalili@huawei.com>
To: Stephen Hemminger <stephen@networkplumber.org>,
	"dev@dpdk.org" <dev@dpdk.org>
Subject: RE: [PATCH 07/12] net/pcap: avoid use of volatile
Date: Wed, 7 Jan 2026 10:31:40 +0000	[thread overview]
Message-ID: <234ce78433ba40a4963e06d4ea0d1c3c@huawei.com> (raw)
In-Reply-To: <20260106182823.192350-8-stephen@networkplumber.org>

> Using volatile for statistics generates expensive atomic rmw
> operations when not necessary.

I am not sure it is true, AFAIK volatile only affects the compiler. In this 
case it mostly guards against these variables being completely cached in 
registers. Your new version is actually more correct, but also potentially 
slower since general fence affects all reads or writes, not just counters in 
question. I think it is common among drivers to not guarantee visibility of 
the most recent counter values for the sake of performance.

> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  drivers/net/pcap/pcap_ethdev.c | 38 ++++++++++++++++++++++++++--------
>  1 file changed, 29 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/pcap/pcap_ethdev.c b/drivers/net/pcap/pcap_ethdev.c
> index 1658685a28..175d6998f9 100644
> --- a/drivers/net/pcap/pcap_ethdev.c
> +++ b/drivers/net/pcap/pcap_ethdev.c
> @@ -47,10 +47,10 @@ static uint64_t timestamp_rx_dynflag;
>  static int timestamp_dynfield_offset = -1;
> 
>  struct queue_stat {
> -	volatile unsigned long pkts;
> -	volatile unsigned long bytes;
> -	volatile unsigned long err_pkts;
> -	volatile unsigned long rx_nombuf;
> +	uint64_t pkts;
> +	uint64_t bytes;
> +	uint64_t err_pkts;
> +	uint64_t rx_nombuf;
>  };
> 
>  struct queue_missed_stat {
> @@ -267,6 +267,9 @@ eth_pcap_rx_infinite(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
>  	pcap_q->rx_stat.pkts += i;
>  	pcap_q->rx_stat.bytes += rx_bytes;
> 
> +	/* ensure store operations of statistics are visible */
> +	rte_atomic_thread_fence(rte_memory_order_release);
> +
>  	return i;
>  }
> 
> @@ -345,6 +348,9 @@ eth_pcap_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
>  	pcap_q->rx_stat.pkts += num_rx;
>  	pcap_q->rx_stat.bytes += rx_bytes;
> 
> +	/* ensure store operations of statistics are visible */
> +	rte_atomic_thread_fence(rte_memory_order_release);
> +
>  	return num_rx;
>  }
> 
> @@ -440,6 +446,9 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
>  	dumper_q->tx_stat.bytes += tx_bytes;
>  	dumper_q->tx_stat.err_pkts += nb_pkts - num_tx;
> 
> +	/* ensure store operations of statistics are visible */
> +	rte_atomic_thread_fence(rte_memory_order_release);
> +
>  	return nb_pkts;
>  }
> 
> @@ -464,6 +473,9 @@ eth_tx_drop(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
>  	tx_queue->tx_stat.pkts += nb_pkts;
>  	tx_queue->tx_stat.bytes += tx_bytes;
> 
> +	/* ensure store operations of statistics are visible */
> +	rte_atomic_thread_fence(rte_memory_order_release);
> +
>  	return nb_pkts;
>  }
> 
> @@ -515,6 +527,9 @@ eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
>  	tx_queue->tx_stat.bytes += tx_bytes;
>  	tx_queue->tx_stat.err_pkts += nb_pkts - num_tx;
> 
> +	/* ensure store operations of statistics are visible */
> +	rte_atomic_thread_fence(rte_memory_order_release);
> +
>  	return nb_pkts;
>  }
> 
> @@ -821,13 +836,16 @@ eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
>  	      struct eth_queue_stats *qstats)
>  {
>  	unsigned int i;
> -	unsigned long rx_packets_total = 0, rx_bytes_total = 0;
> -	unsigned long rx_missed_total = 0;
> -	unsigned long rx_nombuf_total = 0, rx_err_total = 0;
> -	unsigned long tx_packets_total = 0, tx_bytes_total = 0;
> -	unsigned long tx_packets_err_total = 0;
> +	uint64_t rx_packets_total = 0, rx_bytes_total = 0;
> +	uint64_t rx_missed_total = 0;
> +	uint64_t rx_nombuf_total = 0, rx_err_total = 0;
> +	uint64_t tx_packets_total = 0, tx_bytes_total = 0;
> +	uint64_t tx_packets_err_total = 0;
>  	const struct pmd_internals *internal = dev->data->dev_private;
> 
> +	/* ensure that current statistics are visible */
> +	rte_atomic_thread_fence(rte_memory_order_acquire);
> +
>  	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&
>  			i < dev->data->nb_rx_queues; i++) {
>  		if (qstats != NULL) {
> @@ -884,6 +902,8 @@ eth_stats_reset(struct rte_eth_dev *dev)
>  		internal->tx_queue[i].tx_stat.err_pkts = 0;
>  	}
> 
> +	/* ensure store operations of statistics are visible */
> +	rte_atomic_thread_fence(rte_memory_order_release);
>  	return 0;
>  }
> 
> --
> 2.51.0
> 


  reply	other threads:[~2026-01-07 10:31 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-06 18:26 [PATCH 00/12] net/pcap: cleanups and test Stephen Hemminger
2026-01-06 18:26 ` [PATCH 01/12] net/pcap: avoid using rte_malloc and rte_memcpy Stephen Hemminger
2026-01-06 18:26 ` [PATCH 02/12] net/pcap: support MTU set Stephen Hemminger
2026-01-06 18:26 ` [PATCH 03/12] net/pcap: use bool for flags Stephen Hemminger
2026-01-07 10:28   ` Marat Khalili
2026-01-09  0:23     ` Stephen Hemminger
2026-01-06 18:26 ` [PATCH 04/12] net/pcap: support Tx offloads Stephen Hemminger
2026-01-06 18:26 ` [PATCH 05/12] net/pcap: support nanosecond timestamp precision Stephen Hemminger
2026-01-06 18:26 ` [PATCH 06/12] net/pcap: remove global variables Stephen Hemminger
2026-01-07  9:48   ` Marat Khalili
2026-01-06 18:26 ` [PATCH 07/12] net/pcap: avoid use of volatile Stephen Hemminger
2026-01-07 10:31   ` Marat Khalili [this message]
2026-01-06 18:26 ` [PATCH 08/12] net/pcap: optimize calculation of receive timestamp Stephen Hemminger
2026-01-07 10:58   ` Marat Khalili
2026-01-06 18:26 ` [PATCH 09/12] net/pcap: report receive clock Stephen Hemminger
2026-01-06 18:26 ` [PATCH 10/12] net/pcap: cleanup MAC address handling Stephen Hemminger
2026-01-06 18:26 ` [PATCH 11/12] net/pcap: support MAC address set Stephen Hemminger
2026-01-06 18:26 ` [PATCH 12/12] test: add test for pcap PMD Stephen Hemminger
2026-01-09  1:16 ` [PATCH v2 0/9] pcap: cleanup pcap PMD and add test Stephen Hemminger
2026-01-09  1:16   ` [PATCH v2 1/9] net/pcap: avoid using rte_malloc and rte_memcpy Stephen Hemminger
2026-01-09  1:16   ` [PATCH v2 2/9] net/pcap: support MTU set Stephen Hemminger
2026-01-09  1:16   ` [PATCH v2 3/9] net/pcap: use bool for flags Stephen Hemminger
2026-01-09  1:16   ` [PATCH v2 4/9] net/pcap: support Tx offloads Stephen Hemminger
2026-01-09  1:16   ` [PATCH v2 5/9] net/pcap: support nanosecond timestamp precision Stephen Hemminger
2026-01-09  1:16   ` [PATCH v2 6/9] net/pcap: remove global variables Stephen Hemminger
2026-01-09  1:16   ` [PATCH v2 7/9] net/pcap: avoid use of volatile Stephen Hemminger
2026-01-09  1:16   ` [PATCH v2 8/9] net/pcap: support MAC address set Stephen Hemminger
2026-01-09  1:16   ` [PATCH v2 9/9] test: add test for pcap PMD Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=234ce78433ba40a4963e06d4ea0d1c3c@huawei.com \
    --to=marat.khalili@huawei.com \
    --cc=dev@dpdk.org \
    --cc=stephen@networkplumber.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).