History

ptr_ring: move free-space check into separate helper

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 a single subsequent __ptr_ring_produce() call will succeed. This information can, for example, be used to temporarily stop producing until __ptr_ring_check_produce() indicates that space is available again. The return values are documented above the helper, as a caller that waits for space must distinguish the transient -ENOSPC from the permanent -EINVAL.

Simon Schippers committed 3 months ago

Commit 43be21e1 parent f65c1fb1 file · +24 −2Browse files

Showing the changes to include (1 of 1 file). Show all

Unified · Split

include/linux/ptr_ring.h+24−2
@@ -96,6 +96,26 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r) · 95 unmodified lines
9696 return ret;
9797 }
9898
99+/* Report whether the next __ptr_ring_produce() has room for one entry:
100+ * 0 means the single slot at r->queue[r->producer] is free, -ENOSPC means
101+ * the ring is full, which is transient, and -EINVAL means r->size is 0,
102+ * which is permanent. A caller that stops producing and waits for space
103+ * must therefore do so only for -ENOSPC.
104+ *
105+ * Note: callers invoking this in a loop must use a compiler barrier,
106+ * for example cpu_relax(). Callers must hold producer_lock.
107+ */
108+static inline int __ptr_ring_check_produce(struct ptr_ring *r)
109+{
110+ if (unlikely(!r->size))
111+ return -EINVAL;
112+
113+ if (data_race(r->queue[r->producer]))
114+ return -ENOSPC;
115+
116+ return 0;
117+}
118+
99119 /* Note: callers invoking this in a loop must use a compiler barrier,
100120 * for example cpu_relax(). Callers must hold producer_lock.
101121 * Callers are responsible for making sure pointer that is being queued
@@ -103,8 +123,10 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r) · 1 unmodified line
103123 */
104124 static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr)
105125 {
106− if (unlikely(!r->size) || data_race(r->queue[r->producer]))
107− return -ENOSPC;
126+ int ret = __ptr_ring_check_produce(r);
127+
128+ if (ret)
129+ return ret;
108130
109131 /* Make sure the pointer we are storing points to a valid data. */
110132 /* Pairs with the dependency ordering in __ptr_ring_consume. */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t