Skip to content

Commit

Permalink
drivers/(bdring, imx-enet): fix atomic semantics
Browse files Browse the repository at this point in the history
fix 7b90e8e:
- add _Atomic specifier to volatile vars used as atomics
- change operations on the vars to atomic_*

JIRA: RTOS-507
  • Loading branch information
julianuziemblo committed Dec 5, 2024
1 parent e50518a commit b1b673d
Show file tree
Hide file tree
Showing 4 changed files with 22 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 @@ -44,7 +44,7 @@ typedef struct net_bufdesc_ops_ {
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
3 changes: 2 additions & 1 deletion drivers/imx-enet-regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ typedef struct
/* first 3 same as enet_legacy_desc_t */
union {
struct {
uint16_t len, flags;
uint16_t len;
uint16_t flags;
uint32_t addr;
};
enet_legacy_desc_t legacy;
Expand Down
15 changes: 10 additions & 5 deletions drivers/imx-enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,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 @@ -384,7 +384,7 @@ static void enet_fillRxDesc(const net_bufdesc_ring_t *ring, size_t i, addr_t pa,
#if ENET_USE_ENHANCED_DESCRIPTORS
desc->yflags = ENET_RXDY_INT;
#endif
atomic_store(&desc->flags, ENET_DESC_RDY | wrap);
atomic_store(&desc->flags, ENET_DESC_RDY | wrap); /* NOTE: memory sync */
}


Expand Down Expand Up @@ -423,7 +423,7 @@ static void enet_fillTxDesc(const net_bufdesc_ring_t *ring, size_t i, addr_t pa,
desc->yflags = yflags;
#endif

atomic_store(&desc->flags, flags);
atomic_store(&desc->flags, flags); /* NOTE: memory sync */
}


Expand Down Expand Up @@ -480,9 +480,11 @@ static void enet_irq_thread(void *arg)
{
enet_state_t *state = arg;
size_t rx_done = 0;
unsigned exit;

mutexLock(state->irq_lock);
while (state->drv_exit == 0) {
exit = atomic_load(&state->drv_exit);
while (exit == 0) {
state->mmio->EIR = ENET_IRQ_RXF;
rx_done = net_receivePackets(&state->rx, state->netif, ETH_PAD_SIZE);
if (rx_done > 0 || net_rxFullyFilled(&state->rx) == 0) {
Expand All @@ -497,10 +499,11 @@ static void enet_irq_thread(void *arg)
state->mmio->EIMR |= ENET_IRQ_RXF | ENET_IRQ_TXF;
condWait(state->irq_cond, state->irq_lock, 0);
}
exit = atomic_load(&state->drv_exit);
}
mutexUnlock(state->irq_lock);

if ((state->drv_exit & EV_BUS_ERROR) != 0) {
if ((exit & EV_BUS_ERROR) != 0) {
enet_printf(state, "HW signalled memory bus error -- device halted");
}

Expand Down Expand Up @@ -979,6 +982,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 b1b673d

Please sign in to comment.