public inbox for dtrace@lists.linux.dev
 help / color / mirror / Atom feed
From: eugene.loh@oracle.com
To: dtrace@lists.linux.dev, dtrace-devel@oss.oracle.com
Subject: [PATCH 31/38] Fix dt_pebs_init() call
Date: Thu, 27 Jun 2024 01:38:57 -0400	[thread overview]
Message-ID: <20240627053904.21996-12-eugene.loh@oracle.com> (raw)
In-Reply-To: <20240627053904.21996-1-eugene.loh@oracle.com>

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

The function had a few issues, mainly with its comments,
ranging from typos to incorrect descriptions of behavior.

The function has only one caller.  The enforcement of a
size minimum was problematic in a number of respects:
- it was missing 4 bytes
- it was enforcing the minimum before the size was
    increased by the caller
- it was checking dt_pebs_init()==-1,
    missing errors with other negative return values

So change the function to accept a minimum and change its
return values.

Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
---
 libdtrace/dt_peb.c                          | 27 ++++++++++-----------
 libdtrace/dt_peb.h                          |  2 +-
 libdtrace/dt_work.c                         | 15 +++++++-----
 test/unittest/options/err.b-too-low.d       | 22 +++++++++--------
 test/unittest/options/err.bufsize-too-low.d | 22 +++++++++--------
 test/unittest/options/tst.b.d               | 22 +++++++++--------
 test/unittest/options/tst.bufsize.d         | 22 +++++++++--------
 7 files changed, 71 insertions(+), 61 deletions(-)

diff --git a/libdtrace/dt_peb.c b/libdtrace/dt_peb.c
index 5268f089..4983ba91 100644
--- a/libdtrace/dt_peb.c
+++ b/libdtrace/dt_peb.c
@@ -136,18 +136,14 @@ dt_pebs_exit(dtrace_hdl_t *dtp)
 }
 
 /*
- * Initialize the perf event buffers (one per online CPU).  Each buffer will
- * the given number of pages (i.e. the total size of each buffer will be
- * num_pages * getpagesize()).  The  allocated memory for each buffer is mmap'd
- * so the kernel can write to it, and its representative file descriptor is
- * recorded in the 'buffers' BPF map so that BPF code knows where to write
- * trace data for a specific CPU.
+ * Initialize the perf event buffers, one per online CPU.  Each buffer will
+ * have num_pages * getpagesize()).  The dt_peb_open() call mmaps the allocated
+ * memory so the kernel can write to it.  The file descriptor is recorded in
+ * the 'buffers' BPF map and added to the event polling file descriptor.
  *
- * An event polling file descriptor is created as well, and it is configured to
- * monitor all perf event buffers at once.  This file descriptor is returned
- * upon success..  Failure is indicated with a -1 return value.
+ * The return value indicates success (0) or failure (-1).
  */
-int dt_pebs_init(dtrace_hdl_t *dtp, size_t bufsize)
+int dt_pebs_init(dtrace_hdl_t *dtp, size_t bufsize, size_t bufsizemin)
 {
 	int		i;
 	int		mapfd;
@@ -166,12 +162,15 @@ int dt_pebs_init(dtrace_hdl_t *dtp, size_t bufsize)
 		fprintf(stderr, "bufsize increased to %lu\n",
 			num_pages * getpagesize());
 
+	if (num_pages * getpagesize() < bufsizemin)
+		return dt_set_errno(dtp, EDT_BUFTOOSMALL);
+
 	/*
 	 * Determine the fd for the 'buffers' BPF map.
 	 */
 	idp = dt_dlib_get_map(dtp, "buffers");
 	if (idp == NULL || idp->di_id == DT_IDENT_UNDEF)
-		return -ENOENT;
+		return dt_set_errno(dtp, EDT_NOMEM);    // FIXME we used to do something more akin to ENOENT
 
 	mapfd = idp->di_id;
 
@@ -180,7 +179,7 @@ int dt_pebs_init(dtrace_hdl_t *dtp, size_t bufsize)
 	 */
 	dtp->dt_pebset = dt_zalloc(dtp, sizeof(dt_pebset_t));
 	if (dtp->dt_pebset == NULL)
-		return -ENOMEM;
+		return dt_set_errno(dtp, EDT_NOMEM);
 
 	/*
 	 * Allocate the per-CPU perf event buffers.
@@ -189,7 +188,7 @@ int dt_pebs_init(dtrace_hdl_t *dtp, size_t bufsize)
 			 sizeof(struct dt_peb));
 	if (pebs == NULL) {
 		dt_free(dtp, dtp->dt_pebset);
-		return -ENOMEM;
+		return dt_set_errno(dtp, EDT_NOMEM);
 	}
 
 	dtp->dt_pebset->pebs = pebs;
@@ -241,5 +240,5 @@ int dt_pebs_init(dtrace_hdl_t *dtp, size_t bufsize)
 fail:
 	dt_pebs_exit(dtp);
 
-	return -1;
+	return dt_set_errno(dtp, EDT_NOMEM);  // FIXME need something better
 }
diff --git a/libdtrace/dt_peb.h b/libdtrace/dt_peb.h
index e0f408f2..9ad23252 100644
--- a/libdtrace/dt_peb.h
+++ b/libdtrace/dt_peb.h
@@ -43,7 +43,7 @@ typedef struct dt_pebset {
 } dt_pebset_t;
 
 extern void dt_pebs_exit(dtrace_hdl_t *);
-extern int dt_pebs_init(dtrace_hdl_t *, size_t);
+extern int dt_pebs_init(dtrace_hdl_t *, size_t, size_t);
 
 #ifdef	__cplusplus
 }
diff --git a/libdtrace/dt_work.c b/libdtrace/dt_work.c
index 69a86358..7a0eb1da 100644
--- a/libdtrace/dt_work.c
+++ b/libdtrace/dt_work.c
@@ -267,18 +267,21 @@ dtrace_go(dtrace_hdl_t *dtp, uint_t cflags)
 		return dt_set_errno(dtp, errno);
 
 	/*
-	 * We need enough space for the pref_event_header, a 32-bit size, a
+	 * We need enough space for the perf_event_header, a 32-bit size, a
 	 * 4-byte gap, and the largest trace data record we may be writing to
 	 * the buffer.  In other words, the buffer needs to be large enough to
 	 * hold at least one perf-encapsulated trace data record.
+	 *
+	 * While dt_pebs_init() rounds the requested size up, size==0 is a
+	 * special case.
 	 */
 	dtrace_getopt(dtp, "bufsize", &size);
-	if (size == 0 ||
-	    size < sizeof(struct perf_event_header) + sizeof(uint32_t) +
-		   dtp->dt_maxreclen)
+	if (size == 0)
 		return dt_set_errno(dtp, EDT_BUFTOOSMALL);
-	if (dt_pebs_init(dtp, size) == -1)
-		return dt_set_errno(dtp, EDT_NOMEM);
+	if (dt_pebs_init(dtp, size,
+			 sizeof(struct perf_event_header) + sizeof(uint32_t)
+			 + 4 + dtp->dt_maxreclen) == -1)
+		return -1;
 
 	/*
 	 * We must initialize the aggregation consumer handling before we
diff --git a/test/unittest/options/err.b-too-low.d b/test/unittest/options/err.b-too-low.d
index bb77e37c..f62155dd 100644
--- a/test/unittest/options/err.b-too-low.d
+++ b/test/unittest/options/err.b-too-low.d
@@ -1,6 +1,6 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2024, 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.
  */
@@ -12,19 +12,21 @@
  */
 
 /*
- * We use a buffer size of 59 because that should be just too small to hold the
- * trace records generated in this script:
- *	- perf_event_header (40 bytes)
- *	- size (4 bytes)
- *	- gap (4 bytes)
- *	- EPID (4 bytes)
- *	- tag (4 bytes)
- *	- exit value (4 bytes)
+ * We need over 4k bytes for the 4 string trace records generated in this script
+ * plus some meta data.
+ * A bufsize of 1 to 4096 bytes is rounded up to 4096 and is insufficient.
+ * A bufsize of 4097 to 8192 bytes is rounded up to 8192 and is sufficient.
  */
-/* @@runtest-opts: -b59 */
+/* @@runtest-opts: -b4096 */
+
+#pragma D option strsize=1024
 
 BEGIN
 {
+	trace("abc");
+	trace("def");
+	trace("ghi");
+	trace("jkl");
 	exit(0);
 }
 
diff --git a/test/unittest/options/err.bufsize-too-low.d b/test/unittest/options/err.bufsize-too-low.d
index bbbdb5c5..25efdf72 100644
--- a/test/unittest/options/err.bufsize-too-low.d
+++ b/test/unittest/options/err.bufsize-too-low.d
@@ -1,6 +1,6 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2024, 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.
  */
@@ -12,19 +12,21 @@
  */
 
 /*
- * We use a buffer size of 59 because that should be just too small to hold the
- * trace records generated in this script:
- *	- perf_event_header (40 bytes)
- *	- size (4 bytes)
- *	- gap (4 bytes)
- *	- EPID (4 bytes)
- *	- tag (4 bytes)
- *	- exit value (4 bytes)
+ * We need over 4k bytes for the 4 string trace records generated in this script
+ * plus some meta data.
+ * A bufsize of 1 to 4096 bytes is rounded up to 4096 and is insufficient.
+ * A bufsize of 4097 to 8192 bytes is rounded up to 8192 and is sufficient.
  */
-/* @@runtest-opts: -xbufsize=59 */
+/* @@runtest-opts: -xbufsize=4096 */
+
+#pragma D option strsize=1024
 
 BEGIN
 {
+	trace("abc");
+	trace("def");
+	trace("ghi");
+	trace("jkl");
 	exit(0);
 }
 
diff --git a/test/unittest/options/tst.b.d b/test/unittest/options/tst.b.d
index 57fa030d..3bf08edc 100644
--- a/test/unittest/options/tst.b.d
+++ b/test/unittest/options/tst.b.d
@@ -1,6 +1,6 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2024, 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.
  */
@@ -12,19 +12,21 @@
  */
 
 /*
- * We use a buffer size of 60 because that should be the exact size necessary
- * to hold the trace records generated in this script:
- *	- perf_event_header (40 bytes)
- *	- size (4 bytes)
- *	- gap (4 bytes)
- *	- EPID (4 bytes)
- *	- tag (4 bytes)
- *	- exit value (4 bytes)
+ * We need over 4k bytes for the 4 string trace records generated in this script
+ * plus some meta data.
+ * A bufsize of 1 to 4096 bytes is rounded up to 4096 and is insufficient.
+ * A bufsize of 4097 to 8192 bytes is rounded up to 8192 and is sufficient.
  */
-/* @@runtest-opts: -b60 */
+/* @@runtest-opts: -b4097 */
+
+#pragma D option strsize=1024
 
 BEGIN
 {
+	trace("abc");
+	trace("def");
+	trace("ghi");
+	trace("jkl");
 	exit(0);
 }
 
diff --git a/test/unittest/options/tst.bufsize.d b/test/unittest/options/tst.bufsize.d
index 96b0f1b8..23af81aa 100644
--- a/test/unittest/options/tst.bufsize.d
+++ b/test/unittest/options/tst.bufsize.d
@@ -1,6 +1,6 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2024, 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.
  */
@@ -12,19 +12,21 @@
  */
 
 /*
- * We use a buffer size of 60 because that should be the exact size necessary
- * to hold the trace records generated in this script:
- *	- perf_event_header (40 bytes)
- *	- size (4 bytes)
- *	- gap (4 bytes)
- *	- EPID (4 bytes)
- *	- tag (4 bytes)
- *	- exit value (4 bytes)
+ * We need over 4k bytes for the 4 string trace records generated in this script
+ * plus some meta data.
+ * A bufsize of 1 to 4096 bytes is rounded up to 4096 and is insufficient.
+ * A bufsize of 4097 to 8192 bytes is rounded up to 8192 and is sufficient.
  */
-/* @@runtest-opts: -xbufsize=60 */
+/* @@runtest-opts: -xbufsize=4097 */
+
+#pragma D option strsize=1024
 
 BEGIN
 {
+	trace("abc");
+	trace("def");
+	trace("ghi");
+	trace("jkl");
 	exit(0);
 }
 
-- 
2.18.4


  parent reply	other threads:[~2024-06-27  5:39 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-27  5:38 [PATCH 20/38] Add a hook for a provider-specific "update" function eugene.loh
2024-06-27  5:38 ` [PATCH 21/38] Add some comments eugene.loh
2024-07-19 20:39   ` Kris Van Hees
2024-06-27  5:38 ` [PATCH 22/38] Fix aggs comment in dt_cg_tramp_prologue_act() eugene.loh
2024-07-19 20:44   ` Kris Van Hees
2024-07-19 23:15     ` Eugene Loh
2024-06-27  5:38 ` [PATCH 23/38] test: Clean up the specsize tests eugene.loh
2024-06-27  5:38 ` [PATCH 24/38] test: Make test independent of specific PC eugene.loh
2024-07-19 21:02   ` Kris Van Hees
2024-07-22  0:05     ` Eugene Loh
2024-06-27  5:38 ` [PATCH 25/38] test: Clean up tests still expecting obsolete "at DIF offset NN" eugene.loh
2024-07-19 21:08   ` Kris Van Hees
2024-06-27  5:38 ` [PATCH 26/38] test: Annotate xfail (chill not implemented yet) eugene.loh
2024-07-19 21:12   ` Kris Van Hees
2024-07-19 23:38     ` Eugene Loh
2024-10-29 15:05       ` Kris Van Hees
2024-10-29 21:13         ` Eugene Loh
2024-06-27  5:38 ` [PATCH 27/38] test: Fix the speculative tests that checked bufsize eugene.loh
2024-06-27  5:38 ` [PATCH 28/38] Remove unused "next" arg from dt_flowindent() eugene.loh
2024-08-28 19:41   ` Kris Van Hees
2024-06-27  5:38 ` [PATCH 29/38] Allow relocation of the ERROR PRID eugene.loh
2024-07-19 21:41   ` [DTrace-devel] " Kris Van Hees
2024-07-19 23:49     ` Eugene Loh
2024-06-27  5:38 ` [PATCH 30/38] Allow relocation on BPF_OR instructions eugene.loh
2024-07-19 21:34   ` Kris Van Hees
2024-09-30 21:19     ` Kris Van Hees
2024-09-30 22:00       ` Eugene Loh
2024-06-27  5:38 ` eugene.loh [this message]
2024-08-26 14:30   ` [PATCH 31/38] Fix dt_pebs_init() call Kris Van Hees
2024-08-26 15:42     ` Eugene Loh
2024-08-26 16:20       ` Kris Van Hees
2024-08-28 20:57         ` Eugene Loh
2024-08-28 21:16           ` Kris Van Hees
2024-08-30  0:54             ` Eugene Loh
2024-08-30  2:26               ` [DTrace-devel] " Kris Van Hees
2024-08-30  5:42                 ` Eugene Loh
2024-08-30 16:53                   ` Kris Van Hees
2024-08-30 19:06                     ` Eugene Loh
2024-08-30 20:07                       ` Kris Van Hees
2024-06-27  5:38 ` [PATCH 32/38] Widen the EPID to include the PRID eugene.loh
2024-06-27  5:38 ` [PATCH 33/38] Eliminate dt_pdesc eugene.loh
2024-06-27  5:39 ` [PATCH 34/38] Create the BPF uprobes map eugene.loh
2024-06-27  5:39 ` [PATCH 35/38] Use uprobes map to call clauses conditionally eugene.loh
2024-06-27  5:39 ` [PATCH 36/38] Inline copyout_val() eugene.loh
2024-06-27  5:39 ` [PATCH 37/38] Fix some dctx->mst->specsize comments eugene.loh
2024-07-18 20:41   ` Kris Van Hees
2024-06-27  5:39 ` [PATCH 38/38] Systemwide USDT WIP eugene.loh
2024-07-19 20:31 ` [PATCH 20/38] Add a hook for a provider-specific "update" function Kris Van Hees
2024-07-20  0:08   ` Eugene Loh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240627053904.21996-12-eugene.loh@oracle.com \
    --to=eugene.loh@oracle.com \
    --cc=dtrace-devel@oss.oracle.com \
    --cc=dtrace@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox