kern/160992: buf_ring(9) statistics accounting not MPSAFE
Arnaud Lacombe
lacombar at gmail.com
Sat Sep 24 20:20:11 UTC 2011
>Number: 160992
>Category: kern
>Synopsis: buf_ring(9) statistics accounting not MPSAFE
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sat Sep 24 20:20:10 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator: Arnaud Lacombe
>Release: 9-CURRENT
>Organization:
n/a
>Environment:
>Description:
The following block of code, in `sys/sys/buf_ring.h':
/*
* If there are other enqueues in progress
* that preceeded us, we need to wait for them
* to complete
*/
while (br->br_prod_tail != prod_head)
cpu_spinwait();
br->br_prod_bufs++;
br->br_prod_bytes += nbytes;
br->br_prod_tail = prod_next;
critical_exit();
can be seen at runtime, memory-wise as:
while (br->br_prod_tail != prod_head)
cpu_spinwait();
br->br_prod_tail = prod_next;
br->br_prod_bufs++;
br->br_prod_bytes += nbytes;
critical_exit();
That is, there is no memory barrier to enforce completion of the
load/increment/store/load/load/addition/store operations before
updating what other thread spin on.
Even if `br_prod_tail' is marked `volatile', there is no guarantee that it will not be re-ordered wrt. non-volatile write (to `br_prod_bufs' and `br_prod_bytes').
Confirmed by Kip Macy (kmacy@) in http://lists.freebsd.org/pipermail/freebsd-hackers/2011-September/036454.html.
>How-To-Repeat:
code review.
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list