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.
Showing the changes to include (1 of 1 file). Show all
Unified · Split
| @@ -96,6 +96,26 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r) · 95 unmodified lines | ||
| 96 | 96 | return ret; |
| 97 | 97 | } |
| 98 | 98 | |
| 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 | + | |
| 99 | 119 | /* Note: callers invoking this in a loop must use a compiler barrier, |
| 100 | 120 | * for example cpu_relax(). Callers must hold producer_lock. |
| 101 | 121 | * 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 | ||
| 103 | 123 | */ |
| 104 | 124 | static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr) |
| 105 | 125 | { |
| 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; | |
| 108 | 130 | |
| 109 | 131 | /* Make sure the pointer we are storing points to a valid data. */ |
| 110 | 132 | /* Pairs with the dependency ordering in __ptr_ring_consume. */ |