DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [27.03 RFC PATCH v1 0/8] Add usage counter helpers
@ 2026-10-16 14:02 Anatoly Burakov
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 1/8] eal: add usage count helpers Anatoly Burakov
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Anatoly Burakov @ 2026-10-16 14:02 UTC (permalink / raw)
  To: dev

There is a recurring pattern in DPDK code: on first use, do something,
on last use, undo something. In a lot of cases, these reference counters
are atomic or otherwise thread-safe, but in cases where they're not, we
use raw integers and do manual checks and counter updates instead.

This patchset attempts to provide a really minimal "usage counter" library
that does *only* that: track usage of resources. The patchset does not do
a full DPDK conversion to these counters, but it does convert a few things
to demonstrate what it would look like if we had them.

Anatoly Burakov (8):
  eal: add usage count helpers
  vfio: use usage counters
  dev: replace raw refcount with usage count
  vhost: use usage counters for vchan tracking
  acl: use usage counters for ref counting
  thash: use usage counters for ref counting
  lpm: use usage counters for ref counting
  net/nbl: track devices with usage counters

 doc/api/doxy-api-index.md                |  1 +
 drivers/net/nbl/nbl_common/nbl_userdev.c | 22 +++---
 lib/acl/acl.h                            |  4 +-
 lib/acl/acl_bld.c                        |  9 +--
 lib/eal/include/meson.build              |  1 +
 lib/eal/include/rte_usage_count.h        | 96 ++++++++++++++++++++++++
 lib/eal/linux/eal_dev.c                  | 20 +++--
 lib/eal/linux/eal_vfio.c                 |  7 +-
 lib/eal/linux/eal_vfio.h                 |  5 +-
 lib/eal/linux/eal_vfio_group.c           | 11 +--
 lib/hash/rte_thash.c                     | 10 +--
 lib/lpm/rte_lpm6.c                       | 13 ++--
 lib/vhost/vhost.c                        |  5 +-
 lib/vhost/vhost.h                        |  3 +-
 14 files changed, 151 insertions(+), 56 deletions(-)
 create mode 100644 lib/eal/include/rte_usage_count.h

-- 
2.52.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [27.03 RFC PATCH v1 1/8] eal: add usage count helpers
  2026-10-16 14:02 [27.03 RFC PATCH v1 0/8] Add usage counter helpers Anatoly Burakov
