[DTrace-devel] [PATCH v2] Add support for getmajor() and getminor() subroutines

eugene.loh at oracle.com eugene.loh at oracle.com
Thu Feb 17 02:36:51 UTC 2022


From: Eugene Loh <eugene.loh at oracle.com>

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 libdtrace/dt_cg.c                  | 30 ++++++++++++++++++++++++++++--
 test/unittest/funcs/tst.getmajor.d | 19 +++++++++++++++++++
 test/unittest/funcs/tst.getmajor.r |  1 +
 test/unittest/funcs/tst.getminor.d | 19 +++++++++++++++++++
 test/unittest/funcs/tst.getminor.r |  1 +
 5 files changed, 68 insertions(+), 2 deletions(-)
 create mode 100644 test/unittest/funcs/tst.getmajor.d
 create mode 100644 test/unittest/funcs/tst.getmajor.r
 create mode 100644 test/unittest/funcs/tst.getminor.d
 create mode 100644 test/unittest/funcs/tst.getminor.r

diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index b6b39617..2652b5fc 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -3374,6 +3374,32 @@ dt_cg_subr_dirname(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
 	dt_cg_subr_path_helper(dnp, dlp, drp, "dt_dirname");
 }
 
+/*
+ * For getmajor and getminor, use MAJOR(dev) and MINOR(dev)
+ * as defined in kernel header include/linux/kdev_t.h, not
+ * as defined in user header /usr/include/linux/kdev_t.h.
+ */
+static void
+dt_cg_subr_getmajor(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+	dt_node_t	*arg = dnp->dn_args;
+
+	dt_cg_node(arg, dlp, drp);
+	dnp->dn_reg = arg->dn_reg;
+	emit(dlp, BPF_ALU64_IMM(BPF_LSH, dnp->dn_reg, 32));
+	emit(dlp, BPF_ALU64_IMM(BPF_RSH, dnp->dn_reg, 32 + 20));
+}
+
+static void
+dt_cg_subr_getminor(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+	dt_node_t	*arg = dnp->dn_args;
+
+	dt_cg_node(arg, dlp, drp);
+	dnp->dn_reg = arg->dn_reg;
+	emit(dlp, BPF_ALU64_IMM(BPF_AND, dnp->dn_reg, 0xfffff));
+}
+
 /*
  * Get and return a new speculation ID.  These are unallocated entries in the
  * specs map, obtained by calling dt_speculation().  Return zero if none is
@@ -4120,8 +4146,8 @@ static dt_cg_subr_f *_dt_cg_subr[DIF_SUBR_MAX + 1] = {
 	[DIF_SUBR_COPYINTO]		= NULL,
 	[DIF_SUBR_MSGDSIZE]		= NULL,
 	[DIF_SUBR_MSGSIZE]		= NULL,
-	[DIF_SUBR_GETMAJOR]		= NULL,
-	[DIF_SUBR_GETMINOR]		= NULL,
+	[DIF_SUBR_GETMAJOR]		= &dt_cg_subr_getmajor,
+	[DIF_SUBR_GETMINOR]		= &dt_cg_subr_getminor,
 	[DIF_SUBR_DDI_PATHNAME]		= NULL,
 	[DIF_SUBR_STRJOIN]		= dt_cg_subr_strjoin,
 	[DIF_SUBR_LLTOSTR]		= &dt_cg_subr_lltostr,
diff --git a/test/unittest/funcs/tst.getmajor.d b/test/unittest/funcs/tst.getmajor.d
new file mode 100644
index 00000000..de0e4800
--- /dev/null
+++ b/test/unittest/funcs/tst.getmajor.d
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+	printf("%x", getmajor(0xabcdef0123456789ll));
+	exit(0);
+}
+
+ERROR
+{
+	exit(1);
+}
diff --git a/test/unittest/funcs/tst.getmajor.r b/test/unittest/funcs/tst.getmajor.r
new file mode 100644
index 00000000..7b5813c6
--- /dev/null
+++ b/test/unittest/funcs/tst.getmajor.r
@@ -0,0 +1 @@
+234
diff --git a/test/unittest/funcs/tst.getminor.d b/test/unittest/funcs/tst.getminor.d
new file mode 100644
index 00000000..d1619234
--- /dev/null
+++ b/test/unittest/funcs/tst.getminor.d
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+	printf("%x", getminor(0xabcdef0123456789ll));
+	exit(0);
+}
+
+ERROR
+{
+	exit(1);
+}
diff --git a/test/unittest/funcs/tst.getminor.r b/test/unittest/funcs/tst.getminor.r
new file mode 100644
index 00000000..e2f2476c
--- /dev/null
+++ b/test/unittest/funcs/tst.getminor.r
@@ -0,0 +1 @@
+56789
-- 
2.18.4




More information about the DTrace-devel mailing list