From: David Gibson Date: Wed, 9 Nov 2005 05:34:46 +0000 (-0800) Subject: [PATCH] kconfig: Fix Kconfig performance bug X-Git-Tag: v2.6.15-rc1~378 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3f04e7ddf47a1c821dfaa886161d94774af583fa;p=platform%2Fkernel%2Flinux-3.10.git [PATCH] kconfig: Fix Kconfig performance bug When doing its recursive dependency check, scripts/kconfig/conf uses the flag SYMBOL_CHECK_DONE to avoid rechecking a symbol it has already checked. However, that flag is only set at the top level, so if a symbol is first encountered as a dependency of another symbol it will be rechecked every time it is encountered until it's encountered at the top level. This patch adjusts the flag setting so that each symbol will only be checked once, regardless of whether it is first encountered at the top level, or while recursing down from another symbol. On complex configurations, this vastly speeds up scripts/kconfig/conf. The config in the powerpc merge tree is particularly bad: this patch reduces the time for 'scripts/kconfig/conf -o arch/powerpc/Kconfig' by a factor of 40 on a G5. That's even including the time to print the config, so the speedup in the actual checking is more likely 2 or 3 orders of magnitude. Signed-off-by: David Gibson Signed-off-by: Roman Zippel Cc: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 7d39ff4..1b36ef1 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -93,7 +93,6 @@ struct symbol { #define SYMBOL_NEW 0x0800 #define SYMBOL_AUTO 0x1000 #define SYMBOL_CHECKED 0x2000 -#define SYMBOL_CHECK_DONE 0x4000 #define SYMBOL_WARNED 0x8000 #define SYMBOL_MAXLENGTH 256 diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index affa52f..10d96c4 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -731,12 +731,12 @@ struct symbol *sym_check_deps(struct symbol *sym) struct symbol *sym2; struct property *prop; - if (sym->flags & SYMBOL_CHECK_DONE) - return NULL; if (sym->flags & SYMBOL_CHECK) { printf("Warning! Found recursive dependency: %s", sym->name); return sym; } + if (sym->flags & SYMBOL_CHECKED) + return NULL; sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); sym2 = sym_check_expr_deps(sym->rev_dep.expr); @@ -756,8 +756,13 @@ struct symbol *sym_check_deps(struct symbol *sym) goto out; } out: - if (sym2) + if (sym2) { printf(" %s", sym->name); + if (sym2 == sym) { + printf("\n"); + sym2 = NULL; + } + } sym->flags &= ~SYMBOL_CHECK; return sym2; } diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped index ff4fcc0..da12f7b 100644 --- a/scripts/kconfig/zconf.tab.c_shipped +++ b/scripts/kconfig/zconf.tab.c_shipped @@ -1933,10 +1933,7 @@ void conf_parse(const char *name) exit(1); menu_finalize(&rootmenu); for_all_symbols(i, sym) { - if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) - printf("\n"); - else - sym->flags |= SYMBOL_CHECK_DONE; + sym_check_deps(sym); } sym_change_count = 1; diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index e1a0f45..1e214e9 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -495,10 +495,7 @@ void conf_parse(const char *name) exit(1); menu_finalize(&rootmenu); for_all_symbols(i, sym) { - if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) - printf("\n"); - else - sym->flags |= SYMBOL_CHECK_DONE; + sym_check_deps(sym); } sym_change_count = 1;