forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
kbuild: document recursive dependency limitation / resolution
Recursive dependency issues with kconfig are unavoidable due to some limitations with kconfig, since these issues are recurring provide a hint to the user how they can resolve these dependency issues and also document why such limitation exists. While at it also document a bit of future prospects of ways to enhance Kconfig, including providing formal semantics and evaluation of use of a SAT solver. If you're interested in this work or prospects of it check out the kconfig-sat project wiki [0] and mailing list [1]. [0] http://kernelnewbies.org/KernelProjects/kconfig-sat [1] https://groups.google.com/d/forum/kconfig-sat Cc: Geert Uytterhoeven <[email protected]> Cc: James Bottomley <[email protected]> Cc: Josh Triplett <[email protected]> Cc: Paul Bolle <[email protected]> Cc: Herbert Xu <[email protected]> Cc: Takashi Iwai <[email protected]> Cc: "Yann E. MORIN" <[email protected]> Cc: Jonathan Corbet <[email protected]> Cc: Mate Soos <[email protected]> Signed-off-by: Luis R. Rodriguez <[email protected]> Signed-off-by: Michal Marek <[email protected]>
- Loading branch information
Showing
5 changed files
with
316 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Simple Kconfig recursive issue | ||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
# | ||
# Test with: | ||
# | ||
# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig | ||
# | ||
# This Kconfig file has a simple recursive dependency issue. In order to | ||
# understand why this recursive dependency issue occurs lets consider what | ||
# Kconfig needs to address. We iterate over what Kconfig needs to address | ||
# by stepping through the questions it needs to address sequentially. | ||
# | ||
# * What values are possible for CORE? | ||
# | ||
# CORE_BELL_A_ADVANCED selects CORE, which means that it influences the values | ||
# that are possible for CORE. So for example if CORE_BELL_A_ADVANCED is 'y', | ||
# CORE must be 'y' too. | ||
# | ||
# * What influences CORE_BELL_A_ADVANCED ? | ||
# | ||
# As the name implies CORE_BELL_A_ADVANCED is an advanced feature of | ||
# CORE_BELL_A so naturally it depends on CORE_BELL_A. So if CORE_BELL_A is 'y' | ||
# we know CORE_BELL_A_ADVANCED can be 'y' too. | ||
# | ||
# * What influences CORE_BELL_A ? | ||
# | ||
# CORE_BELL_A depends on CORE, so CORE influences CORE_BELL_A. | ||
# | ||
# But that is a problem, because this means that in order to determine | ||
# what values are possible for CORE we ended up needing to address questions | ||
# regarding possible values of CORE itself again. Answering the original | ||
# question of what are the possible values of CORE would make the kconfig | ||
# tools run in a loop. When this happens Kconfig exits and complains about | ||
# the "recursive dependency detected" error. | ||
# | ||
# Reading the Documentation/kbuild/Kconfig.recursion-issue-01 file it may be | ||
# obvious that an easy to solution to this problem should just be the removal | ||
# of the "select CORE" from CORE_BELL_A_ADVANCED as that is implicit already | ||
# since CORE_BELL_A depends on CORE. Recursive dependency issues are not always | ||
# so trivial to resolve, we provide another example below of practical | ||
# implications of this recursive issue where the solution is perhaps not so | ||
# easy to understand. Note that matching semantics on the dependency on | ||
# CORE also consist of a solution to this recursive problem. | ||
|
||
mainmenu "Simple example to demo kconfig recursive dependency issue" | ||
|
||
config CORE | ||
tristate | ||
|
||
config CORE_BELL_A | ||
tristate | ||
depends on CORE | ||
|
||
config CORE_BELL_A_ADVANCED | ||
tristate | ||
depends on CORE_BELL_A | ||
select CORE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Cumulative Kconfig recursive issue | ||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
# | ||
# Test with: | ||
# | ||
# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig | ||
# | ||
# The recursive limitations with Kconfig has some non intuitive implications on | ||
# kconfig sematics which are documented here. One known practical implication | ||
# of the recursive limitation is that drivers cannot negate features from other | ||
# drivers if they share a common core requirement and use disjoint semantics to | ||
# annotate those requirements, ie, some drivers use "depends on" while others | ||
# use "select". For instance it means if a driver A and driver B share the same | ||
# core requirement, and one uses "select" while the other uses "depends on" to | ||
# annotate this, all features that driver A selects cannot now be negated by | ||
# driver B. | ||
# | ||
# A perhaps not so obvious implication of this is that, if semantics on these | ||
# core requirements are not carefully synced, as drivers evolve features | ||
# they select or depend on end up becoming shared requirements which cannot be | ||
# negated by other drivers. | ||
# | ||
# The example provided in Documentation/kbuild/Kconfig.recursion-issue-02 | ||
# describes a simple driver core layout of example features a kernel might | ||
# have. Let's assume we have some CORE functionality, then the kernel has a | ||
# series of bells and whistles it desires to implement, its not so advanced so | ||
# it only supports bells at this time: CORE_BELL_A and CORE_BELL_B. If | ||
# CORE_BELL_A has some advanced feature CORE_BELL_A_ADVANCED which selects | ||
# CORE_BELL_A then CORE_BELL_A ends up becoming a common BELL feature which | ||
# other bells in the system cannot negate. The reason for this issue is | ||
# due to the disjoint use of semantics on expressing each bell's relationship | ||
# with CORE, one uses "depends on" while the other uses "select". Another | ||
# more important reason is that kconfig does not check for dependencies listed | ||
# under 'select' for a symbol, when such symbols are selected kconfig them | ||
# as mandatory required symbols. For more details on the heavy handed nature | ||
# of select refer to Documentation/kbuild/Kconfig.select-break | ||
# | ||
# To fix this the "depends on CORE" must be changed to "select CORE", or the | ||
# "select CORE" must be changed to "depends on CORE". | ||
# | ||
# For an example real world scenario issue refer to the attempt to remove | ||
# "select FW_LOADER" [0], in the end the simple alternative solution to this | ||
# problem consisted on matching semantics with newly introduced features. | ||
# | ||
# [0] http://lkml.kernel.org/r/[email protected] | ||
|
||
mainmenu "Simple example to demo cumulative kconfig recursive dependency implication" | ||
|
||
config CORE | ||
tristate | ||
|
||
config CORE_BELL_A | ||
tristate | ||
depends on CORE | ||
|
||
config CORE_BELL_A_ADVANCED | ||
tristate | ||
select CORE_BELL_A | ||
|
||
config CORE_BELL_B | ||
tristate | ||
depends on !CORE_BELL_A | ||
select CORE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Select broken dependency issue | ||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
# | ||
# Test with: | ||
# | ||
# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.select-break menuconfig | ||
# | ||
# kconfig will not complain and enable this layout for configuration. This is | ||
# currently a feature of kconfig, given select was designed to be heavy handed. | ||
# Kconfig currently does not check the list of symbols listed on a symbol's | ||
# "select" list, this is done on purpose to help load a set of known required | ||
# symbols. Because of this use of select should be used with caution. An | ||
# example of this issue is below. | ||
# | ||
# The option B and C are clearly contradicting with respect to A. | ||
# However, when A is set, C can be set as well because Kconfig does not | ||
# visit the dependencies of the select target (in this case B). And since | ||
# Kconfig does not visit the dependencies, it breaks the dependencies of B | ||
# (!A). | ||
|
||
mainmenu "Simple example to demo kconfig select broken dependency issue" | ||
|
||
config A | ||
bool "CONFIG A" | ||
|
||
config B | ||
bool "CONFIG B" | ||
depends on !A | ||
|
||
config C | ||
bool "CONFIG C" | ||
depends on A | ||
select B |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters