By default, the TP futexes do not have preference for either readers or writers. Most reader-writer locks allows users to decide if they want to prefer readers or writers more. This patch allows the setting of the prefer-reader mode in the val argument of the futex system call. If that flag is set, it will enable kernel reader to steal the lock when the futex is currently reader-owned and the lock handoff mechanism hasn't been enabled yet. Signed-off-by: Waiman Long <longman@xxxxxxxxxx> --- kernel/futex.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index 4139843..cacaaf1 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -197,6 +197,7 @@ #define FLAGS_CLOCKRT 0x02 #define FLAGS_HAS_TIMEOUT 0x04 #define FLAGS_TP_USLOCK 0x08 /* Do the locking in userspace */ +#define FLAGS_TP_PREADER 0x08 /* Prefer readers */ enum futex_type { TYPE_PI = 0, @@ -4004,6 +4005,20 @@ static noinline int futex_lock(u32 __user *uaddr, unsigned int flags, goto out_put_state_key; } + /* + * For reader, we will try to steal the lock here as if it is the + * top waiter without taking the serialization mutex if the handoff + * PID hasn't been set and is in prefer-reader mode. + */ + if (shared && (flags & FLAGS_TP_PREADER) && !state->handoff_pid) { + ret = futex_trylock(uaddr, vpid, &uval, true); + if (ret) { + if (ret > 0) + ret = TP_LOCK_STOLEN; + goto out_put_state_key; + } + } + if (to) hrtimer_start_expires(&to->timer, HRTIMER_MODE_ABS); @@ -4219,8 +4234,9 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, #ifdef CONFIG_SMP case FUTEX_LOCK: case FUTEX_LOCK_SHARED: - if (val && (cmd == FUTEX_LOCK)) - flags |= FLAGS_TP_USLOCK; + if (val) + flags |= (cmd == FUTEX_LOCK) ? FLAGS_TP_USLOCK + : FLAGS_TP_PREADER; return futex_lock(uaddr, flags, timeout, (cmd == FUTEX_LOCK) ? false : true); case FUTEX_UNLOCK: -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html