[DTrace-devel] [PATCH 1/4] bpf: introduce atomic_add()
Eugene Loh
eugene.loh at oracle.com
Tue May 9 16:40:55 UTC 2023
Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
with usual comments/questions...
On 5/9/23 03:16, Kris Van Hees via DTrace-devel wrote:
> The GCC BPF support does not provide a way to emit an atomic add
> instruction (BPF xadd) without the fetch-flag. But since older
> kernels do not support xadd with the fetch flag, the generated
> BPF programs are rejected by the BPF verifier.
>
> The aotmic_add() macro emits a raw xadd instruction that works on
> all kernels.
aotmic
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
> bpf/speculation.c | 9 +++------
> include/bpf-lib.h | 27 ++++++++++++++++++++++++++-
> 2 files changed, 29 insertions(+), 7 deletions(-)
>
> diff --git a/bpf/speculation.c b/bpf/speculation.c
> index 90433753..0a19ac33 100644
> --- a/bpf/speculation.c
> +++ b/bpf/speculation.c
> @@ -1,10 +1,11 @@
> // SPDX-License-Identifier: GPL-2.0
> /*
> - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
> */
> #include <linux/bpf.h>
> #include <stdint.h>
> #include <bpf-helpers.h>
> +#include <bpf-lib.h>
> #include <dt_bpf_maps.h>
>
> #include <dtrace/faults_defines.h>
> @@ -96,11 +97,7 @@ dt_speculation_speculate(uint32_t id)
> if (spec->draining)
> return -1;
>
> - spec->written++;
> - /* Use atomics once GCC/binutils can emit them in forms that older
> - * kernels support:
> - * __atomic_add_fetch(&spec->written, 1, __ATOMIC_RELAXED);
> - */
> + atomic_add(&spec->written, 1);
> return 0;
> }
>
> diff --git a/include/bpf-lib.h b/include/bpf-lib.h
> index d7078da5..fc3fe4fa 100644
> --- a/include/bpf-lib.h
> +++ b/include/bpf-lib.h
> @@ -1,6 +1,6 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2021, 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.
> */
> @@ -61,5 +61,30 @@
> : /* no clobbers */ \
> );
>
> +/*
> + * Explicit inline assembler to implement atomic add:
> + *
> + * *ptr += val;
> + */
> +#define atomic_add(valp, val) \
> + do { \
> + register uint64_t *ptr asm("%r0") = (valp); \
> + register uint64_t tmp asm("%r1") = (val); \
> + asm (".byte 0xdb, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00" \
> + : /* no outputs */ \
> + : "r" (ptr), "r" (tmp) \
> + : "memory" \
> + ); \
> + } while (0)
> +#define atomic_add32(valp, val) \
> + do { \
> + register uint32_t *ptr asm("%r0") = (valp); \
> + register uint32_t tmp asm("%r1") = (val); \
> + asm (".byte 0xc3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00" \
> + : /* no outputs */ \
> + : "r" (ptr), "r" (tmp) \
> + : "memory" \
> + ); \
> + } while (0)
>
> #endif /* BPF_LIB_H */
It might be nice to have some comments. E.g.,
*) 0xdb==(BPF_XADD|BPF_DW|BPF_STX) and 0xc3==(BPF_XADD|BPF_W|BPF_STX)
*) iiuc, that %r0 and %r1 will be clobbered... is that a concern? (Or we
expect to get lucky? Or user beware?)
Also, BPF_XADD allows an offset to the pointer... worth adding that
generality? The focus on this patch is presumably adding xadd
functionality, which has an offset, and not the specific spec+=1 change,
which doesn't need it.
More information about the DTrace-devel
mailing list