From: Waiman Long <Waiman.Long@hp.com>
To: Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
Arnd Bergmann <arnd@arndb.de>
Cc: linux-arch@vger.kernel.org, x86@kernel.org,
linux-kernel@vger.kernel.org,
Peter Zijlstra <peterz@infradead.org>,
Steven Rostedt <rostedt@goodmis.org>,
Andrew Morton <akpm@linux-foundation.org>,
Michel Lespinasse <walken@google.com>,
Andi Kleen <andi@firstfloor.org>, Rik van Riel <riel@redhat.com>,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>,
George Spelvin <linux@horizon.com>,
Tim Chen <tim.c.chen@linux.intel.com>,
"Aswin Chandramouleeswaran\"" <aswin@hp.com>,
Scott J Norton <scott.norton@hp.com>,
Waiman Long <Waiman.Long@hp.com>
Subject: [PATCH v5 3/4] qrwlock: Enable fair queue read/write lock
Date: Mon, 4 Nov 2013 12:17:19 -0500 [thread overview]
Message-ID: <1383585440-4391-4-git-send-email-Waiman.Long@hp.com> (raw)
In-Reply-To: <1383585440-4391-1-git-send-email-Waiman.Long@hp.com>
By default, queue rwlock is fair among writers and gives preference
to readers allowing them to steal lock even if a writer is
waiting. However, there is a desire to have a fair variant of
rwlock that is more deterministic. To enable this, fair variants
of lock initializers are added by this patch to allow lock owners
to choose to use fair rwlock. These newly added initializers all
have the _fair or _FAIR suffix to indicate the desire to use a fair
rwlock. If the QUEUE_RWLOCK config option is not selected, the fair
rwlock initializers will be the same as the regular ones.
Signed-off-by: Waiman Long <Waiman.Long@hp.com>
---
include/linux/rwlock.h | 15 +++++++++++++++
include/linux/rwlock_types.h | 13 +++++++++++++
lib/spinlock_debug.c | 19 +++++++++++++++++++
3 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h
index bc2994e..5f2628b 100644
--- a/include/linux/rwlock.h
+++ b/include/linux/rwlock.h
@@ -23,9 +23,24 @@ do { \
\
__rwlock_init((lock), #lock, &__key); \
} while (0)
+
+# ifdef CONFIG_QUEUE_RWLOCK
+extern void __rwlock_init_fair(rwlock_t *lock, const char *name,
+ struct lock_class_key *key);
+# define rwlock_init_fair(lock) \
+do { \
+ static struct lock_class_key __key; \
+ \
+ __rwlock_init_fair((lock), #lock, &__key); \
+} while (0)
+# else
+# define __rwlock_init_fair(l, n, k) __rwlock_init(l, n, k)
+# endif /* CONFIG_QUEUE_RWLOCK */
#else
# define rwlock_init(lock) \
do { *(lock) = __RW_LOCK_UNLOCKED(lock); } while (0)
+# define rwlock_init_fair(lock) \
+ do { *(lock) = __RW_LOCK_UNLOCKED_FAIR(lock); } while (0)
#endif
#ifdef CONFIG_DEBUG_SPINLOCK
diff --git a/include/linux/rwlock_types.h b/include/linux/rwlock_types.h
index cc0072e..d27c812 100644
--- a/include/linux/rwlock_types.h
+++ b/include/linux/rwlock_types.h
@@ -37,12 +37,25 @@ typedef struct {
.owner = SPINLOCK_OWNER_INIT, \
.owner_cpu = -1, \
RW_DEP_MAP_INIT(lockname) }
+#define __RW_LOCK_UNLOCKED_FAIR(lockname) \
+ (rwlock_t) { .raw_lock = __ARCH_RW_LOCK_UNLOCKED_FAIR,\
+ .magic = RWLOCK_MAGIC, \
+ .owner = SPINLOCK_OWNER_INIT, \
+ .owner_cpu = -1, \
+ RW_DEP_MAP_INIT(lockname) }
#else
#define __RW_LOCK_UNLOCKED(lockname) \
(rwlock_t) { .raw_lock = __ARCH_RW_LOCK_UNLOCKED, \
RW_DEP_MAP_INIT(lockname) }
+#define __RW_LOCK_UNLOCKED_FAIR(lockname) \
+ (rwlock_t) { .raw_lock = __ARCH_RW_LOCK_UNLOCKED_FAIR,\
+ RW_DEP_MAP_INIT(lockname) }
#endif
#define DEFINE_RWLOCK(x) rwlock_t x = __RW_LOCK_UNLOCKED(x)
+#define DEFINE_RWLOCK_FAIR(x) rwlock_t x = __RW_LOCK_UNLOCKED_FAIR(x)
+#ifndef __ARCH_RW_LOCK_UNLOCKED_FAIR
+#define __ARCH_RW_LOCK_UNLOCKED_FAIR __ARCH_RW_LOCK_UNLOCKED
+#endif
#endif /* __LINUX_RWLOCK_TYPES_H */
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
index 0374a59..d6ef7ce 100644
--- a/lib/spinlock_debug.c
+++ b/lib/spinlock_debug.c
@@ -49,6 +49,25 @@ void __rwlock_init(rwlock_t *lock, const char *name,
EXPORT_SYMBOL(__rwlock_init);
+#ifdef CONFIG_QUEUE_RWLOCK
+void __rwlock_init_fair(rwlock_t *lock, const char *name,
+ struct lock_class_key *key)
+{
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ /*
+ * Make sure we are not reinitializing a held lock:
+ */
+ debug_check_no_locks_freed((void *)lock, sizeof(*lock));
+ lockdep_init_map(&lock->dep_map, name, key, 0);
+#endif
+ lock->raw_lock = (arch_rwlock_t) __ARCH_RW_LOCK_UNLOCKED_FAIR;
+ lock->magic = RWLOCK_MAGIC;
+ lock->owner = SPINLOCK_OWNER_INIT;
+ lock->owner_cpu = -1;
+}
+EXPORT_SYMBOL(__rwlock_init_fair);
+#endif /* CONFIG_QUEUE_RWLOCK */
+
static void spin_dump(raw_spinlock_t *lock, const char *msg)
{
struct task_struct *owner = NULL;
--
1.7.1
next prev parent reply other threads:[~2013-11-04 17:17 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-04 17:17 [PATCH v5 0/4] qrwlock: Introducing a queue read/write lock implementation Waiman Long
2013-11-04 17:17 ` [PATCH v5 1/4] qrwlock: A " Waiman Long
2013-11-04 17:17 ` Waiman Long
2013-11-08 21:11 ` Paul E. McKenney
2013-11-08 22:36 ` Waiman Long
2013-11-08 22:36 ` Waiman Long
2013-11-08 23:51 ` Paul E. McKenney
2013-11-09 3:05 ` Waiman Long
2013-11-04 17:17 ` [PATCH v5 2/4] qrwlock x86: Enable x86 to use queue read/write lock Waiman Long
2013-11-04 17:17 ` Waiman Long
2013-11-04 17:17 ` Waiman Long [this message]
2013-11-04 17:17 ` [PATCH v5 3/4] qrwlock: Enable fair " Waiman Long
2013-11-04 17:17 ` [PATCH v5 4/4] qrwlock: Use the mcs_spinlock helper functions for MCS queuing Waiman Long
2013-11-04 17:17 ` Waiman Long
2013-11-08 21:21 ` Paul E. McKenney
2013-11-08 22:42 ` Waiman Long
2013-11-09 1:17 ` Tim Chen
2013-11-09 3:07 ` Paul E. McKenney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1383585440-4391-4-git-send-email-Waiman.Long@hp.com \
--to=waiman.long@hp.com \
--cc=akpm@linux-foundation.org \
--cc=andi@firstfloor.org \
--cc=arnd@arndb.de \
--cc=aswin@hp.com \
--cc=hpa@zytor.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@horizon.com \
--cc=mingo@redhat.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=raghavendra.kt@linux.vnet.ibm.com \
--cc=riel@redhat.com \
--cc=rostedt@goodmis.org \
--cc=scott.norton@hp.com \
--cc=tglx@linutronix.de \
--cc=tim.c.chen@linux.intel.com \
--cc=torvalds@linux-foundation.org \
--cc=walken@google.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).