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
					
				
			
		
					 1 changed files with 9 additions and 12 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue