Skip to content

Bug: loop counter in ringbuf.h function __store_ring() and __load_ring() is wrong #1

@liuqun

Description

@liuqun

Both __store_ring() and __load_ring() have a same bug.

function __store_ring:

__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: loop should = n>>2 not n&0x03
    Buggy code is at line 240:

    unsigned loops = n & 0x3;

  • Solution:
    The correct logic should be:

unsigned loop = n & ((unsigned) ~0x3U);

see also https://github.com/DPDK/dpdk/blob/07f08a96f5255a0375dce2683db4fb489bbaa8a0/lib/librte_ring/rte_ring.h#L240-L250

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions