]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
locking/locktorture: Fix num reader/writer corner cases
authorDavidlohr Bueso <dave@stgolabs.net>
Mon, 15 May 2017 09:07:23 +0000 (02:07 -0700)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Mon, 11 Dec 2017 17:18:28 +0000 (09:18 -0800)
Things can explode for locktorture if the user does combinations
of nwriters_stress=0 nreaders_stress=0. Fix this by not assuming
we always want to torture writer threads.

Reported-by: Jeremy Linton <jeremy.linton@arm.com>
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Jeremy Linton <jeremy.linton@arm.com>
Tested-by: Jeremy Linton <jeremy.linton@arm.com>
kernel/locking/locktorture.c

index a307a79e6b0b97e8f84eb81d414b31dba23f1415..2a1fc2a58910e210ec73c1d046cea621efc181a1 100644 (file)
@@ -703,8 +703,7 @@ static void __torture_print_stats(char *page,
 {
        bool fail = 0;
        int i, n_stress;
-       long max = 0;
-       long min = statp[0].n_lock_acquired;
+       long max = 0, min = statp ? statp[0].n_lock_acquired : 0;
        long long sum = 0;
 
        n_stress = write ? cxt.nrealwriters_stress : cxt.nrealreaders_stress;
@@ -811,7 +810,7 @@ static void lock_torture_cleanup(void)
         * such, only perform the underlying torture-specific cleanups,
         * and avoid anything related to locktorture.
         */
-       if (!cxt.lwsa)
+       if (!cxt.lwsa && !cxt.lrsa)
                goto end;
 
        if (writer_tasks) {
@@ -886,6 +885,13 @@ static int __init lock_torture_init(void)
                firsterr = -EINVAL;
                goto unwind;
        }
+
+       if (nwriters_stress == 0 && nreaders_stress == 0) {
+               pr_alert("lock-torture: must run at least one locking thread\n");
+               firsterr = -EINVAL;
+               goto unwind;
+       }
+
        if (cxt.cur_ops->init)
                cxt.cur_ops->init();
 
@@ -909,17 +915,19 @@ static int __init lock_torture_init(void)
 #endif
 
        /* Initialize the statistics so that each run gets its own numbers. */
+       if (nwriters_stress) {
+               lock_is_write_held = 0;
+               cxt.lwsa = kmalloc(sizeof(*cxt.lwsa) * cxt.nrealwriters_stress, GFP_KERNEL);
+               if (cxt.lwsa == NULL) {
+                       VERBOSE_TOROUT_STRING("cxt.lwsa: Out of memory");
+                       firsterr = -ENOMEM;
+                       goto unwind;
+               }
 
-       lock_is_write_held = 0;
-       cxt.lwsa = kmalloc(sizeof(*cxt.lwsa) * cxt.nrealwriters_stress, GFP_KERNEL);
-       if (cxt.lwsa == NULL) {
-               VERBOSE_TOROUT_STRING("cxt.lwsa: Out of memory");
-               firsterr = -ENOMEM;
-               goto unwind;
-       }
-       for (i = 0; i < cxt.nrealwriters_stress; i++) {
-               cxt.lwsa[i].n_lock_fail = 0;
-               cxt.lwsa[i].n_lock_acquired = 0;
+               for (i = 0; i < cxt.nrealwriters_stress; i++) {
+                       cxt.lwsa[i].n_lock_fail = 0;
+                       cxt.lwsa[i].n_lock_acquired = 0;
+               }
        }
 
        if (cxt.cur_ops->readlock) {
@@ -936,19 +944,21 @@ static int __init lock_torture_init(void)
                        cxt.nrealreaders_stress = cxt.nrealwriters_stress;
                }
 
-               lock_is_read_held = 0;
-               cxt.lrsa = kmalloc(sizeof(*cxt.lrsa) * cxt.nrealreaders_stress, GFP_KERNEL);
-               if (cxt.lrsa == NULL) {
-                       VERBOSE_TOROUT_STRING("cxt.lrsa: Out of memory");
-                       firsterr = -ENOMEM;
-                       kfree(cxt.lwsa);
-                       cxt.lwsa = NULL;
-                       goto unwind;
-               }
-
-               for (i = 0; i < cxt.nrealreaders_stress; i++) {
-                       cxt.lrsa[i].n_lock_fail = 0;
-                       cxt.lrsa[i].n_lock_acquired = 0;
+               if (nreaders_stress) {
+                       lock_is_read_held = 0;
+                       cxt.lrsa = kmalloc(sizeof(*cxt.lrsa) * cxt.nrealreaders_stress, GFP_KERNEL);
+                       if (cxt.lrsa == NULL) {
+                               VERBOSE_TOROUT_STRING("cxt.lrsa: Out of memory");
+                               firsterr = -ENOMEM;
+                               kfree(cxt.lwsa);
+                               cxt.lwsa = NULL;
+                               goto unwind;
+                       }
+
+                       for (i = 0; i < cxt.nrealreaders_stress; i++) {
+                               cxt.lrsa[i].n_lock_fail = 0;
+                               cxt.lrsa[i].n_lock_acquired = 0;
+                       }
                }
        }
 
@@ -978,12 +988,14 @@ static int __init lock_torture_init(void)
                        goto unwind;
        }
 
-       writer_tasks = kzalloc(cxt.nrealwriters_stress * sizeof(writer_tasks[0]),
-                              GFP_KERNEL);
-       if (writer_tasks == NULL) {
-               VERBOSE_TOROUT_ERRSTRING("writer_tasks: Out of memory");
-               firsterr = -ENOMEM;
-               goto unwind;
+       if (nwriters_stress) {
+               writer_tasks = kzalloc(cxt.nrealwriters_stress * sizeof(writer_tasks[0]),
+                                      GFP_KERNEL);
+               if (writer_tasks == NULL) {
+                       VERBOSE_TOROUT_ERRSTRING("writer_tasks: Out of memory");
+                       firsterr = -ENOMEM;
+                       goto unwind;
+               }
        }
 
        if (cxt.cur_ops->readlock) {