Skip to content

Commit 3b9a19e

Browse files
kconfig: loop as long as we changed some symbols in randconfig
Because of choice-in-a-choice constructs, it can happen that not all symbols are assigned a value during randconfig, leading in rare cases to this situation: ---8<--- choice-in-choice.in choice bool "A/B/C" config A bool "A" config B bool "B" if B choice bool "E/F" config E bool "E" config F bool "F" endchoice endif # B config C bool "C" endchoice ---8<--- $ ./scripts/kconfig/conf --randconfig choice-in-choice.in [--SNIP--] $ ./scripts/kconfig/conf --silentoldconfig choice-in-choice.in </dev/null [--SNIP--] A/B/C 1. A (A) > 2. B (B) 3. C (C) choice[1-3]: 2 E/F > 1. E (E) (NEW) 2. F (F) (NEW) choice[1-2]: aborted! Console input/output is redirected. Run 'make oldconfig' to update configuration. Fix this by looping in randconfig for as long as some symbol gets assigned a value. Note: this was spotted with the USB EHCI Debug Device Gadget (USB_G_DBGP), which uses this choice-in-a-choice construct, and exhibits this problem. The example above is just a stripped-down minimalist test-case. Signed-off-by: "Yann E. MORIN" <[email protected]>
1 parent a1ce636 commit 3b9a19e

File tree

3 files changed

+17
-6
lines changed

3 files changed

+17
-6
lines changed

scripts/kconfig/conf.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,8 @@ int main(int ac, char **av)
654654
conf_set_all_new_symbols(def_default);
655655
break;
656656
case randconfig:
657-
conf_set_all_new_symbols(def_random);
657+
/* Really nothing to do in this loop */
658+
while (conf_set_all_new_symbols(def_random)) ;
658659
break;
659660
case defconfig:
660661
conf_set_all_new_symbols(def_default);

scripts/kconfig/confdata.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,7 @@ void conf_set_changed_callback(void (*fn)(void))
10401040
conf_changed_callback = fn;
10411041
}
10421042

1043-
static void randomize_choice_values(struct symbol *csym)
1043+
static bool randomize_choice_values(struct symbol *csym)
10441044
{
10451045
struct property *prop;
10461046
struct symbol *sym;
@@ -1053,7 +1053,7 @@ static void randomize_choice_values(struct symbol *csym)
10531053
* In both cases stop.
10541054
*/
10551055
if (csym->curr.tri != yes)
1056-
return;
1056+
return false;
10571057

10581058
prop = sym_get_choice_prop(csym);
10591059

@@ -1084,6 +1084,8 @@ static void randomize_choice_values(struct symbol *csym)
10841084
csym->flags |= SYMBOL_DEF_USER;
10851085
/* clear VALID to get value calculated */
10861086
csym->flags &= ~(SYMBOL_VALID);
1087+
1088+
return true;
10871089
}
10881090

10891091
void set_all_choice_values(struct symbol *csym)
@@ -1106,7 +1108,7 @@ void set_all_choice_values(struct symbol *csym)
11061108
csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
11071109
}
11081110

1109-
void conf_set_all_new_symbols(enum conf_def_mode mode)
1111+
bool conf_set_all_new_symbols(enum conf_def_mode mode)
11101112
{
11111113
struct symbol *sym, *csym;
11121114
int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y
@@ -1154,13 +1156,15 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
11541156
exit( 1 );
11551157
}
11561158
}
1159+
bool has_changed = false;
11571160

11581161
for_all_symbols(i, sym) {
11591162
if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
11601163
continue;
11611164
switch (sym_get_type(sym)) {
11621165
case S_BOOLEAN:
11631166
case S_TRISTATE:
1167+
has_changed = true;
11641168
switch (mode) {
11651169
case def_yes:
11661170
sym->def[S_DEF_USER].tri = yes;
@@ -1219,6 +1223,12 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
12191223

12201224
sym_calc_value(csym);
12211225
if (mode == def_random)
1222-
randomize_choice_values(csym);
1226+
has_changed = randomize_choice_values(csym);
1227+
else {
1228+
set_all_choice_values(csym);
1229+
has_changed = true;
1230+
}
12231231
}
1232+
1233+
return has_changed;
12241234
}

scripts/kconfig/lkc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ const char *conf_get_autoconfig_name(void);
8686
char *conf_get_default_confname(void);
8787
void sym_set_change_count(int count);
8888
void sym_add_change_count(int count);
89-
void conf_set_all_new_symbols(enum conf_def_mode mode);
89+
bool conf_set_all_new_symbols(enum conf_def_mode mode);
9090
void set_all_choice_values(struct symbol *csym);
9191

9292
struct conf_printer {

0 commit comments

Comments
 (0)