* [PATCH 0/4] locktorture: Torture rwlocks
@ 2014-09-29 13:14 Davidlohr Bueso
2014-09-29 13:14 ` [PATCH 1/4] locktorture: Support rwlocks Davidlohr Bueso
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Davidlohr Bueso @ 2014-09-29 13:14 UTC (permalink / raw)
To: paulmck; +Cc: peterz, mingo, dave, linux-kernel
We are still missing the ability to torture rwlocks, particularly the
new queued variant (patch 1). The rest of the patches are miscellaneous
updates.
Hopefully the set is straightforward enough that it can still be
considered for v3.18.
Davidlohr Bueso (4):
locktorture: Support rwlocks
locktorture: Fix __acquire annotation for spinlock irq
locktorture: Cannot hold read and write lock
locktorture: Cleanup header usage
Documentation/locking/locktorture.txt | 5 +
kernel/locking/locktorture.c | 141 ++++++++++++++++++---
.../selftests/rcutorture/configs/lock/CFLIST | 1 +
.../selftests/rcutorture/configs/lock/LOCK04 | 6 +
.../selftests/rcutorture/configs/lock/LOCK04.boot | 1 +
5 files changed, 137 insertions(+), 17 deletions(-)
create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK04
create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK04.boot
--
1.8.4.5
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] locktorture: Support rwlocks
2014-09-29 13:14 [PATCH 0/4] locktorture: Torture rwlocks Davidlohr Bueso
@ 2014-09-29 13:14 ` Davidlohr Bueso
2014-09-29 13:14 ` [PATCH 2/4] locktorture: Fix __acquire annotation for spinlock irq Davidlohr Bueso
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Davidlohr Bueso @ 2014-09-29 13:14 UTC (permalink / raw)
To: paulmck; +Cc: peterz, mingo, dave, linux-kernel, Davidlohr Bueso
Add a "rw_lock" torture test to stress kernel rwlocks and their irq
variant. Reader critical regions are 5x longer than writers. As such
a similar ratio of lock acquisitions is seen in the statistics. In the
case of massive contention, both hold the lock for 1/10 of a second.
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
---
Documentation/locking/locktorture.txt | 5 +
kernel/locking/locktorture.c | 115 ++++++++++++++++++++-
.../selftests/rcutorture/configs/lock/CFLIST | 1 +
.../selftests/rcutorture/configs/lock/LOCK04 | 6 ++
.../selftests/rcutorture/configs/lock/LOCK04.boot | 1 +
5 files changed, 125 insertions(+), 3 deletions(-)
create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK04
create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK04.boot
diff --git a/Documentation/locking/locktorture.txt b/Documentation/locking/locktorture.txt
index be71501..619f2bb 100644
--- a/Documentation/locking/locktorture.txt
+++ b/Documentation/locking/locktorture.txt
@@ -45,6 +45,11 @@ torture_type Type of lock to torture. By default, only spinlocks will
o "spin_lock_irq": spin_lock_irq() and spin_unlock_irq()
pairs.
+ o "rw_lock": read/write lock() and unlock() rwlock pairs.
+
+ o "rw_lock_irq": read/write lock_irq() and unlock_irq()
+ rwlock pairs.
+
o "mutex_lock": mutex_lock() and mutex_unlock() pairs.
o "rwsem_lock": read/write down() and up() semaphore pairs.
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index 540d5df..0762b25 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -27,6 +27,7 @@
#include <linux/kthread.h>
#include <linux/err.h>
#include <linux/spinlock.h>
+#include <linux/rwlock.h>
#include <linux/mutex.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
@@ -229,6 +230,110 @@ static struct lock_torture_ops spin_lock_irq_ops = {
.name = "spin_lock_irq"
};
+static DEFINE_RWLOCK(torture_rwlock);
+
+static int torture_rwlock_write_lock(void) __acquires(torture_rwlock)
+{
+ write_lock(&torture_rwlock);
+ return 0;
+}
+
+static void torture_rwlock_write_delay(struct torture_random_state *trsp)
+{
+ const unsigned long shortdelay_us = 2;
+ const unsigned long longdelay_ms = 100;
+
+ /* We want a short delay mostly to emulate likely code, and
+ * we want a long delay occasionally to force massive contention.
+ */
+ if (!(torture_random(trsp) %
+ (cxt.nrealwriters_stress * 2000 * longdelay_ms)))
+ mdelay(longdelay_ms);
+ else
+ udelay(shortdelay_us);
+}
+
+static void torture_rwlock_write_unlock(void) __releases(torture_rwlock)
+{
+ write_unlock(&torture_rwlock);
+}
+
+static int torture_rwlock_read_lock(void) __acquires(torture_rwlock)
+{
+ read_lock(&torture_rwlock);
+ return 0;
+}
+
+static void torture_rwlock_read_delay(struct torture_random_state *trsp)
+{
+ const unsigned long shortdelay_us = 10;
+ const unsigned long longdelay_ms = 100;
+
+ /* We want a short delay mostly to emulate likely code, and
+ * we want a long delay occasionally to force massive contention.
+ */
+ if (!(torture_random(trsp) %
+ (cxt.nrealreaders_stress * 2000 * longdelay_ms)))
+ mdelay(longdelay_ms);
+ else
+ udelay(shortdelay_us);
+}
+
+static void torture_rwlock_read_unlock(void) __releases(torture_rwlock)
+{
+ read_unlock(&torture_rwlock);
+}
+
+static struct lock_torture_ops rw_lock_ops = {
+ .writelock = torture_rwlock_write_lock,
+ .write_delay = torture_rwlock_write_delay,
+ .writeunlock = torture_rwlock_write_unlock,
+ .readlock = torture_rwlock_read_lock,
+ .read_delay = torture_rwlock_read_delay,
+ .readunlock = torture_rwlock_read_unlock,
+ .name = "rw_lock"
+};
+
+static int torture_rwlock_write_lock_irq(void) __acquires(torture_rwlock)
+{
+ unsigned long flags;
+
+ write_lock_irqsave(&torture_rwlock, flags);
+ cxt.cur_ops->flags = flags;
+ return 0;
+}
+
+static void torture_rwlock_write_unlock_irq(void)
+__releases(torture_rwlock)
+{
+ write_unlock_irqrestore(&torture_rwlock, cxt.cur_ops->flags);
+}
+
+static int torture_rwlock_read_lock_irq(void) __acquires(torture_rwlock)
+{
+ unsigned long flags;
+
+ read_lock_irqsave(&torture_rwlock, flags);
+ cxt.cur_ops->flags = flags;
+ return 0;
+}
+
+static void torture_rwlock_read_unlock_irq(void)
+__releases(torture_rwlock)
+{
+ write_unlock_irqrestore(&torture_rwlock, cxt.cur_ops->flags);
+}
+
+static struct lock_torture_ops rw_lock_irq_ops = {
+ .writelock = torture_rwlock_write_lock_irq,
+ .write_delay = torture_rwlock_write_delay,
+ .writeunlock = torture_rwlock_write_unlock_irq,
+ .readlock = torture_rwlock_read_lock_irq,
+ .read_delay = torture_rwlock_read_delay,
+ .readunlock = torture_rwlock_read_unlock_irq,
+ .name = "rw_lock_irq"
+};
+
static DEFINE_MUTEX(torture_mutex);
static int torture_mutex_lock(void) __acquires(torture_mutex)
@@ -535,8 +640,11 @@ static int __init lock_torture_init(void)
int i, j;
int firsterr = 0;
static struct lock_torture_ops *torture_ops[] = {
- &lock_busted_ops, &spin_lock_ops, &spin_lock_irq_ops,
- &mutex_lock_ops, &rwsem_lock_ops,
+ &lock_busted_ops,
+ &spin_lock_ops, &spin_lock_irq_ops,
+ &rw_lock_ops, &rw_lock_irq_ops,
+ &mutex_lock_ops,
+ &rwsem_lock_ops,
};
if (!torture_init_begin(torture_type, verbose, &torture_runnable))
@@ -571,7 +679,8 @@ static int __init lock_torture_init(void)
cxt.debug_lock = true;
#endif
#ifdef CONFIG_DEBUG_SPINLOCK
- if (strncmp(torture_type, "spin", 4) == 0)
+ if ((strncmp(torture_type, "spin", 4) == 0) ||
+ (strncmp(torture_type, "rw_lock", 7) == 0))
cxt.debug_lock = true;
#endif
diff --git a/tools/testing/selftests/rcutorture/configs/lock/CFLIST b/tools/testing/selftests/rcutorture/configs/lock/CFLIST
index 6108137..6910b73 100644
--- a/tools/testing/selftests/rcutorture/configs/lock/CFLIST
+++ b/tools/testing/selftests/rcutorture/configs/lock/CFLIST
@@ -1,3 +1,4 @@
LOCK01
LOCK02
LOCK03
+LOCK04
\ No newline at end of file
diff --git a/tools/testing/selftests/rcutorture/configs/lock/LOCK04 b/tools/testing/selftests/rcutorture/configs/lock/LOCK04
new file mode 100644
index 0000000..1d1da14
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/configs/lock/LOCK04
@@ -0,0 +1,6 @@
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+CONFIG_PREEMPT_NONE=n
+CONFIG_PREEMPT_VOLUNTARY=n
+CONFIG_PREEMPT=y
diff --git a/tools/testing/selftests/rcutorture/configs/lock/LOCK04.boot b/tools/testing/selftests/rcutorture/configs/lock/LOCK04.boot
new file mode 100644
index 0000000..48c04fe
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/configs/lock/LOCK04.boot
@@ -0,0 +1 @@
+locktorture.torture_type=rw_lock
--
1.8.4.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] locktorture: Fix __acquire annotation for spinlock irq
2014-09-29 13:14 [PATCH 0/4] locktorture: Torture rwlocks Davidlohr Bueso
2014-09-29 13:14 ` [PATCH 1/4] locktorture: Support rwlocks Davidlohr Bueso
@ 2014-09-29 13:14 ` Davidlohr Bueso
2014-09-29 13:14 ` [PATCH 3/4] locktorture: Cannot hold read and write lock Davidlohr Bueso
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Davidlohr Bueso @ 2014-09-29 13:14 UTC (permalink / raw)
To: paulmck; +Cc: peterz, mingo, dave, linux-kernel, Davidlohr Bueso
Its quite easy to get mixed up with the names -- 'torture_spinlock_irq'
is not actually a valid spinlock name.
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
---
kernel/locking/locktorture.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index 0762b25..9e9cd11 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -205,7 +205,7 @@ static struct lock_torture_ops spin_lock_ops = {
};
static int torture_spin_lock_write_lock_irq(void)
-__acquires(torture_spinlock_irq)
+__acquires(torture_spinlock)
{
unsigned long flags;
--
1.8.4.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] locktorture: Cannot hold read and write lock
2014-09-29 13:14 [PATCH 0/4] locktorture: Torture rwlocks Davidlohr Bueso
2014-09-29 13:14 ` [PATCH 1/4] locktorture: Support rwlocks Davidlohr Bueso
2014-09-29 13:14 ` [PATCH 2/4] locktorture: Fix __acquire annotation for spinlock irq Davidlohr Bueso
@ 2014-09-29 13:14 ` Davidlohr Bueso
2014-09-29 13:14 ` [PATCH 4/4] locktorture: Cleanup header usage Davidlohr Bueso
2014-09-30 7:57 ` [PATCH 0/4] locktorture: Torture rwlocks Paul E. McKenney
4 siblings, 0 replies; 6+ messages in thread
From: Davidlohr Bueso @ 2014-09-29 13:14 UTC (permalink / raw)
To: paulmck; +Cc: peterz, mingo, dave, linux-kernel, Davidlohr Bueso
... trigger an error if so.
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
---
kernel/locking/locktorture.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index 9e9cd11..b05dc46 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -453,14 +453,19 @@ static int lock_torture_writer(void *arg)
do {
if ((torture_random(&rand) & 0xfffff) == 0)
schedule_timeout_uninterruptible(1);
+
cxt.cur_ops->writelock();
if (WARN_ON_ONCE(lock_is_write_held))
lwsp->n_lock_fail++;
lock_is_write_held = 1;
+ if (WARN_ON_ONCE(lock_is_read_held))
+ lwsp->n_lock_fail++; /* rare, but... */
+
lwsp->n_lock_acquired++;
cxt.cur_ops->write_delay(&rand);
lock_is_write_held = 0;
cxt.cur_ops->writeunlock();
+
stutter_wait("lock_torture_writer");
} while (!torture_must_stop());
torture_kthread_stopping("lock_torture_writer");
@@ -482,12 +487,17 @@ static int lock_torture_reader(void *arg)
do {
if ((torture_random(&rand) & 0xfffff) == 0)
schedule_timeout_uninterruptible(1);
+
cxt.cur_ops->readlock();
lock_is_read_held = 1;
+ if (WARN_ON_ONCE(lock_is_write_held))
+ lrsp->n_lock_fail++; /* rare, but... */
+
lrsp->n_lock_acquired++;
cxt.cur_ops->read_delay(&rand);
lock_is_read_held = 0;
cxt.cur_ops->readunlock();
+
stutter_wait("lock_torture_reader");
} while (!torture_must_stop());
torture_kthread_stopping("lock_torture_reader");
--
1.8.4.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] locktorture: Cleanup header usage
2014-09-29 13:14 [PATCH 0/4] locktorture: Torture rwlocks Davidlohr Bueso
` (2 preceding siblings ...)
2014-09-29 13:14 ` [PATCH 3/4] locktorture: Cannot hold read and write lock Davidlohr Bueso
@ 2014-09-29 13:14 ` Davidlohr Bueso
2014-09-30 7:57 ` [PATCH 0/4] locktorture: Torture rwlocks Paul E. McKenney
4 siblings, 0 replies; 6+ messages in thread
From: Davidlohr Bueso @ 2014-09-29 13:14 UTC (permalink / raw)
To: paulmck; +Cc: peterz, mingo, dave, linux-kernel, Davidlohr Bueso
Remove some unnecessary ones and explicitly include rwsem.h
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
---
kernel/locking/locktorture.c | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index b05dc46..ec8cce2 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -20,32 +20,20 @@
* Author: Paul E. McKenney <paulmck@us.ibm.com>
* Based on kernel/rcu/torture.c.
*/
-#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/init.h>
#include <linux/module.h>
#include <linux/kthread.h>
-#include <linux/err.h>
#include <linux/spinlock.h>
#include <linux/rwlock.h>
#include <linux/mutex.h>
+#include <linux/rwsem.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/atomic.h>
-#include <linux/bitops.h>
-#include <linux/completion.h>
#include <linux/moduleparam.h>
-#include <linux/percpu.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/freezer.h>
-#include <linux/cpu.h>
#include <linux/delay.h>
-#include <linux/stat.h>
#include <linux/slab.h>
-#include <linux/trace_clock.h>
-#include <asm/byteorder.h>
#include <linux/torture.h>
MODULE_LICENSE("GPL");
--
1.8.4.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/4] locktorture: Torture rwlocks
2014-09-29 13:14 [PATCH 0/4] locktorture: Torture rwlocks Davidlohr Bueso
` (3 preceding siblings ...)
2014-09-29 13:14 ` [PATCH 4/4] locktorture: Cleanup header usage Davidlohr Bueso
@ 2014-09-30 7:57 ` Paul E. McKenney
4 siblings, 0 replies; 6+ messages in thread
From: Paul E. McKenney @ 2014-09-30 7:57 UTC (permalink / raw)
To: Davidlohr Bueso; +Cc: peterz, mingo, linux-kernel
On Mon, Sep 29, 2014 at 06:14:22AM -0700, Davidlohr Bueso wrote:
> We are still missing the ability to torture rwlocks, particularly the
> new queued variant (patch 1). The rest of the patches are miscellaneous
> updates.
>
> Hopefully the set is straightforward enough that it can still be
> considered for v3.18.
Queued, thank you!
Running a quick set of tests, if these pass, will send a pull request along.
Thanx, Paul
> Davidlohr Bueso (4):
> locktorture: Support rwlocks
> locktorture: Fix __acquire annotation for spinlock irq
> locktorture: Cannot hold read and write lock
> locktorture: Cleanup header usage
>
> Documentation/locking/locktorture.txt | 5 +
> kernel/locking/locktorture.c | 141 ++++++++++++++++++---
> .../selftests/rcutorture/configs/lock/CFLIST | 1 +
> .../selftests/rcutorture/configs/lock/LOCK04 | 6 +
> .../selftests/rcutorture/configs/lock/LOCK04.boot | 1 +
> 5 files changed, 137 insertions(+), 17 deletions(-)
> create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK04
> create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK04.boot
>
> --
> 1.8.4.5
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-09-30 7:57 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-29 13:14 [PATCH 0/4] locktorture: Torture rwlocks Davidlohr Bueso
2014-09-29 13:14 ` [PATCH 1/4] locktorture: Support rwlocks Davidlohr Bueso
2014-09-29 13:14 ` [PATCH 2/4] locktorture: Fix __acquire annotation for spinlock irq Davidlohr Bueso
2014-09-29 13:14 ` [PATCH 3/4] locktorture: Cannot hold read and write lock Davidlohr Bueso
2014-09-29 13:14 ` [PATCH 4/4] locktorture: Cleanup header usage Davidlohr Bueso
2014-09-30 7:57 ` [PATCH 0/4] locktorture: Torture rwlocks Paul E. McKenney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox