devicetree-compiler.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andreas Gnau <andreas.gnau@iopsys.eu>
To: devicetree-compiler@vger.kernel.org
Cc: andreas.gnau@iopsys.eu
Subject: [PATCH v1 1/2] util: Only read files until fdt_totalsize
Date: Tue, 24 Sep 2024 16:50:51 +0200	[thread overview]
Message-ID: <20240924145320.613246-2-andreas.gnau@iopsys.eu> (raw)
In-Reply-To: <20240924145320.613246-1-andreas.gnau@iopsys.eu>

When reading files, it is actually only necessary to read the amount of
bytes specified in the FDT header. Any trailing data that is not part of
the FDT is not relevant to the operation of any of the utilities and is
discarded anyways. Stop reading when reaching either fdt_totalsize bytes
or end-of-file.

Stopping reading before end-of-file saves a considerable amount of
memory when using FIT (Flattened Image Tree) [1] images with "external
data" which are used by bootloaders such as Das U-Boot. In case of FIT
images, the FDT is a few kilobytes, while the actual file can be several
megabytes, which is quite a significant difference in memory usage.

[1] https://fitspec.osfw.foundation/

Signed-off-by: Andreas Gnau <andreas.gnau@iopsys.eu>
---
 util.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/util.c b/util.c
index 507f0120cd13..093303078d5f 100644
--- a/util.c
+++ b/util.c
@@ -249,6 +249,7 @@ int utilfdt_read_err(const char *filename, char **buffp, size_t *len)
 	char *buf = NULL;
 	size_t bufsize = 1024, offset = 0;
 	int ret = 0;
+	uint32_t totalsize = UINT32_MAX;
 
 	*buffp = NULL;
 	if (strcmp(filename, "-") != 0) {
@@ -257,7 +258,7 @@ int utilfdt_read_err(const char *filename, char **buffp, size_t *len)
 			return errno;
 	}
 
-	/* Loop until we have read everything */
+	/* Loop until we have read until the end of file or end of FDT */
 	buf = xmalloc(bufsize);
 	do {
 		/* Expand the buffer to hold the next chunk */
@@ -272,14 +273,24 @@ int utilfdt_read_err(const char *filename, char **buffp, size_t *len)
 			break;
 		}
 		offset += ret;
-	} while (ret != 0);
+
+		/* assumes that the size is always stored in V1 part */
+		if (totalsize == UINT32_MAX && offset >= FDT_V1_SIZE) {
+			totalsize = fdt_totalsize(buf);
+			if (totalsize <= 0)
+				/* read file up to INT32_MAX in case of errors */
+				totalsize = UINT32_MAX;
+		}
+	} while (ret != 0 && offset < totalsize);
 
 	/* Clean up, including closing stdin; return errno on error */
 	close(fd);
-	if (ret)
+	if (ret <= 0)
 		free(buf);
-	else
+	else {
 		*buffp = buf;
+		ret = 0;
+	}
 	if (len)
 		*len = bufsize;
 	return ret;
-- 
2.46.1


  reply	other threads:[~2024-09-24 14:54 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-24 14:50 [PATCH v1 0/2] Reduce memory usage of FDT utils Andreas Gnau
2024-09-24 14:50 ` Andreas Gnau [this message]
2024-09-25  2:04   ` [PATCH v1 1/2] util: Only read files until fdt_totalsize David Gibson
2024-09-24 14:50 ` [PATCH v1 2/2] util: Once size is known, allocate fdt_totalsize Andreas Gnau

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=20240924145320.613246-2-andreas.gnau@iopsys.eu \
    --to=andreas.gnau@iopsys.eu \
    --cc=devicetree-compiler@vger.kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).