Перейти к основному содержимому

⚠️ Проблемы рекурсии в Kconfig

warning

Материал возможно устарел.

к сведению

Проблема #1

# Простая проблема рекурсивной зависимости Kconfig
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Проверяйте следующим образом:
#
# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig
#
# Этот файл Kconfig имеет простую проблему рекурсивной зависимости.
# Чтобы понять, почему возникает эта проблема, давайте рассмотрим,
# что Kconfig'у нужно учитывать. Мы последовательно рассмотрим вопросы,
# на которые Kconfig должен ответить, шаг за шагом.
#
# * Какие возможны значения для CORE?
#
# CORE_BELL_A_ADVANCED "выбирает" (select) CORE, что значит, что он влияет на значения,
# которые возможны для CORE. Для примера: если у CORE_BELL_A_ADVANCED значение 'y',
# то у CORE должно быть аналогичное значение 'y'.
#
# * Что влияет на CORE_BELL_A_ADVANCED?
#
# Как можно понять из именить, CORE_BELL_A_ADVANCED это продвинутый функционал CORE_BELL_A,
# поэтому само собой он зависит от CORE_BELL_A. Из-за этого если CORE_BELL_A
# в значении 'y', то мы значем, что CORE_BELL_A_ADVANCED может быть 'y' тоже.
#
# * Что влияет на CORE_BELL_A?
#
# CORE_BELL_A зависит от CORE, так что CORE влияет на CORE_BELL_A.
#
# Но в этом и проблема, потому что это значит, что для того чтобы
# определить какое значения возможны для CORE мы приходим к тому, что
# нам нужно снова рассмотреть вопросы, касающиеся возможных значений самого CORE.
# Отвечая на изначальный вопрос о том, какие значени возможны для CORE,
# введут kconfig в состояние цикла. Когда такое происходит, Kconfig
# завершает свою работу и выводит ошибку "recursive dependency detected".
#
# Читая файл Documentation/kbuild/Kconfig.recursion-issue-01, может показаться
# очевидным, что простое решение для этой проблемы – просто удалить
# "select CORE" из CORE_BELL_A_ADVANCED так как это в любом случае
# будет из-за того, что CORE_BELL_A_ADVANCED зависит от CORE_BELL_A,
# которая зависит от CORE. Рекурсивные зависимости не всегда так
# просто разрешить, ниже мы привели пример практических последствий
# этой рекурсивной проблемы, решение которой, возможно, не так легко понять.
# Обратите внимание, что совпадающие семантики зависимости от CORE
# также состоят в решении этой проблемы.

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

Проблема #2

# Накопительная проблема рекурсивной зависимости в Kconfig
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Проверяйте следующим образом:
#
# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig
#
# Рекурсивные ограничения в Kconfig имеют некоторые неочевидные
# последствия для семантики kconfig, которые задокументированы здесь.
# Одно из известных практических последствий рекурсивного ограничения
# заключается в том, что драйверы не могут отрицать функции других драйверов,
# если они имеют общую основную зависимость и используют непересекающуюся семантику
# для обозначения этих требований, например, некоторые драйверы используют
# "depends on", в то время как другие используют "select". Например, это означает,
# что если драйвер A и драйвер B имеют одну и ту же основную зависимость,
# и драйвер A использует "select", а драйвер B использует "depends on",
# все функции, которые "выбирает" (select) драйвер A, теперь не могут быть
# отклонены драйвером B.
#
# Возможно, не столь очевидное следствие этого заключается в том,
# что если семантика этих основных требований не синхронизирована
# должным образом, по мере того как драйверы развиваются, функции,
# которые они "выбирают" или от которых зависят, в конечном итоге
# становятся общими требованиями, которые не могут быть
# отклонены другими драйверами.
#
# Пример, приведенный в документации `Documentation/kbuild/Kconfig.recursion-issue-02`,
# описывает простую структуру ядра драйвера с примером функций, которые может иметь ядро linux. \
# Предположим, у нас есть какая-то основная функциональность (CORE),
# и ядро, имееющее ряд дополнительных функций, которые оно хочет реализовать,
# но в данный момент поддерживает только одни из них: CORE_BELL_A и CORE_BELL_B.
# Если CORE_BELL_A имеет некоторую продвинутую функцию CORE_BELL_A_ADVANCED,
# которая "выбирает" CORE_BELL_A, то CORE_BELL_A в конечном итоге становится
# общей функцией для других функций в системе, которые не могут её отменить.
# Причина этой проблемы заключается в разном использовании семантики
# для выражения взаимосвязи каждой функции с ядром: одна функция
# использует "depends on", а другая — "select". Еще более важная причина состоит в том,
# что kconfig не проверяет зависимости символа, выбранного через "select".
# Когда такие символы выбираются, kconfig определяет их как обязательные.
# Для получения более подробной информации о таком категоричном подходе "select",
# см. документацию `Documentation/kbuild/Kconfig.select-break` (перевод доступен по ссылке снизу).
#
# Для того чтобы пофиксить это, необходимо заменить "depends on CORE" на "select CORE",
# или наоборот "select CORE" должен быть заменен на "depends on CORE".
#
# Для примера проблемы из реальной жизни можно рассмотреть попытку
# удалить "select FW_LOADER" [0]. В конечном итоге простым альтернативным
# решением этой проблемы стали исправления семантики с учетом недавно введенным функционалом.
#
# [0] https://lore.kernel.org/r/1432241149-8762-1-git-send-email-mcgrof@do-not-panic.com

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