Skip to content

Commit

Permalink
drivers/(bdring, imx-enet): fix 7b90e8e: improve atomic semantics
Browse files Browse the repository at this point in the history
add _Atomic specifier to volatile vars used as atomic
change every operation on the vars to atomic_*
JIRA: RTOS-507
  • Loading branch information
Julian Uziemblo committed Sep 6, 2024
1 parent 26b2ea0 commit e11d5db
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 15 deletions.
17 changes: 9 additions & 8 deletions drivers/bdring.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ int net_initRings(net_bufdesc_ring_t *rings, const size_t *sizes, size_t nrings,
for (i = 0; i < nrings; ++i) {
rings[i].ring = p;
rings[i].bufp = bufp;
rings[i].head = rings[i].tail = 0;
atomic_init(&rings[i].head, 0);
atomic_init(&rings[i].tail, 0);
rings[i].last = sizes[i] - 1;
rings[i].phys = phys;
rings[i].ops = ops;
Expand All @@ -131,11 +132,11 @@ size_t net_receivePackets(net_bufdesc_ring_t *ring, struct netif *ni, unsigned e

mutexLock(ring->lock);
n = 0;
i = ring->head;
i = atomic_load(&ring->head);
pkt = NULL;

for (;;) {
if (i == ring->tail) {
if (i == atomic_load(&ring->tail)) {
break;
}

Expand Down Expand Up @@ -172,7 +173,7 @@ size_t net_receivePackets(net_bufdesc_ring_t *ring, struct netif *ni, unsigned e
++n;
}

ring->head = i;
atomic_store(&ring->head, i);
mutexUnlock(ring->lock);
return n;
}
Expand All @@ -190,7 +191,7 @@ size_t net_refillRx(net_bufdesc_ring_t *ring, size_t ethpad)
nxt = (i + 1) & ring->last; // NOTE: 2^n ring size verified in net_initRings
sz = ring->ops->pkt_buf_sz;

while (nxt != ring->head) {
while (nxt != atomic_load(&ring->head)) {
p = net_allocDMAPbuf(&pa, sz);
if (p == NULL) {
break;
Expand All @@ -206,7 +207,7 @@ size_t net_refillRx(net_bufdesc_ring_t *ring, size_t ethpad)
++n;
}

ring->tail = i;
atomic_store(&ring->tail, i);
mutexUnlock(ring->lock);
return n;
}
Expand All @@ -218,7 +219,7 @@ size_t net_reapTxFinished(net_bufdesc_ring_t *ring)
mutexLock(ring->lock);

n = 0;
i = ring->tail;
i = atomic_load(&ring->tail);
head = atomic_load(&ring->head);
while (i != head) {
if (ring->ops->nextTxDone(ring, i) == 0) {
Expand Down Expand Up @@ -295,7 +296,7 @@ size_t net_transmitPacket(net_bufdesc_ring_t *ring, struct pbuf *p)
mutexLock(ring->lock);
// NOTE: 2^n ring size verified in net_initRings
n = atomic_load(&ring->tail); // access tail once - it may be advanced by tx_done thread
i = ring->head;
i = atomic_load(&ring->head);
n = (n - i - 1) & ring->last;
if (n > MAX_TX_FRAGMENTS) {
n = MAX_TX_FRAGMENTS;
Expand Down
2 changes: 1 addition & 1 deletion drivers/bdring.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct net_bufdesc_ring_
{
volatile void *ring;
struct pbuf **bufp;
volatile unsigned head, tail;
_Atomic volatile unsigned head, tail;
unsigned last;
addr_t phys;
const net_bufdesc_ops_t *ops;
Expand Down
5 changes: 3 additions & 2 deletions drivers/imx-enet-regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ struct enet_regs {
typedef struct
{
uint16_t len; /* for last frag = whole frame size? (TBV) */
uint16_t flags;
_Atomic volatile uint16_t flags;
uint32_t addr; /* 64B-aligned buffer [size = TRUNC_FL ?] */
} enet_legacy_desc_t;

Expand All @@ -317,7 +317,8 @@ typedef struct
/* first 3 same as enet_short_desc_t */
union {
struct {
uint16_t len, flags;
uint16_t len;
_Atomic volatile uint16_t flags;
uint32_t addr;
};
enet_legacy_desc_t legacy;
Expand Down
10 changes: 6 additions & 4 deletions drivers/imx-enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ typedef struct
volatile struct enet_regs *mmio;

struct netif *netif;
unsigned drv_exit;
_Atomic volatile unsigned drv_exit;

#define PRIV_RESOURCES(s) &(s)->irq_lock, 3, ~0x03
handle_t irq_lock, tx_lock;
Expand Down Expand Up @@ -374,7 +374,7 @@ static size_t enet_nextRxBufferSize(const net_bufdesc_ring_t *ring, size_t i)
}
#endif

if ((desc->flags & ENET_DESC_RDY) != 0) {
if ((atomic_load(&desc->flags) & ENET_DESC_RDY) != 0) {
return 0;
}

Expand All @@ -392,7 +392,7 @@ static int enet_pktRxFinished(const net_bufdesc_ring_t *ring, size_t i)
{
volatile enet_buf_desc_t *desc = (volatile enet_buf_desc_t *)ring->ring + i;

return desc->flags & ENET_DESC_LAST;
return atomic_load(&desc->flags) & ENET_DESC_LAST;
}


Expand All @@ -414,7 +414,7 @@ static int enet_nextTxDone(const net_bufdesc_ring_t *ring, size_t i)
{
volatile enet_buf_desc_t *desc = (volatile enet_buf_desc_t *)ring->ring + i;

return !(desc->flags & ENET_DESC_RDY);
return !(atomic_load(&desc->flags) & ENET_DESC_RDY);
}


Expand Down Expand Up @@ -1012,6 +1012,8 @@ static int enet_initDevice(enet_state_t *state, int irq, int mdio)
return err;
}

atomic_init(&state->drv_exit, 0x0);

err = enet_clockEnable(state);
if (err < 0) {
return err;
Expand Down

0 comments on commit e11d5db

Please sign in to comment.