| From foo@baz Fri Mar 16 15:43:17 CET 2018 |
| From: Davidlohr Bueso <dave@stgolabs.net> |
| Date: Mon, 15 May 2017 02:07:23 -0700 |
| Subject: locking/locktorture: Fix num reader/writer corner cases |
| |
| From: Davidlohr Bueso <dave@stgolabs.net> |
| |
| |
| [ 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 | 76 ++++++++++++++++++++++++------------------- |
| 1 file changed, 44 insertions(+), 32 deletions(-) |
| |
| --- a/kernel/locking/locktorture.c |
| +++ b/kernel/locking/locktorture.c |
| @@ -715,8 +715,7 @@ static void __torture_print_stats(char * |
| { |
| 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) { |