Commit 04c439f8 authored by David S. Miller's avatar David S. Miller

[SPARC64]: Get preempt building and working again.

- HAVE_DEC_LOCK depends on SMP
- Trap return preemption check needs interrupt disabled check
- Implement write_trylock
- Fix in_atomic() definition when PREEMPT enabled
parent 7bcacd88
......@@ -813,7 +813,7 @@ config DEBUG_SPINLOCK
# the generic version in that case.
config HAVE_DEC_LOCK
bool
depends on !DEBUG_SPINLOCK
depends on SMP && !DEBUG_SPINLOCK
default y
config DEBUG_SPINLOCK_SLEEP
......
......@@ -270,9 +270,14 @@ to_kernel:
#ifdef CONFIG_PREEMPT
ldsw [%g6 + TI_PRE_COUNT], %l5
brnz %l5, kern_fpucheck
ldx [%g6 + TI_FLAGS], %l5
andcc %l5, _TIF_NEED_RESCHED, %g0
be,pt %xcc, kern_fpucheck
srl %l4, 20, %l5
cmp %l5, 0
bne,pn %xcc, kern_fpucheck
sethi %hi(PREEMPT_ACTIVE), %l6
stw %l6, [%g6 + TI_PRE_COUNT]
wrpr 0, %pil
call schedule
nop
ba,pt %xcc, rtrap
......
......@@ -136,6 +136,7 @@ EXPORT_SYMBOL(__read_lock);
EXPORT_SYMBOL(__read_unlock);
EXPORT_SYMBOL(__write_lock);
EXPORT_SYMBOL(__write_unlock);
EXPORT_SYMBOL(__write_trylock);
#endif
/* Hard IRQ locking */
......
......@@ -63,5 +63,27 @@ __write_lock: /* %o0 = lock_ptr */
be,pt %icc, 99b
membar #StoreLoad | #StoreStore
ba,a,pt %xcc, 1b
.globl __write_trylock
__write_trylock: /* %o0 = lock_ptr */
sethi %hi(0x80000000), %g2
1: lduw [%o0], %g5
brnz,pn %g5, __write_trylock_fail
4: or %g5, %g2, %g7
cas [%o0], %g5, %g7
cmp %g5, %g7
be,pt %icc, __write_trylock_succeed
membar #StoreLoad | #StoreStore
ba,pt %xcc, 1b
nop
__write_trylock_succeed:
retl
mov 1, %o0
__write_trylock_fail:
retl
mov 0, %o0
rwlock_impl_end:
......@@ -79,7 +79,8 @@ typedef struct {
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#ifdef CONFIG_PREEMPT
# define in_atomic() (preempt_count() != kernel_locked())
# include <linux/smp_lock.h>
# define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
#else
# define in_atomic() (preempt_count() != 0)
......
......@@ -118,11 +118,13 @@ extern void __read_lock(rwlock_t *);
extern void __read_unlock(rwlock_t *);
extern void __write_lock(rwlock_t *);
extern void __write_unlock(rwlock_t *);
extern int __write_trylock(rwlock_t *);
#define _raw_read_lock(p) __read_lock(p)
#define _raw_read_unlock(p) __read_unlock(p)
#define _raw_write_lock(p) __write_lock(p)
#define _raw_write_unlock(p) __write_unlock(p)
#define _raw_write_trylock(p) __write_trylock(p)
#else /* !(CONFIG_DEBUG_SPINLOCK) */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment