public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ian Rogers <irogers@google.com>
To: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>,
	Ian Rogers <irogers@google.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Nick Terrell <terrelln@fb.com>,
	Kan Liang <kan.liang@linux.intel.com>,
	Andi Kleen <ak@linux.intel.com>, Kajol Jain <kjain@linux.ibm.com>,
	Athira Rajeev <atrajeev@linux.vnet.ibm.com>,
	Huacai Chen <chenhuacai@kernel.org>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Vincent Whitchurch <vincent.whitchurch@axis.com>,
	"Steinar H. Gunderson" <sesse@google.com>,
	Liam Howlett <liam.howlett@oracle.com>,
	Miguel Ojeda <ojeda@kernel.org>,
	Colin Ian King <colin.i.king@gmail.com>,
	Dmitrii Dolgov <9erthalion6@gmail.com>,
	Yang Jihong <yangjihong1@huawei.com>,
	Ming Wang <wangming01@loongson.cn>,
	James Clark <james.clark@arm.com>,
	K Prateek Nayak <kprateek.nayak@amd.com>,
	Sean Christopherson <seanjc@google.com>,
	Leo Yan <leo.yan@linaro.org>,
	Ravi Bangoria <ravi.bangoria@amd.com>,
	German Gomez <german.gomez@arm.com>,
	Changbin Du <changbin.du@huawei.com>,
	Paolo Bonzini <pbonzini@redhat.com>, Li Dong <lidong@vivo.com>,
	Sandipan Das <sandipan.das@amd.com>,
	liuwenyu <liuwenyu7@huawei.com>,
	linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org
Subject: [PATCH v4 06/53] tools api fs: Switch filename__read_str to use io.h
Date: Thu,  2 Nov 2023 10:56:48 -0700	[thread overview]
Message-ID: <20231102175735.2272696-7-irogers@google.com> (raw)
In-Reply-To: <20231102175735.2272696-1-irogers@google.com>

filename__read_str has its own string reading code that allocates
memory before reading into it. The memory allocated is sized at BUFSIZ
that is 8kb. Most strings are short and so most of this 8kb is
wasted.

Refactor io__getline so that the newline character can be configurable
and ignored in the case of filename__read_str.

Code like build_caches_for_cpu in perf's header.c will read many
strings and hold them in a data structure, in this case multiple
strings per cache level per CPU. Using io.h's io__getline avoids the
wasted memory as strings are temporarily read into a buffer on the
stack before being copied to a buffer that grows 128 bytes at a time
and is never sized larger than the string.

For a 16 hyperthread system the memory consumption of "perf record
true" is reduced by 180kb, primarily through saving memory when
reading the cache information.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/lib/api/fs/fs.c | 56 +++++++++++--------------------------------
 tools/lib/api/io.h    |  9 +++++--
 2 files changed, 21 insertions(+), 44 deletions(-)

diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c
index 5cb0eeec2c8a..496812b5f1d2 100644
--- a/tools/lib/api/fs/fs.c
+++ b/tools/lib/api/fs/fs.c
@@ -16,6 +16,7 @@
 #include <sys/mount.h>
 
 #include "fs.h"
+#include "../io.h"
 #include "debug-internal.h"
 
 #define _STR(x) #x
@@ -344,53 +345,24 @@ int filename__read_ull(const char *filename, unsigned long long *value)
 	return filename__read_ull_base(filename, value, 0);
 }
 
-#define STRERR_BUFSIZE  128     /* For the buffer size of strerror_r */
-
 int filename__read_str(const char *filename, char **buf, size_t *sizep)
 {
-	size_t size = 0, alloc_size = 0;
-	void *bf = NULL, *nbf;
-	int fd, n, err = 0;
-	char sbuf[STRERR_BUFSIZE];
+	struct io io;
+	char bf[128];
+	int err;
 
-	fd = open(filename, O_RDONLY);
-	if (fd < 0)
+	io.fd = open(filename, O_RDONLY);
+	if (io.fd < 0)
 		return -errno;
-
-	do {
-		if (size == alloc_size) {
-			alloc_size += BUFSIZ;
-			nbf = realloc(bf, alloc_size);
-			if (!nbf) {
-				err = -ENOMEM;
-				break;
-			}
-
-			bf = nbf;
-		}
-
-		n = read(fd, bf + size, alloc_size - size);
-		if (n < 0) {
-			if (size) {
-				pr_warn("read failed %d: %s\n", errno,
-					strerror_r(errno, sbuf, sizeof(sbuf)));
-				err = 0;
-			} else
-				err = -errno;
-
-			break;
-		}
-
-		size += n;
-	} while (n > 0);
-
-	if (!err) {
-		*sizep = size;
-		*buf   = bf;
+	io__init(&io, io.fd, bf, sizeof(bf));
+	*buf = NULL;
+	err = io__getline_nl(&io, buf, sizep, /*nl=*/-1);
+	if (err < 0) {
+		free(*buf);
+		*buf = NULL;
 	} else
-		free(bf);
-
-	close(fd);
+		err = 0;
+	close(io.fd);
 	return err;
 }
 
diff --git a/tools/lib/api/io.h b/tools/lib/api/io.h
index a77b74c5fb65..50d33e14fb56 100644
--- a/tools/lib/api/io.h
+++ b/tools/lib/api/io.h
@@ -141,7 +141,7 @@ static inline int io__get_dec(struct io *io, __u64 *dec)
 }
 
 /* Read up to and including the first newline following the pattern of getline. */
-static inline ssize_t io__getline(struct io *io, char **line_out, size_t *line_len_out)
+static inline ssize_t io__getline_nl(struct io *io, char **line_out, size_t *line_len_out, int nl)
 {
 	char buf[128];
 	int buf_pos = 0;
@@ -151,7 +151,7 @@ static inline ssize_t io__getline(struct io *io, char **line_out, size_t *line_l
 
 	/* TODO: reuse previously allocated memory. */
 	free(*line_out);
-	while (ch != '\n') {
+	while (ch != nl) {
 		ch = io__get_char(io);
 
 		if (ch < 0)
@@ -184,4 +184,9 @@ static inline ssize_t io__getline(struct io *io, char **line_out, size_t *line_l
 	return -ENOMEM;
 }
 
+static inline ssize_t io__getline(struct io *io, char **line_out, size_t *line_len_out)
+{
+	return io__getline_nl(io, line_out, line_len_out, /*nl=*/'\n');
+}
+
 #endif /* __API_IO__ */
-- 
2.42.0.869.gea05f2083d-goog


  parent reply	other threads:[~2023-11-02 17:58 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-02 17:56 [PATCH v4 00/53] Improvements to memory use Ian Rogers
2023-11-02 17:56 ` [PATCH v4 01/53] perf comm: Use regular mutex Ian Rogers
2023-11-05 17:31   ` Namhyung Kim
2023-11-05 21:35     ` Ian Rogers
2023-11-06  3:58       ` Namhyung Kim
2023-11-27 18:59         ` Ian Rogers
2023-11-27 21:53     ` Arnaldo Carvalho de Melo
2023-11-28  0:48       ` Arnaldo Carvalho de Melo
2023-11-02 17:56 ` [PATCH v4 02/53] perf record: Lazy load kernel symbols Ian Rogers
2023-11-05 17:34   ` Namhyung Kim
2023-11-06 11:00   ` Adrian Hunter
2023-11-08 16:01     ` Arnaldo Carvalho de Melo
2023-11-02 17:56 ` [PATCH v4 03/53] libperf: Lazily allocate mmap event copy Ian Rogers
2023-11-03  8:32   ` Guilherme Amadio
2023-11-03 15:48     ` Ian Rogers
2023-11-05 18:12       ` Namhyung Kim
2023-11-27 19:28         ` Ian Rogers
2023-11-02 17:56 ` [PATCH v4 04/53] perf mmap: Lazily initialize zstd streams Ian Rogers
2023-11-27 22:00   ` Arnaldo Carvalho de Melo
2023-11-28 17:14     ` Arnaldo Carvalho de Melo
2023-11-28 17:38       ` Arnaldo Carvalho de Melo
2023-11-28 17:55         ` Ian Rogers
2023-11-28 20:29           ` Arnaldo Carvalho de Melo
2023-11-02 17:56 ` [PATCH v4 05/53] perf machine thread: Remove exited threads by default Ian Rogers
2023-11-06 11:28   ` Adrian Hunter
2023-11-08 16:04     ` Arnaldo Carvalho de Melo
2023-11-02 17:56 ` Ian Rogers [this message]
2023-11-06  3:53   ` [PATCH v4 06/53] tools api fs: Switch filename__read_str to use io.h Namhyung Kim
2023-11-27 20:26     ` Ian Rogers
2023-11-02 17:56 ` [PATCH v4 07/53] tools api fs: Avoid reading whole file for a 1 byte bool Ian Rogers
2023-11-06  3:55   ` Namhyung Kim
2023-11-27 20:41     ` Ian Rogers
2023-11-02 17:56 ` [PATCH v4 08/53] tools lib api: Add io_dir an allocation free readdir alternative Ian Rogers
2023-11-02 17:56 ` [PATCH v4 09/53] perf maps: Switch modules tree walk to io_dir__readdir Ian Rogers
2023-11-02 17:56 ` [PATCH v4 10/53] perf record: Be lazier in allocating lost samples buffer Ian Rogers
2023-11-27 22:03   ` Arnaldo Carvalho de Melo
2023-11-27 22:23     ` Ian Rogers
2023-11-02 17:56 ` [PATCH v4 11/53] perf pmu: Switch to io_dir__readdir Ian Rogers
2023-11-02 17:56 ` [PATCH v4 12/53] perf bpf: Don't synthesize BPF events when disabled Ian Rogers
2023-11-08 16:14   ` Arnaldo Carvalho de Melo
2023-11-08 23:03     ` Song Liu
2023-11-09 16:10       ` Arnaldo Carvalho de Melo
2023-11-02 17:56 ` [PATCH v4 13/53] perf header: Switch mem topology to io_dir__readdir Ian Rogers
2023-11-02 17:56 ` [PATCH v4 14/53] perf events: Remove scandir in thread synthesis Ian Rogers
2023-11-02 17:56 ` [PATCH v4 15/53] perf map: Simplify map_ip/unmap_ip and make map size smaller Ian Rogers
2023-11-02 17:56 ` [PATCH v4 16/53] perf maps: Move symbol maps functions to maps.c Ian Rogers
2023-11-02 17:56 ` [PATCH v4 17/53] perf thread: Add missing RC_CHK_EQUAL Ian Rogers
2023-11-02 17:57 ` [PATCH v4 18/53] perf maps: Add maps__for_each_map to call a function on each entry Ian Rogers
2023-11-02 17:57 ` [PATCH v4 19/53] perf maps: Add remove maps function to remove a map based on callback Ian Rogers
2023-11-02 17:57 ` [PATCH v4 20/53] perf debug: Expose debug file Ian Rogers
2023-11-02 17:57 ` [PATCH v4 21/53] perf maps: Refactor maps__fixup_overlappings Ian Rogers
2023-11-02 17:57 ` [PATCH v4 22/53] perf maps: Do simple merge if given map doesn't overlap Ian Rogers
2023-11-02 17:57 ` [PATCH v4 23/53] perf maps: Rename clone to copy from Ian Rogers
2023-11-02 17:57 ` [PATCH v4 24/53] perf maps: Add maps__load_first Ian Rogers
2023-11-02 17:57 ` [PATCH v4 25/53] perf maps: Add find next entry to give entry after the given map Ian Rogers
2023-11-02 17:57 ` [PATCH v4 26/53] perf maps: Reduce scope of map_rb_node and maps internals Ian Rogers
2023-11-02 17:57 ` [PATCH v4 27/53] perf maps: Fix up overlaps during fixup_end Ian Rogers
2023-11-02 17:57 ` [PATCH v4 28/53] perf maps: Switch from rbtree to lazily sorted array for addresses Ian Rogers
2023-11-02 17:57 ` [PATCH v4 29/53] perf maps: Get map before returning in maps__find Ian Rogers
2023-11-02 17:57 ` [PATCH v4 30/53] perf maps: Get map before returning in maps__find_by_name Ian Rogers
2023-11-02 17:57 ` [PATCH v4 31/53] perf maps: Get map before returning in maps__find_next_entry Ian Rogers
2023-11-02 17:57 ` [PATCH v4 32/53] perf maps: Hide maps internals Ian Rogers
2023-11-02 17:57 ` [PATCH v4 33/53] perf maps: Locking tidy up of nr_maps Ian Rogers
2023-11-02 17:57 ` [PATCH v4 34/53] perf dso: Reorder variables to save space in struct dso Ian Rogers
2023-11-02 17:57 ` [PATCH v4 35/53] perf report: Sort child tasks by tid Ian Rogers
2023-11-02 17:57 ` [PATCH v4 36/53] perf trace: Ignore thread hashing in summary Ian Rogers
2023-11-02 17:57 ` [PATCH v4 37/53] perf machine: Move fprintf to for_each loop and a callback Ian Rogers
2023-11-02 17:57 ` [PATCH v4 38/53] perf threads: Move threads to its own files Ian Rogers
2023-11-02 17:57 ` [PATCH v4 39/53] perf threads: Switch from rbtree to hashmap Ian Rogers
2023-11-02 17:57 ` [PATCH v4 40/53] perf threads: Reduce table size from 256 to 8 Ian Rogers
2023-11-02 17:57 ` [PATCH v4 41/53] perf dsos: Attempt to better abstract dsos internals Ian Rogers
2023-11-02 17:57 ` [PATCH v4 42/53] perf dsos: Tidy reference counting and locking Ian Rogers
2023-11-02 17:57 ` [PATCH v4 43/53] perf dsos: Add dsos__for_each_dso Ian Rogers
2023-11-02 17:57 ` [PATCH v4 44/53] perf dso: Move dso functions out of dsos Ian Rogers
2023-11-02 17:57 ` [PATCH v4 45/53] perf dsos: Switch more loops to dsos__for_each_dso Ian Rogers
2023-11-02 17:57 ` [PATCH v4 46/53] perf dsos: Switch backing storage to array from rbtree/list Ian Rogers
2023-11-02 17:57 ` [PATCH v4 47/53] perf dsos: Remove __dsos__addnew Ian Rogers
2023-11-02 17:57 ` [PATCH v4 48/53] perf dsos: Remove __dsos__findnew_link_by_longname_id Ian Rogers
2023-11-02 17:57 ` [PATCH v4 49/53] perf dsos: Switch hand code to bsearch Ian Rogers
2023-11-02 17:57 ` [PATCH v4 50/53] perf dso: Add reference count checking and accessor functions Ian Rogers
2023-11-02 17:57 ` [PATCH v4 51/53] perf dso: Reference counting related fixes Ian Rogers
2023-11-02 17:57 ` [PATCH v4 52/53] perf dso: Use container_of to avoid a pointer in dso_data Ian Rogers
2023-11-02 17:57 ` [PATCH v4 53/53] perf env: Avoid recursively taking env->bpf_progs.lock Ian Rogers

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=20231102175735.2272696-7-irogers@google.com \
    --to=irogers@google.com \
    --cc=9erthalion6@gmail.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=atrajeev@linux.vnet.ibm.com \
    --cc=changbin.du@huawei.com \
    --cc=chenhuacai@kernel.org \
    --cc=colin.i.king@gmail.com \
    --cc=german.gomez@arm.com \
    --cc=james.clark@arm.com \
    --cc=jolsa@kernel.org \
    --cc=kan.liang@linux.intel.com \
    --cc=kjain@linux.ibm.com \
    --cc=kprateek.nayak@amd.com \
    --cc=leo.yan@linaro.org \
    --cc=liam.howlett@oracle.com \
    --cc=lidong@vivo.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=liuwenyu7@huawei.com \
    --cc=mark.rutland@arm.com \
    --cc=mhiramat@kernel.org \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=ravi.bangoria@amd.com \
    --cc=sandipan.das@amd.com \
    --cc=seanjc@google.com \
    --cc=sesse@google.com \
    --cc=terrelln@fb.com \
    --cc=vincent.whitchurch@axis.com \
    --cc=wangming01@loongson.cn \
    --cc=yangjihong1@huawei.com \
    /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