| .. | .. | 
|---|
 | 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 |   */ | 
|---|
| .. | .. | 
|---|
| 44 | 31 |  #include <linux/torture.h> | 
|---|
| 45 | 32 |   | 
|---|
| 46 | 33 |  MODULE_LICENSE("GPL"); | 
|---|
| 47 |  | -MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com>");  | 
|---|
 | 34 | +MODULE_AUTHOR("Paul E. McKenney <paulmck@linux.ibm.com>");  | 
|---|
| 48 | 35 |   | 
|---|
| 49 | 36 |  torture_param(int, nwriters_stress, -1, | 
|---|
| 50 | 37 |  	     "Number of write-locking stress-test threads"); | 
|---|
| .. | .. | 
|---|
| 449 | 436 |   | 
|---|
| 450 | 437 |  static void torture_rtmutex_boost(struct torture_random_state *trsp) | 
|---|
| 451 | 438 |  { | 
|---|
| 452 |  | -	int policy;  | 
|---|
| 453 |  | -	struct sched_param param;  | 
|---|
| 454 | 439 |  	const unsigned int factor = 50000; /* yes, quite arbitrary */ | 
|---|
| 455 | 440 |   | 
|---|
| 456 | 441 |  	if (!rt_task(current)) { | 
|---|
| .. | .. | 
|---|
| 461 | 446 |  		 */ | 
|---|
| 462 | 447 |  		if (trsp && !(torture_random(trsp) % | 
|---|
| 463 | 448 |  			      (cxt.nrealwriters_stress * factor))) { | 
|---|
| 464 |  | -			policy = SCHED_FIFO;  | 
|---|
| 465 |  | -			param.sched_priority = MAX_RT_PRIO - 1;  | 
|---|
 | 449 | +			sched_set_fifo(current);  | 
|---|
| 466 | 450 |  		} else /* common case, do nothing */ | 
|---|
| 467 | 451 |  			return; | 
|---|
| 468 | 452 |  	} else { | 
|---|
| .. | .. | 
|---|
| 475 | 459 |  		 */ | 
|---|
| 476 | 460 |  		if (!trsp || !(torture_random(trsp) % | 
|---|
| 477 | 461 |  			       (cxt.nrealwriters_stress * factor * 2))) { | 
|---|
| 478 |  | -			policy = SCHED_NORMAL;  | 
|---|
| 479 |  | -			param.sched_priority = 0;  | 
|---|
 | 462 | +			sched_set_normal(current, 0);  | 
|---|
| 480 | 463 |  		} else /* common case, do nothing */ | 
|---|
| 481 | 464 |  			return; | 
|---|
| 482 | 465 |  	} | 
|---|
| 483 |  | -  | 
|---|
| 484 |  | -	sched_setscheduler_nocheck(current, policy, ¶m);  | 
|---|
| 485 | 466 |  } | 
|---|
| 486 | 467 |   | 
|---|
| 487 | 468 |  static void torture_rtmutex_delay(struct torture_random_state *trsp) | 
|---|
| .. | .. | 
|---|
| 585 | 566 |  #include <linux/percpu-rwsem.h> | 
|---|
| 586 | 567 |  static struct percpu_rw_semaphore pcpu_rwsem; | 
|---|
| 587 | 568 |   | 
|---|
| 588 |  | -void torture_percpu_rwsem_init(void)  | 
|---|
 | 569 | +static void torture_percpu_rwsem_init(void)  | 