@ 2026-10-16 14:02 ` Anatoly Burakov
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 2/8] vfio: use usage counters Anatoly Burakov
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Anatoly Burakov @ 2026-10-16 14:02 UTC (permalink / raw)
  To: dev

In writing DPDK code, one of the often-seen pattern is counting usage of
resources - programming a HW block on first/last flow rule, or even just
tracking references to software structures. In a lot of cases, a simple
usage count is not a good fit because of atomicity/thread safety
requirements, but for trivial/already synchronized cases it can be useful.

Add a "usage count" library to EAL to enable such use cases.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 doc/api/doxy-api-index.md         |  1 +
 lib/eal/include/meson.build       |  1 +
 lib/eal/include/rte_usage_count.h | 96 +++++++++++++++++++++++++++++++
 3 files changed, 98 insertions(+)
 create mode 100644 lib/eal/include/rte_usage_count.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 62390f7be3..ab4ff04797 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -177,6 +177,7 @@ The public API headers are grouped by topics:
   [soring](@ref rte_soring.h),
   [stack](@ref rte_stack.h),
   [tailq](@ref rte_tailq.h),
+  [usage count](@ref rte_usage_count.h),
   [bitset](@ref rte_bitset.h),
   [bitmap](@ref rte_bitmap.h)
 
diff --git a/lib/eal/include/meson.build b/lib/eal/include/meson.build
index 67c6a8021a..5ff432051e 100644
--- a/lib/eal/include/meson.build
+++ b/lib/eal/include/meson.build
@@ -53,6 +53,7 @@ headers += files(
         'rte_trace.h',
         'rte_trace_point.h',
         'rte_trace_point_register.h',
+        'rte_usage_count.h',
         'rte_uuid.h',
         'rte_version.h',
 )
diff --git a/lib/eal/include/rte_usage_count.h b/lib/eal/include/rte_usage_count.h
new file mode 100644
index 0000000000..3056436ba8
--- /dev/null
+++ b/lib/eal/include/rte_usage_count.h
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2026 Intel Corporation
+ */
+
+#ifndef _RTE_USAGE_COUNT_H_
+#define _RTE_USAGE_COUNT_H_
+
+/**
+ * @file
+ * RTE Usage Counter
+ *
+ * Trivial usage (reference) counters intended to express increment/decrement
+ * sequences with first/last user edge detection, for example "do X on first Y,
+ * undo X on last Y".
+ *
+ * The counters are neither thread-safe nor atomic; callers must provide their
+ * own serialization.
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <rte_compat.h>
+#include <rte_debug.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Usage counter type.
+ */
+typedef uint32_t rte_usage_count_t;
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Claim a usage.
+ *
+ * @param counter
+ *   Usage counter to claim.
+ * @return
+ *   true if this is the first usage, false otherwise.
+ */
+__rte_experimental
+static inline bool
+rte_usage_count_claim(rte_usage_count_t *counter)
+{
+	RTE_ASSERT(*counter != UINT32_MAX);
+	return (*counter)++ == 0;
+}
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Release a usage.
+ *
+ * @param counter
+ *   Usage counter to release. Must have at least one usage.
+ * @return
+ *   true if this was the last usage, false otherwise.
+ */
+__rte_experimental
+static inline bool
+rte_usage_count_release(rte_usage_count_t *counter)
+{
+	RTE_ASSERT(*counter != 0);
+	return --(*counter) == 0;
+}
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Test whether the currently claimed usage is the last one,
+ * i.e. whether a subsequent release would return true.
+ *
+ * @param counter
+ *   Usage counter to test.
+ * @return
+ *   true if exactly one usage is currently claimed, false otherwise.
+ */
+__rte_experimental
+static inline bool
+rte_usage_count_is_last(const rte_usage_count_t *counter)
+{
+	return *counter == 1;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_USAGE_COUNT_H_ */
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [27.03 RFC PATCH v1 2/8] vfio: use usage counters
  2026-10-16 14:02 [27.03 RFC PATCH v1 0/8] Add usage counter helpers Anatoly Burakov
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 1/8] eal: add usage count helpers Anatoly Burakov
@ 2026-10-16 14:02 ` Anatoly Burakov
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 3/8] dev: replace raw refcount with usage count Anatoly Burakov
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Anatoly Burakov @ 2026-10-16 14:02 UTC (permalink / raw)
  To: dev

Currently, resources in VFIO (such as groups or devices) are tracked for
first/last usage due to things needing to happen on first/last reference.
Use EAL usage counters instead of manual arithmetic and checks.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 lib/eal/linux/eal_vfio.c       |  7 ++-----
 lib/eal/linux/eal_vfio.h       |  5 +++--
 lib/eal/linux/eal_vfio_group.c | 11 ++++-------
 3 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/lib/eal/linux/eal_vfio.c b/lib/eal/linux/eal_vfio.c
