[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