Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
linux_kernel_cleanup [2025/06/30 17:52] – [Overview] rpjday | linux_kernel_cleanup [2025/07/02 13:03] (current) – [5. Finding allegedly "unused" header files] rpjday | ||
---|---|---|---|
Line 1: | Line 1: | ||
==== Overview ==== | ==== Overview ==== | ||
- | Several years ago, I wrote a number of Linux kernel " | + | Several years ago, I wrote a number of Linux kernel " |
- | The point here is that beginners to working with the Linux kernel are welcome to examine these scripts, tweak them, run them, and submit organized and well-documented patches if they want to become contributors to the kernel. | + | Over the next several days, I'll be adding |
- | + | ||
- | Over the next several days, I'll be adding | + | |
So far, the cleanup scripts below are for: | So far, the cleanup scripts below are for: | ||
* calculating the length of an array | * calculating the length of an array | ||
- | * checking for testing for power of 2 | + | * checking for testing for a power of 2 |
* identifying " | * identifying " | ||
+ | * identifying "bad #if" preprocessor checks for non-existent Kconfig variables | ||
+ | * identifying allegedly " | ||
NOTE: Don't try to submit a mega-patch with as many similar patches as you possibly can; rather, submit patches on a subsystem by subsystem basis, to make the patches manageable so that they can be reviewed and approved by just the maintainers of that subsystem. | NOTE: Don't try to submit a mega-patch with as many similar patches as you possibly can; rather, submit patches on a subsystem by subsystem basis, to make the patches manageable so that they can be reviewed and approved by just the maintainers of that subsystem. | ||
- | **// | + | **// |
- | + | ||
- | ==== The cleanup scripts ==== | + | |
- | === 1. Calculating the length of an array === | + | ==== 1. Calculating the length of an array ==== |
A lot of kernel code needs to calculate the length of an array, frequently to iterate through all of its elements. There are two standard ways to do this in C language: | A lot of kernel code needs to calculate the length of an array, frequently to iterate through all of its elements. There are two standard ways to do this in C language: | ||
Line 72: | Line 70: | ||
Note that there some obvious examples of what the script is looking for, as well as some false positives. Note also how various files insist on re-inventing the test in defining a macro that does what is already in that Linux header file. | Note that there some obvious examples of what the script is looking for, as well as some false positives. Note also how various files insist on re-inventing the test in defining a macro that does what is already in that Linux header file. | ||
- | === 2. Check if something is a power of two === | + | ==== 2. Check if something is a power of two ==== |
Quite a lot of kernel code needs to check if an integer value is an exact power of two -- the general test for that is already defined in the header file '' | Quite a lot of kernel code needs to check if an integer value is an exact power of two -- the general test for that is already defined in the header file '' | ||
Line 121: | Line 119: | ||
</ | </ | ||
- | Note well that if you search for that expression, many tests are actually checking if the number in question is **not** a power of two, so make sure you notice the difference. | + | Note well that if you search for that expression, many tests are actually checking if the number in question is **not** a power of two, so make sure you notice the difference. |
- | === 3. Finding " | + | < |
+ | arch/ | ||
+ | arch/ | ||
+ | arch/ | ||
+ | arch/ | ||
+ | arch/ | ||
+ | arch/ | ||
+ | arch/ | ||
+ | arch/ | ||
+ | arch/ | ||
+ | </ | ||
+ | |||
+ | so you need to be careful as to what you think any of that simplifies to. | ||
+ | |||
+ | ==== 3. Finding " | ||
Many kernel Kconfig files contain " | Many kernel Kconfig files contain " | ||
Line 174: | Line 186: | ||
arch/ | arch/ | ||
</ | </ | ||
+ | |||
+ | Run the same script against the " | ||
+ | |||
+ | < | ||
+ | $ find_bad_selects.sh drivers | ||
+ | ===== DRM_DEBUG_SELFTEST | ||
+ | drivers/ | ||
+ | ===== DRM_KMS_DMA_HELPER | ||
+ | drivers/ | ||
+ | drivers/ | ||
+ | ===== TEST_KUNIT_DEVICE_HELPERS | ||
+ | drivers/ | ||
+ | $ | ||
+ | </ | ||
+ | |||
+ | In other words, the above " | ||
+ | |||
+ | ==== 4. Find " | ||
+ | |||
+ | This check refers to " | ||
+ | |||
+ | As one example, here is the output generated by the script for the string " | ||
+ | |||
+ | < | ||
+ | >>>>> | ||
+ | drivers/ | ||
+ | drivers/ | ||
+ | drivers/ | ||
+ | </ | ||
+ | |||
+ | The standard approach here would be to check carefully that there are no references to that string anywhere in the source tree, and check the Git log to see if/when that symbol was removed, and why, and clean it up. | ||
+ | |||
+ | Additional examples from the drivers/ directory: | ||
+ | |||
+ | < | ||
+ | >>>>> | ||
+ | drivers/ | ||
+ | >>>>> | ||
+ | drivers/ | ||
+ | >>>>> | ||
+ | drivers/ | ||
+ | >>>>> | ||
+ | drivers/ | ||
+ | drivers/ | ||
+ | drivers/ | ||
+ | drivers/ | ||
+ | </ | ||
+ | |||
+ | However, there is a complication in that there are " | ||
+ | |||
+ | < | ||
+ | >>>>> | ||
+ | drivers/ | ||
+ | drivers/ | ||
+ | </ | ||
+ | |||
+ | This messes up what should have been a simple search, and it also seems to fly in the face of an old coding standard that the macro prefix " | ||
+ | |||
+ | < | ||
+ | #!/bin/sh | ||
+ | |||
+ | ################################################ | ||
+ | # Make sure you install autoconf for " | ||
+ | ################################################ | ||
+ | |||
+ | SCAN_DIR=${1-*} | ||
+ | |||
+ | CVARS=$(find ${SCAN_DIR} -name " | ||
+ | grep -v " | ||
+ | xargs ifnames | \ | ||
+ | grep " | ||
+ | cut -d' ' -f1 | \ | ||
+ | sed " | ||
+ | sed " | ||
+ | sort -u) | ||
+ | |||
+ | ALL_KC_FILES=$(find . -name " | ||
+ | |||
+ | # | ||
+ | # Scan the entire tree, just to see what turns up. | ||
+ | # NOTE the extra grep to see if the CONFIG_ symbol | ||
+ | # is defined as perhaps part of cflags in a Makefile. | ||
+ | # | ||
+ | |||
+ | for cv in ${CVARS} ; do | ||
+ | egrep -q " | ||
+ | grep -q " | ||
+ | egrep -qr " | ||
+ | echo ">>>>> | ||
+ | grep -rwn " | ||
+ | grep -rwn " | ||
+ | grep -rn -- " | ||
+ | } | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | ==== 5. Finding allegedly " | ||
+ | |||
+ | " | ||
+ | |||
+ | One reason is that a source file was removed, but its associated supporting header file was overlooked and is still sitting there, now having no purpose in life. Another (quite common) reason is that many of those header files contain enums or macros for hex offsets for particular devices, so that even if nothing is including them at the moment, they still need to be preserved in case something needs all that content. | ||
+ | |||
+ | As a basic example of the current '' | ||
+ | |||
+ | < | ||
+ | ===== phy-mv-usb.h ===== | ||
+ | ./ | ||
+ | ===== sisusb_tables.h ===== | ||
+ | ./ | ||
+ | </ | ||
+ | |||
+ | The above tells us simply that there are two header files under that directory that appear to not be included from // | ||
+ | |||
+ | Here is the admittedly brute force script '' | ||
+ | |||
+ | < | ||
+ | #!/bin/sh | ||
+ | |||
+ | DIR=${1-*} | ||
+ | |||
+ | LONGHDRS=$(find ${DIR} -name " | ||
+ | |||
+ | HDRS="" | ||
+ | |||
+ | for h in ${LONGHDRS} ; do | ||
+ | HDRS=" | ||
+ | done | ||
+ | |||
+ | HDRS=$(for h in ${HDRS} ; do echo $h ; done | sort -u) | ||
+ | |||
+ | # Test that each header file is included from *somewhere*. | ||
+ | |||
+ | for h in ${HDRS} ; do | ||
+ | # echo " | ||
+ | egrep -rq " | ||
+ | echo "===== ${h} =====" | ||
+ | find . -name " | ||
+ | grep -rwH ${h} * | ||
+ | } | ||
+ | done | ||
+ | </ | ||
+ | |||
+ | **EXERCISE**: |