kern/177862: Fix atomic bitstring operations in sys/ofed/include/linux/bitops.h
Maxim Ignatenko
gelraen.ua at gmail.com
Mon Apr 15 00:20:01 UTC 2013
>Number: 177862
>Category: kern
>Synopsis: Fix atomic bitstring operations in sys/ofed/include/linux/bitops.h
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Apr 15 00:20:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator: Maxim Ignatenko
>Release: stable/9
>Organization:
>Environment:
>Description:
test_and_{set,clear}_bit are currently broken as they do nothing if bit > sizeof(long) * CHAR_BIT. Attached patch also changes int to long in 3 previous macros, which could lead to inconsistent behavior on non-little-endian architectures where sizeof(int) != sizeof(long).
>How-To-Repeat:
>Fix:
Patch attached with submission follows:
Index: sys/ofed/include/linux/bitops.h
===================================================================
--- sys/ofed/include/linux/bitops.h (revision 244048)
+++ sys/ofed/include/linux/bitops.h (working copy)
@@ -272,22 +272,24 @@
return (1);
}
-#define NBINT (NBBY * sizeof(int))
+#define NBLONG (NBBY * sizeof(long))
#define set_bit(i, a) \
- atomic_set_int(&((volatile int *)(a))[(i)/NBINT], 1 << (i) % NBINT)
+ atomic_set_long(&((volatile long *)(a))[(i)/NBLONG], 1 << (i) % NBLONG)
#define clear_bit(i, a) \
- atomic_clear_int(&((volatile int *)(a))[(i)/NBINT], 1 << (i) % NBINT)
+ atomic_clear_long(&((volatile long *)(a))[(i)/NBLONG], 1 << (i) % NBLONG)
#define test_bit(i, a) \
- !!(atomic_load_acq_int(&((volatile int *)(a))[(i)/NBINT]) & 1 << ((i) % NBINT))
+ !!(atomic_load_acq_long(&((volatile long *)(a))[(i)/NBLONG]) & 1 << ((i) % NBLONG))
static inline long
test_and_clear_bit(long bit, long *var)
{
long val;
+ var += bit / (sizeof(long) * NBBY);
+ bit %= sizeof(long) * NBBY;
bit = 1 << bit;
do {
val = *(volatile long *)var;
@@ -301,6 +303,8 @@
{
long val;
+ var += bit / (sizeof(long) * NBBY);
+ bit %= sizeof(long) * NBBY;
bit = 1 << bit;
do {
val = *(volatile long *)var;
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list