[5/6] kconfig: implement KCONFIG_PROBABILITY for randconfig
diff mbox

Message ID e5fafd7ae13357e3d5cc604c89022982022a8909.1366665922.git.yann.morin.1998@free.fr
State New, archived
Headers show

Commit Message

Yann E. MORIN April 22, 2013, 9:31 p.m. UTC
From: "Yann E. MORIN" <yann.morin.1998@free.fr>

Introduce a KCONFIG_PROBABILITY environment variable to tweak the
probability between 0 (all options off) and 100 (all options on).

[Patch originally written by Peter for Buildroot, see:    ]
[http://git.buildroot.org/buildroot/commit/?id=3435c1afb5 ]

Signed-off-by: Peter Korsgaard <jacmet@uclibc.org>
[yann.morin.1998@free.fr: add to Documentation/]
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
---
 Documentation/kbuild/kconfig.txt |   17 +++++++++++++++++
 scripts/kconfig/confdata.c       |   22 +++++++++++++++++++---
 2 files changed, 36 insertions(+), 3 deletions(-)

Comments

Michal Marek April 23, 2013, 8:44 a.m. UTC | #1
On 22.4.2013 23:31, Yann E. MORIN wrote:
> diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
> index 13ddf11..8d8d853 100644
> --- a/scripts/kconfig/confdata.c
> +++ b/scripts/kconfig/confdata.c
> @@ -1106,7 +1106,16 @@ static void set_all_choice_values(struct symbol *csym)
>  void conf_set_all_new_symbols(enum conf_def_mode mode)
>  {
>  	struct symbol *sym, *csym;
> -	int i, cnt;
> +	int i, cnt, prob = 50;
> +
[...]
>  			case def_random:
> -				cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
> -				sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
> +				cnt = (rand() % 100) - (100 - prob);
> +				if (cnt < 0)
> +					sym->def[S_DEF_USER].tri = no;
> +				else
> +					if ((sym_get_type(sym) == S_TRISTATE)
> +					    && (cnt > prob/2))
> +						sym->def[S_DEF_USER].tri = mod;
> +					else
> +						sym->def[S_DEF_USER].tri = yes;

Previously, the distribution was 50%-50% for boolean options and
33%-33%-33% for tristate options. Now the default for tristate options
changed to 50%-25%-25% (no-mod-yes). Wouldn't it make more sense to have
a special case for KCONFIG_PROBABILITY not set, that would use the same
distribution as before. I.e.

if (prob == -1) {
	cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
	sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
} else {
	/* new math */
}

Not building half of all drivers is rather boring :)

Thanks,
Michal
--
To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Yann E. MORIN April 23, 2013, 4:34 p.m. UTC | #2
Michal, All,

On Tue, Apr 23, 2013 at 10:44:58AM +0200, Michal Marek wrote:
> On 22.4.2013 23:31, Yann E. MORIN wrote:
> > diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
> > index 13ddf11..8d8d853 100644
> > --- a/scripts/kconfig/confdata.c
> > +++ b/scripts/kconfig/confdata.c
> > @@ -1106,7 +1106,16 @@ static void set_all_choice_values(struct symbol *csym)
> >  void conf_set_all_new_symbols(enum conf_def_mode mode)
> >  {
> >  	struct symbol *sym, *csym;
> > -	int i, cnt;
> > +	int i, cnt, prob = 50;
> > +
> [...]
> >  			case def_random:
> > -				cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
> > -				sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
> > +				cnt = (rand() % 100) - (100 - prob);
> > +				if (cnt < 0)
> > +					sym->def[S_DEF_USER].tri = no;
> > +				else
> > +					if ((sym_get_type(sym) == S_TRISTATE)
> > +					    && (cnt > prob/2))
> > +						sym->def[S_DEF_USER].tri = mod;
> > +					else
> > +						sym->def[S_DEF_USER].tri = yes;
> 
> Previously, the distribution was 50%-50% for boolean options and
> 33%-33%-33% for tristate options. Now the default for tristate options
> changed to 50%-25%-25% (no-mod-yes). Wouldn't it make more sense to have
> a special case for KCONFIG_PROBABILITY not set, that would use the same
> distribution as before. I.e.
> 
> if (prob == -1) {
> 	cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
> 	sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
> } else {
> 	/* new math */
> }

OK, what about this proposal, instead:
    KCONFIG_PROBABILITY     y:n split           y:m:n split             Notes
    -------------------------------------------------------------------------
    unset or empty          50  : 50            33  : 33  : 34          [1]
    N                        N  : 100-N         N/2 : N/2 : 100-N       [2]
    N:M                     N+M : 100-(N+M)      N  :  M  : 100-(N+M)   [3]
    N:M:L                    N  : 100-N          M  :  L  : 100-(M+L)   [4]

[1] current behaviour
[2] the curent patch's behaviour
[3] boolean's Y probability is tristate's Y plus tristate's M probabilities
[4] all probabilities explicitly stated

I have a prototype for this I need to clean up. If that's OK for you, I'll
submit that; if not, I'll use your suggestion.

> Not building half of all drivers is rather boring :)

Oh! No! All that idle CPU time that could be put to better use... ;-]

