mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-27 22:13:55 -04:00
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. 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> Link: https://patch.msgid.link/20260803183641.96882-5-simon.schippers@tu-dortmund.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
f65c1fb427
commit
43be21ec2e
@@ -96,6 +96,26 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Report whether the next __ptr_ring_produce() has room for one entry:
|
||||
* 0 means the single slot at r->queue[r->producer] is free, -ENOSPC means
|
||||
* the ring is full, which is transient, and -EINVAL means r->size is 0,
|
||||
* which is permanent. A caller that stops producing and waits for space
|
||||
* must therefore do so only for -ENOSPC.
|
||||
*
|
||||
* 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 +123,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 ret = __ptr_ring_check_produce(r);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Make sure the pointer we are storing points to a valid data. */
|
||||
/* Pairs with the dependency ordering in __ptr_ring_consume. */
|
||||
|
||||
Reference in New Issue
Block a user