]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ptr_ring: move free-space check into separate helper
authorSimon Schippers <simon.schippers@tu-dortmund.de>
Sun, 10 May 2026 15:15:28 +0000 (17:15 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 14 May 2026 00:52:55 +0000 (17:52 -0700)
This patch moves the check for available free space for a new entry into
a separate function. Existing callers that only check for a non-zero
return value are unaffected; __ptr_ring_produce() now returns -EINVAL
for a zero-size ring and -ENOSPC when full, whereas before both cases
returned -ENOSPC. The new helper allows callers to determine in advance
whether subsequent __ptr_ring_produce() calls will succeed. This
information can, for example, be used to temporarily stop producing until
__ptr_ring_check_produce() indicates that space is available again.

Co-developed-by: Tim Gebauer <tim.gebauer@tu-dortmund.de>
Signed-off-by: Tim Gebauer <tim.gebauer@tu-dortmund.de>
Signed-off-by: Simon Schippers <simon.schippers@tu-dortmund.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Link: https://patch.msgid.link/20260510151529.43895-4-simon.schippers@tu-dortmund.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/linux/ptr_ring.h

index d2c3629bbe4517d222a0ac9958b203d530d35c73..c95e891903f0545fe83d46b2f0a7cefa5955111e 100644 (file)
@@ -96,6 +96,20 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r)
        return ret;
 }
 
+/* Note: callers invoking this in a loop must use a compiler barrier,
+ * for example cpu_relax(). Callers must hold producer_lock.
+ */
+static inline int __ptr_ring_check_produce(struct ptr_ring *r)
+{
+       if (unlikely(!r->size))
+               return -EINVAL;
+
+       if (data_race(r->queue[r->producer]))
+               return -ENOSPC;
+
+       return 0;
+}
+
 /* Note: callers invoking this in a loop must use a compiler barrier,
  * for example cpu_relax(). Callers must hold producer_lock.
  * Callers are responsible for making sure pointer that is being queued
@@ -103,8 +117,10 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r)
  */
 static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr)
 {
-       if (unlikely(!r->size) || data_race(r->queue[r->producer]))
-               return -ENOSPC;
+       int p = __ptr_ring_check_produce(r);
+
+       if (p)
+               return p;
 
        /* Make sure the pointer we are storing points to a valid data. */
        /* Pairs with the dependency ordering in __ptr_ring_consume. */