Yes. A soft lockup will often be found when it interferes with another function.
Despite how complicated the following is going to sound it is much easier in practice to use a patch. I’m just trying to give some information on how patch works, and how you could manually edit to produce the same thing. Patching is where I am starting because I don’t know if you already have kernel source and have any experience building kernels and/or modules. Kernel build has a lot of options in how it can be done, and official docs do show how to build from cross compile on an Ubuntu 18.04 host PC. You can ask more if you need, but it is useful to have some reference available on the forum for other people looking at this.
The provided patch looks like a copy of an email with the patch itself appended. The actual patch mentions the involved files on lines 104 and 105 (you could delete the email content in lines 1 through 102 and you’d have the actual patch which the “patch
” command can work with). Those first mentions of files to be patched are:
drivers/net/ethernet/nvidia/eqos/drv.c
drivers/net/ethernet/nvidia/eqos/mdio.c
(which are in the kernel source…you can check official documents on kernel build, but the gist is that you would compile with a match to your current system’s configuration, and then build…perhaps just modules, which is simplest, but perhaps an entire kernel Image plus modules)
You could remove the email part of the patch and use the patch
program to apply, but the gist is that where you see something like this it means the change is being applied to remove code from that file, and then to add code to the file:
--- a/drivers/net/ethernet/nvidia/eqos/drv.c
+++ b/drivers/net/ethernet/nvidia/eqos/drv.c
Lines like this imply removing a line, and then adding it back in with edits:
- spin_lock(&pdata->lock);
+ spin_lock_bh(&pdata->lock);
(in this case to file drivers/net/ethernet/nvidia/eqos/drv.c
)
You could manually examine the lines listed in the patch and look and you would see the line as it currently exists (presumably an exact match to the “-
” line). Then imagine using your editor to change that line to the “+
” line.
The patch
program (see “man patch
”, and especially in the man page find the “-pnum
” description) simply automates those edits. It finds the mentioned files, finds the lines, checks that the correct content is there, removes that content, and adds back in the new content.
The “-p<number>
” option is just how much of the parent directory to strip away. Notice that the top level listing of the file to cut from and paste to has an abstract “a/
” or “b/
” prefix:
--- a/drivers/net/ethernet/nvidia/eqos/drv.c
+++ b/drivers/net/ethernet/nvidia/eqos/drv.c
(note that “a/
” and “b/
” are just abstract symbols for “where you are currently at”…the top level of kernel source…where “a” and “b” mean “before” and “after”)
If you have actually changed to some directory which has subdirectory drivers/net/ethernet/nvidia/eqos/
, then patch would need to ignore the “a/
” and “b/
”, and work on the “drivers/
” subdirectory content; if you had used cd
to change directly to the “drivers/net/ethernet/nvidia/equos/
” subdirectory, then you would have to trim all of that prefix path since you are already in that directory. Each level of the “-p
” strips a leading part of the path to the file. A “-p6
” strips 6 leading path subdirectory names (and this means throwing away “a/drivers/net/ethernet/nvidia/eqos/
”, with only “drv.c
” remaining).
If you run patch
and it fails from not finding files, then probably the “-p#
” was wrong. No harm done. If you run patch
and it fails because it does not find the original code, then perhaps the patch is already complete. No harm done. Or perhaps your source code is from a kernel release too far different, and patch is unable to figure out what is going on…in which case the patch probably does not apply to that kernel release.
FYI, the “diff
” tool compares two files (e.g., edited and original file versions), and outputs the content which creates a patch. The “patch
” tool is the reverse of a “diff
” tool. Someone ran diff
, and the result can be used to automate the same edits through patch
.
If you are at the top of the kernel source, then you will be able to see this file exists:
ls drivers/net/ethernet/nvidia/eqos/drv.c
This is an example patch command, and would result in either saying “hunks” succeeded, or failed. The “hunks” are just blocks of code which are removed and then reinserted with edits. Example:
patch -p0 < /where/ever/that/patch/is/0001-ethernet-eqos-fix-lockup-due-to-SOFTIRQ-unsafe.patch
You could post the result of this command if it looks like some “hunk” did not succeed. Perhaps that part of the patch is already installed (I have not personally installed that patch).
After that it is a case of kernel and/or module compile.
Topics on actual kernel build can get quite long. I don’t consider it difficult, but people tend to fear the number of steps. The gist is that if you save a copy of your running system’s current “/proc/config.gz
”, then other than the option known as “CONFIG_LOCALVERSION
”, this is an exact match to your running system. If you can build an exact match, then it is much easier to introduce small changes. Two kernels of the same release with different configurations are incompatible and not the same thing until configuration matches.
One can build a whole kernel, or one can build a module. Not everything can be built as a module, and not everything can be built as integrated. If you patch something which was built as a module, then your life is very simple. If you patch something which requires editing a feature which was integrated directly in to your kernel, then it gets more complicated. Save a safe copy of your “/proc/config.gz
” before starting, as this will answer the question.
Also, before starting, along with the config.gz
, write down the result of the command “uname -r
”.
For the URLs below you may need to go there, log in, and then go there again, but kernel source is available for your particular L4T release (see either “head -n 1 /etc/nv_tegra_release
” or "dpkg -l | grep 'nvidia-l4t-core'
for finding L4T release version):
https://developer.nvidia.com/linux-tegra
…and general documents:
https://developer.nvidia.com/embedded/downloads
The documents above show how to cross compile and install from a host PC, but feel free to ask more if you want to build directly on the Jetson (native compile) or ask questions before installing. Do be sure to save a copy of your “/proc/config.gz
” to post here with your questions. You probably would want to “gunzip config.gz
” (from a copy somewhere else, e.g., after a copy to your host PC), and rename it with a “.txt
” filename suffix…the file is human readable). Also comment on the output of “uname -r
” with any post of the config file.
Mostly you will be free to experiment while patching and building, but do ask questions on adding content to the Jetson before actually adding it. Perhaps you don’t need to install the full Image
, and a simple module copy might do the job.