| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Module-based torture test facility for locking |
|---|
| 3 | 4 | * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 5 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 6 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 7 | | - * (at your option) any later version. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 12 | | - * GNU General Public License for more details. |
|---|
| 13 | | - * |
|---|
| 14 | | - * You should have received a copy of the GNU General Public License |
|---|
| 15 | | - * along with this program; if not, you can access it online at |
|---|
| 16 | | - * http://www.gnu.org/licenses/gpl-2.0.html. |
|---|
| 17 | | - * |
|---|
| 18 | 5 | * Copyright (C) IBM Corporation, 2014 |
|---|
| 19 | 6 | * |
|---|
| 20 | | - * Authors: Paul E. McKenney <paulmck@us.ibm.com> |
|---|
| 7 | + * Authors: Paul E. McKenney <paulmck@linux.ibm.com> |
|---|
| 21 | 8 | * Davidlohr Bueso <dave@stgolabs.net> |
|---|
| 22 | 9 | * Based on kernel/rcu/torture.c. |
|---|
| 23 | 10 | */ |
|---|
| .. | .. |
|---|
| 29 | 16 | #include <linux/kthread.h> |
|---|
| 30 | 17 | #include <linux/sched/rt.h> |
|---|
| 31 | 18 | #include <linux/spinlock.h> |
|---|
| 32 | | -#include <linux/rwlock.h> |
|---|
| 33 | 19 | #include <linux/mutex.h> |
|---|
| 34 | 20 | #include <linux/rwsem.h> |
|---|
| 35 | 21 | #include <linux/smp.h> |
|---|
| .. | .. |
|---|
| 45 | 31 | #include <linux/torture.h> |
|---|
| 46 | 32 | |
|---|
| 47 | 33 | MODULE_LICENSE("GPL"); |
|---|
| 48 | | -MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com>"); |
|---|
| 34 | +MODULE_AUTHOR("Paul E. McKenney <paulmck@linux.ibm.com>"); |
|---|
| 49 | 35 | |
|---|
| 50 | 36 | torture_param(int, nwriters_stress, -1, |
|---|
| 51 | 37 | "Number of write-locking stress-test threads"); |
|---|
| .. | .. |
|---|
| 450 | 436 | |
|---|
| 451 | 437 | static void torture_rtmutex_boost(struct torture_random_state *trsp) |
|---|
| 452 | 438 | { |
|---|
| 453 | | - int policy; |
|---|
| 454 | | - struct sched_param param; |
|---|
| 455 | 439 | const unsigned int factor = 50000; /* yes, quite arbitrary */ |
|---|
| 456 | 440 | |
|---|
| 457 | 441 | if (!rt_task(current)) { |
|---|
| .. | .. |
|---|
| 462 | 446 | */ |
|---|
| 463 | 447 | if (trsp && !(torture_random(trsp) % |
|---|
| 464 | 448 | (cxt.nrealwriters_stress * factor))) { |
|---|
| 465 | | - policy = SCHED_FIFO; |
|---|
| 466 | | - param.sched_priority = MAX_RT_PRIO - 1; |
|---|
| 449 | + sched_set_fifo(current); |
|---|
| 467 | 450 | } else /* common case, do nothing */ |
|---|
| 468 | 451 | return; |
|---|
| 469 | 452 | } else { |
|---|
| .. | .. |
|---|
| 476 | 459 | */ |
|---|
| 477 | 460 | if (!trsp || !(torture_random(trsp) % |
|---|
| 478 | 461 | (cxt.nrealwriters_stress * factor * 2))) { |
|---|
| 479 | | - policy = SCHED_NORMAL; |
|---|
| 480 | | - param.sched_priority = 0; |
|---|
| 462 | + sched_set_normal(current, 0); |
|---|
| 481 | 463 | } else /* common case, do nothing */ |
|---|
| 482 | 464 | return; |
|---|
| 483 | 465 | } |
|---|
| 484 | | - |
|---|
| 485 | | - sched_setscheduler_nocheck(current, policy, ¶m); |
|---|
| 486 | 466 | } |
|---|
| 487 | 467 | |
|---|
| 488 | 468 | static void torture_rtmutex_delay(struct torture_random_state *trsp) |
|---|
| .. | .. |
|---|
| 586 | 566 | #include <linux/percpu-rwsem.h> |
|---|
| 587 | 567 | static struct percpu_rw_semaphore pcpu_rwsem; |
|---|
| 588 | 568 | |
|---|
| 589 | | -void torture_percpu_rwsem_init(void) |
|---|
| 569 | +static void torture_percpu_rwsem_init(void) |
|---|
| 590 | 570 | { |
|---|
| 591 | 571 | BUG_ON(percpu_init_rwsem(&pcpu_rwsem)); |
|---|
| 592 | 572 | } |
|---|
| .. | .. |
|---|
| 632 | 612 | static int lock_torture_writer(void *arg) |
|---|
| 633 | 613 | { |
|---|
| 634 | 614 | struct lock_stress_stats *lwsp = arg; |
|---|
| 635 | | - static DEFINE_TORTURE_RANDOM(rand); |
|---|
| 615 | + DEFINE_TORTURE_RANDOM(rand); |
|---|
| 636 | 616 | |
|---|
| 637 | 617 | VERBOSE_TOROUT_STRING("lock_torture_writer task started"); |
|---|
| 638 | 618 | set_user_nice(current, MAX_NICE); |
|---|
| .. | .. |
|---|
| 645 | 625 | cxt.cur_ops->writelock(); |
|---|
| 646 | 626 | if (WARN_ON_ONCE(lock_is_write_held)) |
|---|
| 647 | 627 | lwsp->n_lock_fail++; |
|---|
| 648 | | - lock_is_write_held = 1; |
|---|
| 628 | + lock_is_write_held = true; |
|---|
| 649 | 629 | if (WARN_ON_ONCE(lock_is_read_held)) |
|---|
| 650 | 630 | lwsp->n_lock_fail++; /* rare, but... */ |
|---|
| 651 | 631 | |
|---|
| 652 | 632 | lwsp->n_lock_acquired++; |
|---|
| 653 | 633 | cxt.cur_ops->write_delay(&rand); |
|---|
| 654 | | - lock_is_write_held = 0; |
|---|
| 634 | + lock_is_write_held = false; |
|---|
| 655 | 635 | cxt.cur_ops->writeunlock(); |
|---|
| 656 | 636 | |
|---|
| 657 | 637 | stutter_wait("lock_torture_writer"); |
|---|
| .. | .. |
|---|
| 669 | 649 | static int lock_torture_reader(void *arg) |
|---|
| 670 | 650 | { |
|---|
| 671 | 651 | struct lock_stress_stats *lrsp = arg; |
|---|
| 672 | | - static DEFINE_TORTURE_RANDOM(rand); |
|---|
| 652 | + DEFINE_TORTURE_RANDOM(rand); |
|---|
| 673 | 653 | |
|---|
| 674 | 654 | VERBOSE_TOROUT_STRING("lock_torture_reader task started"); |
|---|
| 675 | 655 | set_user_nice(current, MAX_NICE); |
|---|
| .. | .. |
|---|
| 679 | 659 | schedule_timeout_uninterruptible(1); |
|---|
| 680 | 660 | |
|---|
| 681 | 661 | cxt.cur_ops->readlock(); |
|---|
| 682 | | - lock_is_read_held = 1; |
|---|
| 662 | + lock_is_read_held = true; |
|---|
| 683 | 663 | if (WARN_ON_ONCE(lock_is_write_held)) |
|---|
| 684 | 664 | lrsp->n_lock_fail++; /* rare, but... */ |
|---|
| 685 | 665 | |
|---|
| 686 | 666 | lrsp->n_lock_acquired++; |
|---|
| 687 | 667 | cxt.cur_ops->read_delay(&rand); |
|---|
| 688 | | - lock_is_read_held = 0; |
|---|
| 668 | + lock_is_read_held = false; |
|---|
| 689 | 669 | cxt.cur_ops->readunlock(); |
|---|
| 690 | 670 | |
|---|
| 691 | 671 | stutter_wait("lock_torture_reader"); |
|---|
| .. | .. |
|---|
| 700 | 680 | static void __torture_print_stats(char *page, |
|---|
| 701 | 681 | struct lock_stress_stats *statp, bool write) |
|---|
| 702 | 682 | { |
|---|
| 703 | | - bool fail = 0; |
|---|
| 683 | + bool fail = false; |
|---|
| 704 | 684 | int i, n_stress; |
|---|
| 705 | 685 | long max = 0, min = statp ? statp[0].n_lock_acquired : 0; |
|---|
| 706 | 686 | long long sum = 0; |
|---|
| .. | .. |
|---|
| 718 | 698 | page += sprintf(page, |
|---|
| 719 | 699 | "%s: Total: %lld Max/Min: %ld/%ld %s Fail: %d %s\n", |
|---|
| 720 | 700 | write ? "Writes" : "Reads ", |
|---|
| 721 | | - sum, max, min, max / 2 > min ? "???" : "", |
|---|
| 701 | + sum, max, min, |
|---|
| 702 | + !onoff_interval && max / 2 > min ? "???" : "", |
|---|
| 722 | 703 | fail, fail ? "!!!" : ""); |
|---|
| 723 | 704 | if (fail) |
|---|
| 724 | 705 | atomic_inc(&cxt.n_lock_torture_errors); |
|---|
| .. | .. |
|---|
| 842 | 823 | "End of test: SUCCESS"); |
|---|
| 843 | 824 | |
|---|
| 844 | 825 | kfree(cxt.lwsa); |
|---|
| 826 | + cxt.lwsa = NULL; |
|---|
| 845 | 827 | kfree(cxt.lrsa); |
|---|
| 828 | + cxt.lrsa = NULL; |
|---|
| 846 | 829 | |
|---|
| 847 | 830 | end: |
|---|
| 848 | 831 | torture_cleanup_end(); |
|---|
| .. | .. |
|---|
| 900 | 883 | cxt.nrealwriters_stress = 2 * num_online_cpus(); |
|---|
| 901 | 884 | |
|---|
| 902 | 885 | #ifdef CONFIG_DEBUG_MUTEXES |
|---|
| 903 | | - if (strncmp(torture_type, "mutex", 5) == 0) |
|---|
| 886 | + if (str_has_prefix(torture_type, "mutex")) |
|---|
| 904 | 887 | cxt.debug_lock = true; |
|---|
| 905 | 888 | #endif |
|---|
| 906 | 889 | #ifdef CONFIG_DEBUG_RT_MUTEXES |
|---|
| 907 | | - if (strncmp(torture_type, "rtmutex", 7) == 0) |
|---|
| 890 | + if (str_has_prefix(torture_type, "rtmutex")) |
|---|
| 908 | 891 | cxt.debug_lock = true; |
|---|
| 909 | 892 | #endif |
|---|
| 910 | 893 | #ifdef CONFIG_DEBUG_SPINLOCK |
|---|
| 911 | | - if ((strncmp(torture_type, "spin", 4) == 0) || |
|---|
| 912 | | - (strncmp(torture_type, "rw_lock", 7) == 0)) |
|---|
| 894 | + if ((str_has_prefix(torture_type, "spin")) || |
|---|
| 895 | + (str_has_prefix(torture_type, "rw_lock"))) |
|---|
| 913 | 896 | cxt.debug_lock = true; |
|---|
| 914 | 897 | #endif |
|---|
| 915 | 898 | |
|---|
| 916 | 899 | /* Initialize the statistics so that each run gets its own numbers. */ |
|---|
| 917 | 900 | if (nwriters_stress) { |
|---|
| 918 | | - lock_is_write_held = 0; |
|---|
| 901 | + lock_is_write_held = false; |
|---|
| 919 | 902 | cxt.lwsa = kmalloc_array(cxt.nrealwriters_stress, |
|---|
| 920 | 903 | sizeof(*cxt.lwsa), |
|---|
| 921 | 904 | GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 946 | 929 | } |
|---|
| 947 | 930 | |
|---|
| 948 | 931 | if (nreaders_stress) { |
|---|
| 949 | | - lock_is_read_held = 0; |
|---|
| 932 | + lock_is_read_held = false; |
|---|
| 950 | 933 | cxt.lrsa = kmalloc_array(cxt.nrealreaders_stress, |
|---|
| 951 | 934 | sizeof(*cxt.lrsa), |
|---|
| 952 | 935 | GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 970 | 953 | /* Prepare torture context. */ |
|---|
| 971 | 954 | if (onoff_interval > 0) { |
|---|
| 972 | 955 | firsterr = torture_onoff_init(onoff_holdoff * HZ, |
|---|
| 973 | | - onoff_interval * HZ); |
|---|
| 956 | + onoff_interval * HZ, NULL); |
|---|
| 974 | 957 | if (firsterr) |
|---|
| 975 | 958 | goto unwind; |
|---|
| 976 | 959 | } |
|---|
| .. | .. |
|---|
| 986 | 969 | goto unwind; |
|---|
| 987 | 970 | } |
|---|
| 988 | 971 | if (stutter > 0) { |
|---|
| 989 | | - firsterr = torture_stutter_init(stutter); |
|---|
| 972 | + firsterr = torture_stutter_init(stutter, stutter); |
|---|
| 990 | 973 | if (firsterr) |
|---|
| 991 | 974 | goto unwind; |
|---|
| 992 | 975 | } |
|---|