index fdf500cd5b..056795a6e4 100644
--- a/lib/eal/linux/eal_vfio.c
+++ b/lib/eal/linux/eal_vfio.c
@@ -1125,11 +1125,8 @@ dev_vfio_release_device(const char *sysfs_base __rte_unused, const char *dev_add
 		/* close device handle */
 		vfio_device_erase(cfg, dev);
 
-		/* remove device from group */
-		grp->n_devices--;
-
-		/* was this the last device? */
-		if (grp->n_devices == 0)
+		/* remove device from group, erase the group if it was the last device */
+		if (rte_usage_count_release(&grp->n_devices))
 			vfio_group_erase(cfg, grp);
 
 		/* if no more groups left, remove callback */
diff --git a/lib/eal/linux/eal_vfio.h b/lib/eal/linux/eal_vfio.h
index 980bdae0ba..8aaff4f335 100644
--- a/lib/eal/linux/eal_vfio.h
+++ b/lib/eal/linux/eal_vfio.h
@@ -7,6 +7,7 @@
 
 #include <rte_common.h>
 #include <rte_spinlock.h>
+#include <rte_usage_count.h>
 
 #include <stdint.h>
 
@@ -42,7 +43,7 @@ struct vfio_group {
 	bool active;
 	int group_num;
 	int fd;
-	int n_devices;
+	rte_usage_count_t n_devices;
 };
 
 /* device tracking (common for group and cdev modes) */
@@ -66,7 +67,7 @@ struct vfio_device {
 struct vfio_group_config {
 	bool iommu_type_set;
 	bool mem_event_clb_set;
-	size_t n_groups;
+	rte_usage_count_t n_groups;
 	struct vfio_group groups[RTE_MAX_VFIO_GROUPS];
 };
 
diff --git a/lib/eal/linux/eal_vfio_group.c b/lib/eal/linux/eal_vfio_group.c
index 7c879830ac..55ada5046b 100644
--- a/lib/eal/linux/eal_vfio_group.c
+++ b/lib/eal/linux/eal_vfio_group.c
@@ -508,7 +508,7 @@ vfio_group_create(struct vfio_container *cfg, int iommu_group)
 	VFIO_GROUP_FOREACH(cfg, grp) {
 		if (grp->active)
 			continue;
-		cfg->group_cfg.n_groups++;
+		rte_usage_count_claim(&cfg->group_cfg.n_groups);
 		grp->active = true;
 		grp->group_num = iommu_group;
 		grp->fd = -1;
@@ -527,10 +527,8 @@ vfio_group_erase(struct vfio_container *cfg, struct vfio_group *grp)
 		EAL_LOG(ERR, "Error when closing group fd %d", grp->fd);
 
 	*grp = (struct vfio_group){0};
-	group_cfg->n_groups--;
-
-	/* if this was the last group in config, erase IOMMU setup and unregister callback */
-	if (group_cfg->n_groups == 0) {
+	/* if this was the last group in config, erase IOMMU setup */
+	if (rte_usage_count_release(&group_cfg->n_groups)) {
 		cfg->dma_setup_done = false;
 		group_cfg->iommu_type_set = false;
 	}
@@ -880,8 +878,7 @@ vfio_group_setup_device_fd(const char *dev_addr, struct vfio_group *grp, struct
 	dev->fd = fd;
 	/* store backreference to group */
 	dev->group = grp->group_num;
-	/* increment number of devices in group */
-	grp->n_devices++;
+	rte_usage_count_claim(&grp->n_devices);
 	return 0;
 }
 
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [27.03 RFC PATCH v1 3/8] dev: replace raw refcount with usage count
  2026-10-16 14:02 [27.03 RFC PATCH v1 0/8] Add usage counter helpers Anatoly Burakov
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 1/8] eal: add usage count helpers Anatoly Burakov
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 2/8] vfio: use usage counters Anatoly Burakov
@ 2026-10-16 14:02 ` Anatoly Burakov
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 4/8] vhost: use usage counters for vchan tracking Anatoly Burakov
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Anatoly Burakov @ 2026-10-16 14:02 UTC (permalink / raw)
  To: dev

Use EAL usage counter to track number of dev monitors.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 lib/eal/linux/eal_dev.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/lib/eal/linux/eal_dev.c b/lib/eal/linux/eal_dev.c
index 35223b6b26..1b33309baf 100644
--- a/lib/eal/linux/eal_dev.c
+++ b/lib/eal/linux/eal_dev.c
@@ -17,13 +17,14 @@
 #include <bus_driver.h>
 #include <rte_spinlock.h>
 #include <rte_errno.h>
+#include <rte_usage_count.h>
 
 #include <eal_export.h>
 #include "eal_private.h"
 
 static struct rte_intr_handle *intr_handle;
 static rte_rwlock_t monitor_lock = RTE_RWLOCK_INITIALIZER;
-static uint32_t monitor_refcount;
+static rte_usage_count_t monitor_refcount;
 static bool hotplug_handle;
 
 #define EAL_UEV_MSG_LEN 4096
@@ -342,10 +343,8 @@ rte_dev_event_monitor_start(void)
 
 	rte_rwlock_write_lock(&monitor_lock);
 
-	if (monitor_refcount) {
-		monitor_refcount++;
+	if (!rte_usage_count_claim(&monitor_refcount))
 		goto exit;
-	}
 
 	intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
 	if (intr_handle == NULL) {
@@ -370,12 +369,11 @@ rte_dev_event_monitor_start(void)
 		goto exit;
 	}
 
-	monitor_refcount++;
-
 exit:
 	if (ret) {
 		rte_intr_instance_free(intr_handle);
 		intr_handle = NULL;
+		rte_usage_count_release(&monitor_refcount);
 	}
 	rte_rwlock_write_unlock(&monitor_lock);
 	return ret;
@@ -389,14 +387,13 @@ rte_dev_event_monitor_stop(void)
 
 	rte_rwlock_write_lock(&monitor_lock);
 
-	if (!monitor_refcount) {
+	if (monitor_refcount == 0) {
 		EAL_LOG(ERR, "device event monitor already stopped");
 		goto exit;
 	}
 
-	if (monitor_refcount > 1) {
-		monitor_refcount--;
-		goto exit;
+	if (!rte_usage_count_is_last(&monitor_refcount)) {
+		goto release;
 	}
 
 	ret = rte_intr_callback_unregister(intr_handle, dev_uev_handler,
@@ -411,7 +408,8 @@ rte_dev_event_monitor_stop(void)
 	intr_handle = NULL;
 	ret = 0;
 
-	monitor_refcount--;
+release:
+	rte_usage_count_release(&monitor_refcount);
 
 exit:
 	rte_rwlock_write_unlock(&monitor_lock);
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [27.03 RFC PATCH v1 4/8] vhost: use usage counters for vchan tracking
  2026-10-16 14:02 [27.03 RFC PATCH v1 0/8] Add usage counter helpers Anatoly Burakov
                   ` (2 preceding siblings ...)
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 3/8] dev: replace raw refcount with usage count Anatoly Burakov
@ 2026-10-16 14:02 ` Anatoly Burakov
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 5/8] acl: use usage counters for ref counting Anatoly Burakov
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Anatoly Burakov @ 2026-10-16 14:02 UTC (permalink / raw)
  To: dev, Maxime Coquelin, Chenbo Xia

Use EAL usage counters instead of raw integers for vchan tracking.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 lib/vhost/vhost.c | 5 ++---
 lib/vhost/vhost.h | 3 ++-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c
index 918e50ed43..4535e30d44 100644
--- a/lib/vhost/vhost.c
+++ b/lib/vhost/vhost.c
@@ -2152,7 +2152,7 @@ rte_vhost_async_dma_configure(int16_t dma_id, uint16_t vchan_id)
 	dma_copy_track[dma_id].vchans[vchan_id].pkts_cmpl_flag_addr = pkts_cmpl_flag_addr;
 	dma_copy_track[dma_id].vchans[vchan_id].ring_size = max_desc;
 	dma_copy_track[dma_id].vchans[vchan_id].ring_mask = max_desc - 1;
-	dma_copy_track[dma_id].nr_vchans++;
+	rte_usage_count_claim(&dma_copy_track[dma_id].nr_vchans);
 
 	pthread_mutex_unlock(&vhost_dma_lock);
 	return 0;
@@ -2437,9 +2437,8 @@ rte_vhost_async_dma_unconfigure(int16_t dma_id, uint16_t vchan_id)
 
 	rte_free(dma_copy_track[dma_id].vchans[vchan_id].pkts_cmpl_flag_addr);
 	dma_copy_track[dma_id].vchans[vchan_id].pkts_cmpl_flag_addr = NULL;
-	dma_copy_track[dma_id].nr_vchans--;
 
-	if (dma_copy_track[dma_id].nr_vchans == 0) {
+	if (rte_usage_count_release(&dma_copy_track[dma_id].nr_vchans)) {
 		rte_free(dma_copy_track[dma_id].vchans);
 		dma_copy_track[dma_id].vchans = NULL;
 	}
diff --git a/lib/vhost/vhost.h b/lib/vhost/vhost.h
index 1f0568dcb5..215a513934 100644
--- a/lib/vhost/vhost.h
+++ b/lib/vhost/vhost.h
@@ -19,6 +19,7 @@
 #include <rte_ether.h>
 #include <rte_malloc.h>
 #include <rte_dmadev.h>
+#include <rte_usage_count.h>
 
 #include "rte_vhost.h"
 #include "vdpa_driver.h"
@@ -202,7 +203,7 @@ struct async_dma_vchan_info {
 struct async_dma_info {
 	struct async_dma_vchan_info *vchans;
 	/* number of registered virtual channels */
-	uint16_t nr_vchans;
+	rte_usage_count_t nr_vchans;
 };
 
 extern struct async_dma_info dma_copy_track[RTE_DMADEV_DEFAULT_MAX];
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [27.03 RFC PATCH v1 5/8] acl: use usage counters for ref counting
  2026-10-16 14:02 [27.03 RFC PATCH v1 0/8] Add usage counter helpers Anatoly Burakov
                   ` (3 preceding siblings ...)
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 4/8] vhost: use usage counters for vchan tracking Anatoly Burakov
@ 2026-10-16 14:02 ` Anatoly Burakov
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 6/8] thash: " Anatoly Burakov
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Anatoly Burakov @ 2026-10-16 14:02 UTC (permalink / raw)
  To: dev, Konstantin Ananyev

Replace raw integer refcounts with EAL usage counters.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 lib/acl/acl.h     | 4 +++-
 lib/acl/acl_bld.c | 9 ++++-----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/lib/acl/acl.h b/lib/acl/acl.h
index e1ecd1567b..8159915ea3 100644
--- a/lib/acl/acl.h
+++ b/lib/acl/acl.h
@@ -5,6 +5,8 @@
 #ifndef	_ACL_H_
 #define	_ACL_H_
 
+#include <rte_usage_count.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -104,7 +106,7 @@ struct rte_acl_match_results {
 struct rte_acl_node {
 	uint64_t node_index;  /* index for this node */
 	uint32_t level;       /* level 0-n in the trie */
-	uint32_t ref_count;   /* ref count for this node */
+	rte_usage_count_t ref_count; /* ref count for this node */
 	struct rte_acl_bitset  values;
 	/* set of all values that map to another node
 	 * (union of bits in each transition.
diff --git a/lib/acl/acl_bld.c b/lib/acl/acl_bld.c
index 99d1dbc467..60ca33a077 100644
--- a/lib/acl/acl_bld.c
+++ b/lib/acl/acl_bld.c
@@ -296,7 +296,7 @@ acl_add_ptr(struct acl_build_context *context,
 			acl_include(&node->ptrs[n].values, bits, 0);
 			acl_include(&node->values, bits, -1);
 			if (ptr != NULL)
-				ptr->ref_count++;
+				rte_usage_count_claim(&ptr->ref_count);
 			if (node->num_ptrs <= n)
 				node->num_ptrs = n + 1;
 			return 0;
@@ -411,7 +411,7 @@ acl_dup_node(struct acl_build_context *context, struct rte_acl_node *node)
 	for (n = 0; n < node->num_ptrs; n++) {
 		if (node->ptrs[n].ptr != NULL) {
 			next->ptrs[n].ptr = node->ptrs[n].ptr;
-			next->ptrs[n].ptr->ref_count++;
+			rte_usage_count_claim(&next->ptrs[n].ptr->ref_count);
 			acl_include(&next->ptrs[n].values,
 				&node->ptrs[n].values, -1);
 		}
@@ -449,8 +449,7 @@ acl_deref_ptr(struct acl_build_context *context,
 	/* De-reference the node at the specified pointer */
 	if (node != NULL && node->ptrs[index].ptr != NULL) {
 		ref_node = node->ptrs[index].ptr;
-		ref_node->ref_count--;
-		if (ref_node->ref_count == 0)
+		if (rte_usage_count_release(&ref_node->ref_count))
 			acl_free_node(context, ref_node);
 	}
 }
@@ -966,7 +965,7 @@ build_trie(struct acl_build_context *context, struct rte_acl_build_rule *head,
 
 		root = acl_alloc_node(context, 0);
 
-		root->ref_count = 1;
+		rte_usage_count_claim(&root->ref_count);
 		end = root;
 
 		for (n = 0; n < rule->config->num_fields; n++) {
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [27.03 RFC PATCH v1 6/8] thash: use usage counters for ref counting
  2026-10-16 14:02 [27.03 RFC PATCH v1 0/8] Add usage counter helpers Anatoly Burakov
                   ` (4 preceding siblings ...)
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 5/8] acl: use usage counters for ref counting Anatoly Burakov
@ 2026-10-16 14:02 ` Anatoly Burakov
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 7/8] lpm: " Anatoly Burakov
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 8/8] net/nbl: track devices with usage counters Anatoly Burakov
  7 siblings, 0 replies; 9+ messages in thread
From: Anatoly Burakov @ 2026-10-16 14:02 UTC (permalink / raw)
  To: dev, Yipeng Wang, Sameh Gobriel, Bruce Richardson,
	Vladimir Medvedkin

Use EAL usage counters instead of raw integers for ref counting.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 lib/hash/rte_thash.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/hash/rte_thash.c b/lib/hash/rte_thash.c
index fcd41248b9..bbbd932f92 100644
--- a/lib/hash/rte_thash.c
+++ b/lib/hash/rte_thash.c
@@ -15,6 +15,7 @@
 #include <rte_log.h>
 #include <rte_malloc.h>
 #include <rte_cpuflags.h>
+#include <rte_usage_count.h>
 
 RTE_LOG_REGISTER_SUFFIX(thash_logtype, thash, INFO);
 #define RTE_LOGTYPE_HASH thash_logtype
@@ -34,7 +35,7 @@ static struct rte_tailq_elem rte_thash_tailq = {
 EAL_REGISTER_TAILQ(rte_thash_tailq)
 
 struct thash_lfsr {
-	uint32_t	ref_cnt;
+	rte_usage_count_t	ref_cnt;
 	uint32_t	poly;
 	/**< polynomial associated with the lfsr */
 	uint32_t	rev_poly;
@@ -187,7 +188,7 @@ alloc_lfsr(uint32_t poly_degree)
 
 	/* clear bits_cnt after rev_state was inited */
 	lfsr->bits_cnt = 0;
-	lfsr->ref_cnt = 1;
+	rte_usage_count_claim(&lfsr->ref_cnt);
 
 	return lfsr;
 }
@@ -195,15 +196,14 @@ alloc_lfsr(uint32_t poly_degree)
 static void
 attach_lfsr(struct rte_thash_subtuple_helper *h, struct thash_lfsr *lfsr)
 {
-	lfsr->ref_cnt++;
+	rte_usage_count_claim(&lfsr->ref_cnt);
 	h->lfsr = lfsr;
 }
 
 static void
 free_lfsr(struct thash_lfsr *lfsr)
 {
-	lfsr->ref_cnt--;
-	if (lfsr->ref_cnt == 0)
+	if (rte_usage_count_release(&lfsr->ref_cnt))
 		rte_free(lfsr);
 }
 
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [27.03 RFC PATCH v1 7/8] lpm: use usage counters for ref counting
  2026-10-16 14:02 [27.03 RFC PATCH v1 0/8] Add usage counter helpers Anatoly Burakov
                   ` (5 preceding siblings ...)
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 6/8] thash: " Anatoly Burakov
@ 2026-10-16 14:02 ` Anatoly Burakov
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 8/8] net/nbl: track devices with usage counters Anatoly Burakov
  7 siblings, 0 replies; 9+ messages in thread
From: Anatoly Burakov @ 2026-10-16 14:02 UTC (permalink / raw)
  To: dev, Bruce Richardson, Vladimir Medvedkin

Use EAL usage counters instead of raw integers for ref counting.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 lib/lpm/rte_lpm6.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/lib/lpm/rte_lpm6.c b/lib/lpm/rte_lpm6.c
index e23c886766..3c927a8642 100644
--- a/lib/lpm/rte_lpm6.c
+++ b/lib/lpm/rte_lpm6.c
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include <rte_jhash.h>
 #include <rte_tailq.h>
+#include <rte_usage_count.h>
 
 #include "rte_lpm6.h"
 #include "lpm_log.h"
@@ -87,7 +88,7 @@ struct rte_lpm_tbl8_hdr {
 	uint32_t owner_entry_ind; /**< index of the owner table entry where
 				    *  pointer to the tbl8 is stored
 				    */
-	uint32_t ref_cnt; /**< table reference counter */
+	rte_usage_count_t ref_cnt; /**< table reference counter */
 };
 
 /** LPM6 structure. */
@@ -676,7 +677,7 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl,
 
 		/* update tbl8 rule reference counter */
 		if (tbl_ind != TBL24_IND && is_new_rule)
-			lpm->tbl8_hdrs[tbl_ind].ref_cnt++;
+			rte_usage_count_claim(&lpm->tbl8_hdrs[tbl_ind].ref_cnt);
 
 		return 0;
 	}
@@ -717,7 +718,7 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl,
 
 			/* update the current table's reference counter */
 			if (tbl_ind != TBL24_IND)
-				lpm->tbl8_hdrs[tbl_ind].ref_cnt++;
+				rte_usage_count_claim(&lpm->tbl8_hdrs[tbl_ind].ref_cnt);
 		}
 		/*
 		 * If it's valid but not extended the rule that was stored
@@ -768,7 +769,7 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl,
 
 			/* update the current table's reference counter */
 			if (tbl_ind != TBL24_IND)
-				lpm->tbl8_hdrs[tbl_ind].ref_cnt++;
+				rte_usage_count_claim(&lpm->tbl8_hdrs[tbl_ind].ref_cnt);
 		}
 
 		*next_tbl_ind = tbl[entry_ind].lpm6_tbl8_gindex;
@@ -1231,7 +1232,7 @@ remove_tbl(struct rte_lpm6 *lpm, struct rte_lpm_tbl8_hdr *tbl_hdr,
 
 		struct rte_lpm_tbl8_hdr *owner_tbl_hdr =
 			&lpm->tbl8_hdrs[owner_tbl_ind];
-		if (--owner_tbl_hdr->ref_cnt == 0)
+		if (rte_usage_count_release(&owner_tbl_hdr->ref_cnt))
 			remove_tbl(lpm, owner_tbl_hdr, owner_tbl_ind, lsp_rule);
 	}
 
@@ -1306,7 +1307,7 @@ rte_lpm6_delete(struct rte_lpm6 *lpm, const struct rte_ipv6_addr *ip, uint8_t de
 	 */
 	if (tbl_ind != TBL24_IND) {
 		struct rte_lpm_tbl8_hdr *tbl_hdr = &lpm->tbl8_hdrs[tbl_ind];
-		if (--tbl_hdr->ref_cnt == 0) {
+		if (rte_usage_count_release(&tbl_hdr->ref_cnt)) {
 			/* remove the table */
 			remove_tbl(lpm, tbl_hdr, tbl_ind, lsp_rule);
 			return 0;
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [27.03 RFC PATCH v1 8/8] net/nbl: track devices with usage counters
  2026-10-16 14:02 [27.03 RFC PATCH v1 0/8] Add usage counter helpers Anatoly Burakov
                   ` (6 preceding siblings ...)
  2026-10-16 14:02 ` [27.03 RFC PATCH v1 7/8] lpm: " Anatoly Burakov
@ 2026-10-16 14:02 ` Anatoly Burakov
  7 siblings, 0 replies; 9+ messages in thread
From: Anatoly Burakov @ 2026-10-16 14:02 UTC (permalink / raw)
  To: dev, Dimon Zhao, Leon Yu, Sam Chen

Use EAL usage counters to track VFIO device references.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 drivers/net/nbl/nbl_common/nbl_userdev.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/net/nbl/nbl_common/nbl_userdev.c b/drivers/net/nbl/nbl_common/nbl_userdev.c
index 295c617d9d..426cffbc0d 100644
--- a/drivers/net/nbl/nbl_common/nbl_userdev.c
+++ b/drivers/net/nbl/nbl_common/nbl_userdev.c
@@ -4,6 +4,8 @@
 
 #include <uapi/linux/vfio.h>
 
+#include <rte_usage_count.h>
+
 #include "nbl_userdev.h"
 #include <dev_vfio.h>
 
@@ -26,7 +28,7 @@ struct nbl_userdev_map_record {
 };
 
 static int nbl_default_container = -1;
-static int nbl_group_count;
+static rte_usage_count_t nbl_group_count;
 
 TAILQ_HEAD(nbl_adapter_list_head, nbl_adapter);
 static struct nbl_adapter_list_head nbl_adapter_list =
@@ -423,7 +425,7 @@ static int nbl_mdev_map_device(struct nbl_adapter *adapter)
 	u64 dma_limit = NBL_USERDEV_DMA_LIMIT;
 	int ret, container_create = 0, container_set = 0;
 	int vfio_group_fd, container = nbl_default_container;
-	bool new_group = false;
+	bool new_group = false, first_group = false;
 
 	rte_pci_device_name(&pci_dev->addr, dev_name, RTE_DEV_NAME_MAX_LEN);
 	snprintf(pathname, sizeof(pathname),
@@ -481,11 +483,11 @@ static int nbl_mdev_map_device(struct nbl_adapter *adapter)
 			goto free_group;
 		}
 
-		nbl_group_count++;
+		first_group = rte_usage_count_claim(&nbl_group_count);
 		container_set = 1;
 		/* set an IOMMU type for container */
 
-		if (container_create || nbl_group_count == 1) {
+		if (container_create || first_group) {
 			if (ioctl(container, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU)) {
 				ret = ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1v2_IOMMU);
 				if (ret) {
@@ -548,13 +550,13 @@ static int nbl_mdev_map_device(struct nbl_adapter *adapter)
 close_fd:
 	close(common->devfd);
 unregister_mem_event:
-	if (container_set && nbl_group_count == 1) {
+	if (first_group) {
 		rte_mcfg_mem_read_lock();
 		rte_mem_event_callback_unregister(NBL_USERDEV_EVENT_CLB_NAME, NULL);
 		rte_mcfg_mem_read_unlock();
 	}
 free_dma_map:
-	if (container_set && nbl_group_count == 1) {
+	if (first_group) {
 		rte_mcfg_mem_read_lock();
 		nbl_userdev_dma_free();
 		rte_mcfg_mem_read_unlock();
@@ -562,7 +564,7 @@ static int nbl_mdev_map_device(struct nbl_adapter *adapter)
 unset_container:
 	if (container_set) {
 		ioctl(vfio_group_fd, VFIO_GROUP_UNSET_CONTAINER, &container);
-		nbl_group_count--;
+		rte_usage_count_release(&nbl_group_count);
 	}
 free_group:
 	if (new_group)
@@ -577,7 +579,7 @@ static int nbl_mdev_unmap_device(struct nbl_adapter *adapter)
 {
 	struct nbl_common_info *common = &adapter->common;
 	int vfio_group_fd, ret;
-	bool last_group_user;
+	bool last_group_user, last_group = false;
 
 	rte_mcfg_mem_read_lock();
 	TAILQ_REMOVE(&nbl_adapter_list, adapter, next);
@@ -591,11 +593,11 @@ static int nbl_mdev_unmap_device(struct nbl_adapter *adapter)
 		if (ret)
 			NBL_LOG(ERR, "unset container, error %i (%s) %d",
 				errno, strerror(errno), ret);
-		nbl_group_count--;
+		last_group = rte_usage_count_release(&nbl_group_count);
 		close(vfio_group_fd);
 		common->groupfd = -1;
 	}
-	if (!nbl_group_count) {
+	if (last_group) {
 		rte_mem_event_callback_unregister(NBL_USERDEV_EVENT_CLB_NAME, NULL);
 		nbl_userdev_dma_free();
 	}
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-10-16 14:03 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-16 14:02 [27.03 RFC PATCH v1 0/8] Add usage counter helpers Anatoly Burakov
2026-10-16 14:02 ` [27.03 RFC PATCH v1 1/8] eal: add usage count helpers Anatoly Burakov
2026-10-16 14:02 ` [27.03 RFC PATCH v1 2/8] vfio: use usage counters Anatoly Burakov
2026-10-16 14:02 ` [27.03 RFC PATCH v1 3/8] dev: replace raw refcount with usage count Anatoly Burakov
2026-10-16 14:02 ` [27.03 RFC PATCH v1 4/8] vhost: use usage counters for vchan tracking Anatoly Burakov
2026-10-16 14:02 ` [27.03 RFC PATCH v1 5/8] acl: use usage counters for ref counting Anatoly Burakov
2026-10-16 14:02 ` [27.03 RFC PATCH v1 6/8] thash: " Anatoly Burakov
2026-10-16 14:02 ` [27.03 RFC PATCH v1 7/8] lpm: " Anatoly Burakov
2026-10-16 14:02 ` [27.03 RFC PATCH v1 8/8] net/nbl: track devices with usage counters Anatoly Burakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox