[DTrace-devel] [PATCH] Add support for mutex-related subroutines
Kris Van Hees
kris.van.hees at oracle.com
Fri Apr 22 06:02:51 UTC 2022
On Thu, Mar 03, 2022 at 05:55:40AM -0500, eugene.loh--- via DTrace-devel wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
>
> Implement the relevant subroutines. Clean up the tests.
>
> A few tests were broken in ways that were not being detected:
> early on because runtest.sh was not checking error tags and later
> because the tests were marked XFAIL. Clean these tests up.
>
> Changes include not using kmutex_t any longer in the tests. This
> type was not recognized even in legacy DTrace. The documentation
> needs a corresponding update.
>
> Similarly, probe lockstat:genunix:mutex_enter:adaptive-acquire was
> not recognized, even by legacy DTrace, and it was not needed for the
> tests in question.
>
> There were no rw_* tests. One has been added, but it remains
> unclear how stable the test is -- specifically, whether enough
> write-lock events are generated.
>
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>
... and I will put it on dev.
I think the two mutex_*.S could have been put in a single file (they are small
and closely related), and the same for the three rw_*.S ones, but I am going
with it as is for now. We can always consolidate in a later patch.
> ---
> bpf/Build | 5 +
> bpf/mutex_owned.S | 38 ++++++
> bpf/mutex_owner.S | 29 +++++
> bpf/rw_iswriter.S | 29 +++++
> bpf/rw_read_held.S | 29 +++++
> bpf/rw_write_held.S | 29 +++++
> libdtrace/dt_bpf.h | 2 +
> libdtrace/dt_cc.c | 50 ++++++++
> libdtrace/dt_cg.c | 114 ++++++++++++++++--
> libdtrace/dt_dlibs.c | 2 +
> ...tabadarg.d => err.D_PROTO_ARG.mtabadarg.d} | 2 +-
> .../funcs/err.D_PROTO_ARG.mtabadarg.r | 4 +
> .../unittest/funcs/err.D_PROTO_LEN.motoofew.d | 10 +-
> .../unittest/funcs/err.D_PROTO_LEN.motoofew.r | 2 +
> .../funcs/err.D_PROTO_LEN.motoomany.d | 11 +-
> .../funcs/err.D_PROTO_LEN.motoomany.r | 2 +-
> .../funcs/err.D_PROTO_LEN.mtabadarg.r | 2 -
> .../funcs/err.D_PROTO_LEN.mtatoofew.d | 11 +-
> .../funcs/err.D_PROTO_LEN.mtatoofew.r | 2 +
> .../funcs/err.D_PROTO_LEN.mtatoomany.d | 12 +-
> .../funcs/err.D_PROTO_LEN.mtatoomany.r | 2 +-
> test/unittest/funcs/tst.mutex_owned.d | 3 +-
> test/unittest/funcs/tst.mutex_owner.d | 3 +-
> test/unittest/funcs/tst.mutex_type_adaptive.d | 3 +-
> test/unittest/funcs/tst.mutex_type_spin.d | 3 +-
> test/unittest/funcs/tst.rw_.r | 12 ++
> test/unittest/funcs/tst.rw_.sh | 96 +++++++++++++++
> test/unittest/funcs/tst.rw_.x | 15 +++
> 28 files changed, 472 insertions(+), 50 deletions(-)
> create mode 100644 bpf/mutex_owned.S
> create mode 100644 bpf/mutex_owner.S
> create mode 100644 bpf/rw_iswriter.S
> create mode 100644 bpf/rw_read_held.S
> create mode 100644 bpf/rw_write_held.S
> rename test/unittest/funcs/{err.D_PROTO_LEN.mtabadarg.d => err.D_PROTO_ARG.mtabadarg.d} (90%)
> create mode 100644 test/unittest/funcs/err.D_PROTO_ARG.mtabadarg.r
> create mode 100644 test/unittest/funcs/err.D_PROTO_LEN.motoofew.r
> delete mode 100644 test/unittest/funcs/err.D_PROTO_LEN.mtabadarg.r
> create mode 100644 test/unittest/funcs/err.D_PROTO_LEN.mtatoofew.r
> create mode 100644 test/unittest/funcs/tst.rw_.r
> create mode 100755 test/unittest/funcs/tst.rw_.sh
> create mode 100755 test/unittest/funcs/tst.rw_.x
>
> diff --git a/bpf/Build b/bpf/Build
> index 5cf9c45f..43f4b638 100644
> --- a/bpf/Build
> +++ b/bpf/Build
> @@ -30,9 +30,14 @@ bpf_dlib_SOURCES = \
> index.S \
> inet_ntoa.S \
> lltostr.S \
> + mutex_owned.S \
> + mutex_owner.S \
> progenyof.S \
> probe_error.c \
> rindex.S \
> + rw_iswriter.S \
> + rw_read_held.S \
> + rw_write_held.S \
> speculation.c \
> strchr.S \
> strcmp.S \
> diff --git a/bpf/mutex_owned.S b/bpf/mutex_owned.S
> new file mode 100644
> index 00000000..19c61bc5
> --- /dev/null
> +++ b/bpf/mutex_owned.S
> @@ -0,0 +1,38 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> + */
> +
> +#define BPF_FUNC_probe_read 4
> +#define BPF_FUNC_get_current_task 35
> +#define MUTEX_FLAGS 0x07
> +
> + .text
> + .align 4
> + .global dt_mutex_owned
> + .type dt_mutex_owned, @function
> +dt_mutex_owned:
> + /* dt_mutex_owned(tmp, mutex) */
> +
> + /* %r6 = tmp */
> + mov %r6, %r1
> +
> + /* probe_read(tmp, 8, &mutex->owner) */
> + lddw %r3, MUTEX_OWNER
> + add %r3, %r2
> + mov %r2, 8
> + call BPF_FUNC_probe_read
> +
> + /* %r6 = *tmp & ~MUTEX_FLAGS */
> + ldxdw %r6, [%r6+0]
> + and %r6, ~MUTEX_FLAGS
> +
> + call BPF_FUNC_get_current_task
> + jeq %r0, %r6, .Lowned
> + mov %r0, 0
> + exit
> +
> +.Lowned:
> + mov %r0, 1
> + exit
> + .size dt_mutex_owned, .-dt_mutex_owned
> diff --git a/bpf/mutex_owner.S b/bpf/mutex_owner.S
> new file mode 100644
> index 00000000..3668d643
> --- /dev/null
> +++ b/bpf/mutex_owner.S
> @@ -0,0 +1,29 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> + */
> +
> +#define BPF_FUNC_probe_read 4
> +#define MUTEX_FLAGS 0x07
> +
> + .text
> + .align 4
> + .global dt_mutex_owner
> + .type dt_mutex_owner, @function
> +dt_mutex_owner:
> + /* dt_mutex_owner(tmp, mutex) */
> +
> + /* %r6 = tmp */
> + mov %r6, %r1
> +
> + /* probe_read(tmp, 8, &mutex->owner) */
> + lddw %r3, MUTEX_OWNER
> + add %r3, %r2
> + mov %r2, 8
> + call BPF_FUNC_probe_read
> +
> + /* %r0 = *tmp & ~MUTEX_FLAGS */
> + ldxdw %r0, [%r6+0]
> + and %r0, ~MUTEX_FLAGS
> + exit
> + .size dt_mutex_owner, .-dt_mutex_owner
> diff --git a/bpf/rw_iswriter.S b/bpf/rw_iswriter.S
> new file mode 100644
> index 00000000..e324ad56
> --- /dev/null
> +++ b/bpf/rw_iswriter.S
> @@ -0,0 +1,29 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> + */
> +
> +#define BPF_FUNC_probe_read 4
> +#define _QW_WMASK 0x1ff
> +
> + .text
> + .align 4
> + .global dt_rw_iswriter
> + .type dt_rw_iswriter, @function
> +dt_rw_iswriter:
> + /* dt_rw_iswriter(tmp, rwlock) */
> +
> + /* %r6 = tmp */
> + mov %r6, %r1
> +
> + /* probe_read(tmp, 8, &rwlock->cnts) */
> + lddw %r3, RWLOCK_CNTS
> + add %r3, %r2
> + mov %r2, 8
> + call BPF_FUNC_probe_read
> +
> + /* %r0 = *tmp & _QW_WMASK */
> + ldxdw %r0, [%r6+0]
> + and %r0, _QW_WMASK
> + exit
> + .size dt_rw_iswriter, .-dt_rw_iswriter
> diff --git a/bpf/rw_read_held.S b/bpf/rw_read_held.S
> new file mode 100644
> index 00000000..efe1467c
> --- /dev/null
> +++ b/bpf/rw_read_held.S
> @@ -0,0 +1,29 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> + */
> +
> +#define BPF_FUNC_probe_read 4
> +#define _QW_WMASK 0x1ff
> +
> + .text
> + .align 4
> + .global dt_rw_read_held
> + .type dt_rw_read_held, @function
> +dt_rw_read_held:
> + /* dt_rw_read_held(tmp, rwlock) */
> +
> + /* %r6 = tmp */
> + mov %r6, %r1
> +
> + /* probe_read(tmp, 8, &rwlock->cnts) */
> + lddw %r3, RWLOCK_CNTS
> + add %r3, %r2
> + mov %r2, 8
> + call BPF_FUNC_probe_read
> +
> + /* %r0 = *tmp & ~_QW_WMASK */
> + ldxdw %r0, [%r6+0]
> + and %r0, ~_QW_WMASK
> + exit
> + .size dt_rw_read_held, .-dt_rw_read_held
> diff --git a/bpf/rw_write_held.S b/bpf/rw_write_held.S
> new file mode 100644
> index 00000000..9fdf09cd
> --- /dev/null
> +++ b/bpf/rw_write_held.S
> @@ -0,0 +1,29 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> + */
> +
> +#define BPF_FUNC_probe_read 4
> +#define _QW_LOCKED 0x0ff
> +
> + .text
> + .align 4
> + .global dt_rw_write_held
> + .type dt_rw_write_held, @function
> +dt_rw_write_held:
> + /* dt_rw_write_held(tmp, rwlock) */
> +
> + /* %r6 = tmp */
> + mov %r6, %r1
> +
> + /* probe_read(tmp, 8, &rwlock->cnts) */
> + lddw %r3, RWLOCK_CNTS
> + add %r3, %r2
> + mov %r2, 8
> + call BPF_FUNC_probe_read
> +
> + /* %r0 = *tmp & _QW_LOCKED */
> + ldxdw %r0, [%r6+0]
> + and %r0, _QW_LOCKED
> + exit
> + .size dt_rw_write_held, .-dt_rw_write_held
> diff --git a/libdtrace/dt_bpf.h b/libdtrace/dt_bpf.h
> index 957d593e..de34bb58 100644
> --- a/libdtrace/dt_bpf.h
> +++ b/libdtrace/dt_bpf.h
> @@ -32,6 +32,8 @@ extern "C" {
> #define DT_CONST_TASK_TGID 12
> #define DT_CONST_TASK_REAL_PARENT 13
> #define DT_CONST_TASK_COMM 14
> +#define DT_CONST_MUTEX_OWNER 15
> +#define DT_CONST_RWLOCK_CNTS 16
>
> extern int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,
> int group_fd, unsigned long flags);
> diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
> index c0556522..d33b2768 100644
> --- a/libdtrace/dt_cc.c
> +++ b/libdtrace/dt_cc.c
> @@ -2398,6 +2398,56 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
> nrp->dofr_data = ctm.ctm_offset / NBBY;
> continue;
> }
> + case DT_CONST_MUTEX_OWNER: {
> + ctf_file_t *cfp = dtp->dt_shared_ctf;
> + ctf_id_t type = ctf_lookup_by_name(cfp, "struct mutex");
> + ctf_membinfo_t ctm;
> + ctf_id_t rc = CTF_ERR;
> +
> + if (type == CTF_ERR)
> + return -1;
> +
> + rc = ctf_member_info(cfp, type, "owner", &ctm);
> + if (rc == CTF_ERR)
> + return -1;
> + nrp->dofr_data = ctm.ctm_offset / NBBY;
> + continue;
> + }
> + case DT_CONST_RWLOCK_CNTS: {
> + /*
> + * For !CONFIG_PREEMPT_RT, in type rwlock_t, we
> + * want the offset to member raw_lock, and then
> + * (in type arch_rwlock_t == struct qrwlock) we
> + * add the offset to member cnts. (It turns
> + * out the total offset is 0.)
> + *
> + * FIXME: what about CONFIG_PREEMPT_RT?
> + */
> + ctf_file_t *cfp = dtp->dt_shared_ctf;
> + ctf_id_t type;
> + ctf_membinfo_t ctm;
> + ctf_id_t rc = CTF_ERR;
> + uint64_t total_offset;
> +
> + type = ctf_lookup_by_name(cfp, "rwlock_t");
> + if (type == CTF_ERR)
> + return -1;
> + rc = ctf_member_info(cfp, type, "raw_lock", &ctm);
> + if (rc == CTF_ERR)
> + return -1;
> + total_offset = ctm.ctm_offset / NBBY;
> +
> + type = ctf_lookup_by_name(cfp, "arch_rwlock_t");
> + if (type == CTF_ERR)
> + return -1;
> + rc = ctf_member_info(cfp, type, "cnts", &ctm);
> + if (rc == CTF_ERR)
> + return -1;
> + total_offset += ctm.ctm_offset / NBBY;
> +
> + nrp->dofr_data = total_offset;
> + continue;
> + }
> default:
> /* probe name -> value is probe id */
> if (strchr(idp->di_name, ':') != NULL)
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 22ccac2b..028f1178 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -3547,6 +3547,106 @@ dt_cg_subr_rand(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> TRACE_REGSET(" subr-rand:End ");
> }
>
> +/*
> + * This function is a helper function for subroutines that take some
> + * (8-byte) temporary space and a lock argument, returning the value
> + * from a given BPF function (passed by name).
> + */
> +static void
> +dt_cg_subr_lock_helper(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
> + const char *fname)
> +{
> + dt_ident_t *idp = dt_dlib_get_func(yypcb->pcb_hdl, fname);
> + dt_node_t *lock = dnp->dn_args;
> + uint64_t off = dt_cg_tstring_xalloc(yypcb);
> +
> + assert(idp != NULL);
> +
> + TRACE_REGSET(" subr-lock_helper:Begin");
> +
> + dt_cg_node(lock, dlp, drp);
> + dt_cg_check_notnull(dlp, drp, lock->dn_reg);
> +
> + if (dt_regset_xalloc_args(drp) == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> +
> + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_FP, DT_STK_DCTX));
> + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_1, DCTX_MEM));
> + emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, off));
> +
> + emit(dlp, BPF_MOV_REG(BPF_REG_2, lock->dn_reg));
> + dt_regset_free(drp, lock->dn_reg);
> +
> + dt_regset_xalloc(drp, BPF_REG_0);
> + emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
> + dt_regset_free_args(drp);
> + dt_cg_tstring_xfree(yypcb, off);
> +
> + dnp->dn_reg = dt_regset_alloc(drp);
> + if (dnp->dn_reg == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> + emit(dlp, BPF_MOV_REG(dnp->dn_reg, BPF_REG_0));
> + dt_regset_free(drp, BPF_REG_0);
> +
> + TRACE_REGSET(" subr-lock_helper:End ");
> +}
> +
> +static void
> +dt_cg_subr_mutex_owned(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + dt_cg_subr_lock_helper(dnp, dlp, drp, "dt_mutex_owned");
> +}
> +
> +static void
> +dt_cg_subr_mutex_owner(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + dt_cg_subr_lock_helper(dnp, dlp, drp, "dt_mutex_owner");
> +}
> +
> +static void
> +dt_cg_subr_rw_read_held(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + dt_cg_subr_lock_helper(dnp, dlp, drp, "dt_rw_read_held");
> +}
> +
> +static void
> +dt_cg_subr_rw_write_held(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + dt_cg_subr_lock_helper(dnp, dlp, drp, "dt_rw_write_held");
> +}
> +
> +static void
> +dt_cg_subr_rw_iswriter(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + dt_cg_subr_lock_helper(dnp, dlp, drp, "dt_rw_iswriter");
> +}
> +
> +/* On Linux, all mutexes are adaptive. */
> +
> +static void
> +dt_cg_subr_mutex_type_adaptive(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + dt_node_t *arg = dnp->dn_args;
> +
> + TRACE_REGSET(" subr-mutex_type_adaptive:Begin");
> + dt_cg_node(arg, dlp, drp);
> + dnp->dn_reg = arg->dn_reg;
> + emit(dlp, BPF_MOV_IMM(dnp->dn_reg, 1));
> + TRACE_REGSET(" subr-mutex_type_adaptive:End ");
> +}
> +
> +static void
> +dt_cg_subr_mutex_type_spin(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + dt_node_t *arg = dnp->dn_args;
> +
> + TRACE_REGSET(" subr-mutex_type_spin:Begin");
> + dt_cg_node(arg, dlp, drp);
> + dnp->dn_reg = arg->dn_reg;
> + emit(dlp, BPF_MOV_IMM(dnp->dn_reg, 0));
> + TRACE_REGSET(" subr-mutex_type_spin:End ");
> +}
> +
> static void
> dt_cg_subr_rindex(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> {
> @@ -4154,13 +4254,13 @@ typedef void dt_cg_subr_f(dt_node_t *, dt_irlist_t *, dt_regset_t *);
>
> static dt_cg_subr_f *_dt_cg_subr[DIF_SUBR_MAX + 1] = {
> [DIF_SUBR_RAND] = &dt_cg_subr_rand,
> - [DIF_SUBR_MUTEX_OWNED] = NULL,
> - [DIF_SUBR_MUTEX_OWNER] = NULL,
> - [DIF_SUBR_MUTEX_TYPE_ADAPTIVE] = NULL,
> - [DIF_SUBR_MUTEX_TYPE_SPIN] = NULL,
> - [DIF_SUBR_RW_READ_HELD] = NULL,
> - [DIF_SUBR_RW_WRITE_HELD] = NULL,
> - [DIF_SUBR_RW_ISWRITER] = NULL,
> + [DIF_SUBR_MUTEX_OWNED] = &dt_cg_subr_mutex_owned,
> + [DIF_SUBR_MUTEX_OWNER] = &dt_cg_subr_mutex_owner,
> + [DIF_SUBR_MUTEX_TYPE_ADAPTIVE] = &dt_cg_subr_mutex_type_adaptive,
> + [DIF_SUBR_MUTEX_TYPE_SPIN] = &dt_cg_subr_mutex_type_spin,
> + [DIF_SUBR_RW_READ_HELD] = &dt_cg_subr_rw_read_held,
> + [DIF_SUBR_RW_WRITE_HELD] = &dt_cg_subr_rw_write_held,
> + [DIF_SUBR_RW_ISWRITER] = &dt_cg_subr_rw_iswriter,
> [DIF_SUBR_COPYIN] = NULL,
> [DIF_SUBR_COPYINSTR] = NULL,
> [DIF_SUBR_SPECULATION] = &dt_cg_subr_speculation,
> diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
> index efbd3261..9d742ab5 100644
> --- a/libdtrace/dt_dlibs.c
> +++ b/libdtrace/dt_dlibs.c
> @@ -83,6 +83,8 @@ static const dt_ident_t dt_bpf_symbols[] = {
> DT_BPF_SYMBOL_ID(TASK_TGID, DT_IDENT_SCALAR, DT_CONST_TASK_TGID),
> DT_BPF_SYMBOL_ID(TASK_REAL_PARENT, DT_IDENT_SCALAR, DT_CONST_TASK_REAL_PARENT),
> DT_BPF_SYMBOL_ID(TASK_COMM, DT_IDENT_SCALAR, DT_CONST_TASK_COMM),
> + DT_BPF_SYMBOL_ID(MUTEX_OWNER, DT_IDENT_SCALAR, DT_CONST_MUTEX_OWNER),
> + DT_BPF_SYMBOL_ID(RWLOCK_CNTS, DT_IDENT_SCALAR, DT_CONST_RWLOCK_CNTS),
>
> /* End-of-list marker */
> { NULL, }
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.mtabadarg.d b/test/unittest/funcs/err.D_PROTO_ARG.mtabadarg.d
> similarity index 90%
> rename from test/unittest/funcs/err.D_PROTO_LEN.mtabadarg.d
> rename to test/unittest/funcs/err.D_PROTO_ARG.mtabadarg.d
> index 7dad4aa0..4fe39003 100644
> --- a/test/unittest/funcs/err.D_PROTO_LEN.mtabadarg.d
> +++ b/test/unittest/funcs/err.D_PROTO_ARG.mtabadarg.d
> @@ -16,6 +16,6 @@
>
> BEGIN
> {
> - mutex_type_adaptive(trace());
> + mutex_type_adaptive(trace("badarg"));
> exit(1);
> }
> diff --git a/test/unittest/funcs/err.D_PROTO_ARG.mtabadarg.r b/test/unittest/funcs/err.D_PROTO_ARG.mtabadarg.r
> new file mode 100644
> index 00000000..29bdbcd9
> --- /dev/null
> +++ b/test/unittest/funcs/err.D_PROTO_ARG.mtabadarg.r
> @@ -0,0 +1,4 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_ARG.mtabadarg.d: [D_PROTO_ARG] line 19: mutex_type_adaptive( ) argument #1 is incompatible with prototype:
> + prototype: struct mutex *
> + argument: void
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.motoofew.d b/test/unittest/funcs/err.D_PROTO_LEN.motoofew.d
> index 779bb547..7b310c3a 100644
> --- a/test/unittest/funcs/err.D_PROTO_LEN.motoofew.d
> +++ b/test/unittest/funcs/err.D_PROTO_LEN.motoofew.d
> @@ -1,20 +1,16 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2007, 2022, 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.
> */
> -/* @@xfail: dtv2 */
> -
> /*
> - * ASSERTION:
> - * mutex_owned() should handle too few args passed
> + * ASSERTION: mutex_owned() should handle too few args passed
> *
> * SECTION: Actions and Subroutines/mutex_owned()
> - *
> */
>
> -lockstat:genunix:mutex_enter:adaptive-acquire
> +BEGIN
> {
> mutex_owned();
> exit(1);
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.motoofew.r b/test/unittest/funcs/err.D_PROTO_LEN.motoofew.r
> new file mode 100644
> index 00000000..1367ae0b
> --- /dev/null
> +++ b/test/unittest/funcs/err.D_PROTO_LEN.motoofew.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.motoofew.d: [D_PROTO_LEN] line 15: mutex_owned( ) prototype mismatch: 0 args passed, 1 expected
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.motoomany.d b/test/unittest/funcs/err.D_PROTO_LEN.motoomany.d
> index bdeb30bc..3b197467 100644
> --- a/test/unittest/funcs/err.D_PROTO_LEN.motoomany.d
> +++ b/test/unittest/funcs/err.D_PROTO_LEN.motoomany.d
> @@ -1,20 +1,17 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2007, 2022, 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.
> */
> -/* @@xfail: dtv2 */
> /*
> - * ASSERTION:
> - * mutex_owned() should handle too many args passed
> + * ASSERTION: mutex_owned() should handle too many args passed
> *
> * SECTION: Actions and Subroutines/mutex_owned()
> - *
> */
>
> -lockstat:genunix:mutex_enter:adaptive-acquire
> +BEGIN
> {
> - mutex_owned((kmutex_t *)arg0, 99);
> + mutex_owned(0, 99);
> exit(1);
> }
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.motoomany.r b/test/unittest/funcs/err.D_PROTO_LEN.motoomany.r
> index f0d0ca22..3cf80ef1 100644
> --- a/test/unittest/funcs/err.D_PROTO_LEN.motoomany.r
> +++ b/test/unittest/funcs/err.D_PROTO_LEN.motoomany.r
> @@ -1,2 +1,2 @@
> -- @@stderr --
> -dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.motoomany.d: [D_SYNTAX] line 18: syntax error near ")"
> +dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.motoomany.d: [D_PROTO_LEN] line 15: mutex_owned( ) prototype mismatch: 2 args passed, 1 expected
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.mtabadarg.r b/test/unittest/funcs/err.D_PROTO_LEN.mtabadarg.r
> deleted file mode 100644
> index 79810cfe..00000000
> --- a/test/unittest/funcs/err.D_PROTO_LEN.mtabadarg.r
> +++ /dev/null
> @@ -1,2 +0,0 @@
> --- @@stderr --
> -dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.mtabadarg.d: [D_PROTO_LEN] line 19: trace( ) prototype mismatch: 0 args passed, 1 expected
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.mtatoofew.d b/test/unittest/funcs/err.D_PROTO_LEN.mtatoofew.d
> index dce985c6..b582d554 100644
> --- a/test/unittest/funcs/err.D_PROTO_LEN.mtatoofew.d
> +++ b/test/unittest/funcs/err.D_PROTO_LEN.mtatoofew.d
> @@ -1,21 +1,16 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, 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.
> */
> -/* @@xfail: dtv2 */
> -
> /*
> - * ASSERTION:
> - * mutex_type_adaptive() should handle too few args passed
> + * ASSERTION: mutex_type_adaptive() should handle too few args passed
> *
> * SECTION: Actions and Subroutines/mutex_type_adaptive()
> - *
> */
>
> -
> -lockstat:genunix:mutex_enter:adaptive-acquire
> +BEGIN
> {
> mutex_type_adaptive();
> exit(1);
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.mtatoofew.r b/test/unittest/funcs/err.D_PROTO_LEN.mtatoofew.r
> new file mode 100644
> index 00000000..7a1936d4
> --- /dev/null
> +++ b/test/unittest/funcs/err.D_PROTO_LEN.mtatoofew.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.mtatoofew.d: [D_PROTO_LEN] line 15: mutex_type_adaptive( ) prototype mismatch: 0 args passed, 1 expected
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.mtatoomany.d b/test/unittest/funcs/err.D_PROTO_LEN.mtatoomany.d
> index e516890c..6f08673d 100644
> --- a/test/unittest/funcs/err.D_PROTO_LEN.mtatoomany.d
> +++ b/test/unittest/funcs/err.D_PROTO_LEN.mtatoomany.d
> @@ -1,21 +1,17 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, 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.
> */
> -/* @@xfail: dtv2 */
> /*
> - * ASSERTION:
> - * mutex_type_adaptive() should handle too many args passed
> + * ASSERTION: mutex_type_adaptive() should handle too many args passed
> *
> * SECTION: Actions and Subroutines/mutex_type_adaptive()
> - *
> */
>
> -
> -lockstat:genunix:mutex_enter:adaptive-acquire
> +BEGIN
> {
> - mutex_type_adaptive((kmutex_t *)arg0, 99);
> + mutex_type_adaptive(0, 99);
> exit(1);
> }
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.mtatoomany.r b/test/unittest/funcs/err.D_PROTO_LEN.mtatoomany.r
> index 5efeff80..efc9b4ed 100644
> --- a/test/unittest/funcs/err.D_PROTO_LEN.mtatoomany.r
> +++ b/test/unittest/funcs/err.D_PROTO_LEN.mtatoomany.r
> @@ -1,2 +1,2 @@
> -- @@stderr --
> -dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.mtatoomany.d: [D_SYNTAX] line 19: syntax error near ")"
> +dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.mtatoomany.d: [D_PROTO_LEN] line 15: mutex_type_adaptive( ) prototype mismatch: 2 args passed, 1 expected
> diff --git a/test/unittest/funcs/tst.mutex_owned.d b/test/unittest/funcs/tst.mutex_owned.d
> index 8e9c2893..4fd94c35 100644
> --- a/test/unittest/funcs/tst.mutex_owned.d
> +++ b/test/unittest/funcs/tst.mutex_owned.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, 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.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/funcs/tst.mutex_owner.d b/test/unittest/funcs/tst.mutex_owner.d
> index d68af367..162533a6 100644
> --- a/test/unittest/funcs/tst.mutex_owner.d
> +++ b/test/unittest/funcs/tst.mutex_owner.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, 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.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/funcs/tst.mutex_type_adaptive.d b/test/unittest/funcs/tst.mutex_type_adaptive.d
> index c8c60872..e095da69 100644
> --- a/test/unittest/funcs/tst.mutex_type_adaptive.d
> +++ b/test/unittest/funcs/tst.mutex_type_adaptive.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, 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.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/funcs/tst.mutex_type_spin.d b/test/unittest/funcs/tst.mutex_type_spin.d
> index 894f5ced..6e853387 100644
> --- a/test/unittest/funcs/tst.mutex_type_spin.d
> +++ b/test/unittest/funcs/tst.mutex_type_spin.d
> @@ -1,10 +1,9 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 2022, 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.
> */
> -/* @@xfail: dtv2 */
>
> /*
> * ASSERTION:
> diff --git a/test/unittest/funcs/tst.rw_.r b/test/unittest/funcs/tst.rw_.r
> new file mode 100644
> index 00000000..3b7de46e
> --- /dev/null
> +++ b/test/unittest/funcs/tst.rw_.r
> @@ -0,0 +1,12 @@
> +finish
> +read entry 0 0 0
> +read entry 0 0 0
> +read entry 0 0 0
> +read entry 0 0 0
> +read return 0 1 0
> +read return 0 1 0
> +read return 0 1 0
> +read return 0 1 0
> +write entry 0 0 0
> +write return 1 0 1
> +
> diff --git a/test/unittest/funcs/tst.rw_.sh b/test/unittest/funcs/tst.rw_.sh
> new file mode 100755
> index 00000000..163a4f4e
> --- /dev/null
> +++ b/test/unittest/funcs/tst.rw_.sh
> @@ -0,0 +1,96 @@
> +#!/bin/bash
> +#
> +# Oracle Linux DTrace.
> +# Copyright (c) 2022, 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.
> +
> +# This test for the subroutines
> +# rw_read_held()
> +# rw_write_held()
> +# rw_iswriter()
> +# may prove not to be very robust. It does not identify a workload that
> +# is known to exercise the read-write locks well. So we simply sit on
> +# _raw_read_lock and _raw_write_lock FBT probes and hope there is some
> +# activity. The .r file assumes the locks are uncontested.
> +
> +dtrace=$1
> +tmpfile=$tmpdir/tst.rw_.$$
> +
> +$dtrace $dt_flags -qn '
> +
> +/* desired numbers of read and write events */
> +
> +BEGIN
> +{
> + nr = 4;
> + nw = 1;
> +}
> +
> +/* read events */
> +
> +fbt:vmlinux:_raw_read_lock:entry
> +/nr > 0/
> +{
> + self->rlock = (rwlock_t *)arg0;
> + nr--;
> + printf("read entry %x %x %x\n",
> + 0 != rw_iswriter(self->rlock),
> + 0 != rw_read_held(self->rlock),
> + 0 != rw_write_held(self->rlock));
> +}
> +
> +fbt:vmlinux:_raw_read_lock:return
> +/self->rlock/
> +{
> + printf("read return %x %x %x\n",
> + 0 != rw_iswriter(self->rlock),
> + 0 != rw_read_held(self->rlock),
> + 0 != rw_write_held(self->rlock));
> + self->rlock = 0;
> +}
> +
> +/* write events */
> +
> +fbt:vmlinux:_raw_write_lock:entry
> +/nw > 0/
> +{
> + self->wlock = (rwlock_t *)arg0;
> + nw--;
> + printf("write entry %x %x %x\n",
> + 0 != rw_iswriter(self->wlock),
> + 0 != rw_read_held(self->wlock),
> + 0 != rw_write_held(self->wlock));
> +}
> +
> +fbt:vmlinux:_raw_write_lock:return
> +/self->wlock/
> +{
> + printf("write return %x %x %x\n",
> + 0 != rw_iswriter(self->wlock),
> + 0 != rw_read_held(self->wlock),
> + 0 != rw_write_held(self->wlock));
> + self->wlock = 0;
> +}
> +
> +/* termination */
> +
> +fbt:vmlinux:_raw_read_lock:return,
> +fbt:vmlinux:_raw_write_lock:return
> +/nr == 0 && nw == 0/
> +{
> + printf("finish\n");
> + exit(0);
> +}
> +' >& $tmpfile
> +
> +if [ $? -ne 0 ]; then
> + echo "DTrace error"
> + cat $tmpfile
> + exit 1
> +fi
> +
> +sort $tmpfile
> +
> +exit 0
> +
> diff --git a/test/unittest/funcs/tst.rw_.x b/test/unittest/funcs/tst.rw_.x
> new file mode 100755
> index 00000000..29c58111
> --- /dev/null
> +++ b/test/unittest/funcs/tst.rw_.x
> @@ -0,0 +1,15 @@
> +#!/bin/sh
> +
> +FUNCS=/sys/kernel/debug/tracing/available_filter_functions
> +
> +if ! grep -qw _raw_read_lock $FUNCS; then
> + echo no _raw_read_lock FBT probe due to kernel config
> + exit 1
> +fi
> +
> +if ! grep -w _raw_write_lock $FUNCS; then
> + echo no _raw_write_lock FBT probe due to kernel config
> + exit 1
> +fi
> +
> +exit 0
> --
> 2.18.4
>
>
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
More information about the DTrace-devel
mailing list