locking/locktorture: Fix num reader/writer corner cases
authorDavidlohr Bueso <dave@stgolabs.net>
Mon, 15 May 2017 09:07:23 +0000 (02:07 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 19 Mar 2018 07:42:56 +0000 (08:42 +0100)
[ Upstream commit 2ce77d16db4240dd2e422fc0a5c26d3e2ec03446 ]

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>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
kernel/locking/locktorture.c

index f24582d..6dca260 100644 (file)
@@ -715,8 +715,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;
@@ -823,7 +822,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) {
@@ -898,6 +897,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();
 
@@ -921,17 +927,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) {
@@ -948,19 +956,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;
+                       }
                }
        }
 
@@ -990,12 +1000,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) {