FILE
futex_requeue_pi_mismatched_ops.c
File preview with syntax highlighting.
linux-6.19.14/tools/testing/selftests/futex/functional/futex_requeue_pi_mismatched_ops.c
1// SPDX-License-Identifier: GPL-2.0-or-later 2/****************************************************************************** 3 * 4 * Copyright © International Business Machines Corp., 2009 5 * 6 * DESCRIPTION 7 * 1. Block a thread using FUTEX_WAIT 8 * 2. Attempt to use FUTEX_CMP_REQUEUE_PI on the futex from 1. 9 * 3. The kernel must detect the mismatch and return -EINVAL. 10 * 11 * AUTHOR 12 * Darren Hart <dvhart@linux.intel.com> 13 * 14 * HISTORY 15 * 2009-Nov-9: Initial version by Darren Hart <dvhart@linux.intel.com> 16 * 17 *****************************************************************************/ 18 19#include <errno.h> 20#include <getopt.h> 21#include <pthread.h> 22#include <stdio.h> 23#include <stdlib.h> 24#include <string.h> 25#include <time.h> 26 27#include "futextest.h" 28#include "kselftest_harness.h" 29 30futex_t f1 = FUTEX_INITIALIZER; 31futex_t f2 = FUTEX_INITIALIZER; 32int child_ret = 0; 33 34void *blocking_child(void *arg) 35{ 36 child_ret = futex_wait(&f1, f1, NULL, FUTEX_PRIVATE_FLAG); 37 if (child_ret < 0) { 38 child_ret = -errno; 39 ksft_exit_fail_msg("futex_wait\n"); 40 } 41 return (void *)&child_ret; 42} 43 44TEST(requeue_pi_mismatched_ops) 45{ 46 pthread_t child; 47 int ret; 48 49 if (pthread_create(&child, NULL, blocking_child, NULL)) 50 ksft_exit_fail_msg("pthread_create\n"); 51 52 /* Allow the child to block in the kernel. */ 53 sleep(1); 54 55 /* 56 * The kernel should detect the waiter did not setup the 57 * q->requeue_pi_key and return -EINVAL. If it does not, 58 * it likely gave the lock to the child, which is now hung 59 * in the kernel. 60 */ 61 ret = futex_cmp_requeue_pi(&f1, f1, &f2, 1, 0, FUTEX_PRIVATE_FLAG); 62 if (ret < 0) { 63 if (errno == EINVAL) { 64 /* 65 * The kernel correctly detected the mismatched 66 * requeue_pi target and aborted. Wake the child with 67 * FUTEX_WAKE. 68 */ 69 ret = futex_wake(&f1, 1, FUTEX_PRIVATE_FLAG); 70 if (ret == 1) 71 ret = 0; 72 else if (ret < 0) 73 ksft_exit_fail_msg("futex_wake\n"); 74 else 75 ksft_exit_fail_msg("futex_wake did not wake the child\n"); 76 } else { 77 ksft_exit_fail_msg("futex_cmp_requeue_pi\n"); 78 } 79 } else if (ret > 0) { 80 ksft_test_result_fail("futex_cmp_requeue_pi failed to detect the mismatch\n"); 81 } else { 82 ksft_exit_fail_msg("futex_cmp_requeue_pi found no waiters\n"); 83 } 84 85 pthread_join(child, NULL); 86 87 if (!ret && !child_ret) 88 ksft_test_result_pass("futex_requeue_pi_mismatched_ops passed\n"); 89 else 90 ksft_test_result_pass("futex_requeue_pi_mismatched_ops failed\n"); 91} 92 93TEST_HARNESS_MAIN
~/
Read-only file preview.