Regards,
Yann E. MORIN.
Michal Marek April 23, 2013, 8:05 p.m. UTC | #3
Dne 23.4.2013 18:34, Yann E. MORIN napsal(a):
> Michal, All,
> 
> On Tue, Apr 23, 2013 at 10:44:58AM +0200, Michal Marek wrote:
>> On 22.4.2013 23:31, Yann E. MORIN wrote:
>>> diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
>>> index 13ddf11..8d8d853 100644
>>> --- a/scripts/kconfig/confdata.c
>>> +++ b/scripts/kconfig/confdata.c
>>> @@ -1106,7 +1106,16 @@ static void set_all_choice_values(struct symbol *csym)
>>>  void conf_set_all_new_symbols(enum conf_def_mode mode)
>>>  {
>>>  	struct symbol *sym, *csym;
>>> -	int i, cnt;
>>> +	int i, cnt, prob = 50;
>>> +
>> [...]
>>>  			case def_random:
>>> -				cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
>>> -				sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
>>> +				cnt = (rand() % 100) - (100 - prob);
>>> +				if (cnt < 0)
>>> +					sym->def[S_DEF_USER].tri = no;
>>> +				else
>>> +					if ((sym_get_type(sym) == S_TRISTATE)
>>> +					    && (cnt > prob/2))
>>> +						sym->def[S_DEF_USER].tri = mod;
>>> +					else
>>> +						sym->def[S_DEF_USER].tri = yes;
>>
>> Previously, the distribution was 50%-50% for boolean options and
>> 33%-33%-33% for tristate options. Now the default for tristate options
>> changed to 50%-25%-25% (no-mod-yes). Wouldn't it make more sense to have
>> a special case for KCONFIG_PROBABILITY not set, that would use the same
>> distribution as before. I.e.
>>
>> if (prob == -1) {
>> 	cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
>> 	sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
>> } else {
>> 	/* new math */
>> }
> 
> OK, what about this proposal, instead:
>     KCONFIG_PROBABILITY     y:n split           y:m:n split             Notes
>     -------------------------------------------------------------------------
>     unset or empty          50  : 50            33  : 33  : 34          [1]
>     N                        N  : 100-N         N/2 : N/2 : 100-N       [2]
>     N:M                     N+M : 100-(N+M)      N  :  M  : 100-(N+M)   [3]
>     N:M:L                    N  : 100-N          M  :  L  : 100-(M+L)   [4]
> 
> [1] current behaviour
> [2] the curent patch's behaviour
> [3] boolean's Y probability is tristate's Y plus tristate's M probabilities
> [4] all probabilities explicitly stated
> 
> I have a prototype for this I need to clean up. If that's OK for you, I'll
> submit that; if not, I'll use your suggestion.

As long as the default behavior does not change (1/3 vs. 34% is fine
:)), then I am fine with any semantics of $KCONFIG_PROBABILITY.

Michal
--
To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Yann E. MORIN April 23, 2013, 9:50 p.m. UTC | #4
Michal, All,

On Mon, Apr 22, 2013 at 11:31:24PM +0200, Yann E. MORIN wrote:
> From: "Yann E. MORIN" <yann.morin.1998@free.fr>
> Introduce a KCONFIG_PROBABILITY environment variable to tweak the
> probability between 0 (all options off) and 100 (all options on).

Please, drop this patch: randconfig is utterly broken is a very subtle
way (even without this patch applied), which I still have to track down,
and I'm not confident I can find and properly fis it before the end of
the week.

The core of the problem is the following code (as seen in current master
from Linus' tree):

scripts/kconfig/confdata.c:
[--SNIP--]
  1106  void conf_set_all_new_symbols(enum conf_def_mode mode)
  1107  {
  1108          struct symbol *sym, *csym;
  1109          int i, cnt;
  1110
  1111          for_all_symbols(i, sym) {
  1112                  if (sym_has_value(sym))
  1113                          continue;
  1114                  switch (sym_get_type(sym)) {
  1115                  case S_BOOLEAN:
  1116                  case S_TRISTATE:
  1117                          switch (mode) {
  1118                          case def_yes:
  1119                                  sym->def[S_DEF_USER].tri = yes;
  1120                                  break;
  1121                          case def_mod:
  1122                                  sym->def[S_DEF_USER].tri = mod;
  1123                                  break;
  1124                          case def_no:
  1125                                  sym->def[S_DEF_USER].tri = no;
  1126                                  break;
  1127                          case def_random:
  1128                                  cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
  1129                                  sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
  1130                                  break;
  1131                          default:
  1132                                  continue;
  1133                          }
  1134                          if (!(sym_is_choice(sym) && mode == def_random))
  1135                                  sym->flags |= SYMBOL_DEF_USER;
  1136                          break;
  1137                  default:
  1138                          break;
  1139                  }
  1140
  1141          }
  1142
  1143          sym_clear_all_valid();
[--SNIP--]

Fact is, sym_get_type(sym) is never ever equal to S_TRISTATE when we
test it on line 1128.

I'm currently investigating, but I suspect that's because CONFIG_MODULES
is not yet set, which only happens after we call to sym_clear_all_valid()
later on line 1143, which is too late.

I'll be testing this solution (pseudo-code):

    find symbol defining MODULES
        randomly set it to y or no
    sym_clear_all_valid();
    for_all_symbols(i, sym) {
        current code
    }
    sym_clear_all_valid();

More on this later. For now, just drop this probability patch. The other
patches are still good for 3.10.

Regards,
Yann E. MORIN.
Yann E. MORIN April 24, 2013, 5:56 p.m. UTC | #5
Michal, All,

On Tue, Apr 23, 2013 at 11:50:44PM +0200, Yann E. MORIN wrote:
> On Mon, Apr 22, 2013 at 11:31:24PM +0200, Yann E. MORIN wrote:
> > From: "Yann E. MORIN" <yann.morin.1998@free.fr>
> > Introduce a KCONFIG_PROBABILITY environment variable to tweak the
> > probability between 0 (all options off) and 100 (all options on).
> 
> Please, drop this patch: randconfig is utterly broken is a very subtle
> way (even without this patch applied), which I still have to track down,
> and I'm not confident I can find and properly fis it before the end of
[--SNIP--]
> More on this later. For now, just drop this probability patch. The other
> patches are still good for 3.10.

Michal, I have something interesting now that I'm testing. If you did
not already apply the rest of the series, just hold-on just a bit more,
I'll re-spin a new version of the series later tonight.

Regards,
Yann E. MORIN.
Michal Marek April 24, 2013, 10:28 p.m. UTC | #6
Dne 24.4.2013 19:56, Yann E. MORIN napsal(a):
> Michal, All,
> 
> On Tue, Apr 23, 2013 at 11:50:44PM +0200, Yann E. MORIN wrote:
>> On Mon, Apr 22, 2013 at 11:31:24PM +0200, Yann E. MORIN wrote:
>>> From: "Yann E. MORIN" <yann.morin.1998@free.fr>
>>> Introduce a KCONFIG_PROBABILITY environment variable to tweak the
>>> probability between 0 (all options off) and 100 (all options on).
>>
>> Please, drop this patch: randconfig is utterly broken is a very subtle
>> way (even without this patch applied), which I still have to track down,
>> and I'm not confident I can find and properly fis it before the end of
> [--SNIP--]
>> More on this later. For now, just drop this probability patch. The other
>> patches are still good for 3.10.
> 
> Michal, I have something interesting now that I'm testing. If you did
> not already apply the rest of the series, just hold-on just a bit more,
> I'll re-spin a new version of the series later tonight.

OK, I'll wait.

Michal
--
To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

diff --git a/Documentation/kbuild/kconfig.txt b/Documentation/kbuild/kconfig.txt
index dbf746b..1817128 100644
--- a/Documentation/kbuild/kconfig.txt
+++ b/Documentation/kbuild/kconfig.txt
@@ -98,6 +98,23 @@  You can set this to the integer value used to seed the RNG, if you want
 to somehow debug the behaviour of the kconfig parser/frontends.
 If not set, the current time will be used.
 
+KCONFIG_PROBABILITY
+--------------------------------------------------
+If this variable is set and contains an integer in the range [0,100],
+then its value is used as a probability each variable is set. If the
+variable is a tristate, there is then a further 50% chance it is set
+to either 'M' or 'Y'. If KCONFIG_PROBABILITY is not set, then the
+default is 50. Examples (rounded figures):
+	KCONFIG_PROBABILITY=33
+		boolean     :     no : 67%                yes: 33%
+		tristrate   :     no : 67%    mod: 16%    yes: 16%
+	KCONFIG_PROBABILITY=50
+		boolean     :     no : 50%                yes: 50%
+		tristate    :     no : 50%    mod: 25%    yes: 25%
+	KCONFIG_PROBABILITY=67
+		boolean     :     no : 33%                yes: 67%
+		tristrate   :     no : 33%    mod: 33%    yes: 33%
+
 ______________________________________________________________________
 Environment variables for 'silentoldconfig'
 
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 13ddf11..8d8d853 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -1106,7 +1106,16 @@  static void set_all_choice_values(struct symbol *csym)
 void conf_set_all_new_symbols(enum conf_def_mode mode)
 {
 	struct symbol *sym, *csym;
-	int i, cnt;
+	int i, cnt, prob = 50;
+
+	if (mode == def_random) {
+		char *endp, *env = getenv("KCONFIG_PROBABILITY");
+		if (env && *env) {
+			int tmp = (int)strtol(env, &endp, 10);
+			if (*endp == '\0' && tmp >= 0 && tmp <= 100)
+				prob = tmp;
+		}
+	}
 
 	for_all_symbols(i, sym) {
 		if (sym_has_value(sym))
@@ -1125,8 +1134,15 @@  void conf_set_all_new_symbols(enum conf_def_mode mode)
 				sym->def[S_DEF_USER].tri = no;
 				break;
 			case def_random:
-				cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
-				sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
+				cnt = (rand() % 100) - (100 - prob);
+				if (cnt < 0)
+					sym->def[S_DEF_USER].tri = no;
+				else
+					if ((sym_get_type(sym) == S_TRISTATE)
+					    && (cnt > prob/2))
+						sym->def[S_DEF_USER].tri = mod;
+					else
+						sym->def[S_DEF_USER].tri = yes;
 				break;
 			default:
 				continue;