From 8af27e1dc4e4dd7a7b04c2cd0fc3d419d91d45b0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 9 Nov 2010 16:29:27 +0100 Subject: fixdep: use hash table instead of a single array I noticed fixdep uses ~2% of cpu time in kernel build, in function use_config() fixdep spends a lot of cpu cycles in linear searches in its internal string array. With about 400 stored strings per dep file, this begins to be noticeable. Convert fixdep to use a hash table. kbuild results on my x86_64 allmodconfig Before patch : real 10m30.414s user 61m51.456s sys 8m28.200s real 10m12.334s user 61m50.236s sys 8m30.448s real 10m42.947s user 61m50.028s sys 8m32.380s After: real 10m8.180s user 61m22.506s sys 8m32.384s real 10m35.039s user 61m21.654s sys 8m32.212s real 10m14.487s user 61m23.498s sys 8m32.312s Signed-off-by: Eric Dumazet Signed-off-by: Michal Marek --- scripts/basic/fixdep.c | 109 +++++++++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 48 deletions(-) (limited to 'scripts') diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index ea26b23de082..ed0584623690 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -138,38 +138,36 @@ static void print_cmdline(void) printf("cmd_%s := %s\n\n", target, cmdline); } -char * str_config = NULL; -int size_config = 0; -int len_config = 0; +struct item { + struct item *next; + unsigned int len; + unsigned int hash; + char name[0]; +}; -/* - * Grow the configuration string to a desired length. - * Usually the first growth is plenty. - */ -static void grow_config(int len) -{ - while (len_config + len > size_config) { - if (size_config == 0) - size_config = 2048; - str_config = realloc(str_config, size_config *= 2); - if (str_config == NULL) - { perror("fixdep:malloc"); exit(1); } - } -} +#define HASHSZ 256 +static struct item *hashtab[HASHSZ]; +static unsigned int strhash(const char *str, unsigned int sz) +{ + /* fnv32 hash */ + unsigned int i, hash = 2166136261U; + for (i = 0; i < sz; i++) + hash = (hash ^ str[i]) * 0x01000193; + return hash; +} /* * Lookup a value in the configuration string. */ -static int is_defined_config(const char * name, int len) +static int is_defined_config(const char *name, int len, unsigned int hash) { - const char * pconfig; - const char * plast = str_config + len_config - len; - for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) { - if (pconfig[ -1] == '\n' - && pconfig[len] == '\n' - && !memcmp(pconfig, name, len)) + struct item *aux; + + for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) { + if (aux->hash == hash && aux->len == len && + memcmp(aux->name, name, len) == 0) return 1; } return 0; @@ -178,13 +176,19 @@ static int is_defined_config(const char * name, int len) /* * Add a new value to the configuration string. */ -static void define_config(const char * name, int len) +static void define_config(const char *name, int len, unsigned int hash) { - grow_config(len + 1); + struct item *aux = malloc(sizeof(*aux) + len); - memcpy(str_config+len_config, name, len); - len_config += len; - str_config[len_config++] = '\n'; + if (!aux) { + perror("fixdep:malloc"); + exit(1); + } + memcpy(aux->name, name, len); + aux->len = len; + aux->hash = hash; + aux->next = hashtab[hash % HASHSZ]; + hashtab[hash % HASHSZ] = aux; } /* @@ -192,40 +196,49 @@ static void define_config(const char * name, int len) */ static void clear_config(void) { - len_config = 0; - define_config("", 0); + struct item *aux, *next; + unsigned int i; + + for (i = 0; i < HASHSZ; i++) { + for (aux = hashtab[i]; aux; aux = next) { + next = aux->next; + free(aux); + } + hashtab[i] = NULL; + } } /* * Record the use of a CONFIG_* word. */ -static void use_config(char *m, int slen) +static void use_config(const char *m, int slen) { - char s[PATH_MAX]; - char *p; + unsigned int hash = strhash(m, slen); + int c, i; - if (is_defined_config(m, slen)) + if (is_defined_config(m, slen, hash)) return; - define_config(m, slen); - - memcpy(s, m, slen); s[slen] = 0; + define_config(m, slen, hash); - for (p = s; p < s + slen; p++) { - if (*p == '_') - *p = '/'; + printf(" $(wildcard include/config/"); + for (i = 0; i < slen; i++) { + c = m[i]; + if (c == '_') + c = '/'; else - *p = tolower((int)*p); + c = tolower(c); + putchar(c); } - printf(" $(wildcard include/config/%s.h) \\\n", s); + printf(".h) \\\n"); } -static void parse_config_file(char *map, size_t len) +static void parse_config_file(const char *map, size_t len) { - int *end = (int *) (map + len); + const int *end = (const int *) (map + len); /* start at +1, so that p can never be < map */ - int *m = (int *) map + 1; - char *p, *q; + const int *m = (const int *) map + 1; + const char *p, *q; for (; m < end; m++) { if (*m == INT_CONF) { p = (char *) m ; goto conf; } @@ -265,7 +278,7 @@ static int strrcmp(char *s, char *sub) return memcmp(s + slen - sublen, sub, sublen); } -static void do_config_file(char *filename) +static void do_config_file(const char *filename) { struct stat st; int fd; -- cgit v1.2.3-59-g8ed1b From 01660dfc37933c92dbb7c5718aea61f88025d71f Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Mon, 8 Nov 2010 18:31:53 -0500 Subject: scripts/genksyms: fix header usage FreeBSD does not like when __STDC__ is defined, use the standard instead. Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/genksyms/parse.c_shipped | 2 +- scripts/genksyms/parse.y | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/genksyms/parse.c_shipped b/scripts/genksyms/parse.c_shipped index eaee44e66a43..809b949e495b 100644 --- a/scripts/genksyms/parse.c_shipped +++ b/scripts/genksyms/parse.c_shipped @@ -160,7 +160,7 @@ #include -#include +#include #include "genksyms.h" static int is_typedef; diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 10d7dc724b6d..09a265cd7193 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -24,7 +24,7 @@ %{ #include -#include +#include #include "genksyms.h" static int is_typedef; -- cgit v1.2.3-59-g8ed1b From 2979076fbf17a0947d6eba367b0cac19c907c160 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 23 Nov 2010 19:54:02 -0500 Subject: headers_install: check exit status of unifdef MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If unifdef fails for any reason (like segfaulting), we should be aborting the install steps. So check its exit status in this unlikely scenario. Reported-by: Diego Elio Pettenò Signed-off-by: Mike Frysinger Signed-off-by: Michal Marek --- scripts/headers_install.pl | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'scripts') diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl index 4ca3be3b2e50..efb3be10d428 100644 --- a/scripts/headers_install.pl +++ b/scripts/headers_install.pl @@ -45,6 +45,13 @@ foreach my $file (@files) { close $in; system $unifdef . " $tmpfile > $installdir/$file"; + # unifdef will exit 0 on success, and will exit 1 when the + # file was processed successfully but no changes were made, + # so abort only when it's higher than that. + my $e = $? >> 8; + if ($e > 1) { + die "$tmpfile: $!\n"; + } unlink $tmpfile; } exit 0; -- cgit v1.2.3-59-g8ed1b From f6820308e025d645d9d766c97586badd4ddb8754 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Mon, 13 Dec 2010 19:10:28 +0200 Subject: kbuild: introduce HDR_ARCH_LIST for headers_install_all Using HDR_ARCH_LIST you can specify subset of architectures you want to get headers for. Signed-off-by: Kirill A. Shutemov Signed-off-by: Michal Marek --- Documentation/make/headers_install.txt | 5 +++-- scripts/headers.sh | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/Documentation/make/headers_install.txt b/Documentation/make/headers_install.txt index f2481cabffcb..951eb9f1e040 100644 --- a/Documentation/make/headers_install.txt +++ b/Documentation/make/headers_install.txt @@ -39,8 +39,9 @@ INSTALL_HDR_PATH indicates where to install the headers. It defaults to The command "make headers_install_all" exports headers for all architectures simultaneously. (This is mostly of interest to distribution maintainers, who create an architecture-independent tarball from the resulting include -directory.) Remember to provide the appropriate linux/asm directory via "mv" -or "ln -s" before building a C library with headers exported this way. +directory.) You also can use HDR_ARCH_LIST to specify list of architectures. +Remember to provide the appropriate linux/asm directory via "mv" or "ln -s" +before building a C library with headers exported this way. The kernel header export infrastructure is maintained by David Woodhouse . diff --git a/scripts/headers.sh b/scripts/headers.sh index 1ddcdd38d97f..978b42b3acd7 100755 --- a/scripts/headers.sh +++ b/scripts/headers.sh @@ -13,7 +13,7 @@ do_command() fi } -archs=$(ls ${srctree}/arch) +archs=${HDR_ARCH_LIST:-$(ls ${srctree}/arch)} for arch in ${archs}; do case ${arch} in -- cgit v1.2.3-59-g8ed1b From 1121584f5db8a99a7ad94c6c5d62431b3187ad98 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 15 Dec 2010 17:11:22 -0800 Subject: modpost: Put .zdebug* section on white list "as --compress-debug-sections" will generate compressed debug sections with section names ".zdebug*". This patch puts .zdebug* section on white list. Signed-off-by: H.J. Lu Signed-off-by: Michal Marek --- scripts/mod/modpost.c | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 33122ca04e7c..194e2c453609 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -790,6 +790,7 @@ static const char *section_white_list[] = { ".comment*", ".debug*", + ".zdebug*", /* Compressed debug sections. */ ".GCC-command-line", /* mn10300 */ ".mdebug*", /* alpha, score, mips etc. */ ".pdr", /* alpha, score, mips etc. */ -- cgit v1.2.3-59-g8ed1b From 6e5f6856427abe5418f535cb46c454ae8ea7f8e7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 25 Aug 2010 12:22:40 +0200 Subject: checksyscalls: Fix stand-alone usage The usage help in the comments - refers to the wrong script name, - doesn't mention that $srctree must be set. Hence correct the script name, and derive the source tree path from the script path, so we no longer need to rely on $srctree being set by the caller. Signed-off-by: Geert Uytterhoeven Acked-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/checksyscalls.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index 6bb42e72e0e5..3ab316e52313 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh @@ -6,7 +6,7 @@ # and listed below so they are ignored. # # Usage: -# syscallchk gcc gcc-options +# checksyscalls.sh gcc gcc-options # ignore_list() { @@ -204,5 +204,5 @@ sed -n -e '/^\#define/ s/[^_]*__NR_\([^[:space:]]*\).*/\ \#endif/p' $1 } -(ignore_list && syscall_list ${srctree}/arch/x86/include/asm/unistd_32.h) | \ +(ignore_list && syscall_list $(dirname $0)/../arch/x86/include/asm/unistd_32.h) | \ $* -E -x c - > /dev/null -- cgit v1.2.3-59-g8ed1b From a3ba81131aca243bfecfa78c42edec0cd69f72d6 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 22 Dec 2010 13:30:14 -0500 Subject: Make fixdep error handling more explicit Also add missing error handling to fstat call Signed-off-by: Ben Gamari Signed-off-by: Michal Marek --- scripts/basic/fixdep.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index ed0584623690..c9a16abacab4 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -286,7 +286,7 @@ static void do_config_file(const char *filename) fd = open(filename, O_RDONLY); if (fd < 0) { - fprintf(stderr, "fixdep: "); + fprintf(stderr, "fixdep: error opening config file: "); perror(filename); exit(2); } @@ -357,11 +357,15 @@ static void print_deps(void) fd = open(depfile, O_RDONLY); if (fd < 0) { - fprintf(stderr, "fixdep: "); + fprintf(stderr, "fixdep: error opening depfile: "); perror(depfile); exit(2); } - fstat(fd, &st); + if (fstat(fd, &st) < 0) { + fprintf(stderr, "fixdep: error fstat'ing depfile: "); + perror(depfile); + exit(2); + } if (st.st_size == 0) { fprintf(stderr,"fixdep: %s is empty\n",depfile); close(fd); -- cgit v1.2.3-59-g8ed1b From 731ece41fb1047816303295a0cdfed90a528137e Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Fri, 10 Dec 2010 02:09:23 -0600 Subject: modpost: Fix address calculation in reloc_location() This patch fixes a segfault in modpost that is observed when the gold linker is used to link the input objects. The problem is that reloc_location (modpost.c) is computing the address of the relocation target incorrectly. Here, elf->hdr points to the beginning of the ELF file in memory, sechdr points to the relocation section header, section is the index of the section being relocated, and sechdrs[section].sh_offset would be the offset of that section, relative to the beginning of the ELF file. Adding elf->hdr + sechdrs[section].sh_offset gives you the address of the beginning of the section, and adding r->r_offset to that gives you the address of the location to be relocated. You do not need to subtract sechdrs[section].sh_addr from that -- the result of this is an address outside the file, and causes the segfault when addend_386_rel tries to dereference it. This bug is not observed when GNU ld is used to link the inputs. The object file ubuntu/omnibook/omnibook.o is the result of an ld -r of several other files. When GNU ld does an ld -r, it sets the vaddr field for each section to 0, but gold lays out the section addresses sequentially instead: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .text PROGBITS 00000000 000034 004794 00 AX 0 0 4 [ 2] .data PROGBITS 0000b9d0 0047c8 0009c0 00 WA 0 0 4 [ 3] .bss NOBITS 000162f8 005188 00013c 00 WA 0 0 4 [ 4] .rodata.str1.1 PROGBITS 00004f2d 0052c4 001b1a 01 AMS 0 0 1 [ 5] .init.text PROGBITS 00004794 006dde 0005fa 00 AX 0 0 1 [ 6] .exit.text PROGBITS 00004d8e 0073d8 00018a 00 AX 0 0 1 ... So the bug in the tool remained undiscovered because the section's vaddr always happened to be 0. Signed-off-by: Raymes Khoury Signed-off-by: Olof Johansson Signed-off-by: Michal Marek --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 194e2c453609..97d2259ae999 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1442,7 +1442,7 @@ static unsigned int *reloc_location(struct elf_info *elf, int section = shndx2secindex(sechdr->sh_info); return (void *)elf->hdr + sechdrs[section].sh_offset + - r->r_offset - sechdrs[section].sh_addr; + r->r_offset; } static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) -- cgit v1.2.3-59-g8ed1b From bc91c9f313309915f6ec767f56f78dcd0305b20f Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Fri, 17 Dec 2010 17:19:17 +0100 Subject: mkuboot.sh: Fail if mkimage is missing on building an uImage, I get: $ make uImage CHK include/linux/version.h CHK include/generated/utsrelease.h make[1]: `include/generated/mach-types.h' is up to date. CALL scripts/checksyscalls.sh CHK include/generated/compile.h Kernel: arch/arm/boot/Image is ready SHIPPED arch/arm/boot/compressed/lib1funcs.S AS arch/arm/boot/compressed/lib1funcs.o LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready UIMAGE arch/arm/boot/uImage "mkimage" command not found - U-Boot images will not be built Image arch/arm/boot/uImage is ready $ I.e. it says: "uImage is ready" even though the uImage file doesn't exist because mkimage is missing. I propose the attached patch. Signed-off-by: Roland Stigge Signed-off-by: Michal Marek --- scripts/mkuboot.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/mkuboot.sh b/scripts/mkuboot.sh index 2e3d3cd916b8..446739c7843a 100755 --- a/scripts/mkuboot.sh +++ b/scripts/mkuboot.sh @@ -11,7 +11,7 @@ if [ -z "${MKIMAGE}" ]; then if [ -z "${MKIMAGE}" ]; then # Doesn't exist echo '"mkimage" command not found - U-Boot images will not be built' >&2 - exit 0; + exit 1; fi fi -- cgit v1.2.3-59-g8ed1b