[DTrace-devel] [PATCH v4] fixup! proc: rip out waitfd() and hit waitpidding thread with a signal instead
Nick Alcock
nick.alcock at oracle.com
Wed Oct 25 14:07:31 UTC 2023
On 25 Oct 2023, Kris Van Hees verbalised:
> On Mon, Oct 23, 2023 at 04:25:06PM +0100, Nick Alcock via DTrace-devel wrote:
>> /*
>> * These are lint comments with no compiler equivalent.
>> diff --git a/libproc/Pcontrol.c b/libproc/Pcontrol.c
>> index 371b547c5e07b..79bcb5c24d34c 100644
>> --- a/libproc/Pcontrol.c
>> +++ b/libproc/Pcontrol.c
>> @@ -691,11 +691,13 @@ Pwait_internal(struct ps_prochandle *P, boolean_t block, int *return_early)
>> * unlock again to minimize the size of the race window in which
>> * the signal might hit before waitpid() starts.)
>> */
>> + _dt_barrier_(*return_early);
>> if (return_early && *return_early > 0) {
>
> Um??? So, if return_early is NULL, that barier expression is really going
> to pose a problem, right? Like, SEGV? Surely you need to check whether
> return_early is NULL before doing the barrier here (and below).
Uh, right. I pushed the wrong commit, sorry!
Obvious fix:
>From 6dcbe39e636ed1bd8132e2861b26eeeea1638546 Mon Sep 17 00:00:00 2001
From: Nick Alcock <nick.alcock at oracle.com>
Date: Mon, 23 Oct 2023 13:49:36 +0100
Subject: [PATCH v4] fixup! proc: rip out waitfd() and hit waitpidding thread
with a signal instead
Introduce and use a compiler barrier to prevent use of return_early's
dereferent from being moved around.
We want this to be right next to the call to waitpid(): if the compiler
moves it up, it widens a race window, and if it moves it down, it makes it
useless.
Introduce a compiler barrier to make sure it does neither of these things.
---
include/sys/compiler.h | 4 +++-
libproc/Pcontrol.c | 2 ++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/sys/compiler.h b/include/sys/compiler.h
index c3ffccfc0f9e0..82066e5e48d5f 100644
--- a/include/sys/compiler.h
+++ b/include/sys/compiler.h
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
@@ -38,6 +38,7 @@
#define _dt_unused_ __attribute__((__unused__))
#define _dt_noreturn_ __attribute__((__noreturn__))
#define _dt_unlikely_(x) __builtin_expect((x),0)
+#define _dt_barrier_(x) __asm__ __volatile__("": :"r"(x):"memory")
#elif defined (__SUNPRO_C)
@@ -45,6 +46,7 @@
#define _dt_destructor_(x) _Pragma("fini(" #x ")")
#define _dt_noreturn_
#define _dt_unlikely_(x) (x)
+#define _dt_barrier_(x)
/*
* These are lint comments with no compiler equivalent.
diff --git a/libproc/Pcontrol.c b/libproc/Pcontrol.c
index 371b547c5e07b..97735c848cf84 100644
--- a/libproc/Pcontrol.c
+++ b/libproc/Pcontrol.c
@@ -691,11 +691,13 @@ Pwait_internal(struct ps_prochandle *P, boolean_t block, int *return_early)
* unlock again to minimize the size of the race window in which
* the signal might hit before waitpid() starts.)
*/
+ _dt_barrier_(return_early);
if (return_early && *return_early > 0) {
if (block && waitpid_lock_hook)
waitpid_lock_hook(P, P->wrap_arg, 0);
return 0;
}
+ _dt_barrier_(return_early);
err = waitpid(P->pid, &status, __WALL | (!block ? WNOHANG : 0));
base-commit: cb3a9e81efd9d4fbc413b9427f86af079b5faab6
prerequisite-patch-id: ce4dfaceb9baa012a354643f839cc413de5fd9d9
prerequisite-patch-id: b525e5cb144cc160e18531916c8e4bba2666a39a
--
2.42.0.271.g85384428f1
More information about the DTrace-devel
mailing list