[PATCH 3/3] rt-tests: pi_stress: Remove racy state variables that cause watchdog to trigger

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When using pthread_barrier_wait, it is important that barriers are called
the correct number of times. That is - the same number given as the count
when initializing the barrier.

There was a do-while loop around elevate_barrier in the med priority thread.
On most machines, it actually never looped.

On threads with enough processors (nehalem for example), there was a racy
situation in which the high priority thread could come out of the finish
barrier, and before it could set high_has_run = 0, the medium priority
thread would test the value and call the elevate barrier an extra time.

This patch removes the bogus loop and related state variables and fixes
the hang.

Signed-off-by: John Kacur <jkacur@xxxxxxxxxx>
---
 src/pi_tests/pi_stress.c |   22 +++++++---------------
 1 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/src/pi_tests/pi_stress.c b/src/pi_tests/pi_stress.c
index f4b43ed..6f1a309 100644
--- a/src/pi_tests/pi_stress.c
+++ b/src/pi_tests/pi_stress.c
@@ -201,8 +201,6 @@ struct group_parameters {
 	int loop;	/* boolean, loop or not, connected to shutdown */
 
 	/* state variables */
-	volatile int high_has_run;
-	volatile int low_unlocked;
 	volatile int watchdog;
 
 	/* total number of inversions performed */
@@ -703,7 +701,6 @@ void *low_priority(void *arg)
 		}
 		/* wait for priority boost */
 		debug("low_priority[%d]: entering elevated wait\n", p->id);
-		p->low_unlocked = 0;	/* prevent race with med_priority */
 		status = pthread_barrier_wait(&p->elevate_barrier);
 		if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
 			error
@@ -711,7 +708,6 @@ void *low_priority(void *arg)
 			     p->id, status);
 			return NULL;
 		}
-		p->low_unlocked = 1;
 
 		/* release the mutex */
 		debug("low_priority[%d]: unlocking mutex\n", p->id);
@@ -812,15 +808,12 @@ void *med_priority(void *arg)
 			return NULL;
 		}
 		debug("med_priority[%d]: entering elevate state\n", p->id);
-		do {
-			status = pthread_barrier_wait(&p->elevate_barrier);
-			if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
-				error
-				    ("med_priority[%d]: pthread_barrier_wait(elevate): %x",
-				     p->id, status);
-				return NULL;
-			}
-		} while (!p->high_has_run && !p->low_unlocked);
+		status = pthread_barrier_wait(&p->elevate_barrier);
+		if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
+			error ("med_priority[%d]: pthread_barrier_wait(elevate): %x", p->id, status);
+			return NULL;
+		}
+
 		debug("med_priority[%d]: entering finish state\n", p->id);
 		status = pthread_barrier_wait(&p->finish_barrier);
 		if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
@@ -906,7 +899,6 @@ void *high_priority(void *arg)
 			}
 			pthread_mutex_unlock(&shutdown_mtx);
 		}
-		p->high_has_run = 0;
 		debug("high_priority[%d]: entering start state (%d)\n", p->id,
 		      count++);
 		status = pthread_barrier_wait(&p->start_barrier);
@@ -928,7 +920,7 @@ void *high_priority(void *arg)
 		debug("high_priority[%d]: locking mutex\n", p->id);
 		pthread_mutex_lock(&p->mutex);
 		debug("high_priority[%d]: got mutex\n", p->id);
-		p->high_has_run = 1;
+
 		debug("high_priority[%d]: unlocking mutex\n", p->id);
 		pthread_mutex_unlock(&p->mutex);
 		debug("high_priority[%d]: entering finish state\n", p->id);
-- 
1.6.2.5

--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [RT Stable]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux