1. 20 Sep, 2024 11 commits
    • Masahiro Yamada's avatar
      kconfig: cache expression values · 95573cac
      Masahiro Yamada authored
      Cache expression values to avoid recalculating them repeatedly.
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      95573cac
    • Masahiro Yamada's avatar
      kconfig: use hash table to reuse expressions · f93d6bfb
      Masahiro Yamada authored
      Currently, every expression in Kconfig files produces a new abstract
      syntax tree (AST), even if it is identical to a previously encountered
      one.
      
      Consider the following code:
      
          config FOO
                 bool "FOO"
                 depends on (A || B) && C
      
          config BAR
                 bool "BAR"
                 depends on (A || B) && C
      
          config BAZ
                 bool "BAZ"
                 depends on A || B
      
      The "depends on" lines are similar, but currently a separate AST is
      allocated for each one.
      
      The current data structure looks like this:
      
        FOO->dep ==> AND        BAR->dep ==> AND        BAZ->dep ==> OR
                    /   \                   /   \                   /  \
                  OR     C                OR     C                 A    B
                 /  \                    /  \
                A    B                  A    B
      
      This is redundant; FOO->dep and BAR->dep have identical ASTs but
      different memory instances.
      
      We can optimize this; FOO->dep and BAR->dep can share the same AST, and
      BAZ->dep can reference its sub tree.
      
      The optimized data structure looks like this:
      
        FOO->dep, BAR->dep ==> AND
                              /   \
               BAZ->dep ==> OR     C
                           /  \
                          A    B
      
      This commit introduces a hash table to keep track of allocated
      expressions. If an identical expression is found, it is reused.
      
      This does not necessarily result in memory savings, as menu_finalize()
      transforms expressions without freeing up stale ones. This will be
      addressed later.
      
      One optimization that can be easily implemented is caching the
      expression's value. Once FOO's dependency, (A || B) && C, is calculated,
      it can be cached, eliminating the need to recalculate it for BAR.
      
      This commit also reverts commit e983b7b1 ("kconfig/menu.c: fix
      multiple references to expressions in menu_add_prop()").
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      f93d6bfb
    • Masahiro Yamada's avatar
      kconfig: refactor expr_eliminate_dups() · 440f67cc
      Masahiro Yamada authored
      Currently, expr_eliminate_dups() passes two identical pointers down to
      expr_eliminate_dups1(), which later skips processing identical leaves.
      
      This approach is somewhat tricky and, more importantly, it will not work
      with the refactoring made in the next commit.
      
      This commit slightly changes the recursion logic; it deduplicates both
      the left and right arms, and then passes them to expr_eliminate_dups1().
      expr_eliminate_dups() should produce the same result.
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      440f67cc
    • Masahiro Yamada's avatar
      kconfig: add comments to expression transformations · 4fa146ea
      Masahiro Yamada authored
      Provide explanations for complex transformations.
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      4fa146ea
    • Masahiro Yamada's avatar
      kconfig: change some expr_*() functions to bool · d607e0e7
      Masahiro Yamada authored
      This clarifies the behavior of these functions.
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      d607e0e7
    • Masahiro Yamada's avatar
      scripts: move hash function from scripts/kconfig/ to scripts/include/ · a16219bd
      Masahiro Yamada authored
      This function was originally added by commit 8af27e1d ("fixdep: use
      hash table instead of a single array").
      
      Move it to scripts/include/ so that other host programs can use it.
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      a16219bd
    • Masahiro Yamada's avatar
      kallsyms: change overflow variable to bool type · 9a418218
      Masahiro Yamada authored
      Change the 'overflow' variable to bool. Also, remove unnecessary
      parentheses.
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      9a418218
    • Masahiro Yamada's avatar
      kallsyms: squash output_address() · 327df5bf
      Masahiro Yamada authored
      After commit 64e16609 ("kallsyms: get rid of code for absolute,
      kallsyms"), there is only one call site for output_address(). Squash it.
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      327df5bf
    • Kris Van Hees's avatar
      kbuild: add install target for modules.builtin.ranges · ae70d708
      Kris Van Hees authored
      When CONFIG_BUILTIN_MODULE_RANGES is enabled, the modules.builtin.ranges
      file should be installed in the module install location.
      Signed-off-by: default avatarKris Van Hees <kris.van.hees@oracle.com>
      Reviewed-by: default avatarNick Alcock <nick.alcock@oracle.com>
      Tested-by: default avatarSam James <sam@gentoo.org>
      Reviewed-by: default avatarSami Tolvanen <samitolvanen@google.com>
      Tested-by: default avatarSami Tolvanen <samitolvanen@google.com>
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      ae70d708
    • Kris Van Hees's avatar
      scripts: add verifier script for builtin module range data · ac7bd094
      Kris Van Hees authored
      The modules.builtin.ranges offset range data for builtin modules is
      generated at compile time based on the list of built-in modules and
      the vmlinux.map and vmlinux.o.map linker maps.  This data can be used
      to determine whether a symbol at a particular address belongs to
      module code that was configured to be compiled into the kernel proper
      as a built-in module (rather than as a standalone module).
      
      This patch adds a script that uses the generated modules.builtin.ranges
      data to annotate the symbols in the System.map with module names if
      their address falls within a range that belongs to one or more built-in
      modules.
      
      It then processes the vmlinux.map (and if needed, vmlinux.o.map) to
      verify the annotation:
      
        - For each top-level section:
           - For each object in the section:
              - Determine whether the object is part of a built-in module
                (using modules.builtin and the .*.cmd file used to compile
                 the object as suggested in [0])
              - For each symbol in that object, verify that the built-in
                module association (or lack thereof) matches the annotation
                given to the symbol.
      Signed-off-by: default avatarKris Van Hees <kris.van.hees@oracle.com>
      Reviewed-by: default avatarNick Alcock <nick.alcock@oracle.com>
      Reviewed-by: default avatarAlan Maguire <alan.maguire@oracle.com>
      Tested-by: default avatarSam James <sam@gentoo.org>
      Reviewed-by: default avatarSami Tolvanen <samitolvanen@google.com>
      Tested-by: default avatarSami Tolvanen <samitolvanen@google.com>
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      ac7bd094
    • Kris Van Hees's avatar
      kbuild: generate offset range data for builtin modules · 5f5e7344
      Kris Van Hees authored
      Create file module.builtin.ranges that can be used to find where
      built-in modules are located by their addresses. This will be useful for
      tracing tools to find what functions are for various built-in modules.
      
      The offset range data for builtin modules is generated using:
       - modules.builtin: associates object files with module names
       - vmlinux.map: provides load order of sections and offset of first member
          per section
       - vmlinux.o.map: provides offset of object file content per section
       - .*.cmd: build cmd file with KBUILD_MODFILE
      
      The generated data will look like:
      
      .text 00000000-00000000 = _text
      .text 0000baf0-0000cb10 amd_uncore
      .text 0009bd10-0009c8e0 iosf_mbi
      ...
      .text 00b9f080-00ba011a intel_skl_int3472_discrete
      .text 00ba0120-00ba03c0 intel_skl_int3472_discrete intel_skl_int3472_tps68470
      .text 00ba03c0-00ba08d6 intel_skl_int3472_tps68470
      ...
      .data 00000000-00000000 = _sdata
      .data 0000f020-0000f680 amd_uncore
      
      For each ELF section, it lists the offset of the first symbol.  This can
      be used to determine the base address of the section at runtime.
      
      Next, it lists (in strict ascending order) offset ranges in that section
      that cover the symbols of one or more builtin modules.  Multiple ranges
      can apply to a single module, and ranges can be shared between modules.
      
      The CONFIG_BUILTIN_MODULE_RANGES option controls whether offset range data
      is generated for kernel modules that are built into the kernel image.
      
      How it works:
      
       1. The modules.builtin file is parsed to obtain a list of built-in
          module names and their associated object names (the .ko file that
          the module would be in if it were a loadable module, hereafter
          referred to as <kmodfile>).  This object name can be used to
          identify objects in the kernel compile because any C or assembler
          code that ends up into a built-in module will have the option
          -DKBUILD_MODFILE=<kmodfile> present in its build command, and those
          can be found in the .<obj>.cmd file in the kernel build tree.
      
          If an object is part of multiple modules, they will all be listed
          in the KBUILD_MODFILE option argument.
      
          This allows us to conclusively determine whether an object in the
          kernel build belong to any modules, and which.
      
       2. The vmlinux.map is parsed next to determine the base address of each
          top level section so that all addresses into the section can be
          turned into offsets.  This makes it possible to handle sections
          getting loaded at different addresses at system boot.
      
          We also determine an 'anchor' symbol at the beginning of each
          section to make it possible to calculate the true base address of
          a section at runtime (i.e. symbol address - symbol offset).
      
          We collect start addresses of sections that are included in the top
          level section.  This is used when vmlinux is linked using vmlinux.o,
          because in that case, we need to look at the vmlinux.o linker map to
          know what object a symbol is found in.
      
          And finally, we process each symbol that is listed in vmlinux.map
          (or vmlinux.o.map) based on the following structure:
      
          vmlinux linked from vmlinux.a:
      
            vmlinux.map:
              <top level section>
                <included section>  -- might be same as top level section)
                  <object>          -- built-in association known
                    <symbol>        -- belongs to module(s) object belongs to
                    ...
      
          vmlinux linked from vmlinux.o:
      
            vmlinux.map:
              <top level section>
                <included section>  -- might be same as top level section)
                  vmlinux.o         -- need to use vmlinux.o.map
                    <symbol>        -- ignored
                    ...
      
            vmlinux.o.map:
              <section>
                  <object>          -- built-in association known
                    <symbol>        -- belongs to module(s) object belongs to
                    ...
      
       3. As sections, objects, and symbols are processed, offset ranges are
          constructed in a straight-forward way:
      
            - If the symbol belongs to one or more built-in modules:
                - If we were working on the same module(s), extend the range
                  to include this object
                - If we were working on another module(s), close that range,
                  and start the new one
            - If the symbol does not belong to any built-in modules:
                - If we were working on a module(s) range, close that range
      Signed-off-by: default avatarKris Van Hees <kris.van.hees@oracle.com>
      Reviewed-by: default avatarNick Alcock <nick.alcock@oracle.com>
      Reviewed-by: default avatarAlan Maguire <alan.maguire@oracle.com>
      Reviewed-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
      Tested-by: default avatarSam James <sam@gentoo.org>
      Reviewed-by: default avatarSami Tolvanen <samitolvanen@google.com>
      Tested-by: default avatarSami Tolvanen <samitolvanen@google.com>
      Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
      5f5e7344
  2. 10 Sep, 2024 3 commits
  3. 09 Sep, 2024 1 commit
  4. 08 Sep, 2024 1 commit
  5. 07 Sep, 2024 5 commits
  6. 01 Sep, 2024 19 commits