diff mbox series

[1/6] kallsyms: Optimize multiple times of realloc() to one time of malloc()

Message ID 20240613133711.2867745-2-zhengyejian1@huawei.com (mailing list archive)
State Handled Elsewhere
Headers show
Series kallsyms: Emit symbol for holes in text and fix weak function issue | expand

Commit Message

Zheng Yejian June 13, 2024, 1:37 p.m. UTC
Array 'table' is used to store pointers of symbols that read from in.map
file, and its size depends on the number of symbols. Currently 'table'
is expanded by calling realloc() every 10000 symbols read.

However, there generally are around 100000+ symbols, which means that
the expansion is generally 10+ times.

As an optimization, introduce linked list 'sym_list' to associate and
count all symbols, then store them into 'table' at one time.

Signed-off-by: Zheng Yejian <zhengyejian1@huawei.com>
---
 scripts/kallsyms.c | 33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

Comments

Masahiro Yamada July 15, 2024, 8:12 p.m. UTC | #1
On Thu, Jun 13, 2024 at 10:36 PM Zheng Yejian <zhengyejian1@huawei.com> wrote:
>
> Array 'table' is used to store pointers of symbols that read from in.map
> file, and its size depends on the number of symbols. Currently 'table'
> is expanded by calling realloc() every 10000 symbols read.
>
> However, there generally are around 100000+ symbols, which means that
> the expansion is generally 10+ times.
>
> As an optimization, introduce linked list 'sym_list' to associate and
> count all symbols, then store them into 'table' at one time.
>
> Signed-off-by: Zheng Yejian <zhengyejian1@huawei.com>


I do not think this is worthwhile.

realloc() is simple.

If this is a problem, you can increase the
"+= 10000" to "+= 65536" or something.
diff mbox series

Patch

diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 47978efe4797..6559a9802f6e 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -33,6 +33,7 @@ 
 #define KSYM_NAME_LEN		512
 
 struct sym_entry {
+	struct sym_entry *next;
 	unsigned long long addr;
 	unsigned int len;
 	unsigned int seq;
@@ -60,7 +61,8 @@  static struct addr_range percpu_range = {
 };
 
 static struct sym_entry **table;
-static unsigned int table_size, table_cnt;
+static struct sym_entry *sym_list;
+static unsigned int table_cnt;
 static int all_symbols;
 static int absolute_percpu;
 static int base_relative;
@@ -273,6 +275,7 @@  static void read_map(const char *in)
 	struct sym_entry *sym;
 	char *buf = NULL;
 	size_t buflen = 0;
+	int i;
 
 	fp = fopen(in, "r");
 	if (!fp) {
@@ -286,18 +289,22 @@  static void read_map(const char *in)
 			continue;
 
 		sym->start_pos = table_cnt;
-
-		if (table_cnt >= table_size) {
-			table_size += 10000;
-			table = realloc(table, sizeof(*table) * table_size);
-			if (!table) {
-				fprintf(stderr, "out of memory\n");
-				fclose(fp);
-				exit (1);
-			}
-		}
-
-		table[table_cnt++] = sym;
+		table_cnt++;
+		sym->next = sym_list;
+		sym_list = sym;
+	}
+	table = malloc(sizeof(*table) * table_cnt);
+	if (!table) {
+		fprintf(stderr, "unable to allocate memory for table\n");
+		free(buf);
+		fclose(fp);
+		exit(EXIT_FAILURE);
+	}
+	sym = sym_list;
+	i = table_cnt - 1;
+	while (sym) {
+		table[i--] = sym;
+		sym = sym->next;
 	}
 
 	free(buf);