Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c20f326a authored by Takashi Yoshii's avatar Takashi Yoshii Committed by Paul Mundt
Browse files

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: default avatarTakashi YOSHII <yoshii.takashi@renesas.com>
Signed-off-by: default avatarKuninori Morimoto <morimoto.kuninori@renesas.com>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 03f07876
Loading
Loading
Loading
Loading
+9 −12
Original line number Diff line number Diff line
@@ -21,38 +21,36 @@
static inline void
__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
{
	int __ex_flag, __res;
	int __done, __res;

	__asm__ __volatile__ (
		"movli.l	@%2, %0	\n"
		"add		#-1, %0	\n"
		"movco.l	%0, @%2	\n"
		"movt		%1	\n"
		: "=&z" (__res), "=&r" (__ex_flag)
		: "=&z" (__res), "=&r" (__done)
		: "r" (&(count)->counter)
		: "t");

	__res |= !__ex_flag;
	if (unlikely(__res != 0))
	if (unlikely(!__done || __res != 0))
		fail_fn(count);
}

static inline int
__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
{
	int __ex_flag, __res;
	int __done, __res;

	__asm__ __volatile__ (
		"movli.l	@%2, %0	\n"
		"add		#-1, %0	\n"
		"movco.l	%0, @%2	\n"
		"movt		%1	\n"
		: "=&z" (__res), "=&r" (__ex_flag)
		: "=&z" (__res), "=&r" (__done)
		: "r" (&(count)->counter)
		: "t");

	__res |= !__ex_flag;
	if (unlikely(__res != 0))
	if (unlikely(!__done || __res != 0))
		__res = fail_fn(count);

	return __res;
@@ -61,19 +59,18 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
static inline void
__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
{
	int __ex_flag, __res;
	int __done, __res;

	__asm__ __volatile__ (
		"movli.l	@%2, %0	\n\t"
		"add		#1, %0	\n\t"
		"movco.l	%0, @%2 \n\t"
		"movt		%1	\n\t"
		: "=&z" (__res), "=&r" (__ex_flag)
		: "=&z" (__res), "=&r" (__done)
		: "r" (&(count)->counter)
		: "t");

	__res |= !__ex_flag;
	if (unlikely(__res <= 0))
	if (unlikely(!__done || __res <= 0))
		fail_fn(count);
}