diff mbox series

syscalls/futex_waitv02: replace TST_THREAD_STATE_WAIT with repeated wake

Message ID 6bac7035adc2cfc8ab3800fe1d2d03223ec57ff5.1663662348.git.jstancek@redhat.com
State Changes Requested
Headers show
Series syscalls/futex_waitv02: replace TST_THREAD_STATE_WAIT with repeated wake | expand

Commit Message

Jan Stancek Sept. 20, 2022, 8:28 a.m. UTC
Same patch as for futex_waitv03. TST_THREAD_STATE_WAIT isn't reliable to
tell that it's safe to call futex_wake(). futex_wake() can be called
prematurely and return 0, which leaves other thread timing out.

Replace it with repeated futex_wake() until it fails or wakes at least 1 waiter.
Also extend timeout to 5 seconds to avoid false positives from systems with
high steal time (e.g. overloaded s390x host).

Signed-off-by: Jan Stancek <jstancek@redhat.com>
---
 .../kernel/syscalls/futex/futex_waitv02.c     | 26 +++++++++----------
 1 file changed, 12 insertions(+), 14 deletions(-)

Comments

Andrea Cervesato Sept. 20, 2022, 8:52 a.m. UTC | #1
Hi!

On 9/20/22 10:28, Jan Stancek wrote:
> Same patch as for futex_waitv03. TST_THREAD_STATE_WAIT isn't reliable to
> tell that it's safe to call futex_wake(). futex_wake() can be called
> prematurely and return 0, which leaves other thread timing out.
>
> Replace it with repeated futex_wake() until it fails or wakes at least 1 waiter.
> Also extend timeout to 5 seconds to avoid false positives from systems with
> high steal time (e.g. overloaded s390x host).
>
> Signed-off-by: Jan Stancek <jstancek@redhat.com>
> ---
>   .../kernel/syscalls/futex/futex_waitv02.c     | 26 +++++++++----------
>   1 file changed, 12 insertions(+), 14 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/futex/futex_waitv02.c b/testcases/kernel/syscalls/futex/futex_waitv02.c
> index 0a0e2b62075c..00cf0960808a 100644
> --- a/testcases/kernel/syscalls/futex/futex_waitv02.c
> +++ b/testcases/kernel/syscalls/futex/futex_waitv02.c
> @@ -50,19 +50,20 @@ static void setup(void)
>   	}
>   }
>   
> -static void *threaded(void *arg)
> +static void *threaded(LTP_ATTRIBUTE_UNUSED void *arg)
>   {
>   	struct futex_test_variants tv = futex_variant();
> -	int tid = *(int *)arg;
>   
> -	TST_THREAD_STATE_WAIT(tid, 'S', 0);
> -
> -	TEST(futex_wake(tv.fntype, (void *)(uintptr_t)waitv[numfutex - 1].uaddr,
> +	do {
> +		TEST(futex_wake(tv.fntype,
> +			(void *)(uintptr_t)waitv[numfutex - 1].uaddr,
>   			1, FUTEX_PRIVATE_FLAG));
> -	if (TST_RET < 0) {
> -		tst_brk(TBROK | TTERRNO,
> -			"futex_wake private returned: %ld", TST_RET);
> -	}
> +		if (TST_RET < 0) {
> +			tst_brk(TBROK | TTERRNO,
> +				"futex_wake private returned: %ld", TST_RET);
> +		}
> +		usleep(1000);
> +	} while (TST_RET < 1);
>   

Why not using TST_RETRY_FUNC macro instead?

     TST_RETRY_FUNC(futex_wake(tv.fntype, (void 
*)(uintptr_t)waitv[numfutex - 1].uaddr, 1, FUTEX_PRIVATE_FLAG), 
TST_RETVAL_GE0);

>   	return NULL;
>   }
> @@ -70,16 +71,13 @@ static void *threaded(void *arg)
>   static void run(void)
>   {
>   	struct timespec to;
> -	int tid;
>   	pthread_t t;
>   
> -	tid = tst_syscall(__NR_gettid);
> -
> -	SAFE_PTHREAD_CREATE(&t, NULL, threaded, (void *)&tid);
> +	SAFE_PTHREAD_CREATE(&t, NULL, threaded, NULL);
>   
>   	/* setting absolute timeout for futex2 */
>   	SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC, &to);
> -	to.tv_sec++;
> +	to.tv_sec += 5;
>   
>   	TEST(futex_waitv(waitv, numfutex, 0, &to, CLOCK_MONOTONIC));
>   	if (TST_RET < 0) {

--
Regards,
Andrea Cervesato
diff mbox series

Patch

diff --git a/testcases/kernel/syscalls/futex/futex_waitv02.c b/testcases/kernel/syscalls/futex/futex_waitv02.c
index 0a0e2b62075c..00cf0960808a 100644
--- a/testcases/kernel/syscalls/futex/futex_waitv02.c
+++ b/testcases/kernel/syscalls/futex/futex_waitv02.c
@@ -50,19 +50,20 @@  static void setup(void)
 	}
 }
 
-static void *threaded(void *arg)
+static void *threaded(LTP_ATTRIBUTE_UNUSED void *arg)
 {
 	struct futex_test_variants tv = futex_variant();
-	int tid = *(int *)arg;
 
-	TST_THREAD_STATE_WAIT(tid, 'S', 0);
-
-	TEST(futex_wake(tv.fntype, (void *)(uintptr_t)waitv[numfutex - 1].uaddr,
+	do {
+		TEST(futex_wake(tv.fntype,
+			(void *)(uintptr_t)waitv[numfutex - 1].uaddr,
 			1, FUTEX_PRIVATE_FLAG));
-	if (TST_RET < 0) {
-		tst_brk(TBROK | TTERRNO,
-			"futex_wake private returned: %ld", TST_RET);
-	}
+		if (TST_RET < 0) {
+			tst_brk(TBROK | TTERRNO,
+				"futex_wake private returned: %ld", TST_RET);
+		}
+		usleep(1000);
+	} while (TST_RET < 1);
 
 	return NULL;
 }
@@ -70,16 +71,13 @@  static void *threaded(void *arg)
 static void run(void)
 {
 	struct timespec to;
-	int tid;
 	pthread_t t;
 
-	tid = tst_syscall(__NR_gettid);
-
-	SAFE_PTHREAD_CREATE(&t, NULL, threaded, (void *)&tid);
+	SAFE_PTHREAD_CREATE(&t, NULL, threaded, NULL);
 
 	/* setting absolute timeout for futex2 */
 	SAFE_CLOCK_GETTIME(CLOCK_MONOTONIC, &to);
-	to.tv_sec++;
+	to.tv_sec += 5;
 
 	TEST(futex_waitv(waitv, numfutex, 0, &to, CLOCK_MONOTONIC));
 	if (TST_RET < 0) {