[DTrace-devel] [PATCH] Replace dt_memcpy() with bpf_probe_read()
Kris Van Hees
kris.van.hees at oracle.com
Thu Aug 19 23:46:41 PDT 2021
The dt_memcpy() functionality can be provided by the bpf_probe_read()
helper. Thanks to Eugene Loh for pointing this out.
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
bpf/Build | 1 -
bpf/memcpy.c | 106 -------------------------------------------
libdtrace/dt_cg.c | 39 +++++++---------
libdtrace/dt_dlibs.c | 1 -
4 files changed, 17 insertions(+), 130 deletions(-)
delete mode 100644 bpf/memcpy.c
diff --git a/bpf/Build b/bpf/Build
index a436bc96..e08a28b6 100644
--- a/bpf/Build
+++ b/bpf/Build
@@ -25,7 +25,6 @@ bpf_dlib_SOURCES = \
agg_lqbin.c agg_qbin.c \
get_bvar.c \
get_tvar.c set_tvar.c \
- memcpy.c \
probe_error.c \
strnlen.c \
varint.c
diff --git a/bpf/memcpy.c b/bpf/memcpy.c
deleted file mode 100644
index 77c7463f..00000000
--- a/bpf/memcpy.c
+++ /dev/null
@@ -1,106 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
- */
-#include <stddef.h>
-#include <stdint.h>
-
-#ifndef noinline
-# define noinline __attribute__((noinline))
-#endif
-
-noinline int dt_memcpy_int(void *dst, const void *src, size_t n)
-{
- uint64_t *d = dst;
- const uint64_t *s = src;
- size_t q;
-
- if (n > 128)
- return -1;
-
- q = n / 8;
- switch (q) {
- case 16:
- d[15] = s[15];
- case 15:
- d[14] = s[14];
- case 14:
- d[13] = s[13];
- case 13:
- d[12] = s[12];
- case 12:
- d[11] = s[11];
- case 11:
- d[10] = s[10];
- case 10:
- d[9] = s[9];
- case 9:
- d[8] = s[8];
- case 8:
- d[7] = s[7];
- case 7:
- d[6] = s[6];
- case 6:
- d[5] = s[5];
- case 5:
- d[4] = s[4];
- case 4:
- d[3] = s[3];
- case 3:
- d[2] = s[2];
- case 2:
- d[1] = s[1];
- case 1:
- d[0] = s[0];
- }
-
- if ((n % 8) == 0)
- return 0;
-
- dst = &d[q];
- src = &s[q];
-
- if (n & 4) {
- *(uint32_t *)dst = *(uint32_t *)src;
- dst += 4;
- src += 4;
- }
- if (n & 2) {
- *(uint16_t *)dst = *(uint16_t *)src;
- dst += 2;
- src += 2;
- }
- if (n & 1)
- *(uint8_t *)dst = *(uint8_t *)src;
-
- return 0;
-}
-
-/*
- * Copy a byte sequence of length n from src to dst. The function returns 0
- * upon success and -1 when n is greater than 256. Both src and dst must be on
- * a 64-bit address boundary.
- *
- * The size (n) must be no more than 256.
- */
-noinline int dt_memcpy(void *dst, const void *src, size_t n)
-{
- uint64_t *d = dst;
- const uint64_t *s = src;
-
- if (n == 0)
- return 0;
- if (n > 256)
- n = 256;
-
- if (n > 128) {
- if (dt_memcpy_int(d, s, 128))
- return -1;
- n -= 128;
-
- d += 16;
- s += 16;
- }
-
- return dt_memcpy_int(d, s, n);
-}
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index be61b4b0..854816ec 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -725,17 +725,14 @@ dt_cg_fill_gap(dt_pcb_t *pcb, int gap)
static void
dt_cg_memcpy(dt_irlist_t *dlp, dt_regset_t *drp, int dst, int src, size_t size)
{
- dt_ident_t *idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_memcpy");
-
- assert(idp != NULL);
if (dt_regset_xalloc_args(drp) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
emit(dlp, BPF_MOV_REG(BPF_REG_1, dst));
- emit(dlp, BPF_MOV_REG(BPF_REG_2, src));
- emit(dlp, BPF_MOV_IMM(BPF_REG_3, size));
+ emit(dlp, BPF_MOV_IMM(BPF_REG_2, size));
+ emit(dlp, BPF_MOV_REG(BPF_REG_3, src));
dt_regset_xalloc(drp, BPF_REG_0);
- emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
+ emit(dlp, BPF_CALL_HELPER(BPF_FUNC_probe_read));
dt_regset_free_args(drp);
/* FIXME: check BPF_REG_0 for error? */
dt_regset_free(drp, BPF_REG_0);
@@ -820,9 +817,9 @@ dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
if (dt_regset_xalloc_args(drp) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
dt_regset_xalloc(drp, BPF_REG_0);
- emit(dlp, BPF_CALL_HELPER(BPF_FUNC_get_current_pid_tgid));
+ emit(dlp, BPF_CALL_HELPER(BPF_FUNC_get_current_pid_tgid));
dt_regset_free_args(drp);
- emit(dlp, BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffffffff));
+ emit(dlp, BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffffffff));
emit(dlp, BPF_STORE(BPF_DW, BPF_REG_9, off, BPF_REG_0));
dt_regset_free(drp, BPF_REG_0);
@@ -859,15 +856,15 @@ dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
/* Determine the number of bytes used for the length. */
- emit(dlp, BPF_MOV_REG(BPF_REG_1, reg));
+ emit(dlp, BPF_MOV_REG(BPF_REG_1, reg));
idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_vint_size");
assert(idp != NULL);
dt_regset_xalloc(drp, BPF_REG_0);
- emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
+ emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
/* Add length of the string (adjusted for terminating byte). */
- emit(dlp, BPF_ALU64_IMM(BPF_ADD, reg, 1));
- emit(dlp, BPF_ALU64_REG(BPF_ADD, BPF_REG_0, reg));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, reg, 1));
+ emit(dlp, BPF_ALU64_REG(BPF_ADD, BPF_REG_0, reg));
dt_regset_free(drp, reg);
/*
@@ -875,19 +872,17 @@ dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
* output buffer at [%r9 + off]. The amount of bytes copied is
* the lesser of the data size and the maximum string size.
*/
- emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_9));
- emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, off));
- emit(dlp, BPF_MOV_REG(BPF_REG_2, dnp->dn_reg));
+ emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_9));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, off));
+ emit(dlp, BPF_MOV_REG(BPF_REG_3, dnp->dn_reg));
dt_regset_free(drp, dnp->dn_reg);
- emit(dlp, BPF_MOV_REG(BPF_REG_3, BPF_REG_0));
+ emit(dlp, BPF_MOV_REG(BPF_REG_2, BPF_REG_0));
dt_regset_free(drp, BPF_REG_0);
- emit(dlp, BPF_BRANCH_IMM(BPF_JLT, BPF_REG_3, size, vcopy));
- emit(dlp, BPF_MOV_IMM(BPF_REG_3, size));
- idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_memcpy");
- assert(idp != NULL);
+ emit(dlp, BPF_BRANCH_IMM(BPF_JLT, BPF_REG_2, size, vcopy));
+ emit(dlp, BPF_MOV_IMM(BPF_REG_2, size));
dt_regset_xalloc(drp, BPF_REG_0);
- emitle(dlp, vcopy,
- BPF_CALL_FUNC(idp->di_id), idp);
+ emitl(dlp, vcopy,
+ BPF_CALL_HELPER(BPF_FUNC_probe_read));
dt_regset_free_args(drp);
dt_regset_free(drp, BPF_REG_0);
diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
index 53abe2f7..5980768b 100644
--- a/libdtrace/dt_dlibs.c
+++ b/libdtrace/dt_dlibs.c
@@ -58,7 +58,6 @@ static const dt_ident_t dt_bpf_symbols[] = {
DT_BPF_SYMBOL(dt_get_bvar, DT_IDENT_SYMBOL),
DT_BPF_SYMBOL(dt_get_string, DT_IDENT_SYMBOL),
DT_BPF_SYMBOL(dt_get_tvar, DT_IDENT_SYMBOL),
- DT_BPF_SYMBOL(dt_memcpy, DT_IDENT_SYMBOL),
DT_BPF_SYMBOL(dt_set_tvar, DT_IDENT_SYMBOL),
DT_BPF_SYMBOL(dt_strnlen, DT_IDENT_SYMBOL),
/* BPF maps */
--
2.33.0
More information about the DTrace-devel
mailing list