aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/locking
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/locking')
-rw-r--r--kernel/locking/locktorture.c68
1 files changed, 67 insertions, 1 deletions
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index c1073d79e440..8480118c0ca8 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -265,6 +265,71 @@ static struct lock_torture_ops mutex_lock_ops = {
265 .name = "mutex_lock" 265 .name = "mutex_lock"
266}; 266};
267 267
268static DECLARE_RWSEM(torture_rwsem);
269static int torture_rwsem_down_write(void) __acquires(torture_rwsem)
270{
271 down_write(&torture_rwsem);
272 return 0;
273}
274
275static void torture_rwsem_write_delay(struct torture_random_state *trsp)
276{
277 const unsigned long longdelay_ms = 100;
278
279 /* We want a long delay occasionally to force massive contention. */
280 if (!(torture_random(trsp) %
281 (nrealwriters_stress * 2000 * longdelay_ms)))
282 mdelay(longdelay_ms * 10);
283 else
284 mdelay(longdelay_ms / 10);
285#ifdef CONFIG_PREEMPT
286 if (!(torture_random(trsp) % (nrealwriters_stress * 20000)))
287 preempt_schedule(); /* Allow test to be preempted. */
288#endif
289}
290
291static void torture_rwsem_up_write(void) __releases(torture_rwsem)
292{
293 up_write(&torture_rwsem);
294}
295
296static int torture_rwsem_down_read(void) __acquires(torture_rwsem)
297{
298 down_read(&torture_rwsem);
299 return 0;
300}
301
302static void torture_rwsem_read_delay(struct torture_random_state *trsp)
303{
304 const unsigned long longdelay_ms = 100;
305
306 /* We want a long delay occasionally to force massive contention. */
307 if (!(torture_random(trsp) %
308 (nrealwriters_stress * 2000 * longdelay_ms)))
309 mdelay(longdelay_ms * 2);
310 else
311 mdelay(longdelay_ms / 2);
312#ifdef CONFIG_PREEMPT
313 if (!(torture_random(trsp) % (nrealreaders_stress * 20000)))
314 preempt_schedule(); /* Allow test to be preempted. */
315#endif
316}
317
318static void torture_rwsem_up_read(void) __releases(torture_rwsem)
319{
320 up_read(&torture_rwsem);
321}
322
323static struct lock_torture_ops rwsem_lock_ops = {
324 .writelock = torture_rwsem_down_write,
325 .write_delay = torture_rwsem_write_delay,
326 .writeunlock = torture_rwsem_up_write,
327 .readlock = torture_rwsem_down_read,
328 .read_delay = torture_rwsem_read_delay,
329 .readunlock = torture_rwsem_up_read,
330 .name = "rwsem_lock"
331};
332
268/* 333/*
269 * Lock torture writer kthread. Repeatedly acquires and releases 334 * Lock torture writer kthread. Repeatedly acquires and releases
270 * the lock, checking for duplicate acquisitions. 335 * the lock, checking for duplicate acquisitions.
@@ -467,7 +532,8 @@ static int __init lock_torture_init(void)
467 int i, j; 532 int i, j;
468 int firsterr = 0; 533 int firsterr = 0;
469 static struct lock_torture_ops *torture_ops[] = { 534 static struct lock_torture_ops *torture_ops[] = {
470 &lock_busted_ops, &spin_lock_ops, &spin_lock_irq_ops, &mutex_lock_ops, 535 &lock_busted_ops, &spin_lock_ops, &spin_lock_irq_ops,
536 &mutex_lock_ops, &rwsem_lock_ops,
471 }; 537 };
472 538
473 if (!torture_init_begin(torture_type, verbose, &torture_runnable)) 539 if (!torture_init_begin(torture_type, verbose, &torture_runnable))