Skip to content

Commit

Permalink
ring: use stdatomic API
Browse files Browse the repository at this point in the history
Replace the use of gcc builtin __atomic_xxx intrinsics with
corresponding rte_atomic_xxx optional stdatomic API

Signed-off-by: Tyler Retzlaff <[email protected]>
Acked-by: Konstantin Ananyev <[email protected]>
Acked-by: David Marchand <[email protected]>
  • Loading branch information
Tyler Retzlaff authored and david-marchand committed Oct 30, 2023
1 parent 22c0353 commit 32faaf3
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 63 deletions.
4 changes: 2 additions & 2 deletions drivers/net/mlx5/mlx5_hws_cnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,15 +386,15 @@ __mlx5_hws_cnt_pool_enqueue_revert(struct rte_ring *r, unsigned int n,

MLX5_ASSERT(r->prod.sync_type == RTE_RING_SYNC_ST);
MLX5_ASSERT(r->cons.sync_type == RTE_RING_SYNC_ST);
current_head = __atomic_load_n(&r->prod.head, __ATOMIC_RELAXED);
current_head = rte_atomic_load_explicit(&r->prod.head, rte_memory_order_relaxed);
MLX5_ASSERT(n <= r->capacity);
MLX5_ASSERT(n <= rte_ring_count(r));
revert2head = current_head - n;
r->prod.head = revert2head; /* This ring should be SP. */
__rte_ring_get_elem_addr(r, revert2head, sizeof(cnt_id_t), n,
&zcd->ptr1, &zcd->n1, &zcd->ptr2);
/* Update tail */
__atomic_store_n(&r->prod.tail, revert2head, __ATOMIC_RELEASE);
rte_atomic_store_explicit(&r->prod.tail, revert2head, rte_memory_order_release);
return n;
}

Expand Down
47 changes: 25 additions & 22 deletions lib/ring/rte_ring_c11_pvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ __rte_ring_update_tail(struct rte_ring_headtail *ht, uint32_t old_val,
* we need to wait for them to complete
*/
if (!single)
rte_wait_until_equal_32(&ht->tail, old_val, __ATOMIC_RELAXED);
rte_wait_until_equal_32((uint32_t *)(uintptr_t)&ht->tail, old_val,
rte_memory_order_relaxed);

__atomic_store_n(&ht->tail, new_val, __ATOMIC_RELEASE);
rte_atomic_store_explicit(&ht->tail, new_val, rte_memory_order_release);
}

/**
Expand Down Expand Up @@ -61,19 +62,19 @@ __rte_ring_move_prod_head(struct rte_ring *r, unsigned int is_sp,
unsigned int max = n;
int success;

*old_head = __atomic_load_n(&r->prod.head, __ATOMIC_RELAXED);
*old_head = rte_atomic_load_explicit(&r->prod.head, rte_memory_order_relaxed);
do {
/* Reset n to the initial burst count */
n = max;

/* Ensure the head is read before tail */
__atomic_thread_fence(__ATOMIC_ACQUIRE);
__atomic_thread_fence(rte_memory_order_acquire);

/* load-acquire synchronize with store-release of ht->tail
* in update_tail.
*/
cons_tail = __atomic_load_n(&r->cons.tail,
__ATOMIC_ACQUIRE);
cons_tail = rte_atomic_load_explicit(&r->cons.tail,
rte_memory_order_acquire);

/* The subtraction is done between two unsigned 32bits value
* (the result is always modulo 32 bits even if we have
Expand All @@ -91,14 +92,15 @@ __rte_ring_move_prod_head(struct rte_ring *r, unsigned int is_sp,
return 0;

*new_head = *old_head + n;
if (is_sp)
r->prod.head = *new_head, success = 1;
else
if (is_sp) {
r->prod.head = *new_head;
success = 1;
} else
/* on failure, *old_head is updated */
success = __atomic_compare_exchange_n(&r->prod.head,
success = rte_atomic_compare_exchange_strong_explicit(&r->prod.head,
old_head, *new_head,
0, __ATOMIC_RELAXED,
__ATOMIC_RELAXED);
rte_memory_order_relaxed,
rte_memory_order_relaxed);
} while (unlikely(success == 0));
return n;
}
Expand Down Expand Up @@ -137,19 +139,19 @@ __rte_ring_move_cons_head(struct rte_ring *r, int is_sc,
int success;

/* move cons.head atomically */
*old_head = __atomic_load_n(&r->cons.head, __ATOMIC_RELAXED);
*old_head = rte_atomic_load_explicit(&r->cons.head, rte_memory_order_relaxed);
do {
/* Restore n as it may change every loop */
n = max;

/* Ensure the head is read before tail */
__atomic_thread_fence(__ATOMIC_ACQUIRE);
__atomic_thread_fence(rte_memory_order_acquire);

/* this load-acquire synchronize with store-release of ht->tail
* in update_tail.
*/
prod_tail = __atomic_load_n(&r->prod.tail,
__ATOMIC_ACQUIRE);
prod_tail = rte_atomic_load_explicit(&r->prod.tail,
rte_memory_order_acquire);

/* The subtraction is done between two unsigned 32bits value
* (the result is always modulo 32 bits even if we have
Expand All @@ -166,14 +168,15 @@ __rte_ring_move_cons_head(struct rte_ring *r, int is_sc,
return 0;

*new_head = *old_head + n;
if (is_sc)
r->cons.head = *new_head, success = 1;
else
if (is_sc) {
r->cons.head = *new_head;
success = 1;
} else
/* on failure, *old_head will be updated */
success = __atomic_compare_exchange_n(&r->cons.head,
success = rte_atomic_compare_exchange_strong_explicit(&r->cons.head,
old_head, *new_head,
0, __ATOMIC_RELAXED,
__ATOMIC_RELAXED);
rte_memory_order_relaxed,
rte_memory_order_relaxed);
} while (unlikely(success == 0));
return n;
}
Expand Down
12 changes: 6 additions & 6 deletions lib/ring/rte_ring_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ enum rte_ring_sync_type {
* but offset for *sync_type* and *tail* values should remain the same.
*/
struct rte_ring_headtail {
volatile uint32_t head; /**< prod/consumer head. */
volatile uint32_t tail; /**< prod/consumer tail. */
volatile RTE_ATOMIC(uint32_t) head; /**< prod/consumer head. */
volatile RTE_ATOMIC(uint32_t) tail; /**< prod/consumer tail. */
union {
/** sync type of prod/cons */
enum rte_ring_sync_type sync_type;
Expand All @@ -78,7 +78,7 @@ struct rte_ring_headtail {

union __rte_ring_rts_poscnt {
/** raw 8B value to read/write *cnt* and *pos* as one atomic op */
uint64_t raw __rte_aligned(8);
RTE_ATOMIC(uint64_t) raw __rte_aligned(8);
struct {
uint32_t cnt; /**< head/tail reference counter */
uint32_t pos; /**< head/tail position */
Expand All @@ -94,10 +94,10 @@ struct rte_ring_rts_headtail {

union __rte_ring_hts_pos {
/** raw 8B value to read/write *head* and *tail* as one atomic op */
uint64_t raw __rte_aligned(8);
RTE_ATOMIC(uint64_t) raw __rte_aligned(8);
struct {
uint32_t head; /**< head position */
uint32_t tail; /**< tail position */
RTE_ATOMIC(uint32_t) head; /**< head position */
RTE_ATOMIC(uint32_t) tail; /**< tail position */
} pos;
};

Expand Down
16 changes: 9 additions & 7 deletions lib/ring/rte_ring_generic_pvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ __rte_ring_update_tail(struct rte_ring_headtail *ht, uint32_t old_val,
* we need to wait for them to complete
*/
if (!single)
rte_wait_until_equal_32(&ht->tail, old_val, __ATOMIC_RELAXED);
rte_wait_until_equal_32((volatile uint32_t *)(uintptr_t)&ht->tail, old_val,
rte_memory_order_relaxed);

ht->tail = new_val;
}
Expand Down Expand Up @@ -89,10 +90,11 @@ __rte_ring_move_prod_head(struct rte_ring *r, unsigned int is_sp,
return 0;

*new_head = *old_head + n;
if (is_sp)
r->prod.head = *new_head, success = 1;
else
success = rte_atomic32_cmpset(&r->prod.head,
if (is_sp) {
r->prod.head = *new_head;
success = 1;
} else
success = rte_atomic32_cmpset((uint32_t *)(uintptr_t)&r->prod.head,
*old_head, *new_head);
} while (unlikely(success == 0));
return n;
Expand Down Expand Up @@ -162,8 +164,8 @@ __rte_ring_move_cons_head(struct rte_ring *r, unsigned int is_sc,
rte_smp_rmb();
success = 1;
} else {
success = rte_atomic32_cmpset(&r->cons.head, *old_head,
*new_head);
success = rte_atomic32_cmpset((uint32_t *)(uintptr_t)&r->cons.head,
*old_head, *new_head);
}
} while (unlikely(success == 0));
return n;
Expand Down
22 changes: 12 additions & 10 deletions lib/ring/rte_ring_hts_elem_pvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#ifndef _RTE_RING_HTS_ELEM_PVT_H_
#define _RTE_RING_HTS_ELEM_PVT_H_

#include <rte_stdatomic.h>

/**
* @file rte_ring_hts_elem_pvt.h
* It is not recommended to include this file directly,
Expand All @@ -30,7 +32,7 @@ __rte_ring_hts_update_tail(struct rte_ring_hts_headtail *ht, uint32_t old_tail,
RTE_SET_USED(enqueue);

tail = old_tail + num;
__atomic_store_n(&ht->ht.pos.tail, tail, __ATOMIC_RELEASE);
rte_atomic_store_explicit(&ht->ht.pos.tail, tail, rte_memory_order_release);
}

/**
Expand All @@ -44,7 +46,7 @@ __rte_ring_hts_head_wait(const struct rte_ring_hts_headtail *ht,
{
while (p->pos.head != p->pos.tail) {
rte_pause();
p->raw = __atomic_load_n(&ht->ht.raw, __ATOMIC_ACQUIRE);
p->raw = rte_atomic_load_explicit(&ht->ht.raw, rte_memory_order_acquire);
}
}

Expand All @@ -61,7 +63,7 @@ __rte_ring_hts_move_prod_head(struct rte_ring *r, unsigned int num,

const uint32_t capacity = r->capacity;

op.raw = __atomic_load_n(&r->hts_prod.ht.raw, __ATOMIC_ACQUIRE);
op.raw = rte_atomic_load_explicit(&r->hts_prod.ht.raw, rte_memory_order_acquire);

do {
/* Reset n to the initial burst count */
Expand Down Expand Up @@ -98,9 +100,9 @@ __rte_ring_hts_move_prod_head(struct rte_ring *r, unsigned int num,
* - OOO reads of cons tail value
* - OOO copy of elems from the ring
*/
} while (__atomic_compare_exchange_n(&r->hts_prod.ht.raw,
&op.raw, np.raw,
0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
} while (rte_atomic_compare_exchange_strong_explicit(&r->hts_prod.ht.raw,
(uint64_t *)(uintptr_t)&op.raw, np.raw,
rte_memory_order_acquire, rte_memory_order_acquire) == 0);

*old_head = op.pos.head;
return n;
Expand All @@ -117,7 +119,7 @@ __rte_ring_hts_move_cons_head(struct rte_ring *r, unsigned int num,
uint32_t n;
union __rte_ring_hts_pos np, op;

op.raw = __atomic_load_n(&r->hts_cons.ht.raw, __ATOMIC_ACQUIRE);
op.raw = rte_atomic_load_explicit(&r->hts_cons.ht.raw, rte_memory_order_acquire);

/* move cons.head atomically */
do {
Expand Down Expand Up @@ -153,9 +155,9 @@ __rte_ring_hts_move_cons_head(struct rte_ring *r, unsigned int num,
* - OOO reads of prod tail value
* - OOO copy of elems from the ring
*/
} while (__atomic_compare_exchange_n(&r->hts_cons.ht.raw,
&op.raw, np.raw,
0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
} while (rte_atomic_compare_exchange_strong_explicit(&r->hts_cons.ht.raw,
(uint64_t *)(uintptr_t)&op.raw, np.raw,
rte_memory_order_acquire, rte_memory_order_acquire) == 0);

*old_head = op.pos.head;
return n;
Expand Down
6 changes: 3 additions & 3 deletions lib/ring/rte_ring_peek_elem_pvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ __rte_ring_st_set_head_tail(struct rte_ring_headtail *ht, uint32_t tail,

pos = tail + num;
ht->head = pos;
__atomic_store_n(&ht->tail, pos, __ATOMIC_RELEASE);
rte_atomic_store_explicit(&ht->tail, pos, rte_memory_order_release);
}

/**
Expand All @@ -78,7 +78,7 @@ __rte_ring_hts_get_tail(struct rte_ring_hts_headtail *ht, uint32_t *tail,
uint32_t n;
union __rte_ring_hts_pos p;

p.raw = __atomic_load_n(&ht->ht.raw, __ATOMIC_RELAXED);
p.raw = rte_atomic_load_explicit(&ht->ht.raw, rte_memory_order_relaxed);
n = p.pos.head - p.pos.tail;

RTE_ASSERT(n >= num);
Expand All @@ -104,7 +104,7 @@ __rte_ring_hts_set_head_tail(struct rte_ring_hts_headtail *ht, uint32_t tail,
p.pos.head = tail + num;
p.pos.tail = p.pos.head;

__atomic_store_n(&ht->ht.raw, p.raw, __ATOMIC_RELEASE);
rte_atomic_store_explicit(&ht->ht.raw, p.raw, rte_memory_order_release);
}

/**
Expand Down
27 changes: 14 additions & 13 deletions lib/ring/rte_ring_rts_elem_pvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,19 @@ __rte_ring_rts_update_tail(struct rte_ring_rts_headtail *ht)
* might preceded us, then don't update tail with new value.
*/

ot.raw = __atomic_load_n(&ht->tail.raw, __ATOMIC_ACQUIRE);
ot.raw = rte_atomic_load_explicit(&ht->tail.raw, rte_memory_order_acquire);

do {
/* on 32-bit systems we have to do atomic read here */
h.raw = __atomic_load_n(&ht->head.raw, __ATOMIC_RELAXED);
h.raw = rte_atomic_load_explicit(&ht->head.raw, rte_memory_order_relaxed);

nt.raw = ot.raw;
if (++nt.val.cnt == h.val.cnt)
nt.val.pos = h.val.pos;

} while (__atomic_compare_exchange_n(&ht->tail.raw, &ot.raw, nt.raw,
0, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE) == 0);
} while (rte_atomic_compare_exchange_strong_explicit(&ht->tail.raw,
(uint64_t *)(uintptr_t)&ot.raw, nt.raw,
rte_memory_order_release, rte_memory_order_acquire) == 0);
}

/**
Expand All @@ -59,7 +60,7 @@ __rte_ring_rts_head_wait(const struct rte_ring_rts_headtail *ht,

while (h->val.pos - ht->tail.val.pos > max) {
rte_pause();
h->raw = __atomic_load_n(&ht->head.raw, __ATOMIC_ACQUIRE);
h->raw = rte_atomic_load_explicit(&ht->head.raw, rte_memory_order_acquire);
}
}

Expand All @@ -76,7 +77,7 @@ __rte_ring_rts_move_prod_head(struct rte_ring *r, uint32_t num,

const uint32_t capacity = r->capacity;

oh.raw = __atomic_load_n(&r->rts_prod.head.raw, __ATOMIC_ACQUIRE);
oh.raw = rte_atomic_load_explicit(&r->rts_prod.head.raw, rte_memory_order_acquire);

do {
/* Reset n to the initial burst count */
Expand Down Expand Up @@ -113,9 +114,9 @@ __rte_ring_rts_move_prod_head(struct rte_ring *r, uint32_t num,
* - OOO reads of cons tail value
* - OOO copy of elems to the ring
*/
} while (__atomic_compare_exchange_n(&r->rts_prod.head.raw,
&oh.raw, nh.raw,
0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
} while (rte_atomic_compare_exchange_strong_explicit(&r->rts_prod.head.raw,
(uint64_t *)(uintptr_t)&oh.raw, nh.raw,
rte_memory_order_acquire, rte_memory_order_acquire) == 0);

*old_head = oh.val.pos;
return n;
Expand All @@ -132,7 +133,7 @@ __rte_ring_rts_move_cons_head(struct rte_ring *r, uint32_t num,
uint32_t n;
union __rte_ring_rts_poscnt nh, oh;

oh.raw = __atomic_load_n(&r->rts_cons.head.raw, __ATOMIC_ACQUIRE);
oh.raw = rte_atomic_load_explicit(&r->rts_cons.head.raw, rte_memory_order_acquire);

/* move cons.head atomically */
do {
Expand Down Expand Up @@ -168,9 +169,9 @@ __rte_ring_rts_move_cons_head(struct rte_ring *r, uint32_t num,
* - OOO reads of prod tail value
* - OOO copy of elems from the ring
*/
} while (__atomic_compare_exchange_n(&r->rts_cons.head.raw,
&oh.raw, nh.raw,
0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
} while (rte_atomic_compare_exchange_strong_explicit(&r->rts_cons.head.raw,
(uint64_t *)(uintptr_t)&oh.raw, nh.raw,
rte_memory_order_acquire, rte_memory_order_acquire) == 0);

*old_head = oh.val.pos;
return n;
Expand Down

0 comments on commit 32faaf3

Please sign in to comment.