sh: Fix up T-bit error handling in SH-4A mutex fastpath.
This corrects a deadlock encountered on ap325 in the cases where the mutex is contended and the slow-path needs to be fallen back upon. Signed-off-by: Takashi YOSHII <yoshii.takashi@renesas.com> Signed-off-by: Kuninori Morimoto <morimoto.kuninori@renesas.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
03f07876df
commit
c20f326a62
|
@ -21,38 +21,36 @@
|
||||||
static inline void
|
static inline void
|
||||||
__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
|
__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
|
||||||
{
|
{
|
||||||
int __ex_flag, __res;
|
int __done, __res;
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
"movli.l @%2, %0 \n"
|
"movli.l @%2, %0 \n"
|
||||||
"add #-1, %0 \n"
|
"add #-1, %0 \n"
|
||||||
"movco.l %0, @%2 \n"
|
"movco.l %0, @%2 \n"
|
||||||
"movt %1 \n"
|
"movt %1 \n"
|
||||||
: "=&z" (__res), "=&r" (__ex_flag)
|
: "=&z" (__res), "=&r" (__done)
|
||||||
: "r" (&(count)->counter)
|
: "r" (&(count)->counter)
|
||||||
: "t");
|
: "t");
|
||||||
|
|
||||||
__res |= !__ex_flag;
|
if (unlikely(!__done || __res != 0))
|
||||||
if (unlikely(__res != 0))
|
|
||||||
fail_fn(count);
|
fail_fn(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
|
__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
|
||||||
{
|
{
|
||||||
int __ex_flag, __res;
|
int __done, __res;
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
"movli.l @%2, %0 \n"
|
"movli.l @%2, %0 \n"
|
||||||
"add #-1, %0 \n"
|
"add #-1, %0 \n"
|
||||||
"movco.l %0, @%2 \n"
|
"movco.l %0, @%2 \n"
|
||||||
"movt %1 \n"
|
"movt %1 \n"
|
||||||
: "=&z" (__res), "=&r" (__ex_flag)
|
: "=&z" (__res), "=&r" (__done)
|
||||||
: "r" (&(count)->counter)
|
: "r" (&(count)->counter)
|
||||||
: "t");
|
: "t");
|
||||||
|
|
||||||
__res |= !__ex_flag;
|
if (unlikely(!__done || __res != 0))
|
||||||
if (unlikely(__res != 0))
|
|
||||||
__res = fail_fn(count);
|
__res = fail_fn(count);
|
||||||
|
|
||||||
return __res;
|
return __res;
|
||||||
|
@ -61,19 +59,18 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
|
||||||
static inline void
|
static inline void
|
||||||
__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
|
__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
|
||||||
{
|
{
|
||||||
int __ex_flag, __res;
|
int __done, __res;
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
"movli.l @%2, %0 \n\t"
|
"movli.l @%2, %0 \n\t"
|
||||||
"add #1, %0 \n\t"
|
"add #1, %0 \n\t"
|
||||||
"movco.l %0, @%2 \n\t"
|
"movco.l %0, @%2 \n\t"
|
||||||
"movt %1 \n\t"
|
"movt %1 \n\t"
|
||||||
: "=&z" (__res), "=&r" (__ex_flag)
|
: "=&z" (__res), "=&r" (__done)
|
||||||
: "r" (&(count)->counter)
|
: "r" (&(count)->counter)
|
||||||
: "t");
|
: "t");
|
||||||
|
|
||||||
__res |= !__ex_flag;
|
if (unlikely(!__done || __res <= 0))
|
||||||
if (unlikely(__res <= 0))
|
|
||||||
fail_fn(count);
|
fail_fn(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue