From patchwork Sat Apr 6 15:09:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleg Nesterov X-Patchwork-Id: 13619852 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CBEE120314 for ; Sat, 6 Apr 2024 15:11:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712416309; cv=none; b=JEAzt7unUkXKTA8zQjCDzgxZTHetF6Zgj1qyrA1eTvV1GNtanTjTnXKzfWNqyCyUBFPJMJbsXd5qhvcS6sgTKCEBkwmYevo5G980zJQAEXqM5k3jCv9r7/g5zjGJy94m4CPZ6sk8UHbr57UOq0te506iWAHow+9Nchxh1I0C6ec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712416309; c=relaxed/simple; bh=m7FZIiwrd7YEBY/n2UxCR55958qoIAOrRTaYULHViHY=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=s4+GJh0xhTwMBfQiCG8DGxYU8q2GbfKtOodOPYuVuAsPbQQO0fPsSy3v3vuxhrrTbTWhnw+KzBi2l+5XZUw174kXsx4SJQDPRVQYGepve41iMxTbB/feTIyQcxcuVIks/2QIzCL20JKD4P+lJrrzXp3TYIxh3Jh+US5eJHLDiPI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-505-8qpYagkzMxSV1T4VL2nekg-1; Sat, 06 Apr 2024 11:11:40 -0400 X-MC-Unique: 8qpYagkzMxSV1T4VL2nekg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id F348128AC1E7; Sat, 6 Apr 2024 15:11:39 +0000 (UTC) Received: from dhcp-27-174.brq.redhat.com (unknown [10.45.226.136]) by smtp.corp.redhat.com (Postfix) with SMTP id 0E9593C20; Sat, 6 Apr 2024 15:11:36 +0000 (UTC) Received: by dhcp-27-174.brq.redhat.com (nbSMTP-1.00) for uid 1000 oleg@redhat.com; Sat, 6 Apr 2024 17:10:15 +0200 (CEST) Date: Sat, 6 Apr 2024 17:09:51 +0200 From: Oleg Nesterov To: Thomas Gleixner Cc: John Stultz , Marco Elver , Peter Zijlstra , Ingo Molnar , "Eric W. Biederman" , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Dmitry Vyukov , kasan-dev@googlegroups.com, Edward Liaw , Carlos Llamas , Greg Kroah-Hartman Subject: [PATCH] selftests/timers/posix_timers: reimplement check_timer_distribution() Message-ID: <20240406150950.GA3060@redhat.com> References: <87sf02bgez.ffs@tglx> <87r0fmbe65.ffs@tglx> <87o7aqb6uw.ffs@tglx> <87frw2axv0.ffs@tglx> <20240404145408.GD7153@redhat.com> <87le5t9f14.ffs@tglx> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <87le5t9f14.ffs@tglx> User-Agent: Mutt/1.5.24 (2015-08-30) X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.1 Thomas says: The signal distribution test has a tendency to hang for a long time as the signal delivery is not really evenly distributed. In fact it might never be distributed across all threads ever in the way it is written. To me even the This primarily tests that the kernel does not favour any one. comment doesn't look right. The kernel does favour a thread which hits the timer interrupt when CLOCK_PROCESS_CPUTIME_ID expires. The new version simply checks that the group leader sleeping in join() never receives SIGALRM, cpu_timer_fire() should always send the signal to the thread which burns cpu. Without the commit bcb7ee79029d ("posix-timers: Prefer delivery of signals to the current thread") the test-case fails immediately, the very 1st tick wakes the leader up. Otherwise it quickly succeeds after 100 ticks. Signed-off-by: Oleg Nesterov --- tools/testing/selftests/timers/posix_timers.c | 102 ++++++++---------- 1 file changed, 46 insertions(+), 56 deletions(-) diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c index d49dd3ffd0d9..2586a6552737 100644 --- a/tools/testing/selftests/timers/posix_timers.c +++ b/tools/testing/selftests/timers/posix_timers.c @@ -184,80 +184,70 @@ static int check_timer_create(int which) return 0; } -int remain; -__thread int got_signal; +static pthread_t ctd_thread; +static volatile int ctd_count, ctd_failed; -static void *distribution_thread(void *arg) +static void ctd_sighandler(int sig) { - while (__atomic_load_n(&remain, __ATOMIC_RELAXED)); - return NULL; + if (pthread_self() != ctd_thread) + ctd_failed = 1; + ctd_count--; } -static void distribution_handler(int nr) +static void *ctd_thread_func(void *arg) { - if (!__atomic_exchange_n(&got_signal, 1, __ATOMIC_RELAXED)) - __atomic_fetch_sub(&remain, 1, __ATOMIC_RELAXED); -} - -/* - * Test that all running threads _eventually_ receive CLOCK_PROCESS_CPUTIME_ID - * timer signals. This primarily tests that the kernel does not favour any one. - */ -static int check_timer_distribution(void) -{ - int err, i; - timer_t id; - const int nthreads = 10; - pthread_t threads[nthreads]; struct itimerspec val = { .it_value.tv_sec = 0, .it_value.tv_nsec = 1000 * 1000, .it_interval.tv_sec = 0, .it_interval.tv_nsec = 1000 * 1000, }; + timer_t id; - remain = nthreads + 1; /* worker threads + this thread */ - signal(SIGALRM, distribution_handler); - err = timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &id); - if (err < 0) { - ksft_perror("Can't create timer"); - return -1; - } - err = timer_settime(id, 0, &val, NULL); - if (err < 0) { - ksft_perror("Can't set timer"); - return -1; - } + /* 1/10 seconds to ensure the leader sleeps */ + usleep(10000); - for (i = 0; i < nthreads; i++) { - err = pthread_create(&threads[i], NULL, distribution_thread, - NULL); - if (err) { - ksft_print_msg("Can't create thread: %s (%d)\n", - strerror(errno), errno); - return -1; - } - } + ctd_count = 100; + if (timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &id)) + return "Can't create timer"; + if (timer_settime(id, 0, &val, NULL)) + return "Can't set timer"; - /* Wait for all threads to receive the signal. */ - while (__atomic_load_n(&remain, __ATOMIC_RELAXED)); + while (ctd_count > 0 && !ctd_failed) + ; - for (i = 0; i < nthreads; i++) { - err = pthread_join(threads[i], NULL); - if (err) { - ksft_print_msg("Can't join thread: %s (%d)\n", - strerror(errno), errno); - return -1; - } - } + if (timer_delete(id)) + return "Can't delete timer"; - if (timer_delete(id)) { - ksft_perror("Can't delete timer"); - return -1; - } + return NULL; +} + +/* + * Test that only the running thread receives the timer signal. + */ +static int check_timer_distribution(void) +{ + const char *errmsg; + + signal(SIGALRM, ctd_sighandler); + + errmsg = "Can't create thread"; + if (pthread_create(&ctd_thread, NULL, ctd_thread_func, NULL)) + goto err; + + errmsg = "Can't join thread"; + if (pthread_join(ctd_thread, (void **)&errmsg) || errmsg) + goto err; + + if (ctd_failed) + ksft_test_result_skip("No signal distribution. Assuming old kernel\n"); + else + ksft_test_result_pass("check signal distribution\n"); - ksft_test_result_pass("check_timer_distribution\n"); return 0; +err: + ksft_print_msg(errmsg); + return -1; } int main(int argc, char **argv)