-
Notifications
You must be signed in to change notification settings - Fork 18
Open
Description
Both __store_ring() and __load_ring() have a same bug.
function __store_ring:
portable-lib/inc/fast/ringbuf.h
Lines 237 to 277 in 10c3286
| __store_ring(struct rte_ring *r, uint_fast32_t head, void * const* obj, unsigned n) | |
| { | |
| unsigned i; | |
| unsigned loops = n & 0x3; | |
| unsigned idx = head & r->mask; | |
| // If we know we won't wrap around, we unroll 4 times | |
| if (likely((idx + n) <= r->mask)) { | |
| for (i = 0; i < loops; i += 4, idx += 4) { | |
| r->ring[idx+0] = obj[i+0]; | |
| r->ring[idx+1] = obj[i+1]; | |
| r->ring[idx+2] = obj[i+2]; | |
| r->ring[idx+3] = obj[i+3]; | |
| } | |
| // mop up remainder | |
| switch (n & 0x3) { | |
| case 3: | |
| r->ring[idx+0] = obj[i+0]; | |
| r->ring[idx+1] = obj[i+1]; | |
| r->ring[idx+2] = obj[i+2]; | |
| break; | |
| case 2: | |
| r->ring[idx+0] = obj[i+0]; | |
| r->ring[idx+1] = obj[i+1]; | |
| break; | |
| case 1: | |
| r->ring[idx+0] = obj[i+0]; | |
| break; | |
| } | |
| } else { | |
| const uint32_t mask = r->mask; | |
| for (i = 0; i < n; i++, idx++) { | |
| r->ring[idx & mask] = obj[i]; | |
| } | |
| } | |
| } |
-
Bug: When
n=1, function__store_ring(ring, head, elements, n)actually writes 4 elements into the ring. -
Reason:
loopshould =n>>2notn&0x03
Buggy code is at line 240:
portable-lib/inc/fast/ringbuf.h
Line 240 in 10c3286
unsigned loops = n & 0x3; -
Solution:
The correct logic should be:
unsigned loop = n & ((unsigned) ~0x3U);
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels