All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] libtracefs: Free the allocated kbuffer in tracefs_interate_raw_events()
@ 2021-04-12 20:28 Steven Rostedt
  0 siblings, 0 replies; only message in thread
From: Steven Rostedt @ 2021-04-12 20:28 UTC (permalink / raw)
  To: Linux Trace Devel

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

When reading the ring buffers, a kbuffer is allocated and assigned to be
able to parse out the raw events from the kernel buffer. But it is never
freed and causes leaked memory.

Consolidate page_to_kbuf() into read_next_page(), and instead of
allocating the kbuffer descriptor each time, simply reload it with the new
page.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 src/tracefs-events.c | 57 +++++++++++++++++++-------------------------
 1 file changed, 24 insertions(+), 33 deletions(-)

diff --git a/src/tracefs-events.c b/src/tracefs-events.c
index 3a6196b..3e08571 100644
--- a/src/tracefs-events.c
+++ b/src/tracefs-events.c
@@ -20,37 +20,6 @@
 #include "tracefs.h"
 #include "tracefs-local.h"
 
-static struct kbuffer *
-page_to_kbuf(struct tep_handle *tep, void *page, int size)
-{
-	enum kbuffer_long_size long_size;
-	enum kbuffer_endian endian;
-	struct kbuffer *kbuf;
-
-	if (tep_is_file_bigendian(tep))
-		endian = KBUFFER_ENDIAN_BIG;
-	else
-		endian = KBUFFER_ENDIAN_LITTLE;
-
-	if (tep_get_header_page_size(tep) == 8)
-		long_size = KBUFFER_LSIZE_8;
-	else
-		long_size = KBUFFER_LSIZE_4;
-
-	kbuf = kbuffer_alloc(long_size, endian);
-	if (!kbuf)
-		return NULL;
-
-	kbuffer_load_subbuffer(kbuf, page);
-	if (kbuffer_subbuffer_size(kbuf) > size) {
-		tracefs_warning("%s: page_size > size", __func__);
-		kbuffer_free(kbuf);
-		kbuf = NULL;
-	}
-
-	return kbuf;
-}
-
 struct cpu_iterate {
 	struct tep_record record;
 	struct tep_event *event;
@@ -88,13 +57,34 @@ static int read_kbuf_record(struct cpu_iterate *cpu)
 
 int read_next_page(struct tep_handle *tep, struct cpu_iterate *cpu)
 {
+	enum kbuffer_long_size long_size;
+	enum kbuffer_endian endian;
+
 	cpu->rsize = read(cpu->fd, cpu->page, cpu->psize);
 	if (cpu->rsize <= 0)
 		return -1;
 
-	cpu->kbuf = page_to_kbuf(tep, cpu->page, cpu->rsize);
-	if (!cpu->kbuf)
+	if (!cpu->kbuf) {
+		if (tep_is_file_bigendian(tep))
+			endian = KBUFFER_ENDIAN_BIG;
+		else
+			endian = KBUFFER_ENDIAN_LITTLE;
+
+		if (tep_get_header_page_size(tep) == 8)
+			long_size = KBUFFER_LSIZE_8;
+		else
+			long_size = KBUFFER_LSIZE_4;
+
+		cpu->kbuf = kbuffer_alloc(long_size, endian);
+		if (!cpu->kbuf)
+			return -1;
+	}
+
+	kbuffer_load_subbuffer(cpu->kbuf, cpu->page);
+	if (kbuffer_subbuffer_size(cpu->kbuf) > cpu->rsize) {
+		tracefs_warning("%s: page_size > %d", __func__, cpu->rsize);
 		return -1;
+	}
 
 	return 0;
 }
@@ -256,6 +246,7 @@ int tracefs_iterate_raw_events(struct tep_handle *tep,
 out:
 	if (all_cpus) {
 		for (i = 0; i < count; i++) {
+			kbuffer_free(all_cpus[i].kbuf);
 			close(all_cpus[i].fd);
 			free(all_cpus[i].page);
 		}
-- 
2.29.2


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2021-04-12 20:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-12 20:28 [PATCH] libtracefs: Free the allocated kbuffer in tracefs_interate_raw_events() Steven Rostedt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.