| /* Slow paths of read/write spinlocks. */ |
| |
| #include <linux/linkage.h> |
| #include <asm/alternative-asm.h> |
| #include <asm/frame.h> |
| #include <asm/rwlock.h> |
| |
| #ifdef CONFIG_X86_32 |
| # define __lock_ptr eax |
| #else |
| # define __lock_ptr rdi |
| #endif |
| |
| ENTRY(__write_lock_failed) |
| CFI_STARTPROC |
| FRAME |
| 0: LOCK_PREFIX |
| WRITE_LOCK_ADD($RW_LOCK_BIAS) (%__lock_ptr) |
| 1: rep; nop |
| cmpl $WRITE_LOCK_CMP, (%__lock_ptr) |
| jne 1b |
| LOCK_PREFIX |
| WRITE_LOCK_SUB($RW_LOCK_BIAS) (%__lock_ptr) |
| jnz 0b |
| ENDFRAME |
| ret |
| CFI_ENDPROC |
| END(__write_lock_failed) |
| |
| ENTRY(__read_lock_failed) |
| CFI_STARTPROC |
| FRAME |
| 0: LOCK_PREFIX |
| READ_LOCK_SIZE(inc) (%__lock_ptr) |
| 1: rep; nop |
| READ_LOCK_SIZE(cmp) $1, (%__lock_ptr) |
| js 1b |
| LOCK_PREFIX |
| READ_LOCK_SIZE(dec) (%__lock_ptr) |
| js 0b |
| ENDFRAME |
| ret |
| CFI_ENDPROC |
| END(__read_lock_failed) |