|---|
| 589 | 570 |  { | 
|---|
| 590 | 571 |  	BUG_ON(percpu_init_rwsem(&pcpu_rwsem)); | 
|---|
| 591 | 572 |  } | 
|---|
| .. | .. | 
|---|
| 631 | 612 |  static int lock_torture_writer(void *arg) | 
|---|
| 632 | 613 |  { | 
|---|
| 633 | 614 |  	struct lock_stress_stats *lwsp = arg; | 
|---|
| 634 |  | -	static DEFINE_TORTURE_RANDOM(rand);  | 
|---|
 | 615 | +	DEFINE_TORTURE_RANDOM(rand);  | 
|---|
| 635 | 616 |   | 
|---|
| 636 | 617 |  	VERBOSE_TOROUT_STRING("lock_torture_writer task started"); | 
|---|
| 637 | 618 |  	set_user_nice(current, MAX_NICE); | 
|---|
| .. | .. | 
|---|
| 644 | 625 |  		cxt.cur_ops->writelock(); | 
|---|
| 645 | 626 |  		if (WARN_ON_ONCE(lock_is_write_held)) | 
|---|
| 646 | 627 |  			lwsp->n_lock_fail++; | 
|---|
| 647 |  | -		lock_is_write_held = 1;  | 
|---|
 | 628 | +		lock_is_write_held = true;  | 
|---|
| 648 | 629 |  		if (WARN_ON_ONCE(lock_is_read_held)) | 
|---|
| 649 | 630 |  			lwsp->n_lock_fail++; /* rare, but... */ | 
|---|
| 650 | 631 |   | 
|---|
| 651 | 632 |  		lwsp->n_lock_acquired++; | 
|---|
| 652 | 633 |  		cxt.cur_ops->write_delay(&rand); | 
|---|
| 653 |  | -		lock_is_write_held = 0;  | 
|---|
 | 634 | +		lock_is_write_held = false;  | 
|---|
| 654 | 635 |  		cxt.cur_ops->writeunlock(); | 
|---|
| 655 | 636 |   | 
|---|
| 656 | 637 |  		stutter_wait("lock_torture_writer"); | 
|---|
| .. | .. | 
|---|
| 668 | 649 |  static int lock_torture_reader(void *arg) | 
|---|
| 669 | 650 |  { | 
|---|
| 670 | 651 |  	struct lock_stress_stats *lrsp = arg; | 
|---|
| 671 |  | -	static DEFINE_TORTURE_RANDOM(rand);  | 
|---|
 | 652 | +	DEFINE_TORTURE_RANDOM(rand);  | 
|---|
| 672 | 653 |   | 
|---|
| 673 | 654 |  	VERBOSE_TOROUT_STRING("lock_torture_reader task started"); | 
|---|
| 674 | 655 |  	set_user_nice(current, MAX_NICE); | 
|---|
| .. | .. | 
|---|
| 678 | 659 |  			schedule_timeout_uninterruptible(1); | 
|---|
| 679 | 660 |   | 
|---|
| 680 | 661 |  		cxt.cur_ops->readlock(); | 
|---|
| 681 |  | -		lock_is_read_held = 1;  | 
|---|
 | 662 | +		lock_is_read_held = true;  | 
|---|
| 682 | 663 |  		if (WARN_ON_ONCE(lock_is_write_held)) | 
|---|
| 683 | 664 |  			lrsp->n_lock_fail++; /* rare, but... */ | 
|---|
| 684 | 665 |   | 
|---|
| 685 | 666 |  		lrsp->n_lock_acquired++; | 
|---|
| 686 | 667 |  		cxt.cur_ops->read_delay(&rand); | 
|---|
| 687 |  | -		lock_is_read_held = 0;  | 
|---|
 | 668 | +		lock_is_read_held = false;  | 
|---|
| 688 | 669 |  		cxt.cur_ops->readunlock(); | 
|---|
| 689 | 670 |   | 
|---|
| 690 | 671 |  		stutter_wait("lock_torture_reader"); | 
|---|
| .. | .. | 
|---|
| 699 | 680 |  static void __torture_print_stats(char *page, | 
|---|
| 700 | 681 |  				  struct lock_stress_stats *statp, bool write) | 
|---|
| 701 | 682 |  { | 
|---|
| 702 |  | -	bool fail = 0;  | 
|---|
 | 683 | +	bool fail = false;  | 
|---|
| 703 | 684 |  	int i, n_stress; | 
|---|
| 704 | 685 |  	long max = 0, min = statp ? statp[0].n_lock_acquired : 0; | 
|---|
| 705 | 686 |  	long long sum = 0; | 
|---|
| .. | .. | 
|---|
| 717 | 698 |  	page += sprintf(page, | 
|---|
| 718 | 699 |  			"%s:  Total: %lld  Max/Min: %ld/%ld %s  Fail: %d %s\n", | 
|---|
| 719 | 700 |  			write ? "Writes" : "Reads ", | 
|---|
| 720 |  | -			sum, max, min, max / 2 > min ? "???" : "",  | 
|---|
 | 701 | +			sum, max, min,  | 
|---|
 | 702 | +			!onoff_interval && max / 2 > min ? "???" : "",  | 
|---|
| 721 | 703 |  			fail, fail ? "!!!" : ""); | 
|---|
| 722 | 704 |  	if (fail) | 
|---|
| 723 | 705 |  		atomic_inc(&cxt.n_lock_torture_errors); | 
|---|
| .. | .. | 
|---|
| 841 | 823 |  						"End of test: SUCCESS"); | 
|---|
| 842 | 824 |   | 
|---|
| 843 | 825 |  	kfree(cxt.lwsa); | 
|---|
 | 826 | +	cxt.lwsa = NULL;  | 
|---|
| 844 | 827 |  	kfree(cxt.lrsa); | 
|---|
 | 828 | +	cxt.lrsa = NULL;  | 
|---|
| 845 | 829 |   | 
|---|
| 846 | 830 |  end: | 
|---|
| 847 | 831 |  	torture_cleanup_end(); | 
|---|
| .. | .. | 
|---|
| 899 | 883 |  		cxt.nrealwriters_stress = 2 * num_online_cpus(); | 
|---|
| 900 | 884 |   | 
|---|
| 901 | 885 |  #ifdef CONFIG_DEBUG_MUTEXES | 
|---|
| 902 |  | -	if (strncmp(torture_type, "mutex", 5) == 0)  | 
|---|
 | 886 | +	if (str_has_prefix(torture_type, "mutex"))  | 
|---|
| 903 | 887 |  		cxt.debug_lock = true; | 
|---|
| 904 | 888 |  #endif | 
|---|
| 905 | 889 |  #ifdef CONFIG_DEBUG_RT_MUTEXES | 
|---|
| 906 |  | -	if (strncmp(torture_type, "rtmutex", 7) == 0)  | 
|---|
 | 890 | +	if (str_has_prefix(torture_type, "rtmutex"))  | 
|---|
| 907 | 891 |  		cxt.debug_lock = true; | 
|---|
| 908 | 892 |  #endif | 
|---|
| 909 | 893 |  #ifdef CONFIG_DEBUG_SPINLOCK | 
|---|
| 910 |  | -	if ((strncmp(torture_type, "spin", 4) == 0) ||  | 
|---|
| 911 |  | -	    (strncmp(torture_type, "rw_lock", 7) == 0))  | 
|---|
 | 894 | +	if ((str_has_prefix(torture_type, "spin")) ||  | 
|---|
 | 895 | +	    (str_has_prefix(torture_type, "rw_lock")))  | 
|---|
| 912 | 896 |  		cxt.debug_lock = true; | 
|---|
| 913 | 897 |  #endif | 
|---|
| 914 | 898 |   | 
|---|
| 915 | 899 |  	/* Initialize the statistics so that each run gets its own numbers. */ | 
|---|
| 916 | 900 |  	if (nwriters_stress) { | 
|---|
| 917 |  | -		lock_is_write_held = 0;  | 
|---|
 | 901 | +		lock_is_write_held = false;  | 
|---|
| 918 | 902 |  		cxt.lwsa = kmalloc_array(cxt.nrealwriters_stress, | 
|---|
| 919 | 903 |  					 sizeof(*cxt.lwsa), | 
|---|
| 920 | 904 |  					 GFP_KERNEL); | 
|---|
| .. | .. | 
|---|
| 945 | 929 |  		} | 
|---|
| 946 | 930 |   | 
|---|
| 947 | 931 |  		if (nreaders_stress) { | 
|---|
| 948 |  | -			lock_is_read_held = 0;  | 
|---|
 | 932 | +			lock_is_read_held = false;  | 
|---|
| 949 | 933 |  			cxt.lrsa = kmalloc_array(cxt.nrealreaders_stress, | 
|---|
| 950 | 934 |  						 sizeof(*cxt.lrsa), | 
|---|
| 951 | 935 |  						 GFP_KERNEL); | 
|---|
| .. | .. | 
|---|
| 969 | 953 |  	/* Prepare torture context. */ | 
|---|
| 970 | 954 |  	if (onoff_interval > 0) { | 
|---|
| 971 | 955 |  		firsterr = torture_onoff_init(onoff_holdoff * HZ, | 
|---|
| 972 |  | -					      onoff_interval * HZ);  | 
|---|
 | 956 | +					      onoff_interval * HZ, NULL);  | 
|---|
| 973 | 957 |  		if (firsterr) | 
|---|
| 974 | 958 |  			goto unwind; | 
|---|
| 975 | 959 |  	} | 
|---|
| .. | .. | 
|---|
| 985 | 969 |  			goto unwind; | 
|---|
| 986 | 970 |  	} | 
|---|
| 987 | 971 |  	if (stutter > 0) { | 
|---|
| 988 |  | -		firsterr = torture_stutter_init(stutter);  | 
|---|
 | 972 | +		firsterr = torture_stutter_init(stutter, stutter);  | 
|---|
| 989 | 973 |  		if (firsterr) | 
|---|
| 990 | 974 |  			goto unwind; | 
|---|
| 991 | 975 |  	} | 
|---|