Jan Beulich | 4625cd6 | 2011-07-19 12:59:51 +0100 | [diff] [blame] | 1 | /* Slow paths of read/write spinlocks. */ |
| 2 | |
| 3 | #include <linux/linkage.h> |
| 4 | #include <asm/alternative-asm.h> |
| 5 | #include <asm/frame.h> |
| 6 | #include <asm/rwlock.h> |
| 7 | |
| 8 | #ifdef CONFIG_X86_32 |
| 9 | # define __lock_ptr eax |
| 10 | #else |
| 11 | # define __lock_ptr rdi |
| 12 | #endif |
| 13 | |
| 14 | ENTRY(__write_lock_failed) |
| 15 | CFI_STARTPROC |
| 16 | FRAME |
| 17 | 0: LOCK_PREFIX |
Jan Beulich | a750036 | 2011-07-19 13:00:45 +0100 | [diff] [blame^] | 18 | WRITE_LOCK_ADD($RW_LOCK_BIAS) (%__lock_ptr) |
Jan Beulich | 4625cd6 | 2011-07-19 12:59:51 +0100 | [diff] [blame] | 19 | 1: rep; nop |
Jan Beulich | a750036 | 2011-07-19 13:00:45 +0100 | [diff] [blame^] | 20 | cmpl $WRITE_LOCK_CMP, (%__lock_ptr) |
Jan Beulich | 4625cd6 | 2011-07-19 12:59:51 +0100 | [diff] [blame] | 21 | jne 1b |
| 22 | LOCK_PREFIX |
Jan Beulich | a750036 | 2011-07-19 13:00:45 +0100 | [diff] [blame^] | 23 | WRITE_LOCK_SUB($RW_LOCK_BIAS) (%__lock_ptr) |
Jan Beulich | 4625cd6 | 2011-07-19 12:59:51 +0100 | [diff] [blame] | 24 | jnz 0b |
| 25 | ENDFRAME |
| 26 | ret |
| 27 | CFI_ENDPROC |
| 28 | END(__write_lock_failed) |
| 29 | |
| 30 | ENTRY(__read_lock_failed) |
| 31 | CFI_STARTPROC |
| 32 | FRAME |
| 33 | 0: LOCK_PREFIX |
Jan Beulich | a750036 | 2011-07-19 13:00:45 +0100 | [diff] [blame^] | 34 | READ_LOCK_SIZE(inc) (%__lock_ptr) |
Jan Beulich | 4625cd6 | 2011-07-19 12:59:51 +0100 | [diff] [blame] | 35 | 1: rep; nop |
Jan Beulich | a750036 | 2011-07-19 13:00:45 +0100 | [diff] [blame^] | 36 | READ_LOCK_SIZE(cmp) $1, (%__lock_ptr) |
Jan Beulich | 4625cd6 | 2011-07-19 12:59:51 +0100 | [diff] [blame] | 37 | js 1b |
| 38 | LOCK_PREFIX |
Jan Beulich | a750036 | 2011-07-19 13:00:45 +0100 | [diff] [blame^] | 39 | READ_LOCK_SIZE(dec) (%__lock_ptr) |
Jan Beulich | 4625cd6 | 2011-07-19 12:59:51 +0100 | [diff] [blame] | 40 | js 0b |
| 41 | ENDFRAME |
| 42 | ret |
| 43 | CFI_ENDPROC |
| 44 | END(__read_lock_failed) |