mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-02 07:04:24 +00:00
locking/arch, x86: Add __down_read_killable()
Similar to __down_write_killable(), add read killable primitive: extract current __down_read() code to macros and teach it to get different functions as slow_path argument: store ax register to ret, and add sp register and preserve its value. Add call_rwsem_down_read_failed_killable() assembly entry similar to call_rwsem_down_read_failed(): push dx register to stack in additional to common registers, as it's not declarated as modifiable in ____down_read(). Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: arnd@arndb.de Cc: avagin@virtuozzo.com Cc: davem@davemloft.net Cc: fenghua.yu@intel.com Cc: gorcunov@virtuozzo.com Cc: heiko.carstens@de.ibm.com Cc: hpa@zytor.com Cc: ink@jurassic.park.msu.ru Cc: mattst88@gmail.com Cc: rientjes@google.com Cc: rth@twiddle.net Cc: schwidefsky@de.ibm.com Cc: tony.luck@intel.com Cc: viro@zeniv.linux.org.uk Link: http://lkml.kernel.org/r/150670118802.23930.1316107715255410256.stgit@localhost.localdomain Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
a61ba2c8a4
commit
19c6092301
2 changed files with 37 additions and 10 deletions
|
@ -60,18 +60,33 @@
|
||||||
/*
|
/*
|
||||||
* lock for reading
|
* lock for reading
|
||||||
*/
|
*/
|
||||||
|
#define ____down_read(sem, slow_path) \
|
||||||
|
({ \
|
||||||
|
struct rw_semaphore* ret; \
|
||||||
|
asm volatile("# beginning down_read\n\t" \
|
||||||
|
LOCK_PREFIX _ASM_INC "(%[sem])\n\t" \
|
||||||
|
/* adds 0x00000001 */ \
|
||||||
|
" jns 1f\n" \
|
||||||
|
" call " slow_path "\n" \
|
||||||
|
"1:\n\t" \
|
||||||
|
"# ending down_read\n\t" \
|
||||||
|
: "+m" (sem->count), "=a" (ret), \
|
||||||
|
ASM_CALL_CONSTRAINT \
|
||||||
|
: [sem] "a" (sem) \
|
||||||
|
: "memory", "cc"); \
|
||||||
|
ret; \
|
||||||
|
})
|
||||||
|
|
||||||
static inline void __down_read(struct rw_semaphore *sem)
|
static inline void __down_read(struct rw_semaphore *sem)
|
||||||
{
|
{
|
||||||
asm volatile("# beginning down_read\n\t"
|
____down_read(sem, "call_rwsem_down_read_failed");
|
||||||
LOCK_PREFIX _ASM_INC "(%[sem])\n\t"
|
}
|
||||||
/* adds 0x00000001 */
|
|
||||||
" jns 1f\n"
|
static inline int __down_read_killable(struct rw_semaphore *sem)
|
||||||
" call call_rwsem_down_read_failed\n"
|
{
|
||||||
"1:\n\t"
|
if (IS_ERR(____down_read(sem, "call_rwsem_down_read_failed_killable")))
|
||||||
"# ending down_read\n\t"
|
return -EINTR;
|
||||||
: "+m" (sem->count)
|
return 0;
|
||||||
: [sem] "a" (sem)
|
|
||||||
: "memory", "cc");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -98,6 +98,18 @@ ENTRY(call_rwsem_down_read_failed)
|
||||||
ret
|
ret
|
||||||
ENDPROC(call_rwsem_down_read_failed)
|
ENDPROC(call_rwsem_down_read_failed)
|
||||||
|
|
||||||
|
ENTRY(call_rwsem_down_read_failed_killable)
|
||||||
|
FRAME_BEGIN
|
||||||
|
save_common_regs
|
||||||
|
__ASM_SIZE(push,) %__ASM_REG(dx)
|
||||||
|
movq %rax,%rdi
|
||||||
|
call rwsem_down_read_failed_killable
|
||||||
|
__ASM_SIZE(pop,) %__ASM_REG(dx)
|
||||||
|
restore_common_regs
|
||||||
|
FRAME_END
|
||||||
|
ret
|
||||||
|
ENDPROC(call_rwsem_down_read_failed_killable)
|
||||||
|
|
||||||
ENTRY(call_rwsem_down_write_failed)
|
ENTRY(call_rwsem_down_write_failed)
|
||||||
FRAME_BEGIN
|
FRAME_BEGIN
|
||||||
save_common_regs
|
save_common_regs
|
||||||
|
|
Loading…
Reference in a new issue