| To: | linux-mips@linux-mips.org |
|---|---|
| Subject: | cmpxchg broken in some situation |
| From: | Fuxin Zhang <fxzhang@ict.ac.cn> |
| Date: | Sun, 30 Sep 2007 18:34:42 +0800 |
| Original-recipient: | rfc822;linux-mips@linux-mips.org |
| Sender: | linux-mips-bounce@linux-mips.org |
| User-agent: | IceDove 1.5.0.10 (X11/20070329) |
hi,
Today I run across a possible bug of cmpxchg implementation. When
playing with DRM on our Fulong, the following function
(drivers/char/drm/drm_lock.c) is not working correctly in 64BIT mips:
cmpxchg failed to set *lock to new value. (return 0 with *lock unchanged)It is probably due to type conversions between unisigned int and unsigned long. When I change cmpxchg to mycmpxchg(attached below), problem disappeared.
int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context)
{
unsigned int old, new, prev;
volatile unsigned int *lock = &lock_data->hw_lock->lock;
spin_lock(&lock_data->spinlock);
if (lock_data->kernel_waiters != 0) {
drm_lock_transfer(lock_data, 0);
lock_data->idle_has_lock = 1;
spin_unlock(&lock_data->spinlock);
return 1;
}
spin_unlock(&lock_data->spinlock);
do {
old = *lock;
new = _DRM_LOCKING_CONTEXT(old);
prev = cmpxchg(lock, old, new);
} while (prev != old);
if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) !=
context) {
DRM_ERROR("%d freed heavyweight lock held by %d\n",
context, _DRM_LOCKING_CONTEXT(old));
return 1;
}
wake_up_interruptible(&lock_data->lock_queue);
return 0;
}
static inline unsigned int mycmpxchg(volatile int * m, unsigned int old,
unsigned int new) //unsigned long to unsigned int
{
__u32 retval;
__asm__ __volatile__(
" .set
push \n"
" .set
noat \n"
" .set
mips3 \n"
"1: ll %0, %2 #
__mycmpxchg_u32 \n"
" bne %0, %z3,
2f \n"
" .set
mips0 \n"
" move $1,
%z4 \n"
" .set
mips3 \n"
" sc $1,
%1 \n"
" beqz $1,
3f \n"
"2: \n"
" .subsection
2 \n"
"3: b
1b \n"
"
.previous \n"
" .set
pop \n"
: "=&r" (retval), "=R" (*m)
: "R" (*m), "Jr" (old), "Jr" (new)
: "memory");
smp_llsc_mb();
return retval;
}
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| ||
| Previous by Date: | [PATCH 3/4] RTC: add Xicor 1241 driver, Mark Zhan |
|---|---|
| Next by Date: | [PATCH] mtx1 default config, Florian Fainelli |
| Previous by Thread: | [PATCH 3/4] RTC: add Xicor 1241 driver, Mark Zhan |
| Next by Thread: | [PATCH] mtx1 default config, Florian Fainelli |
| Indexes: | [Date] [Thread] [Top] [All Lists] |