A busier cycle than I had expected for docs, including:

- Translations: some overdue updates to the Japanese translations, Chinese
   translations for some of the Rust documentation, and the beginnings of a
   Portuguese translation.
 
 - New documents covering CPU isolation, managed interrupts, debugging
   Python gbb scripts, and more.
 
 - More tooling work from Mauro, reducing docs-build warnings, adding self
   tests, improving man-page output, bringing in a proper C tokenizer to
   replace (some of) the mess of kernel-doc regexes, and more.
 
 - Update and synchronize changes.rst and scripts/ver_linux, and put both
   into alphabetical order.
 
 ...and a long list of documentation updates, typo fixes, and general
 improvements.
 -----BEGIN PGP SIGNATURE-----
 
 iQFDBAABCgAtFiEEIw+MvkEiF49krdp9F0NaE2wMflgFAmnb9GkPHGNvcmJldEBs
 d24ubmV0AAoJEBdDWhNsDH5YqnEH/R+9jPgcEsdaLGXxM0Li/obLMw2bzj+FhLOT
 tpS53AcK34ObVg9Xe5CsrQyjaI7Advy5QevLTqC3ZpfN7sxAtCZ7alUT/u1pk5+u
 P+OoB/jyD55KA/c5jgIQlgBn574fjaDIVD6W+sf0g9MhmOnDa/7EaOIEdvm+Xpey
 Dxx/Sq0jBk4PziqeCz03txsh//+O/R/wXoRbHeqKIbs3XQt1DF1LLRc+Ni8RYBCB
 PpCacoe1RpvaSG7CqXCwPB1bbiEPXRU3oiW2SPFcn0j4WyNtEJkv56g2lpzzWyCQ
 Gc837Mmu29GifQyH4Vi0bnvLtFBC/x+rJKsvCmp8jFfu6sMpuew=
 =liXF
 -----END PGP SIGNATURE-----

Merge tag 'docs-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/docs/linux

Pull documentation updates from Jonathan Corbet:
 "A busier cycle than I had expected for docs, including:

   - Translations: some overdue updates to the Japanese translations,
     Chinese translations for some of the Rust documentation, and the
     beginnings of a Portuguese translation.

   - New documents covering CPU isolation, managed interrupts, debugging
     Python gbb scripts, and more.

   - More tooling work from Mauro, reducing docs-build warnings, adding
     self tests, improving man-page output, bringing in a proper C
     tokenizer to replace (some of) the mess of kernel-doc regexes, and
     more.

   - Update and synchronize changes.rst and scripts/ver_linux, and put
     both into alphabetical order.

  ... and a long list of documentation updates, typo fixes, and general
  improvements"

* tag 'docs-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/docs/linux: (162 commits)
  Documentation: core-api: real-time: correct spelling
  doc: Add CPU Isolation documentation
  Documentation: Add managed interrupts
  Documentation: seq_file: drop 2.6 reference
  docs/zh_CN: update rust/index.rst translation
  docs/zh_CN: update rust/quick-start.rst translation
  docs/zh_CN: update rust/coding-guidelines.rst translation
  docs/zh_CN: update rust/arch-support.rst translation
  docs/zh_CN: sync process/2.Process.rst with English version
  docs/zh_CN: fix an inconsistent statement in dev-tools/testing-overview
  tracing: Documentation: Update histogram-design.rst for fn() handling
  docs: sysctl: Add documentation for /proc/sys/xen/
  Docs: hid: intel-ish-hid: make long URL usable
  Documentation/kernel-parameters: fix architecture alignment for pt, nopt, and nobypass
  sched/doc: Update yield_task description in sched-design-CFS
  Documentation/rtla: Convert links to RST format
  docs: fix typos and duplicated words across documentation
  docs: fix typo in zoran driver documentation
  docs: add an Assisted-by mention to submitting-patches.rst
  Revert "scripts/checkpatch: add Assisted-by: tag validation"
  ...
This commit is contained in:
Linus Torvalds 2026-04-14 08:47:08 -07:00
commit 5181afcdf9
115 changed files with 11345 additions and 1046 deletions

View File

@ -618,7 +618,7 @@ cache_replacement_policy
One of either lru, fifo or random.
freelist_percent
Size of the freelist as a percentage of nbuckets. Can be written to to
Size of the freelist as a percentage of nbuckets. Can be written to
increase the number of buckets kept on the freelist, which lets you
artificially reduce the size of the cache at runtime. Mostly for testing
purposes (i.e. testing how different size caches affect your hit rate).

View File

@ -0,0 +1,357 @@
.. SPDX-License-Identifier: GPL-2.0
=============
CPU Isolation
=============
Introduction
============
"CPU Isolation" means leaving a CPU exclusive to a given workload
without any undesired code interference from the kernel.
Those interferences, commonly pointed out as "noise", can be triggered
by asynchronous events (interrupts, timers, scheduler preemption by
workqueues and kthreads, ...) or synchronous events (syscalls and page
faults).
Such noise usually goes unnoticed. After all, synchronous events are a
component of the requested kernel service. And asynchronous events are
either sufficiently well-distributed by the scheduler when executed
as tasks or reasonably fast when executed as interrupt. The timer
interrupt can even execute 1024 times per seconds without a significant
and measurable impact most of the time.
However some rare and extreme workloads can be quite sensitive to
those kinds of noise. This is the case, for example, with high
bandwidth network processing that can't afford losing a single packet
or very low latency network processing. Typically those use cases
involve DPDK, bypassing the kernel networking stack and performing
direct access to the networking device from userspace.
In order to run a CPU without or with limited kernel noise, the
related housekeeping work needs to be either shut down, migrated or
offloaded.
Housekeeping
============
In the CPU isolation terminology, housekeeping is the work, often
asynchronous, that the kernel needs to process in order to maintain
all its services. It matches the noises and disturbances enumerated
above except when at least one CPU is isolated. Then housekeeping may
make use of further coping mechanisms if CPU-tied work must be
offloaded.
Housekeeping CPUs are the non-isolated CPUs where the kernel noise
is moved away from isolated CPUs.
The isolation can be implemented in several ways depending on the
nature of the noise:
- Unbound work, where "unbound" means not tied to any CPU, can be
simply migrated away from isolated CPUs to housekeeping CPUs.
This is the case of unbound workqueues, kthreads and timers.
- Bound work, where "bound" means tied to a specific CPU, usually
can't be moved away as-is by nature. Either:
- The work must switch to a locked implementation. E.g.:
This is the case of RCU with CONFIG_RCU_NOCB_CPU.
- The related feature must be shut down and considered
incompatible with isolated CPUs. E.g.: Lockup watchdog,
unreliable clocksources, etc...
- An elaborate and heavyweight coping mechanism stands as a
replacement. E.g.: the timer tick is shut down on nohz_full
CPUs but with the constraint of running a single task on
them. A significant cost penalty is added on kernel entry/exit
and a residual 1Hz scheduler tick is offloaded to housekeeping
CPUs.
In any case, housekeeping work has to be handled, which is why there
must be at least one housekeeping CPU in the system, preferably more
if the machine runs a lot of CPUs. For example one per node on NUMA
systems.
Also CPU isolation often means a tradeoff between noise-free isolated
CPUs and added overhead on housekeeping CPUs, sometimes even on
isolated CPUs entering the kernel.
Isolation features
==================
Different levels of isolation can be configured in the kernel, each of
which has its own drawbacks and tradeoffs.
Scheduler domain isolation
--------------------------
This feature isolates a CPU from the scheduler topology. As a result,
the target isn't part of the load balancing. Tasks won't migrate
either from or to it unless affined explicitly.
As a side effect the CPU is also isolated from unbound workqueues and
unbound kthreads.
Requirements
~~~~~~~~~~~~
- CONFIG_CPUSETS=y for the cpusets-based interface
Tradeoffs
~~~~~~~~~
By nature, the system load is overall less distributed since some CPUs
are extracted from the global load balancing.
Interfaces
~~~~~~~~~~
- Documentation/admin-guide/cgroup-v2.rst cpuset isolated partitions are recommended
because they are tunable at runtime.
- The 'isolcpus=' kernel boot parameter with the 'domain' flag is a
less flexible alternative that doesn't allow for runtime
reconfiguration.
IRQs isolation
--------------
Isolate the IRQs whenever possible, so that they don't fire on the
target CPUs.
Interfaces
~~~~~~~~~~
- The file /proc/irq/\*/smp_affinity as explained in detail in
Documentation/core-api/irq/irq-affinity.rst page.
- The "irqaffinity=" kernel boot parameter for a default setting.
- The "managed_irq" flag in the "isolcpus=" kernel boot parameter
tries a best effort affinity override for managed IRQs.
Full Dynticks (aka nohz_full)
-----------------------------
Full dynticks extends the dynticks idle mode, which stops the tick when
the CPU is idle, to CPUs running a single task in userspace. That is,
the timer tick is stopped if the environment allows it.
Global timer callbacks are also isolated from the nohz_full CPUs.
Requirements
~~~~~~~~~~~~
- CONFIG_NO_HZ_FULL=y
Constraints
~~~~~~~~~~~
- The isolated CPUs must run a single task only. Multitask requires
the tick to maintain preemption. This is usually fine since the
workload usually can't stand the latency of random context switches.
- No call to the kernel from isolated CPUs, at the risk of triggering
random noise.
- No use of POSIX CPU timers on isolated CPUs.
- Architecture must have a stable and reliable clocksource (no
unreliable TSC that requires the watchdog).
Tradeoffs
~~~~~~~~~
In terms of cost, this is the most invasive isolation feature. It is
assumed to be used when the workload spends most of its time in
userspace and doesn't rely on the kernel except for preparatory
work because:
- RCU adds more overhead due to the locked, offloaded and threaded
callbacks processing (the same that would be obtained with "rcu_nocbs"
boot parameter).
- Kernel entry/exit through syscalls, exceptions and IRQs are more
costly due to fully ordered RmW operations that maintain userspace
as RCU extended quiescent state. Also the CPU time is accounted on
kernel boundaries instead of periodically from the tick.
- Housekeeping CPUs must run a 1Hz residual remote scheduler tick
on behalf of the isolated CPUs.
Checklist
=========
You have set up each of the above isolation features but you still
observe jitters that trash your workload? Make sure to check a few
elements before proceeding.
Some of these checklist items are similar to those of real-time
workloads:
- Use mlock() to prevent your pages from being swapped away. Page
faults are usually not compatible with jitter sensitive workloads.
- Avoid SMT to prevent your hardware thread from being "preempted"
by another one.
- CPU frequency changes may induce subtle sorts of jitter in a
workload. Cpufreq should be used and tuned with caution.
- Deep C-states may result in latency issues upon wake-up. If this
happens to be a problem, C-states can be limited via kernel boot
parameters such as processor.max_cstate or intel_idle.max_cstate.
More finegrained tunings are described in
Documentation/admin-guide/pm/cpuidle.rst page
- Your system may be subject to firmware-originating interrupts - x86 has
System Management Interrupts (SMIs) for example. Check your system BIOS
to disable such interference, and with some luck your vendor will have
a BIOS tuning guidance for low-latency operations.
Full isolation example
======================
In this example, the system has 8 CPUs and the 8th is to be fully
isolated. Since CPUs start from 0, the 8th CPU is CPU 7.
Kernel parameters
-----------------
Set the following kernel boot parameters to disable SMT and setup tick
and IRQ isolation:
- Full dynticks: nohz_full=7
- IRQs isolation: irqaffinity=0-6
- Managed IRQs isolation: isolcpus=managed_irq,7
- Prevent SMT: nosmt
The full command line is then:
nohz_full=7 irqaffinity=0-6 isolcpus=managed_irq,7 nosmt
CPUSET configuration (cgroup v2)
--------------------------------
Assuming cgroup v2 is mounted to /sys/fs/cgroup, the following script
isolates CPU 7 from scheduler domains.
::
cd /sys/fs/cgroup
# Activate the cpuset subsystem
echo +cpuset > cgroup.subtree_control
# Create partition to be isolated
mkdir test
cd test
echo +cpuset > cgroup.subtree_control
# Isolate CPU 7
echo 7 > cpuset.cpus
echo "isolated" > cpuset.cpus.partition
The userspace workload
----------------------
Fake a pure userspace workload, the program below runs a dummy
userspace loop on the isolated CPU 7.
::
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
int main(void)
{
// Move the current task to the isolated cpuset (bind to CPU 7)
int fd = open("/sys/fs/cgroup/test/cgroup.procs", O_WRONLY);
if (fd < 0) {
perror("Can't open cpuset file...\n");
return 0;
}
write(fd, "0\n", 2);
close(fd);
// Run an endless dummy loop until the launcher kills us
while (1)
;
return 0;
}
Build it and save for later step:
::
# gcc user_loop.c -o user_loop
The launcher
------------
The below launcher runs the above program for 10 seconds and traces
the noise resulting from preempting tasks and IRQs.
::
TRACING=/sys/kernel/tracing/
# Make sure tracing is off for now
echo 0 > $TRACING/tracing_on
# Flush previous traces
echo > $TRACING/trace
# Record disturbance from other tasks
echo 1 > $TRACING/events/sched/sched_switch/enable
# Record disturbance from interrupts
echo 1 > $TRACING/events/irq_vectors/enable
# Now we can start tracing
echo 1 > $TRACING/tracing_on
# Run the dummy user_loop for 10 seconds on CPU 7
./user_loop &
USER_LOOP_PID=$!
sleep 10
kill $USER_LOOP_PID
# Disable tracing and save traces from CPU 7 in a file
echo 0 > $TRACING/tracing_on
cat $TRACING/per_cpu/cpu7/trace > trace.7
If no specific problem arose, the output of trace.7 should look like
the following:
::
<idle>-0 [007] d..2. 1980.976624: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=user_loop next_pid=1553 next_prio=120
user_loop-1553 [007] d.h.. 1990.946593: reschedule_entry: vector=253
user_loop-1553 [007] d.h.. 1990.946593: reschedule_exit: vector=253
That is, no specific noise triggered between the first trace and the
second during 10 seconds when user_loop was running.
Debugging
=========
Of course things are never so easy, especially on this matter.
Chances are that actual noise will be observed in the aforementioned
trace.7 file.
The best way to investigate further is to enable finer grained
tracepoints such as those of subsystems producing asynchronous
events: workqueue, timer, irq_vector, etc... It also can be
interesting to enable the tick_stop event to diagnose why the tick is
retained when that happens.
Some tools may also be useful for higher level analysis:
- Documentation/tools/rtla/rtla.rst provides a suite of tools to analyze
latency and noise in the system. For example Documentation/tools/rtla/rtla-osnoise.rst
runs a kernel tracer that analyzes and output a summary of the noises.
- dynticks-testing does something similar to rtla-osnoise but in userspace. It is available
at git://git.kernel.org/pub/scm/linux/kernel/git/frederic/dynticks-testing.git

View File

@ -94,6 +94,7 @@ likely to be of interest on almost any system.
cgroup-v2
cgroup-v1/index
cpu-isolation
cpu-load
mm/index
module-signing

View File

@ -2630,15 +2630,11 @@ Kernel parameters
Intel machines). This can be used to prevent the usage
of an available hardware IOMMU.
[X86]
pt
[X86]
nopt
[PPC/POWERNV]
nobypass
nobypass [PPC/POWERNV]
Disable IOMMU bypass, using IOMMU for PCI devices.
[X86]
AMD Gart HW IOMMU-specific options:
<size>
@ -6761,7 +6757,7 @@ Kernel parameters
Default is 'on'.
initramfs_options= [KNL]
Specify mount options for for the initramfs mount.
Specify mount options for the initramfs mount.
rootfstype= [KNL] Set root filesystem type

View File

@ -287,7 +287,7 @@ level.
Check presence of other Intel(R) SST features
---------------------------------------------
Each of the performance profiles also specifies weather there is support of
Each of the performance profiles also specifies whether there is support of
other two Intel(R) SST features (Intel(R) Speed Select Technology - Base Frequency
(Intel(R) SST-BF) and Intel(R) Speed Select Technology - Turbo Frequency (Intel
SST-TF)).

View File

@ -349,12 +349,14 @@ again.
.. _submit_improvements_qbtl:
Did you run into trouble following any of the above steps that is not cleared up
by the reference section below? Or do you have ideas how to improve the text?
Then please take a moment of your time and let the maintainer of this document
know by email (Thorsten Leemhuis <linux@leemhuis.info>), ideally while CCing the
Linux docs mailing list (linux-doc@vger.kernel.org). Such feedback is vital to
improve this document further, which is in everybody's interest, as it will
Did you run into trouble following the step-by-step guide not cleared up by the
reference section below? Did you spot errors? Or do you have ideas on how to
improve the guide?
If any of that applies, please let the developers know by sending a short note
or a patch to Thorsten Leemhuis <linux@leemhuis.info> while ideally CCing the
public Linux docs mailing list <linux-doc@vger.kernel.org>. Such feedback is
vital to improve this text further, which is in everybody's interest, as it will
enable more people to master the task described here.
Reference section for the step-by-step guide

View File

@ -48,6 +48,16 @@ Once the report is out, answer any questions that come up and help where you
can. That includes keeping the ball rolling by occasionally retesting with newer
releases and sending a status update afterwards.
..
Note: If you see this note, you are reading the text's source file. You
might want to switch to a rendered version: It makes it a lot easier to
read and navigate this document -- especially when you want to look something
up in the reference section, then jump back to where you left off.
..
Find the latest rendered version of this text here:
https://docs.kernel.org/admin-guide/reporting-issues.html
Step-by-step guide how to report issues to the kernel maintainers
=================================================================
@ -231,45 +241,54 @@ kernels regularly rebased on those. If that is the case, follow these steps:
The reference section below explains each of these steps in more detail.
Conclusion of the step-by-step guide
------------------------------------
Did you run into trouble following the step-by-step guide not cleared up by the
reference section below? Did you spot errors? Or do you have ideas on how to
improve the guide?
If any of that applies, please let the developers know by sending a short note
or a patch to Thorsten Leemhuis <linux@leemhuis.info> while ideally CCing the
public Linux docs mailing list <linux-doc@vger.kernel.org>. Such feedback is
vital to improve this text further, which is in everybody's interest, as it will
enable more people to master the task described here.
Reference section: Reporting issues to the kernel maintainers
=============================================================
The detailed guides above outline all the major steps in brief fashion, which
should be enough for most people. But sometimes there are situations where even
experienced users might wonder how to actually do one of those steps. That's
what this section is for, as it will provide a lot more details on each of the
above steps. Consider this as reference documentation: it's possible to read it
from top to bottom. But it's mainly meant to skim over and a place to look up
details how to actually perform those steps.
The step-by-step guide above outlines all the major steps in brief fashion,
which usually covers everything required. But even experienced users will
sometimes wonder how to actually realize some of those steps or why they are
needed; there are also corner cases the guide ignores for readability. That is
what the entries in this reference section are for, which provide additional
information for each of the steps in the guide.
A few words of general advice before digging into the details:
A few words of general advice:
* The Linux kernel developers are well aware this process is complicated and
demands more than other FLOSS projects. We'd love to make it simpler. But
that would require work in various places as well as some infrastructure,
which would need constant maintenance; nobody has stepped up to do that
work, so that's just how things are for now.
* The Linux developers are well aware that reporting bugs to them is more
complicated and demanding than in other FLOSS projects. Some of it is because
the kernel is different, among others due to its mail-driven development
process and because it consists mostly of drivers. Some of it is because
improving things would require work in several technical areas and people
triaging bugs and nobody has stepped up to do or fund that work.
* A warranty or support contract with some vendor doesn't entitle you to
request fixes from developers in the upstream Linux kernel community: such
contracts are completely outside the scope of the Linux kernel, its
development community, and this document. That's why you can't demand
anything such a contract guarantees in this context, not even if the
developer handling the issue works for the vendor in question. If you want
to claim your rights, use the vendor's support channel instead. When doing
so, you might want to mention you'd like to see the issue fixed in the
upstream Linux kernel; motivate them by saying it's the only way to ensure
the fix in the end will get incorporated in all Linux distributions.
* A warranty or support contract with some vendor doesn't entitle you to
request fixes from the upstream Linux developers: Such contracts are
completely outside the scope of the upstream Linux kernel, its development
community, and this document -- even if those handling the issue work for the
vendor who issued the contract. If you want to claim your rights, use the
vendor's support channel.
* If you never reported an issue to a FLOSS project before you should consider
reading `How to Report Bugs Effectively
<https://www.chiark.greenend.org.uk/~sgtatham/bugs.html>`_, `How To Ask
Questions The Smart Way
<http://www.catb.org/esr/faqs/smart-questions.html>`_, and `How to ask good
questions <https://jvns.ca/blog/good-questions/>`_.
* If you never reported an issue to a FLOSS project before, consider skimming
guides like `How to ask good questions
<https://jvns.ca/blog/good-questions/>`_, `How To Ask Questions The Smart Way
<http://www.catb.org/esr/faqs/smart-questions.html>`_, and `How to Report
Bugs Effectively <https://www.chiark.greenend.org.uk/~sgtatham/bugs.html>`_,.
With that off the table, find below the details on how to properly report
issues to the Linux kernel developers.
With that off the table, find below details for the steps from the detailed
guide on reporting issues to the Linux kernel developers.
Make sure you're using the upstream Linux kernel
@ -1674,72 +1693,59 @@ for the subsystem where the issue seems to have its roots; CC the mailing list
for the subsystem as well as the stable mailing list (stable@vger.kernel.org).
Why some issues won't get any reaction or remain unfixed after being reported
=============================================================================
Appendix: Why it is somewhat hard to report kernel bugs
=======================================================
When reporting a problem to the Linux developers, be aware only 'issues of high
priority' (regressions, security issues, severe problems) are definitely going
to get resolved. The maintainers or if all else fails Linus Torvalds himself
will make sure of that. They and the other kernel developers will fix a lot of
other issues as well. But be aware that sometimes they can't or won't help; and
sometimes there isn't even anyone to send a report to.
The Linux kernel developers are well aware that reporting bugs to them is harder
than in other Free/Libre Open Source Projects. Many reasons for that lie in the
nature of kernels, Linux' development model, and how the world uses the kernel:
This is best explained with kernel developers that contribute to the Linux
kernel in their spare time. Quite a few of the drivers in the kernel were
written by such programmers, often because they simply wanted to make their
hardware usable on their favorite operating system.
* *Most kernels of Linux distributions are totally unsuitable for reporting bugs
upstream.* The reference section above already explained this in detail:
outdated codebases as well as modifications and add-ons lead to kernel bugs
that were fixed upstream a long time ago or never happened there in the first
place. Developers of other Open Source software face these problems as well,
but the situation is a lot worse when it comes to the kernel, as the changes
and their impact are much more severe -- which is why many kernel developers
expect reports with kernels built from fresh and nearly unmodified sources.
These programmers most of the time will happily fix problems other people
report. But nobody can force them to do, as they are contributing voluntarily.
* *Bugs often only occur in a special environment.* That is because Linux is
mostly drivers and can be used in a multitude of ways. Developers often do not
have a matching setup at hand -- and therefore frequently must rely on bug
reporters for isolating a problems's cause and testing proposed fixes.
Then there are situations where such developers really want to fix an issue,
but can't: sometimes they lack hardware programming documentation to do so.
This often happens when the publicly available docs are superficial or the
driver was written with the help of reverse engineering.
* *The kernel has hundreds of maintainers, but all-rounders are very rare.* That
again is and effect caused by the multitude of features and drivers, due to
which many kernel developers know little about lower or higher layers related
to their code and even less about other areas.
Sooner or later spare time developers will also stop caring for the driver.
Maybe their test hardware broke, got replaced by something more fancy, or is so
old that it's something you don't find much outside of computer museums
anymore. Sometimes developer stops caring for their code and Linux at all, as
something different in their life became way more important. In some cases
nobody is willing to take over the job as maintainer and nobody can be forced
to, as contributing to the Linux kernel is done on a voluntary basis. Abandoned
drivers nevertheless remain in the kernel: they are still useful for people and
removing would be a regression.
* *It is hard finding where to report issues to, among others, due to the lack
of a central bug tracker.* This is something even some kernel developers
dislike, but that's the situation everyone has to deal with currently.
The situation is not that different with developers that are paid for their
work on the Linux kernel. Those contribute most changes these days. But their
employers sooner or later also stop caring for their code or make its
programmer focus on other things. Hardware vendors for example earn their money
mainly by selling new hardware; quite a few of them hence are not investing
much time and energy in maintaining a Linux kernel driver for something they
stopped selling years ago. Enterprise Linux distributors often care for a
longer time period, but in new versions often leave support for old and rare
hardware aside to limit the scope. Often spare time contributors take over once
a company orphans some code, but as mentioned above: sooner or later they will
leave the code behind, too.
* *Stable and longterm kernels are primarily maintained by a dedicated 'stable
team', which only handles regressions introduced within stable and longterm
series.* When someone reports a bug, say, using Linux 6.1.2, the team will,
therefore, always ask if mainline is affected: if the bug already happened
in 6.1 or occurs with latest mainline (say, 6.2-rc3), they in everybody's
interest shove it to the regular developers, as those know the code best.
Priorities are another reason why some issues are not fixed, as maintainers
quite often are forced to set those, as time to work on Linux is limited.
That's true for spare time or the time employers grant their developers to
spend on maintenance work on the upstream kernel. Sometimes maintainers also
get overwhelmed with reports, even if a driver is working nearly perfectly. To
not get completely stuck, the programmer thus might have no other choice than
to prioritize issue reports and reject some of them.
* *Linux developers are free to focus on latest mainline.* Some, thus, react
coldly to reports about bugs in, say, Linux 6.0 when 6.1 is already out;
even the latter might not be enough once 6.2-rc1 is out. Some will also not
be very welcoming to reports with 6.1.5 or 6.1.6, as the problem might be a
series-specific regression the stable team (see above) caused and must fix.
But don't worry too much about all of this, a lot of drivers have active
maintainers who are quite interested in fixing as many issues as possible.
Closing words
=============
Compared with other Free/Libre & Open Source Software it's hard to report
issues to the Linux kernel developers: the length and complexity of this
document and the implications between the lines illustrate that. But that's how
it is for now. The main author of this text hopes documenting the state of the
art will lay some groundwork to improve the situation over time.
* *Sometimes there is nobody to help.* Sometimes this is due to the lack of
hardware documentation -- for example, when a driver was built using reverse
engineering or was taken over by spare-time developers when the hardware
manufacturer left it behind. Other times there is nobody to even report bugs
to: when maintainers move on without a replacement, their code often remains
in the kernel as long as it's useful.
Some of these aspects could be improved to facilitate bug reporting -- many
Linux kernel developers are well aware of this and would be glad if a few
individuals or an entity would make this their mission.
..
end-of-content

View File

@ -0,0 +1,47 @@
=================
/proc/sys/crypto/
=================
These files show up in ``/proc/sys/crypto/``, depending on the
kernel configuration:
.. contents:: :local:
fips_enabled
============
Read-only flag that indicates whether FIPS mode is enabled.
- ``0``: FIPS mode is disabled (default).
- ``1``: FIPS mode is enabled.
This value is set at boot time via the ``fips=1`` kernel command line
parameter. When enabled, the cryptographic API will restrict the use
of certain algorithms and perform self-tests to ensure compliance with
FIPS (Federal Information Processing Standards) requirements, such as
FIPS 140-2 and the newer FIPS 140-3, depending on the kernel
configuration and the module in use.
fips_name
=========
Read-only file that contains the name of the FIPS module currently in use.
The value is typically configured via the ``CONFIG_CRYPTO_FIPS_NAME``
kernel configuration option.
fips_version
============
Read-only file that contains the version string of the FIPS module.
If ``CONFIG_CRYPTO_FIPS_CUSTOM_VERSION`` is set, it uses the value from
``CONFIG_CRYPTO_FIPS_VERSION``. Otherwise, it defaults to the kernel
release version (``UTS_RELEASE``).
Copyright (c) 2026, Shubham Chakraborty <chakrabortyshubham66@gmail.com>
For general info and legal blurb, please look in
Documentation/admin-guide/sysctl/index.rst.
.. See scripts/check-sysctl-docs to keep this up to date:
.. scripts/check-sysctl-docs -vtable="crypto" \
.. $(git grep -l register_sysctl_)

View File

@ -0,0 +1,52 @@
================
/proc/sys/debug/
================
These files show up in ``/proc/sys/debug/``, depending on the
kernel configuration:
.. contents:: :local:
exception-trace
===============
This flag controls whether the kernel prints information about unhandled
signals (like segmentation faults) to the kernel log (``dmesg``).
- ``0``: Unhandled signals are not traced.
- ``1``: Information about unhandled signals is printed.
The default value is ``1`` on most architectures (like x86, MIPS, RISC-V),
but it is ``0`` on **arm64**.
The actual information printed and the context provided varies
significantly depending on the CPU architecture. For example:
- On **x86**, it typically prints the instruction pointer (IP), error
code, and address that caused a page fault.
- On **PowerPC**, it may print the next instruction pointer (NIP),
link register (LR), and other relevant registers.
When enabled, this feature is often rate-limited to prevent the kernel
log from being flooded during a crash loop.
kprobes-optimization
====================
This flag enables or disables the optimization of Kprobes on certain
architectures (like x86).
- ``0``: Kprobes optimization is turned off.
- ``1``: Kprobes optimization is turned on (default).
For more details on Kprobes and its optimization, please refer to
Documentation/trace/kprobes.rst.
Copyright (c) 2026, Shubham Chakraborty <chakrabortyshubham66@gmail.com>
For general info and legal blurb, please look in
Documentation/admin-guide/sysctl/index.rst.
.. See scripts/check-sysctl-docs to keep this up to date:
.. scripts/check-sysctl-docs -vtable="debug" \
.. $(git grep -l register_sysctl_)

View File

@ -67,8 +67,8 @@ This documentation is about:
=============== ===============================================================
abi/ execution domains & personalities
<$ARCH> tuning controls for various CPU architecture (e.g. csky, s390)
crypto/ <undocumented>
debug/ <undocumented>
crypto/ cryptographic subsystem
debug/ debugging features
dev/ device specific information (e.g. dev/cdrom/info)
fs/ specific filesystems
filehandle, inode, dentry and quota tuning
@ -84,7 +84,7 @@ sunrpc/ SUN Remote Procedure Call (NFS)
user/ Per user namespace limits
vm/ memory management tuning
buffer and cache management
xen/ <undocumented>
xen/ Xen hypervisor controls
=============== ===============================================================
These are the subdirs I have on my system or have been discovered by
@ -96,9 +96,12 @@ it :-)
:maxdepth: 1
abi
crypto
debug
fs
kernel
net
sunrpc
user
vm
xen

View File

@ -0,0 +1,31 @@
===============
/proc/sys/xen/
===============
Copyright (c) 2026, Shubham Chakraborty <chakrabortyshubham66@gmail.com>
For general info and legal blurb, please look in
Documentation/admin-guide/sysctl/index.rst.
------------------------------------------------------------------------------
These files show up in ``/proc/sys/xen/``, depending on the
kernel configuration:
.. contents:: :local:
balloon/hotplug_unpopulated
===========================
This flag controls whether unpopulated memory ranges are automatically
hotplugged as system RAM.
- ``0``: Unpopulated ranges are not hotplugged (default).
- ``1``: Unpopulated ranges are automatically hotplugged.
When enabled, the Xen balloon driver will add memory regions that are
marked as unpopulated in the Xen memory map to the system as usable RAM.
This allows for dynamic memory expansion in Xen guest domains.
This option is only available when the kernel is built with
``CONFIG_XEN_BALLOON_MEMORY_HOTPLUG`` enabled.

View File

@ -74,7 +74,7 @@ a particular type of taint. It's best to leave that to the aforementioned
script, but if you need something quick you can use this shell command to check
which bits are set::
$ for i in $(seq 18); do echo $(($i-1)) $(($(cat /proc/sys/kernel/tainted)>>($i-1)&1));done
$ for i in $(seq 20); do echo $(($i-1)) $(($(cat /proc/sys/kernel/tainted)>>($i-1)&1));done
Table for decoding tainted state
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1062,16 +1062,15 @@ Conclusion
You have reached the end of the step-by-step guide.
Did you run into trouble following any of the above steps not cleared up by the
reference section below? Did you spot errors? Or do you have ideas how to
Did you run into trouble following the step-by-step guide not cleared up by the
reference section below? Did you spot errors? Or do you have ideas on how to
improve the guide?
If any of that applies, please take a moment and let the maintainer of this
document know by email (Thorsten Leemhuis <linux@leemhuis.info>), ideally while
CCing the Linux docs mailing list (linux-doc@vger.kernel.org). Such feedback is
vital to improve this text further, which is in everybody's interest, as it
will enable more people to master the task described here -- and hopefully also
improve similar guides inspired by this one.
If any of that applies, please let the developers know by sending a short note
or a patch to Thorsten Leemhuis <linux@leemhuis.info> while ideally CCing the
public Linux docs mailing list <linux-doc@vger.kernel.org>. Such feedback is
vital to improve this text further, which is in everybody's interest, as it will
enable more people to master the task described here.
Reference section for the step-by-step guide

View File

@ -455,6 +455,7 @@ if html_theme == "alabaster":
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = "images/logo.svg"
html_favicon = "images/logo.svg"
# Output file base name for HTML help builder.
htmlhelp_basename = "TheLinuxKerneldoc"

View File

@ -15,7 +15,7 @@ various deferrals etc...
Sometimes housekeeping is just some unbound work (unbound workqueues,
unbound timers, ...) that gets easily assigned to non-isolated CPUs.
But sometimes housekeeping is tied to a specific CPU and requires
elaborated tricks to be offloaded to non-isolated CPUs (RCU_NOCB, remote
elaborate tricks to be offloaded to non-isolated CPUs (RCU_NOCB, remote
scheduler tick, etc...).
Thus, a housekeeping CPU can be considered as the reverse of an isolated

View File

@ -9,3 +9,4 @@ IRQs
irq-affinity
irq-domain
irqflags-tracing
managed_irq

View File

@ -0,0 +1,116 @@
.. SPDX-License-Identifier: GPL-2.0
===========================
Affinity managed interrupts
===========================
The IRQ core provides support for managing interrupts according to a specified
CPU affinity. Under normal operation, an interrupt is associated with a
particular CPU. If that CPU is taken offline, the interrupt is migrated to
another online CPU.
Devices with large numbers of interrupt vectors can stress the available vector
space. For example, an NVMe device with 128 I/O queues typically requests one
interrupt per queue on systems with at least 128 CPUs. Two such devices
therefore request 256 interrupts. On x86, the interrupt vector space is
notoriously low, providing only 256 vectors per CPU, and the kernel reserves a
subset of these, further reducing the number available for device interrupts.
In practice this is not an issue because the interrupts are distributed across
many CPUs, so each CPU only receives a small number of vectors.
During system suspend, however, all secondary CPUs are taken offline and all
interrupts are migrated to the single CPU that remains online. This can exhaust
the available interrupt vectors on that CPU and cause the suspend operation to
fail.
Affinitymanaged interrupts address this limitation. Each interrupt is assigned
a CPU affinity mask that specifies the set of CPUs on which the interrupt may
be targeted. When a CPU in the mask goes offline, the interrupt is moved to the
next CPU in the mask. If the last CPU in the mask goes offline, the interrupt
is shut down. Drivers using affinitymanaged interrupts must ensure that the
associated queue is quiesced before the interrupt is disabled so that no
further interrupts are generated. When a CPU in the affinity mask comes back
online, the interrupt is reenabled.
Implementation
--------------
Devices must provide perinstance interrupts, such as perI/Oqueue interrupts
for storage devices like NVMe. The driver allocates interrupt vectors with the
required affinity settings using struct irq_affinity. For MSIX devices, this
is done via pci_alloc_irq_vectors_affinity() with the PCI_IRQ_AFFINITY flag
set.
Based on the provided affinity information, the IRQ core attempts to spread the
interrupts evenly across the system. The affinity masks are computed during
this allocation step, but the final IRQ assignment is performed when
request_irq() is invoked.
Isolated CPUs
-------------
The affinity of managed interrupts is handled entirely in the kernel and cannot
be modified from user space through the /proc interfaces. The managed_irq
subparameter of the isolcpus boot option specifies a CPU mask that managed
interrupts should attempt to avoid. This isolation is besteffort and only
applies if the automatically assigned interrupt mask also contains online CPUs
outside the avoided mask. If the requested mask contains only isolated CPUs,
the setting has no effect.
CPUs listed in the avoided mask remain part of the interrupts affinity mask.
This means that if all nonisolated CPUs go offline while isolated CPUs remain
online, the interrupt will be assigned to one of the isolated CPUs.
The following examples assume a system with 8 CPUs.
- A QEMU instance is booted with "-device virtio-scsi-pci".
The MSIX device exposes 11 interrupts: 3 "management" interrupts and 8
"queue" interrupts. The driver requests the 8 queue interrupts, each of which
is affine to exactly one CPU. If that CPU goes offline, the interrupt is shut
down.
Assuming interrupt 48 is one of the queue interrupts, the following appears::
/proc/irq/48/effective_affinity_list:7
/proc/irq/48/smp_affinity_list:7
This indicates that the interrupt is served only by CPU7. Shutting down CPU7
does not migrate the interrupt to another CPU::
/proc/irq/48/effective_affinity_list:0
/proc/irq/48/smp_affinity_list:7
This can be verified via the debugfs interface
(/sys/kernel/debug/irq/irqs/48). The dstate field will include
IRQD_IRQ_DISABLED, IRQD_IRQ_MASKED and IRQD_MANAGED_SHUTDOWN.
- A QEMU instance is booted with "-device virtio-scsi-pci,num_queues=2"
and the kernel command line includes:
"irqaffinity=0,1 isolcpus=domain,2-7 isolcpus=managed_irq,1-3,5-7".
The MSIX device exposes 5 interrupts: 3 management interrupts and 2 queue
interrupts. The management interrupts follow the irqaffinity= setting. The
queue interrupts are spread across available CPUs::
/proc/irq/47/effective_affinity_list:0
/proc/irq/47/smp_affinity_list:0-3
/proc/irq/48/effective_affinity_list:4
/proc/irq/48/smp_affinity_list:4-7
The two queue interrupts are evenly distributed. Interrupt 48 is placed on CPU4
because the managed_irq mask avoids CPUs 57 when possible.
Replacing the managed_irq argument with "isolcpus=managed_irq,1-3,4-5,7"
results in::
/proc/irq/48/effective_affinity_list:6
/proc/irq/48/smp_affinity_list:4-7
Interrupt 48 is now served on CPU6 because the system avoids CPUs 4, 5 and
7. If CPU6 is taken offline, the interrupt migrates to one of the "isolated"
CPUs::
/proc/irq/48/effective_affinity_list:7
/proc/irq/48/smp_affinity_list:4-7
The interrupt is shut down once all CPUs listed in its smp_affinity mask are
offline.

View File

@ -96,7 +96,7 @@ NODE_CANCEL_ADDING_FIRST_MEMORY
Generated if NODE_ADDING_FIRST_MEMORY fails.
NODE_ADDED_FIRST_MEMORY
Generated when memory has become available fo this node for the first time.
Generated when memory has become available for this node for the first time.
NODE_REMOVING_LAST_MEMORY
Generated when the last memory available to this node is about to be offlined.

View File

@ -103,6 +103,42 @@ For debugging purposes there are also two conditionally-compiled macros:
pr_debug() and pr_devel(), which are compiled-out unless ``DEBUG`` (or
also ``CONFIG_DYNAMIC_DEBUG`` in the case of pr_debug()) is defined.
Avoiding lockups from excessive printk() use
============================================
.. note::
This section is relevant only for legacy console drivers (those not
using the nbcon API) and !PREEMPT_RT kernels. Once all console drivers
are updated to nbcon, this documentation can be removed.
Using ``printk()`` in hot paths (such as interrupt handlers, timer
callbacks, or high-frequency network receive routines) with legacy
consoles (e.g., ``console=ttyS0``) may cause lockups. Legacy consoles
synchronously acquire ``console_sem`` and block while flushing messages,
potentially disabling interrupts long enough to trigger hard or soft
lockup detectors.
To avoid this:
- Use rate-limited variants (e.g., ``pr_*_ratelimited()``) or one-time
macros (e.g., ``pr_*_once()``) to reduce message frequency.
- Assign lower log levels (e.g., ``KERN_DEBUG``) to non-essential messages
and filter console output via ``console_loglevel``.
- Use ``printk_deferred()`` to log messages immediately to the ringbuffer
and defer console printing. This is a workaround for legacy consoles.
- Port legacy console drivers to the non-blocking ``nbcon`` API (indicated
by ``CON_NBCON``). This is the preferred solution, as nbcon consoles
offload message printing to a dedicated kernel thread.
For temporary debugging, ``trace_printk()`` can be used, but it must not
appear in mainline code. See ``Documentation/trace/debugging.rst`` for
more information.
If more permanent output is needed in a hot path, trace events can be used.
See ``Documentation/trace/events.rst`` and
``samples/trace_events/trace-events-sample.[ch]``.
Function reference
==================

View File

@ -74,7 +74,7 @@ Exception handlers
Enabling interrupts is especially important on PREEMPT_RT, where certain
locks, such as spinlock_t, become sleepable. For example, handling an
invalid opcode may result in sending a SIGILL signal to the user task. A
debug excpetion will send a SIGTRAP signal.
debug exception will send a SIGTRAP signal.
In both cases, if the exception occurred in user space, it is safe to enable
interrupts early. Sending a signal requires both interrupts and kernel
preemption to be enabled.

View File

@ -213,7 +213,7 @@ to suspend until the callback completes, ensuring forward progress without
risking livelock.
In order to solve the problem at the API level, the sequence locks were extended
to allow a proper handover between the the spinning reader and the maybe
to allow a proper handover between the spinning reader and the maybe
blocked writer.
Sequence locks

View File

@ -29,12 +29,13 @@ of many distributions, e.g. :
- Ubuntu
- OpenSUSE
- Arch Linux
- Gentoo
- NetBSD
- FreeBSD
Some distribution packages are obsolete and it is recommended
to use the latest version released from the Coccinelle homepage at
http://coccinelle.lip6.fr/
https://coccinelle.gitlabpages.inria.fr/website
Or from Github at:
@ -60,7 +61,7 @@ Supplemental documentation
For supplemental documentation refer to the wiki:
https://bottest.wiki.kernel.org/coccicheck
https://bottest.wiki.kernel.org/coccicheck.html
The wiki documentation always refers to the linux-next version of the script.

View File

@ -213,6 +213,10 @@ The ``private:`` and ``public:`` tags must begin immediately following a
``/*`` comment marker. They may optionally include comments between the
``:`` and the ending ``*/`` marker.
When ``private:`` is used on nested structs, it propagates only to inner
structs/unions.
Example::
/**
@ -256,8 +260,10 @@ It is possible to document nested structs and unions, like::
union {
struct {
int memb1;
/* private: hides memb2 from documentation */
int memb2;
};
/* Everything here is public again, as private scope finished */
struct {
void *memb3;
int memb4;

View File

@ -47,7 +47,7 @@ generally be avoided and so struct acpi_driver objects should not be used.
Moreover, a device ID is necessary to bind a driver directly to an ACPI device
node, but device IDs are not generally associated with all of them. Some of
them contain alternative information allowing the corresponding pieces of
hardware to be identified, for example represeted by an _ADR object return
hardware to be identified, for example represented by an _ADR object return
value, and device IDs are not used in those cases. In consequence, confusingly
enough, binding an ACPI driver to an ACPI device node may even be impossible.

View File

@ -55,7 +55,7 @@ voltile vs persistent, etc). One or more bits may be set. ::
Bit[1]: CXL Type 3 Memory
Bit[2]: Volatile Memory
Bit[3]: Persistent Memory
Bit[4]: Fixed Config (HPA cannot be re-used)
Bit[4]: Fixed Config (HPA cannot be reused)
INTRA-host-bridge interleave (multiple devices on one host bridge) is NOT
reported in this structure, and is solely defined via CXL device decoder

View File

@ -277,7 +277,7 @@ The CFMWS field of the CEDT has special restriction bits which describe whether
the described memory region allows volatile or persistent memory (or both). If
the platform intends to support either:
1) A device with multiple medias, or
1) A device with multiple media, or
2) Using a persistent memory device as normal memory
A platform may wish to create multiple CEDT CFMWS entries to describe the same

View File

@ -40,7 +40,7 @@ Design
======
a) Virtual channels
Same concept as in sa11x0 driver, ie. a driver was assigned a "virtual
channel" linked to the requestor line, and the physical DMA channel is
channel" linked to the requester line, and the physical DMA channel is
assigned on the fly when the transfer is issued.
b) Transfer anatomy for a scatter-gather transfer

View File

@ -73,7 +73,7 @@ usr/gen_initramfs.sh. This means that CONFIG_INITRAMFS_SOURCE
can really be interpreted as any legal argument to
gen_initramfs.sh. If a directory is specified as an argument then
the contents are scanned, uid/gid translation is performed, and
usr/gen_init_cpio file directives are output. If a directory is
usr/gen_init_cpio file directives are output. If a file is
specified as an argument to usr/gen_initramfs.sh then the
contents of the file are simply copied to the output. All of the output
directives from directory scanning and file contents copying are

View File

@ -84,13 +84,25 @@ be registered with the interconnect provider core.
.. kernel-doc:: include/linux/interconnect-provider.h
.. kernel-doc:: drivers/interconnect/core.c
:functions: icc_provider_init icc_provider_register icc_provider_deregister
icc_node_create icc_node_create_dyn icc_node_destroy
icc_node_add icc_node_del icc_nodes_remove icc_node_set_name
icc_link_create icc_link_nodes
Interconnect consumers
----------------------
Interconnect consumers are the clients which use the interconnect APIs to
get paths between endpoints and set their bandwidth/latency/QoS requirements
for these interconnect paths. These interfaces are not currently
documented.
for these interconnect paths.
.. kernel-doc:: drivers/interconnect/core.c
:functions: devm_of_icc_get of_icc_get_by_index of_icc_get icc_get
icc_put icc_enable icc_disable icc_set_bw icc_set_tag
icc_get_name
.. kernel-doc:: drivers/interconnect/bulk.c
Interconnect debugfs interfaces
-------------------------------

View File

@ -286,7 +286,7 @@ and other exceptional conditions. The primary responsibility of an
implementation is to call :c:func:`ata_std_error_handler`.
:c:func:`ata_std_error_handler` will perform a standard error handling sequence
to resurect failed devices, detach lost devices and add new devices (if any).
to resurrect failed devices, detach lost devices and add new devices (if any).
This function will call the various reset operations for a port, as needed.
These operations are as follows.

View File

@ -222,7 +222,7 @@ The CCIR - I uses the PAL colorsystem, and is used in Great Britain, Hong Kong,
Ireland, Nigeria, South Africa.
The CCIR - N uses the PAL colorsystem and PAL frame size but the NTSC framerate,
and is used in Argentina, Uruguay, an a few others
and is used in Argentina, Uruguay, and a few others
We do not talk about how the audio is broadcast !

View File

@ -38,7 +38,7 @@ for all usage refcounts to reach zero.
At the lowest level the P2P subsystem offers a naked struct p2p_provider that
delegates lifecycle management to the providing driver. It is expected that
drivers using this option will wrap their MMIO memory in DMABUF and use DMABUF
to provide an invalidation shutdown. These MMIO addresess have no struct page, and
to provide an invalidation shutdown. These MMIO addresses have no struct page, and
if used with mmap() must create special PTEs. As such there are very few
kernel uAPIs that can accept pointers to them; in particular they cannot be used
with read()/write(), including O_DIRECT.

View File

@ -18,7 +18,7 @@
| mips: | ok |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
| parisc: | ok |
| powerpc: | ok |
| riscv: | ok |
| s390: | ok |

View File

@ -18,7 +18,7 @@
| mips: | ok |
| nios2: | TODO |
| openrisc: | TODO |
| parisc: | TODO |
| parisc: | ok |
| powerpc: | ok |
| riscv: | ok |
| s390: | ok |

View File

@ -1364,7 +1364,7 @@ it sets ``LOOKUP_AUTOMOUNT``, as does "``quotactl()``" and the handling of
symlinks. Some system calls set or clear it implicitly, while
others have API flags such as ``AT_SYMLINK_FOLLOW`` and
``UMOUNT_NOFOLLOW`` to control it. Its effect is similar to
``WALK_GET`` that we already met, but it is used in a different way.
``WALK_TRAILING`` that we already met, but it is used in a different way.
``LOOKUP_DIRECTORY`` insists that the final component is a directory.
Various callers set this and it is also set when the final component

View File

@ -464,26 +464,37 @@ Memory Area, or VMA) there is a series of lines such as the following::
KSM: 0 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
FilePmdMapped: 0 kB
ShmemPmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
THPeligible: 0
VmFlags: rd ex mr mw me dw
The first of these lines shows the same information as is displayed for
the mapping in /proc/PID/maps. Following lines show the size of the
mapping (size); the size of each page allocated when backing a VMA
(KernelPageSize), which is usually the same as the size in the page table
entries; the page size used by the MMU when backing a VMA (in most cases,
the same as KernelPageSize); the amount of the mapping that is currently
resident in RAM (RSS); the process's proportional share of this mapping
(PSS); and the number of clean and dirty shared and private pages in the
mapping.
mapping (size); the smallest possible page size allocated when backing a
VMA (KernelPageSize), which is the granularity in which VMA modifications
can be performed; the smallest possible page size that could be used by the
MMU (MMUPageSize) when backing a VMA; the amount of the mapping that is
currently resident in RAM (RSS); the process's proportional share of this
mapping (PSS); and the number of clean and dirty shared and private pages
in the mapping.
"KernelPageSize" always corresponds to "MMUPageSize", except when a larger
kernel page size is emulated on a system with a smaller page size used by the
MMU, which is the case for some PPC64 setups with hugetlb. Furthermore,
"KernelPageSize" and "MMUPageSize" always correspond to the smallest
possible granularity (fallback) that can be encountered in a VMA throughout
its lifetime. These values are not affected by Transparent Huge Pages
being in effect, or any usage of larger MMU page sizes (either through
architectural huge-page mappings or other explicit/implicit coalescing of
virtual ranges performed by the MMU). "AnonHugePages", "ShmemPmdMapped" and
"FilePmdMapped" provide insight into the usage of PMD-level architectural
huge-page mappings.
The "proportional set size" (PSS) of a process is the count of pages it has
in memory, where each page is divided by the number of processes sharing it.
@ -528,10 +539,15 @@ pressure if the memory is clean. Please note that the printed value might
be lower than the real value due to optimizations used in the current
implementation. If this is not desirable please file a bug report.
"AnonHugePages" shows the amount of memory backed by transparent hugepage.
"AnonHugePages", "ShmemPmdMapped" and "FilePmdMapped" show the amount of
memory backed by Transparent Huge Pages that are currently mapped by
architectural huge-page mappings at the PMD level. "AnonHugePages"
corresponds to memory that does not belong to a file, "ShmemPmdMapped" to
shared memory (shmem/tmpfs) and "FilePmdMapped" to file-backed memory
(excluding shmem/tmpfs).
"ShmemPmdMapped" shows the amount of shared (shmem/tmpfs) memory backed by
huge pages.
There are no dedicated entries for Transparent Huge Pages (or similar concepts)
that are not mapped by architectural huge-page mappings at the PMD level.
"Shared_Hugetlb" and "Private_Hugetlb" show the amounts of memory backed by
hugetlbfs page which is *not* counted in "RSS" or "PSS" field for historical
@ -727,7 +743,7 @@ files are there, and which are missing.
in the kernel image
cpuinfo Info about the CPU
devices Available devices (block and character)
dma Used DMS channels
dma Used DMA channels
filesystems Supported filesystems
driver Various drivers grouped here, currently rtc (2.4)
execdomains Execdomains, related to security (2.4)
@ -861,14 +877,13 @@ i386 and x86_64 platforms support the new IRQ vector displays.
Of some interest is the introduction of the /proc/irq directory to 2.4.
It could be used to set IRQ to CPU affinity. This means that you can "hook" an
IRQ to only one CPU, or to exclude a CPU of handling IRQs. The contents of the
irq subdir is one subdir for each IRQ, and two files; default_smp_affinity and
prof_cpu_mask.
irq subdir is one subdir for each IRQ, and default_smp_affinity.
For example::
> ls /proc/irq/
0 10 12 14 16 18 2 4 6 8 prof_cpu_mask
1 11 13 15 17 19 3 5 7 9 default_smp_affinity
0 10 12 14 16 18 2 4 6 8 default_smp_affinity
1 11 13 15 17 19 3 5 7 9
> ls /proc/irq/0/
smp_affinity
@ -899,9 +914,6 @@ The node file on an SMP system shows the node to which the device using the IRQ
reports itself as being attached. This hardware locality information does not
include information about any possible driver locality preference.
prof_cpu_mask specifies which CPUs are to be profiled by the system wide
profiler. Default value is ffffffff (all CPUs if there are only 32 of them).
The way IRQs are routed is handled by the IO-APIC, and it's Round Robin
between all the CPUs which are allowed to handle it. As usual the kernel has
more info than you and does a better job than you, so the defaults are the

View File

@ -27,7 +27,7 @@ position within the virtual file - that position is, likely as not, in the
middle of a line of output. The kernel has traditionally had a number of
implementations that got this wrong.
The 2.6 kernel contains a set of functions (implemented by Alexander Viro)
The kernel now contains a set of functions (implemented by Alexander Viro)
which are designed to make it easy for virtual file creators to get it
right.

View File

@ -163,8 +163,8 @@ The transport layer is a bi-directional protocol, which defines:
- A flow control mechanism to avoid buffer overflows
This protocol resembles bus messages described in the following document:
http://www.intel.com/content/dam/www/public/us/en/documents/technical-\
specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer"
http://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/dcmi-hi-1-0-spec.pdf
"Chapter 7: Bus Message Layer".
Connection and Flow Control Mechanism
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -38,7 +38,7 @@ To quote the overview comment::
for the mapping from a vma to a process. Since this case is expected
to be rare we hope we can get away with this.
The code consists of a the high level handler in mm/memory-failure.c,
The code consists of the high level handler in mm/memory-failure.c,
a new page poison bit and various checks in the VM to handle poisoned
pages.

View File

@ -140,7 +140,7 @@ this.
If the architecture supports--does not hide--memoryless nodes, then CPUs
attached to memoryless nodes would always incur the fallback path overhead
or some subsystems would fail to initialize if they attempted to allocated
or some subsystems would fail to initialize if they attempted to allocate
memory exclusively from a node without memory. To support such
architectures transparently, kernel subsystems can use the numa_mem_id()
or cpu_to_mem() function to locate the "local memory node" for the calling or

View File

@ -291,7 +291,7 @@ Use of the MMOTM tree is likely to be a frustrating experience, though;
there is a definite chance that it will not even compile.
The primary tree for next-cycle patch merging is linux-next, maintained by
Stephen Rothwell. The linux-next tree is, by design, a snapshot of what
Mark Brown. The linux-next tree is, by design, a snapshot of what
the mainline is expected to look like after the next merge window closes.
Linux-next trees are announced on the linux-kernel and linux-next mailing
lists when they are assembled; they can be downloaded from:

View File

@ -432,7 +432,7 @@ The same goes for added ``return``, ``break``, and ``continue``
statements.
Error handling is typically located at the bottom of the function, so it
may not be part of the conflict even though could have been changed by
may not be part of the conflict even though it could have been changed by
other patches.
A good way to ensure that you review the error paths is to always use

View File

@ -19,50 +19,52 @@ Current Minimal Requirements
Upgrade to at **least** these software revisions before thinking you've
encountered a bug! If you're unsure what version you're currently
running, the suggested command should tell you.
running, the suggested command should tell you. For a list of the programs
on your system including their version execute ./scripts/ver_linux
Again, keep in mind that this list assumes you are already functionally
running a Linux kernel. Also, not all tools are necessary on all
systems; obviously, if you don't have any PC Card hardware, for example,
you probably needn't concern yourself with pcmciautils.
you probably do not need to concern yourself with pcmciautils.
====================== =============== ========================================
Program Minimal version Command to check the version
====================== =============== ========================================
GNU C 8.1 gcc --version
Clang/LLVM (optional) 15.0.0 clang --version
Rust (optional) 1.85.0 rustc --version
bindgen (optional) 0.71.1 bindgen --version
GNU make 4.0 make --version
bash 4.2 bash --version
binutils 2.30 ld -v
flex 2.5.35 flex --version
bison 2.0 bison --version
pahole 1.22 pahole --version
util-linux 2.10o mount --version
kmod 13 depmod -V
e2fsprogs 1.41.4 e2fsck -V
jfsutils 1.1.3 fsck.jfs -V
xfsprogs 2.6.0 xfs_db -V
squashfs-tools 4.0 mksquashfs -version
btrfs-progs 0.18 btrfs --version
pcmciautils 004 pccardctl -V
quota-tools 3.09 quota -V
PPP 2.4.0 pppd --version
nfs-utils 1.0.5 showmount --version
procps 3.2.0 ps --version
udev 081 udevd --version
grub 0.93 grub --version || grub-install --version
mcelog 0.6 mcelog --version
iptables 1.4.2 iptables -V
openssl & libcrypto 1.0.0 openssl version
bc 1.06.95 bc --version
Sphinx\ [#f1]_ 3.4.3 sphinx-build --version
bindgen (optional) 0.71.1 bindgen --version
binutils 2.30 ld -v
bison 2.0 bison --version
btrfs-progs 0.18 btrfs --version
Clang/LLVM (optional) 15.0.0 clang --version
e2fsprogs 1.41.4 e2fsck -V
flex 2.5.35 flex --version
gdb 7.2 gdb --version
GNU awk (optional) 5.1.0 gawk --version
GNU C 8.1 gcc --version
GNU make 4.0 make --version
GNU tar 1.28 tar --version
GRUB 0.93 grub --version || grub-install --version
gtags (optional) 6.6.5 gtags --version
iptables 1.4.2 iptables -V
jfsutils 1.1.3 fsck.jfs -V
kmod 13 kmod -V
mcelog 0.6 mcelog --version
mkimage (optional) 2017.01 mkimage --version
nfs-utils 1.0.5 showmount --version
openssl & libcrypto 1.0.0 openssl version
pahole 1.22 pahole --version
pcmciautils 004 pccardctl -V
PPP 2.4.0 pppd --version
procps 3.2.0 ps --version
Python 3.9.x python3 --version
GNU AWK (optional) 5.1.0 gawk --version
quota-tools 3.09 quota -V
Rust (optional) 1.85.0 rustc --version
Sphinx\ [#f1]_ 3.4.3 sphinx-build --version
squashfs-tools 4.0 mksquashfs -version
udev 081 udevadm --version
util-linux 2.10o mount --version
xfsprogs 2.6.0 xfs_db -V
====================== =============== ========================================
.. [#f1] Sphinx is needed only to build the Kernel documentation
@ -391,7 +393,7 @@ Kernel documentation
Sphinx
------
Please see :ref:`sphinx_install` in :ref:`Documentation/doc-guide/sphinx.rst <sphinxdoc>`
Please see :ref:`sphinx_install` in Documentation/doc-guide/sphinx.rst
for details about Sphinx requirements.
rustdoc

View File

@ -173,3 +173,12 @@ this is just a snapshot of the initial version::
Detailed help can be obtained via "help <command-name>" for commands and "help
function <function-name>" for convenience functions.
Debugging GDB scripts
---------------------
GDB does not enable a full Python backtrace which can make debugging GDB
scripts more difficult than necessary. The following will allow for printing a
full backtrace of the python environment::
(gdb) set python print-stack full

View File

@ -461,325 +461,556 @@ which both cover more details than the above section.
Quotes from Linus about regression
----------------------------------
Find below a few real life examples of how Linus Torvalds expects regressions to
be handled:
The following statements from Linus Torvalds provide some insight into Linux
"no regressions" rule and how he expects regressions to be handled:
* From `2017-10-26 (1/2)
<https://lore.kernel.org/lkml/CA+55aFwiiQYJ+YoLKCXjN_beDVfu38mg=Ggg5LFOcqHE8Qi7Zw@mail.gmail.com/>`_::
On how quickly regressions should be fixed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you break existing user space setups THAT IS A REGRESSION.
* From `2026-01-22 <https://lore.kernel.org/all/CAHk-=wheQNiW_WtHGO7bKkT7Uib-p+ai2JP9M+z+FYcZ6CAxYA@mail.gmail.com/>`_::
It's not ok to say "but we'll fix the user space setup".
But a user complaining should basically result in an immediate fix -
possibly a "revert and rethink".
Really. NOT OK.
With a later clarification on `2026-01-28 <https://lore.kernel.org/all/CAHk-%3Dwi86AosXs66-yi54%2BmpQjPu0upxB8ZAfG%2BLsMyJmcuMSA@mail.gmail.com/>`_::
[...]
It's also worth noting that "immediate" obviously doesn't mean "right
this *second* when the problem has been reported".
The first rule is:
But if it's a regression with a known commit that caused it, I think
the rule of thumb should generally be "within a week", preferably
before the next rc.
- we don't cause regressions
* From `2023-04-21 <https://lore.kernel.org/all/CAHk-=wgD98pmSK3ZyHk_d9kZ2bhgN6DuNZMAJaV0WTtbkf=RDw@mail.gmail.com/>`_::
and the corollary is that when regressions *do* occur, we admit to
them and fix them, instead of blaming user space.
Known-broken commits either
(a) get a timely fix that doesn't have other questions
or
(b) get reverted
The fact that you have apparently been denying the regression now for
three weeks means that I will revert, and I will stop pulling apparmor
requests until the people involved understand how kernel development
is done.
* From `2021-09-20(2) <https://lore.kernel.org/all/CAHk-=wgOvmtRw1TNbMC1rn5YqyTKyn0hz+sc4k0DGNn++u9aYw@mail.gmail.com/>`_::
* From `2017-10-26 (2/2)
<https://lore.kernel.org/lkml/CA+55aFxW7NMAMvYhkvz1UPbUTUJewRt6Yb51QAx5RtrWOwjebg@mail.gmail.com/>`_::
[...] review shouldn't hold up reported regressions of existing code. That's
just basic _testing_ - either the fix should be applied, or - if the fix is
too invasive or too ugly - the problematic source of the regression should
be reverted.
People should basically always feel like they can update their kernel
and simply not have to worry about it.
Review should be about new code, it shouldn't be holding up "there's a
bug report, here's the obvious fix".
I refuse to introduce "you can only update the kernel if you also
update that other program" kind of limitations. If the kernel used to
work for you, the rule is that it continues to work for you.
* From `2023-05-08 <https://lore.kernel.org/all/CAHk-=wgzU8_dGn0Yg+DyX7ammTkDUCyEJ4C=NvnHRhxKWC7Wpw@mail.gmail.com/>`_::
There have been exceptions, but they are few and far between, and they
generally have some major and fundamental reasons for having happened,
that were basically entirely unavoidable, and people _tried_hard_ to
avoid them. Maybe we can't practically support the hardware any more
after it is decades old and nobody uses it with modern kernels any
more. Maybe there's a serious security issue with how we did things,
and people actually depended on that fundamentally broken model. Maybe
there was some fundamental other breakage that just _had_ to have a
flag day for very core and fundamental reasons.
If something doesn't even build, it should damn well be fixed ASAP.
And notice that this is very much about *breaking* peoples environments.
On how fixing regressions with reverts can help prevent maintainer burnout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Behavioral changes happen, and maybe we don't even support some
feature any more. There's a number of fields in /proc/<pid>/stat that
are printed out as zeroes, simply because they don't even *exist* in
the kernel any more, or because showing them was a mistake (typically
an information leak). But the numbers got replaced by zeroes, so that
the code that used to parse the fields still works. The user might not
see everything they used to see, and so behavior is clearly different,
but things still _work_, even if they might no longer show sensitive
(or no longer relevant) information.
* From `2026-01-28 <https://lore.kernel.org/all/CAHk-%3Dwi86AosXs66-yi54%2BmpQjPu0upxB8ZAfG%2BLsMyJmcuMSA@mail.gmail.com/>`_::
But if something actually breaks, then the change must get fixed or
reverted. And it gets fixed in the *kernel*. Not by saying "well, fix
your user space then". It was a kernel change that exposed the
problem, it needs to be the kernel that corrects for it, because we
have a "upgrade in place" model. We don't have a "upgrade with new
user space".
> So how can I/we make "immediate fixes" happen more often without
> contributing to maintainer burnout?
And I seriously will refuse to take code from people who do not
understand and honor this very simple rule.
[...] the "revert and rethink" model [...] often a good idea in general [...]
This rule is also not going to change.
Exactly so that maintainers don't get stressed out over having a pending
problem report that people keep pestering them about.
And yes, I realize that the kernel is "special" in this respect. I'm
proud of it.
I think people are sometimes a bit too bought into whatever changes
they made, and reverting is seen as "too drastic", but I think it's
often the quick and easy solution for when there isn't some obvious
response to a regression report.
I have seen, and can point to, lots of projects that go "We need to
break that use case in order to make progress" or "you relied on
undocumented behavior, it sucks to be you" or "there's a better way to
do what you want to do, and you have to change to that new better
way", and I simply don't think that's acceptable outside of very early
alpha releases that have experimental users that know what they signed
up for. The kernel hasn't been in that situation for the last two
decades.
On mainlining fixes when the last -rc or a new release is close
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We do API breakage _inside_ the kernel all the time. We will fix
internal problems by saying "you now need to do XYZ", but then it's
about internal kernel API's, and the people who do that then also
obviously have to fix up all the in-kernel users of that API. Nobody
can say "I now broke the API you used, and now _you_ need to fix it
up". Whoever broke something gets to fix it too.
* From `2026-02-01 <https://lore.kernel.org/all/CAHk-%3DwhXTw1oPsa%2BTLuY1Rc9D1OAiPVOdR_-R2xG45kwDObKdA@mail.gmail.com/>`_::
And we simply do not break user space.
So I think I'd rather see them hit rc8 (later today) and have a week
of testing in my tree and be reverted if they cause problems, than
have them go in after rc8 and then cause problems in the 6.19 release
instead.
* From `2020-05-21
<https://lore.kernel.org/all/CAHk-=wiVi7mSrsMP=fLXQrXK_UimybW=ziLOwSzFTtoXUacWVQ@mail.gmail.com/>`_::
* From `2023-04-20 <https://lore.kernel.org/all/CAHk-=wis_qQy4oDNynNKi5b7Qhosmxtoj1jxo5wmB6SRUwQUBQ@mail.gmail.com/>`_::
The rules about regressions have never been about any kind of
documented behavior, or where the code lives.
But something like this, where the regression was in the previous release
and it's just a clear fix with no semantic subtlety, I consider to be just a
regular regression that should be expedited - partly to make it into stable,
and partly to avoid having to put the fix into _another_ stable kernel.
The rules about regressions are always about "breaks user workflow".
On sending merge requests with just one fix
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Users are literally the _only_ thing that matters.
* From `2024-04-24 <https://lore.kernel.org/all/CAHk-=wjy_ph9URuFt-pq+2AJ__p7gFDx=yzVSCsx16xAYvNw9g@mail.gmail.com/>`_::
No amount of "you shouldn't have used this" or "that behavior was
undefined, it's your own fault your app broke" or "that used to work
simply because of a kernel bug" is at all relevant.
If the issue is just that there's nothing else happening, I think people
should just point me to the patch and say "can you apply this single fix?"
Now, reality is never entirely black-and-white. So we've had things
like "serious security issue" etc that just forces us to make changes
that may break user space. But even then the rule is that we don't
really have other options that would allow things to continue.
* From `2023-04-20 <https://lore.kernel.org/all/CAHk-=wis_qQy4oDNynNKi5b7Qhosmxtoj1jxo5wmB6SRUwQUBQ@mail.gmail.com/>`_::
And obviously, if users take years to even notice that something
broke, or if we have sane ways to work around the breakage that
doesn't make for too much trouble for users (ie "ok, there are a
handful of users, and they can use a kernel command line to work
around it" kind of things) we've also been a bit less strict.
I'm always open to direct fixes when there is no controversy about the fix.
No problem. I still happily deal with individual patches.
But no, "that was documented to be broken" (whether it's because the
code was in staging or because the man-page said something else) is
irrelevant. If staging code is so useful that people end up using it,
that means that it's basically regular kernel code with a flag saying
"please clean this up".
On the importance of pointing to bug reports using Link:/Closes: tags
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The other side of the coin is that people who talk about "API
stability" are entirely wrong. API's don't matter either. You can make
any changes to an API you like - as long as nobody notices.
* From `2025-07-29(1) <https://lore.kernel.org/all/CAHk-=wj2kJRPWx8B09AAtzj+_g+T6UBX11TP0ebs1WJdTtv=WQ@mail.gmail.com/>`_::
Again, the regression rule is not about documentation, not about
API's, and not about the phase of the moon.
[...] revert like this, it really would be good to link to the problems, so
that when people try to re-enable it, they have the history for why it
didn't work the first time.
It's entirely about "we caused problems for user space that used to work".
* From `2022-05-08 <https://lore.kernel.org/all/CAHk-=wjMmSZzMJ3Xnskdg4+GGz=5p5p+GSYyFBTh0f-DgvdBWg@mail.gmail.com/>`_::
* From `2017-11-05
<https://lore.kernel.org/all/CA+55aFzUvbGjD8nQ-+3oiMBx14c_6zOj2n7KLN3UsJ-qsd4Dcw@mail.gmail.com/>`_::
So I have to once more complain [...]
And our regression rule has never been "behavior doesn't change".
That would mean that we could never make any changes at all.
[...] There's no link to the actual problem the patch fixes.
For example, we do things like add new error handling etc all the
time, which we then sometimes even add tests for in our kselftest
directory.
* From `2022-06-22 <https://lore.kernel.org/all/CAHk-=wjxzafG-=J8oT30s7upn4RhBs6TX-uVFZ5rME+L5_DoJA@mail.gmail.com/>`_::
So clearly behavior changes all the time and we don't consider that a
regression per se.
See, *that* link [to the report] would have been useful in the commit.
The rule for a regression for the kernel is that some real user
workflow breaks. Not some test. Not a "look, I used to be able to do
X, now I can't".
On why the "no regressions" rule exists
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* From `2018-08-03
<https://lore.kernel.org/all/CA+55aFwWZX=CXmWDTkDGb36kf12XmTehmQjbiMPCqCRG2hi9kw@mail.gmail.com/>`_::
* From `2026-01-22 <https://lore.kernel.org/all/CAHk-=wheQNiW_WtHGO7bKkT7Uib-p+ai2JP9M+z+FYcZ6CAxYA@mail.gmail.com/>`_::
YOU ARE MISSING THE #1 KERNEL RULE.
But the basic rule is: be so good about backwards compatibility that
users never have to worry about upgrading. They should absolutely feel
confident that any kernel-reported problem will either be solved, or
have an easy solution that is appropriate for *them* (ie a
non-technical user shouldn't be expected to be able to do a lot).
We do not regress, and we do not regress exactly because your are 100% wrong.
Because the last thing we want is people holding back from trying new
kernels.
And the reason you state for your opinion is in fact exactly *WHY* you
are wrong.
* From `2024-05-28 <https://lore.kernel.org/all/CAHk-=wgtb7y-bEh7tPDvDWru7ZKQ8-KMjZ53Tsk37zsPPdwXbA@mail.gmail.com/>`_::
Your "good reasons" are pure and utter garbage.
I introduced that "no regressions" rule something like two decades
ago, because people need to be able to update their kernel without
fear of something they relied on suddenly stopping to work.
The whole point of "we do not regress" is so that people can upgrade
the kernel and never have to worry about it.
* From `2018-08-03 <https://lore.kernel.org/all/CA+55aFwWZX=CXmWDTkDGb36kf12XmTehmQjbiMPCqCRG2hi9kw@mail.gmail.com/>`_::
> Kernel had a bug which has been fixed
The whole point of "we do not regress" is so that people can upgrade
the kernel and never have to worry about it.
That is *ENTIRELY* immaterial.
[...]
Guys, whether something was buggy or not DOES NOT MATTER.
Because the only thing that matters IS THE USER.
Why?
* From `2017-10-26(1) <https://lore.kernel.org/lkml/CA+55aFxW7NMAMvYhkvz1UPbUTUJewRt6Yb51QAx5RtrWOwjebg@mail.gmail.com/>`_::
Bugs happen. That's a fact of life. Arguing that "we had to break
something because we were fixing a bug" is completely insane. We fix
tens of bugs every single day, thinking that "fixing a bug" means that
we can break something is simply NOT TRUE.
If the kernel used to work for you, the rule is that it continues to work
for you.
So bugs simply aren't even relevant to the discussion. They happen,
they get found, they get fixed, and it has nothing to do with "we
break users".
[...]
Because the only thing that matters IS THE USER.
People should basically always feel like they can update their kernel
and simply not have to worry about it.
How hard is that to understand?
I refuse to introduce "you can only update the kernel if you also
update that other program" kind of limitations. If the kernel used to
work for you, the rule is that it continues to work for you.
Anybody who uses "but it was buggy" as an argument is entirely missing
the point. As far as the USER was concerned, it wasn't buggy - it
worked for him/her.
On exceptions to the "no regressions" rule
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Maybe it worked *because* the user had taken the bug into account,
maybe it worked because the user didn't notice - again, it doesn't
matter. It worked for the user.
* From `2026-01-22 <https://lore.kernel.org/all/CAHk-=wheQNiW_WtHGO7bKkT7Uib-p+ai2JP9M+z+FYcZ6CAxYA@mail.gmail.com/>`_::
Breaking a user workflow for a "bug" is absolutely the WORST reason
for breakage you can imagine.
There are _very_ few exceptions to that rule, the main one being "the
problem was a fundamental huge and gaping security issue and we *had* to
make that change, and we couldn't even make your limited use-case just
continue to work".
It's basically saying "I took something that worked, and I broke it,
but now it's better". Do you not see how f*cking insane that statement
is?
The other exception is "the problem was reported years after it was
introduced, and now most people rely on the new behavior".
And without users, your program is not a program, it's a pointless
piece of code that you might as well throw away.
[...]
Seriously. This is *why* the #1 rule for kernel development is "we
don't break users". Because "I fixed a bug" is absolutely NOT AN
ARGUMENT if that bug fix broke a user setup. You actually introduced a
MUCH BIGGER bug by "fixing" something that the user clearly didn't
even care about.
Now, if it's one or two users and you can just get them to recompile,
that's one thing. Niche hardware and odd use-cases can sometimes be
solved that way, and regressions can sometimes be fixed by handholding
every single reporter if the reporter is willing and able to change
his or her workflow.
And dammit, we upgrade the kernel ALL THE TIME without upgrading any
other programs at all. It is absolutely required, because flag-days
and dependencies are horribly bad.
* From `2023-04-20 <https://lore.kernel.org/all/CAHk-=wis_qQy4oDNynNKi5b7Qhosmxtoj1jxo5wmB6SRUwQUBQ@mail.gmail.com/>`_::
And it is also required simply because I as a kernel developer do not
upgrade random other tools that I don't even care about as I develop
the kernel, and I want any of my users to feel safe doing the same
time.
And yes, I do consider "regression in an earlier release" to be a
regression that needs fixing.
So no. Your rule is COMPLETELY wrong. If you cannot upgrade a kernel
without upgrading some other random binary, then we have a problem.
There's obviously a time limit: if that "regression in an earlier
release" was a year or more ago, and just took forever for people to
notice, and it had semantic changes that now mean that fixing the
regression could cause a _new_ regression, then that can cause me to
go "Oh, now the new semantics are what we have to live with".
* From `2021-06-05
<https://lore.kernel.org/all/CAHk-=wiUVqHN76YUwhkjZzwTdjMMJf_zN4+u7vEJjmEGh3recw@mail.gmail.com/>`_::
* From `2017-10-26(2) <https://lore.kernel.org/lkml/CA+55aFxW7NMAMvYhkvz1UPbUTUJewRt6Yb51QAx5RtrWOwjebg@mail.gmail.com/>`_::
THERE ARE NO VALID ARGUMENTS FOR REGRESSIONS.
There have been exceptions, but they are few and far between, and they
generally have some major and fundamental reasons for having happened,
that were basically entirely unavoidable, and people _tried_hard_ to
avoid them. Maybe we can't practically support the hardware any more
after it is decades old and nobody uses it with modern kernels any
more. Maybe there's a serious security issue with how we did things,
and people actually depended on that fundamentally broken model. Maybe
there was some fundamental other breakage that just _had_ to have a
flag day for very core and fundamental reasons.
Honestly, security people need to understand that "not working" is not
a success case of security. It's a failure case.
On situations where updating something in userspace can resolve regressions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Yes, "not working" may be secure. But security in that case is *pointless*.
* From `2018-08-03 <https://lore.kernel.org/all/CA+55aFwWZX=CXmWDTkDGb36kf12XmTehmQjbiMPCqCRG2hi9kw@mail.gmail.com/>`_::
* From `2011-05-06 (1/3)
<https://lore.kernel.org/all/BANLkTim9YvResB+PwRp7QTK-a5VNg2PvmQ@mail.gmail.com/>`_::
And dammit, we upgrade the kernel ALL THE TIME without upgrading any
other programs at all. It is absolutely required, because flag-days
and dependencies are horribly bad.
Binary compatibility is more important.
And it is also required simply because I as a kernel developer do not
upgrade random other tools that I don't even care about as I develop the
kernel, and I want any of my users to feel safe doing the same time.
And if binaries don't use the interface to parse the format (or just
parse it wrongly - see the fairly recent example of adding uuid's to
/proc/self/mountinfo), then it's a regression.
* From `2017-10-26(3) <https://lore.kernel.org/lkml/CA+55aFxW7NMAMvYhkvz1UPbUTUJewRt6Yb51QAx5RtrWOwjebg@mail.gmail.com/>`_::
And regressions get reverted, unless there are security issues or
similar that makes us go "Oh Gods, we really have to break things".
But if something actually breaks, then the change must get fixed or
reverted. And it gets fixed in the *kernel*. Not by saying "well, fix your
user space then". It was a kernel change that exposed the problem, it needs
to be the kernel that corrects for it, because we have a "upgrade in place"
model. We don't have a "upgrade with new user space".
I don't understand why this simple logic is so hard for some kernel
developers to understand. Reality matters. Your personal wishes matter
NOT AT ALL.
And I seriously will refuse to take code from people who do not understand
and honor this very simple rule.
If you made an interface that can be used without parsing the
interface description, then we're stuck with the interface. Theory
simply doesn't matter.
This rule is also not going to change.
You could help fix the tools, and try to avoid the compatibility
issues that way. There aren't that many of them.
And yes, I realize that the kernel is "special" in this respect. I'm proud
of it.
From `2011-05-06 (2/3)
<https://lore.kernel.org/all/BANLkTi=KVXjKR82sqsz4gwjr+E0vtqCmvA@mail.gmail.com/>`_::
* From `2017-10-26(4) <https://lore.kernel.org/all/CA+55aFwiiQYJ+YoLKCXjN_beDVfu38mg=Ggg5LFOcqHE8Qi7Zw@mail.gmail.com/>`_::
it's clearly NOT an internal tracepoint. By definition. It's being
used by powertop.
If you break existing user space setups THAT IS A REGRESSION.
From `2011-05-06 (3/3)
<https://lore.kernel.org/all/BANLkTinazaXRdGovYL7rRVp+j6HbJ7pzhg@mail.gmail.com/>`_::
It's not ok to say "but we'll fix the user space setup".
We have programs that use that ABI and thus it's a regression if they break.
Really. NOT OK.
* From `2012-07-06 <https://lore.kernel.org/all/CA+55aFwnLJ+0sjx92EGREGTWOx84wwKaraSzpTNJwPVV8edw8g@mail.gmail.com/>`_::
On what qualifies as userspace interface, ABI, API, documented interfaces, etc.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> Now this got me wondering if Debian _unstable_ actually qualifies as a
> standard distro userspace.
* From `2026-01-20 <https://lore.kernel.org/all/CAHk-=wga8Qu0-OSE9VZbviq9GuqwhPhLUXeAt-S7_9+fMCLkKg@mail.gmail.com/>`_::
Oh, if the kernel breaks some standard user space, that counts. Tons
of people run Debian unstable
So I absolutely detest the whole notion of "ABI changes". It's a
meaningless concept, and I hate it with a passion, [...]
* From `2019-09-15
<https://lore.kernel.org/lkml/CAHk-=wiP4K8DRJWsCo=20hn_6054xBamGKF2kPgUzpB5aMaofA@mail.gmail.com/>`_::
The Linux rule for regressions is basically based on the philosophical
question of "If a tree falls in the forest, and nobody is around to
hear it, does it make a sound?".
One _particularly_ last-minute revert is the top-most commit (ignoring
the version change itself) done just before the release, and while
it's very annoying, it's perhaps also instructive.
So the only thing that matters is if something breaks user-*conscious*
behavior.
What's instructive about it is that I reverted a commit that wasn't
actually buggy. In fact, it was doing exactly what it set out to do,
and did it very well. In fact it did it _so_ well that the much
improved IO patterns it caused then ended up revealing a user-visible
regression due to a real bug in a completely unrelated area.
And when that happens, the distinction between "bug fix" and "new
feature" and "ABI change" matters not one whit, and the change needs
to be done differently.
The actual details of that regression are not the reason I point that
revert out as instructive, though. It's more that it's an instructive
example of what counts as a regression, and what the whole "no
regressions" kernel rule means. The reverted commit didn't change any
API's, and it didn't introduce any new bugs. But it ended up exposing
another problem, and as such caused a kernel upgrade to fail for a
user. So it got reverted.
[...]
The point here being that we revert based on user-reported _behavior_,
not based on some "it changes the ABI" or "it caused a bug" concept.
The problem was really pre-existing, and it just didn't happen to
trigger before. The better IO patterns introduced by the change just
happened to expose an old bug, and people had grown to depend on the
previously benign behavior of that old issue.
I just wanted to point out that the argument about whether it's an ABI
change or not is irrelevant. If it turns out that some program - not a test
script, but something with relevance to conscious user expectations ~
depended on the old broken behavior, then it needs to be done some other
way.
And never fear, we'll re-introduce the fix that improved on the IO
patterns once we've decided just how to handle the fact that we had a
bad interaction with an interface that people had then just happened
to rely on incidental behavior for before. It's just that we'll have
to hash through how to do that (there are no less than three different
patches by three different developers being discussed, and there might
be more coming...). In the meantime, I reverted the thing that exposed
the problem to users for this release, even if I hope it will be
re-introduced (perhaps even backported as a stable patch) once we have
consensus about the issue it exposed.
* From `2026-02-13 <https://lore.kernel.org/all/CAHk-=whY-N8kjm8kiFUV5Ei-8AuYw--EPGD-AR3Pd+5GTx2sAQ@mail.gmail.com/>`_::
Take-away from the whole thing: it's not about whether you change the
kernel-userspace ABI, or fix a bug, or about whether the old code
"should never have worked in the first place". It's about whether
something breaks existing users' workflow.
> [...] this should not fall under the don't break user space rule [...]
Anyway, that was my little aside on the whole regression thing. Since
it's that "first rule of kernel programming", I felt it is perhaps
worth just bringing it up every once in a while
Note that the rule is about breaking *users*, not breaking user space per
se. [...]
If some user setup breaks, things need fixing.
[...] but I want to make it very clear that there are no excuses about "user
space applications".
* From `2021-09-20(4) <https://lore.kernel.org/all/CAHk-=wi7DB2SJ-wngVvsJ7Ak2cM556Q8437sOXo4EJt2BWPdEg@mail.gmail.com/>`_::
[...] a regression is a bit like Schrödinger's cat - if nobody is around
to notice it and it doesn't actually affect any real workload, then you
can treat the regression as if it doesn't exist.
* From `2020-05-21 <https://lore.kernel.org/all/CAHk-=wiVi7mSrsMP=fLXQrXK_UimybW=ziLOwSzFTtoXUacWVQ@mail.gmail.com/>`_::
The rules about regressions have never been about any kind of documented
behavior, or where the code lives.
The rules about regressions are always about "breaks user workflow".
Users are literally the _only_ thing that matters.
* From `2019-09-15 <https://lore.kernel.org/lkml/CAHk-=wiP4K8DRJWsCo=20hn_6054xBamGKF2kPgUzpB5aMaofA@mail.gmail.com/>`_::
One _particularly_ last-minute revert is the top-most commit (ignoring
the version change itself) done just before the release, and while
it's very annoying, it's perhaps also instructive.
What's instructive about it is that I reverted a commit that wasn't
actually buggy. In fact, it was doing exactly what it set out to do,
and did it very well. In fact it did it _so_ well that the much
improved IO patterns it caused then ended up revealing a user-visible
regression due to a real bug in a completely unrelated area.
The actual details of that regression are not the reason I point that
revert out as instructive, though. It's more that it's an instructive
example of what counts as a regression, and what the whole "no
regressions" kernel rule means.
[...] The reverted commit didn't change any API's, and it didn't introduce
any new bugs. But it ended up exposing another problem, and as such caused
a kernel upgrade to fail for a user. So it got reverted.
The point here being that we revert based on user-reported _behavior_, not
based on some "it changes the ABI" or "it caused a bug" concept. The problem
was really pre-existing, and it just didn't happen to trigger before. [...]
Take-away from the whole thing: it's not about whether you change the
kernel-userspace ABI, or fix a bug, or about whether the old code
"should never have worked in the first place". It's about whether
something breaks existing users' workflow.
* From `2017-11-05 <https://lore.kernel.org/all/CA+55aFzUvbGjD8nQ-+3oiMBx14c_6zOj2n7KLN3UsJ-qsd4Dcw@mail.gmail.com/>`_::
And our regression rule has never been "behavior doesn't change".
That would mean that we could never make any changes at all.
* From `2020-05-21 <https://lore.kernel.org/all/CAHk-=wiVi7mSrsMP=fLXQrXK_UimybW=ziLOwSzFTtoXUacWVQ@mail.gmail.com/>`_::
No amount of "you shouldn't have used this" or "that behavior was
undefined, it's your own fault your app broke" or "that used to work
simply because of a kernel bug" is at all relevant.
* From `2021-05-21 <https://lore.kernel.org/all/CAHk-=wiVi7mSrsMP=fLXQrXK_UimybW=ziLOwSzFTtoXUacWVQ@mail.gmail.com/>`_::
But no, "that was documented to be broken" (whether it's because the code
was in staging or because the man-page said something else) is irrelevant.
If staging code is so useful that people end up using it, that means that
it's basically regular kernel code with a flag saying "please clean this
up".
[...]
The other side of the coin is that people who talk about "API stability" are
entirely wrong. API's don't matter either. You can make any changes to an
API you like - as long as nobody notices.
Again, the regression rule is not about documentation, not about API's, and
not about the phase of the moon.
* From `2012-07-06 <https://lore.kernel.org/all/CA+55aFwnLJ+0sjx92EGREGTWOx84wwKaraSzpTNJwPVV8edw8g@mail.gmail.com/>`_::
> Now this got me wondering if Debian _unstable_ actually qualifies as a
> standard distro userspace.
Oh, if the kernel breaks some standard user space, that counts. Tons
of people run Debian unstable
* From `2011-05-06 <https://lore.kernel.org/all/BANLkTi=KVXjKR82sqsz4gwjr+E0vtqCmvA@mail.gmail.com/>`_::
It's clearly NOT an internal tracepoint. By definition. It's being
used by powertop.
On regressions noticed by users or test-suites/CIs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* From `2026-01-22 <https://lore.kernel.org/all/CAHk-=wheQNiW_WtHGO7bKkT7Uib-p+ai2JP9M+z+FYcZ6CAxYA@mail.gmail.com/>`_::
Users complaining is the only real line in the end.
[...] a test-suite complaining is then often a *very* good indication that
maybe users will hit some problem, and test suite issues should be taken
very seriously [...]
But a test-suite error isn't necessarily where you have to draw the
line - it's a big red flag [...]
* From `2024-29-01 <https://lore.kernel.org/all/CAHk-=wg8BrZEzjJ5kUyZzHPZmFqH6ooMN1gRBCofxxCfucgjaw@mail.gmail.com/>`_::
The "no regressions" rule is not about made-up "if I do this, behavior
changes".
The "no regressions" rule is about *users*.
If you have an actual user that has been doing insane things, and we
change something, and now the insane thing no longer works, at that
point it's a regression, and we'll sigh, and go "Users are insane" and
have to fix it.
But if you have some random test that now behaves differently, it's
not a regression. It's a *warning* sign, sure: tests are useful.
On accepting when a regression occurred
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* From `2026-01-22 <https://lore.kernel.org/all/CAHk-=wheQNiW_WtHGO7bKkT7Uib-p+ai2JP9M+z+FYcZ6CAxYA@mail.gmail.com/>`_::
But starting to argue about users reporting breaking changes is
basically the final line for me. I have a couple of people that I have
in my spam block-list and refuse to have anything to do with, and they
have generally been about exactly that.
Note how it's not about making mistakes and _causing_ the regression.
That's normal. That's development. But then arguing about it is a
no-no.
* From `2024-06-23 <https://lore.kernel.org/all/CAHk-=wi_KMO_rJ6OCr8mAWBRg-irziM=T9wxGC+J1VVoQb39gw@mail.gmail.com/>`_::
We don't introduce regressions and then blame others.
There's a very clear rule in kernel development: things that break
other things ARE NOT FIXES.
EVER.
They get reverted, or the thing they broke gets fixed.
* From `2021-06-05 <https://lore.kernel.org/all/CAHk-=wiUVqHN76YUwhkjZzwTdjMMJf_zN4+u7vEJjmEGh3recw@mail.gmail.com/>`_::
THERE ARE NO VALID ARGUMENTS FOR REGRESSIONS.
Honestly, security people need to understand that "not working" is not
a success case of security. It's a failure case.
Yes, "not working" may be secure. But security in that case is *pointless*.
* From `2017-10-26(5) <https://lore.kernel.org/lkml/CA+55aFwiiQYJ+YoLKCXjN_beDVfu38mg=Ggg5LFOcqHE8Qi7Zw@mail.gmail.com/>`_::
[...] when regressions *do* occur, we admit to them and fix them, instead of
blaming user space.
The fact that you have apparently been denying the regression now for
three weeks means that I will revert, and I will stop pulling apparmor
requests until the people involved understand how kernel development
is done.
On back-and-forth
~~~~~~~~~~~~~~~~~
* From `2024-05-28 <https://lore.kernel.org/all/CAHk-=wgtb7y-bEh7tPDvDWru7ZKQ8-KMjZ53Tsk37zsPPdwXbA@mail.gmail.com/>`_::
The "no regressions" rule is that we do not introduce NEW bugs.
It *literally* came about because we had an endless dance of "fix two
bugs, introduce one new one", and that then resulted in a system that
you cannot TRUST.
* From `2021-09-20(1) <https://lore.kernel.org/all/CAHk-=wi7DB2SJ-wngVvsJ7Ak2cM556Q8437sOXo4EJt2BWPdEg@mail.gmail.com/>`_::
And the thing that makes regressions special is that back when I
wasn't so strict about these things, we'd end up in endless "seesaw
situations" where somebody would fix something, it would break
something else, then that something else would break, and it would
never actually converge on anything reliable at all.
* From `2015-08-13 <https://lore.kernel.org/all/CA+55aFxk8-BsiKwr_S-c+4G6wihKPQVMLE34H9wOZpeua6W9+Q@mail.gmail.com/>`_::
The strict policy of no regressions actually originally started mainly wrt
suspend/resume issues, where the "fix one machine, break another" kind of
back-and-forth caused endless problems, and meant that we didn't actually
necessarily make any forward progress, just moving a problem around.
On changes with a risk of causing regressions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* From `2023-06-02 <https://lore.kernel.org/all/CAHk-=wgyAGUMHmQM-5Eb556z5xiHZB7cF05qjrtUH4F7P-1rSA@mail.gmail.com/>`_::
So what I think you should do is to fix the bug right, with a clean
patch, and no crazy hacks. That is something we can then apply and
test. All the while knowing full well that "uhhuh, this is a visible
change, we may have to revert it".
If then some *real* load ends up showing a regression, we may just be
screwed. Our current behavior may be buggy, but we have the rule that
once user space depends on kernel bugs, they become features pretty
much by definition, however much we might dislike it.
On in-kernel workarounds to avoid regressions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* From `2017-10-26(6) <https://lore.kernel.org/lkml/CA+55aFxW7NMAMvYhkvz1UPbUTUJewRt6Yb51QAx5RtrWOwjebg@mail.gmail.com/>`_::
Behavioral changes happen, and maybe we don't even support some
feature any more. There's a number of fields in /proc/<pid>/stat that
are printed out as zeroes, simply because they don't even *exist* in
the kernel any more, or because showing them was a mistake (typically
an information leak). But the numbers got replaced by zeroes, so that
the code that used to parse the fields still works. The user might not
see everything they used to see, and so behavior is clearly different,
but things still _work_, even if they might no longer show sensitive
(or no longer relevant) information.
On regressions caused by bugfixes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* From `2018-08-03 <https://lore.kernel.org/all/CA+55aFwWZX=CXmWDTkDGb36kf12XmTehmQjbiMPCqCRG2hi9kw@mail.gmail.com/>`_::
> Kernel had a bug which has been fixed
That is *ENTIRELY* immaterial.
Guys, whether something was buggy or not DOES NOT MATTER.
[...]
It's basically saying "I took something that worked, and I broke it,
but now it's better". Do you not see how f*cking insane that statement
is?
On internal API changes
~~~~~~~~~~~~~~~~~~~~~~~
* From `2017-10-26(7) <https://lore.kernel.org/lkml/CA+55aFxW7NMAMvYhkvz1UPbUTUJewRt6Yb51QAx5RtrWOwjebg@mail.gmail.com/>`_::
We do API breakage _inside_ the kernel all the time. We will fix
internal problems by saying "you now need to do XYZ", but then it's
about internal kernel API's, and the people who do that then also
obviously have to fix up all the in-kernel users of that API. Nobody
can say "I now broke the API you used, and now _you_ need to fix it
up". Whoever broke something gets to fix it too.
On regressions only found after a long time
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* From `2024-03-28 <https://lore.kernel.org/all/CAHk-=wgFuoHpMk_Z_R3qMXVDgq0N1592+bABkyGjwwSL4zBtHA@mail.gmail.com/>`_::
I'm definitely not reverting a patch from almost a decade ago as a
regression.
If it took that long to find, it can't be that critical of a regression.
So yes, let's treat it as a regular bug.
On testing regressions fixes in linux-next
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* On `maintainers summit 2024 <https://lwn.net/Articles/990599/>`_::
So running fixes though linux-next is just a waste of time.
On a few other aspects related to regressions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* From `2025-07-29(2) <https://lore.kernel.org/all/CAHk-=wjj9DvOZtmTkoLtyfHmy5mNKy6q_96d9=4FUEDXre=cww@mail.gmail.com/>`_
[which `is not quite a regression, but a huge inconvenience <https://lore.kernel.org/all/CAHk-=wgO0Rx2LcYT4f75Xs46orbJ4JxO2jbAFQnVKDYAjV5HeQ@mail.gmail.com/>`_]::
I no longer have sound.
I also suspect that it's purely because "make oldconfig" doesn't work,
and probably turned off my old Intel HDA settings. Or something.
Renaming config parameters is *bad*. I've harped on the Kconfig phase
of the kernel build probably being our nastiest point, and a real pain
point to people getting involved with development simply because
building your own kernel can be so daunting with hundreds of fairly
esoteric questions.
..
end-of-content

View File

@ -1,7 +1,5 @@
.. SPDX-License-Identifier: GPL-2.0
.. _maintainer_handbooks_main:
Subsystem and maintainer tree specific development process notes
================================================================

View File

@ -352,7 +352,7 @@ following tag ordering scheme:
Changelog text starts here....
so the authorship is preserved. The 'From:' line has to be followed
by a empty newline. If that 'From:' line is missing, then the patch
by an empty newline. If that 'From:' line is missing, then the patch
would be attributed to the person who sent (transported, handled) it.
The 'From:' line is automatically removed when the patch is applied
and does not show up in the final git changelog. It merely affects

View File

@ -23,7 +23,7 @@ easier.
Some subsystems and maintainer trees have additional information about
their workflow and expectations, see
:ref:`Documentation/process/maintainer-handbooks.rst <maintainer_handbooks_main>`.
Documentation/process/maintainer-handbooks.rst.
Obtain a current source tree
----------------------------
@ -634,6 +634,16 @@ bugzilla.kernel.org is a public place in this sense, but email addresses
used there are private; so do not expose them in tags, unless the person
used them in earlier contributions.
Using Assisted-by:
------------------
If you used any sort of advanced coding tool in the creation of your patch,
you need to acknowledge that use by adding an Assisted-by tag. Failure to
do so may impede the acceptance of your work. Please see
Documentation/process/coding-assistants.rst for details regarding the
acknowledgment of coding assistants.
.. _the_canonical_patch_format:
The canonical patch format

View File

@ -628,10 +628,21 @@ Deadline Task Scheduling
* the new scheduling related syscalls that manipulate it, i.e.,
sched_setattr() and sched_getattr() are implemented.
For debugging purposes, the leftover runtime and absolute deadline of a
SCHED_DEADLINE task can be retrieved through /proc/<pid>/sched (entries
dl.runtime and dl.deadline, both values in ns). A programmatic way to
retrieve these values from production code is under discussion.
The leftover runtime and absolute deadline of a SCHED_DEADLINE task can be
read using the sched_getattr() syscall, setting the last syscall parameter
flags to the SCHED_GETATTR_FLAG_DL_DYNAMIC=1 value. This updates the
runtime left, converts the absolute deadline in CLOCK_MONOTONIC reference,
then returns these parameters to user-space. The absolute deadline is
returned as the number of nanoseconds since the CLOCK_MONOTONIC time
reference (boot instant), as a u64 in the sched_deadline field of sched_attr,
which can represent nearly 585 years since boot time (calling sched_getattr()
with flags=0 causes retrieval of the static parameters instead).
For debugging purposes, these parameters can also be retrieved through
/proc/<pid>/sched (entries dl.runtime and dl.deadline, both values in ns),
but: this is highly inefficient; the returned runtime left is not updated as
done by sched_getattr(); the deadline is provided in kernel rq_clock time
reference, that is not directly usable from user-space.
4.3 Default behavior
@ -700,7 +711,8 @@ Deadline Task Scheduling
5.2 Using cgroup v2 cpuset controller
-------------------------------------
Assuming the cgroup v2 root is mounted at ``/sys/fs/cgroup``.
Assuming the cgroup v2 root is mounted at ``/sys/fs/cgroup``, an example of a
simple configuration (pin a -deadline task to CPU0) follows::
cd /sys/fs/cgroup
echo '+cpuset' > cgroup.subtree_control

View File

@ -183,9 +183,8 @@ This is the (partial) list of the hooks:
- yield_task(...)
This function is basically just a dequeue followed by an enqueue, unless the
compat_yield sysctl is turned on; in that case, it places the scheduling
entity at the right-most end of the red-black tree.
This function yields the CPU by moving the currently running task's position back
in the runqueue, so that other runnable tasks get scheduled first.
- wakeup_preempt(...)

View File

@ -40,6 +40,13 @@ li { text-indent: 0em; }
dl.function, dl.struct, dl.enum { margin-top: 2em; background-color: #ecf0f3; }
/* indent lines 2+ of multi-line function prototypes */
dl.function dt { margin-left: 10em; text-indent: -10em; }
/*
* Preserve C API signatures on one line and apply contained horizontal
* scrolling to prevent them from exceeding their container width and
* breaking page layout.
*/
dl.c { overflow-x: auto; overflow-y: hidden; }
dl.c > dt.sig.sig-object { white-space: nowrap; }
dt.sig-object { font-size: larger; }
div.kernelindent { margin-left: 2em; margin-right: 4em; }
@ -149,6 +156,25 @@ div.language-selection ul li:hover {
background: #dddddd;
}
/*
* Let long inline literals in paragraph text wrap as needed to prevent
* overflow.
*/
code.docutils.literal span.pre {
white-space: normal;
overflow-wrap: anywhere;
}
/* Let rendered reference links in tables wrap when needed. */
div.body table.docutils a.reference {
overflow-wrap: anywhere;
}
/* Let long link text wrap instead of forcing overflow. */
a {
overflow-wrap: anywhere;
}
/* Make xrefs more universally visible */
a.reference, a.reference:hover {
border-bottom: none;

View File

@ -25,6 +25,7 @@ all_languages = {
'it_IT': 'Italian',
'ja_JP': 'Japanese',
'ko_KR': 'Korean',
'pt_BR': 'Portuguese (Brazilian)',
'sp_SP': 'Spanish',
}

View File

@ -21,6 +21,15 @@ Regular expression class handler
:undoc-members:
C tokenizer
===========
.. automodule:: lib.python.kdoc.c_lex
:members:
:show-inheritance:
:undoc-members:
Chinese, Japanese and Korean variable fonts handler
===================================================
@ -44,3 +53,11 @@ Python version ancillary methods
:members:
:show-inheritance:
:undoc-members:
Write output on YAML file
=========================
.. automodule:: lib.python.kdoc.kdoc_yaml_file
:members:
:show-inheritance:
:undoc-members:

View File

@ -4,6 +4,14 @@
Kernel-doc parser stage
=======================
C replacement rules used by the parser
======================================
.. automodule:: lib.python.kdoc.xforms_lists
:members:
:show-inheritance:
:undoc-members:
File handler classes
====================

View File

@ -11,3 +11,5 @@ Python libraries
feat
kdoc
kabi
unittest

View File

@ -100,7 +100,7 @@ SEE ALSO
**rtla-osnoise**\(1)
Osnoise tracer documentation: <https://www.kernel.org/doc/html/latest/trace/osnoise-tracer.html>
`Osnoise tracer <https://docs.kernel.org/trace/osnoise-tracer.html>`__
AUTHOR
======

View File

@ -59,7 +59,7 @@ SEE ALSO
========
**rtla-osnoise**\(1), **rtla-osnoise-top**\(1)
*osnoise* tracer documentation: <https://www.kernel.org/doc/html/latest/trace/osnoise-tracer.html>
`Osnoise tracer <https://docs.kernel.org/trace/osnoise-tracer.html>`__
AUTHOR
======

View File

@ -54,7 +54,7 @@ SEE ALSO
**rtla-osnoise**\(1), **rtla-osnoise-hist**\(1)
Osnoise tracer documentation: <https://www.kernel.org/doc/html/latest/trace/osnoise-tracer.html>
`Osnoise tracer <https://docs.kernel.org/trace/osnoise-tracer.html>`__
AUTHOR
======

View File

@ -50,7 +50,7 @@ SEE ALSO
========
**rtla-osnoise-top**\(1), **rtla-osnoise-hist**\(1)
Osnoise tracer documentation: <https://www.kernel.org/doc/html/latest/trace/osnoise-tracer.html>
`Osnoise tracer <https://docs.kernel.org/trace/osnoise-tracer.html>`__
AUTHOR
======

View File

@ -104,7 +104,7 @@ SEE ALSO
========
**rtla-timerlat**\(1), **rtla-timerlat-top**\(1)
*timerlat* tracer documentation: <https://www.kernel.org/doc/html/latest/trace/timerlat-tracer.html>
`Timerlat tracer <https://docs.kernel.org/trace/timerlat-tracer.html>`__
AUTHOR
======

View File

@ -127,7 +127,7 @@ SEE ALSO
--------
**rtla-timerlat**\(1), **rtla-timerlat-hist**\(1)
*timerlat* tracer documentation: <https://www.kernel.org/doc/html/latest/trace/timerlat-tracer.html>
`Timerlat tracer <https://docs.kernel.org/trace/timerlat-tracer.html>`__
AUTHOR
------

View File

@ -45,7 +45,7 @@ SEE ALSO
========
**rtla-timerlat-top**\(1), **rtla-timerlat-hist**\(1)
*timerlat* tracer documentation: <https://www.kernel.org/doc/html/latest/trace/timerlat-tracer.html>
`Timerlat tracer <https://docs.kernel.org/trace/timerlat-tracer.html>`__
AUTHOR
======

View File

@ -21,6 +21,10 @@ results.
COMMANDS
========
**hwnoise**
Detect and quantify hardware-related noise.
**osnoise**
Gives information about the operating system noise (osnoise).
@ -39,7 +43,7 @@ For other options, see the man page for the corresponding command.
SEE ALSO
========
**rtla-osnoise**\(1), **rtla-timerlat**\(1)
**rtla-hwnoise**\(1), **rtla-osnoise**\(1), **rtla-timerlat**\(1)
AUTHOR
======

View File

@ -0,0 +1,24 @@
.. SPDX-License-Identifier: GPL-2.0
===============
Python unittest
===============
Checking consistency of python modules can be complex. Sometimes, it is
useful to define a set of unit tests to help checking them.
While the actual test implementation is usecase dependent, Python already
provides a standard way to add unit tests by using ``import unittest``.
Using such class, requires setting up a test suite. Also, the default format
is a little bit ackward. To improve it and provide a more uniform way to
report errors, some unittest classes and functions are defined.
Unittest helper module
======================
.. automodule:: lib.python.unittest_helper
:members:
:show-inheritance:
:undoc-members:

View File

@ -69,7 +69,8 @@ So in this histogram, there's a separate bucket for each pid, and each
bucket contains a value for that bucket, counting the number of times
sched_waking was called for that pid.
Each histogram is represented by a hist_data struct.
Each histogram is represented by a hist_data struct
(struct hist_trigger_data).
To keep track of each key and value field in the histogram, hist_data
keeps an array of these fields named fields[]. The fields[] array is
@ -82,7 +83,7 @@ value or not, which the above histogram does not.
Each struct hist_field contains a pointer to the ftrace_event_field
from the event's trace_event_file along with various bits related to
that such as the size, offset, type, and a hist_field_fn_t function,
that such as the size, offset, type, and a hist field function,
which is used to grab the field's data from the ftrace event buffer
(in most cases - some hist_fields such as hitcount don't directly map
to an event field in the trace buffer - in these cases the function
@ -241,28 +242,33 @@ it, event_hist_trigger() is called. event_hist_trigger() first deals
with the key: for each subkey in the key (in the above example, there
is just one subkey corresponding to pid), the hist_field that
represents that subkey is retrieved from hist_data.fields[] and the
hist_field_fn_t fn() associated with that field, along with the
hist field function associated with that field, along with the
field's size and offset, is used to grab that subkey's data from the
current trace record.
Note, the hist field function use to be a function pointer in the
hist_field stucture. Due to spectre mitigation, it was converted into
a fn_num and hist_fn_call() is used to call the associated hist field
function that corresponds to the fn_num of the hist_field structure.
Once the complete key has been retrieved, it's used to look that key
up in the tracing_map. If there's no tracing_map_elt associated with
that key, an empty one is claimed and inserted in the map for the new
key. In either case, the tracing_map_elt associated with that key is
returned.
Once a tracing_map_elt available, hist_trigger_elt_update() is called.
Once a tracing_map_elt is available, hist_trigger_elt_update() is called.
As the name implies, this updates the element, which basically means
updating the element's fields. There's a tracing_map_field associated
with each key and value in the histogram, and each of these correspond
to the key and value hist_fields created when the histogram was
created. hist_trigger_elt_update() goes through each value hist_field
and, as for the keys, uses the hist_field's fn() and size and offset
and, as for the keys, uses the hist_field's function and size and offset
to grab the field's value from the current trace record. Once it has
that value, it simply adds that value to that field's
continually-updated tracing_map_field.sum member. Some hist_field
fn()s, such as for the hitcount, don't actually grab anything from the
trace record (the hitcount fn() just increments the counter sum by 1),
functions, such as for the hitcount, don't actually grab anything from the
trace record (the hitcount function just increments the counter sum by 1),
but the idea is the same.
Once all the values have been updated, hist_trigger_elt_update() is

View File

@ -10,11 +10,11 @@ Translations
zh_CN/index
zh_TW/index
it_IT/index
ko_KR/index
ja_JP/index
ko_KR/index
pt_BR/index
sp_SP/index
.. _translations_disclaimer:
Disclaimer

View File

@ -329,7 +329,8 @@ Sparse deve essere installato separatamente (se il vostra distribuzione non
lo prevede, potete trovarlo su https://sparse.wiki.kernel.org/index.php/Main_Page);
può essere attivato sul codice aggiungendo "C=1" al comando make.
Lo strumento "Coccinelle" (http://coccinelle.lip6.fr/) è in grado di trovare
Lo strumento "Coccinelle" (https://coccinelle.gitlabpages.inria.fr/website/)
è in grado di trovare
una vasta varietà di potenziali problemi di codifica; e può inoltre proporre
soluzioni per risolverli. Un buon numero di "patch semantiche" per il kernel
sono state preparate nella cartella scripts/coccinelle; utilizzando

View File

@ -35,7 +35,7 @@ Documentation/devicetree/bindings/submitting-patches.rst を読んでくださ
いくつかのサブシステムやメンテナツリーには、各々のワークフローや
期待事項に関する追加情報があります。次を参照してください:
:ref:`Documentation/process/maintainer-handbooks.rst <maintainer_handbooks_main>`.
Documentation/process/maintainer-handbooks.rst.
現在のソースツリーを入手する
----------------------------
@ -52,5 +52,130 @@ Documentation/devicetree/bindings/submitting-patches.rst を読んでくださ
ツリーは MAINTAINERS ファイル内の **T:** エントリを参照して見つけてください。
そこに掲載されていない場合は、メンテナに問い合わせてください。
変更内容を説明する
変更内容を記述する
------------------
まず問題点を記べてください。あなたのパッチが 1 行のバグ修正であっても、
5000 行の新機能であっても、それを行う動機となった根本的な問題が
必ずあるはずです。レビューアが、修正すべき問題がたしかに存在し、冒頭の
段落の続きを読むべきだと納得できるように書いてください。
次にユーザーから見える影響を記述してください。クラッシュやロックアップは
分かりやすいですが、すべてのバグがそこまで露骨とは限りません。
たとえコードレビュー中に見つかった問題であっても、ユーザーに
どのような影響があり得るかを記述してください。
Linux の多くの環境は、上流から特定のパッチだけを取り込む二次的な
安定版ツリーや、ベンダー/製品固有のツリーのカーネルで動いています。
したがって、変更を適切に下流へ流す助けになる情報発生条件、dmesg
の抜粋、クラッシュ内容、性能劣化、レイテンシのスパイク、
ロックアップ等)があれば記載してください。
次に最適化とトレードオフを定量的に示してください。パフォーマンス、
メモリ消費量、スタックフットプリント、バイナリサイズの改善を主張する
場合は、それを裏付ける数値を記載してください。
また、目に見えないコストについても記述してください。多くの場合、
最適化は CPU・メモリ・可読性の間でのトレードオフとなります。
ヒューリスティクスの場合は、異なるワークロード間でのトレードオフと
なります。レビューアがコストとメリットを比較検討できるよう、
最適化に伴って想定されるデメリットも記述してください。
問題点の明確化が済んだら、実際にどのような対策を講じているかを技術的に
詳しく説明してください。コードが意図したとおりに動作していることを
レビューアが確認できるよう、変更内容を平易な言葉で書き下すことが重要です。
パッチの説明が Linux のソースコード管理システム ``git`` の「コミットログ」
としてそのまま取り込める形で書かれていれば、メンテナは助かります。
詳細は原文の該当節 ("The canonical patch format") を参照してください。
.. TODO: Convert to file-local cross-reference when the destination is
translated.
1 つのパッチでは 1 つの問題だけを解決してください。記述が長くなり
始めたら、それはパッチを分割すべきサインです。
詳細は原文の該当節 ("Separate your changes") を参照してください。
.. TODO: Convert to file-local cross-reference when the destination is
translated.
パッチまたはパッチシリーズを投稿/再投稿する際は、その完全な
説明と、それを正当化する理由を含めてください。単に「これはパッチ
(シリーズ)のバージョン N です」とだけ書くのは避けてください。
サブシステムメンテナが以前のパッチバージョンや参照先 URL をさかのぼって
パッチ記述を探し、それをパッチに補うことを期待してはいけません。
つまり、パッチ(シリーズ)とその説明は、それだけで完結しているべき
です。これはメンテナとレビューアの双方に有益です。レビューアの
中には、以前のパッチバージョンを受け取っていない人もいるでしょう。
変更内容は、あたかもコードベースに対してその振る舞いを変えるように
命令するかの如く、(訳補: 英語の)命令形で記述してください。たとえば、
"[This patch] makes xyzzy do frotz" や
"[I] changed xyzzy to do frotz" のような言い回しを避け、
"make xyzzy do frotz" のように書いてください。
特定のコミットに言及したい場合に、コミットの SHA-1 ID だけを
書くのは避けてください。レビューアがそれが何についてのものかを
把握しやすいよう、コミットの 1 行要約も含めてください。例::
Commit e21d2170f36602ae2708 ("video: remove unnecessary
platform_set_drvdata()") removed the unnecessary
platform_set_drvdata(), but left the variable "dev" unused,
delete it.
また、SHA-1 ID は少なくとも先頭 12 文字を使うようにしてください。
カーネルのリポジトリには\ **非常に多くの**\ オブジェクトがあるため、
それより短い ID では衝突が現実問題となります。6 文字の ID が今現在
衝突しないからといって、5 年後もそうであるとは限らないことを念頭に
置いてください。
変更に関連する議論や、その背景情報が Web 上で参照できる場合は、
それを指す 'Link:' タグを追加してください。過去のメーリングリスト
での議論や、Web に記録された何かに由来するパッチならば、
それを示してください。
メーリングリストのアーカイブへリンクする場合は、できれば lore.kernel.org
のメッセージアーカイブサービスを使ってください。リンク URL を作るには、
そのメッセージの ``Message-ID`` ヘッダの内容から、前後の山括弧を取り除いた
ものを使います。例::
Link: https://lore.kernel.org/30th.anniversary.repost@klaava.Helsinki.FI
実際にリンクが機能し、該当するメッセージを指していることを
確認してください。
ただし、外部リソースを見なくても説明が理解できるようにするよう努めてください。
メーリングリストのアーカイブやバグへの URL を示すだけでなく、
投稿されたパッチに至った議論のポイントも要約してください。
パッチがバグを修正するものであれば、メーリングリストのアーカイブや
公開バグトラッカー上の報告を指す URL を付けて、``Closes:`` タグを
使ってください。例::
Closes: https://example.com/issues/1234
このようなタグ付きのコミットが適用されたとき、自動的に issue を
閉じるバグトラッカーもあります。メーリングリストを監視している
ボットの中には、そのようなタグを追跡して一定の動作を行うものも
あります。ただし、非公開バグトラッカーの(訳補: 部外者が)閲覧できない
URL は禁止です。
パッチが特定のコミットに含まれるバグを修正するもの、たとえば
``git bisect`` で問題を見つけたものの場合には、SHA-1 ID の
先頭少なくとも 12 文字と 1 行要約を含めて 'Fixes:' タグを
使ってください。タグを複数行に分割してはいけません。タグは
解析スクリプトを単純にするため、「75 桁で折り返す」規則の
例外です。例::
Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed")
``git log````git show`` の出力を上の形式で整形させるには、
次の ``git config`` 設定が使えます::
[core]
abbrev = 12
[pretty]
fixes = Fixes: %h ("%s")
呼び出し例::
$ git log -1 --pretty=fixes 54a4f0239f2e
Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed")

View File

@ -0,0 +1,11 @@
.. SPDX-License-Identifier: GPL-2.0
Aviso sobre traduções para português
====================================
Esta documentação foi traduzida para português brasileiro por voluntários.
Em caso de qualquer divergência entre esta tradução e o documento original
em inglês, a versão em inglês (encontrada no diretório Documentation/)
deve ser considerada a única fonte de verdade.

View File

@ -0,0 +1,77 @@
.. SPDX-License-Identifier: GPL-2.0
=========================================
Documentação do Kernel Linux em Português
=========================================
.. raw:: latex
\kerneldocCJKoff
:mantenedor: Daniel Pereira <danielmaraboo@gmail.com>
Este é o nível principal da documentação do kernel em língua portuguesa (Brasil).
A tradução ainda está em seu estágio inicial e incompleta; você notará avisos
sinalizando a falta de traduções para grupos específicos de documentos.
De maneira geral, a documentação, assim como o próprio kernel, está em constante
desenvolvimento; isso é especialmente verdade agora, pois estamos trabalhando
na reorganização da documentação de forma mais coerente. Melhorias na
documentação são sempre bem-vindas; se você deseja ajudar, inscreva-se na lista
de discussão linux-doc em vger.kernel.org.
Avisos
======
.. include:: disclaimer-pt_BR.rst
O objetivo desta tradução é facilitar a leitura e compreensão para aqueles que
não dominam o inglês ou têm dúvidas sobre sua interpretação, ou simplesmente
para quem prefere ler em sua língua nativa. No entanto, tenha em mente que a
*única* documentação oficial é a em língua inglesa: :ref:`linux_doc`
A propagação simultânea de uma alteração em :ref:`linux_doc` para todas as
traduções é altamente improvável. Os mantenedores das traduções — e seus
contribuidores — acompanham a evolução da documentação oficial e tentam manter
as respectivas traduções alinhadas na medida do possível. Por este motivo, não
há garantia de que uma tradução esteja atualizada com a última modificação.
Se o que você ler em uma tradução não corresponder ao que ler no código,
informe o mantenedor da tradução e — se puder — verifique também a
documentação em inglês.
Uma tradução não é um *fork* da documentação oficial; portanto, os usuários não
encontrarão nela informações diferentes daquelas contidas na versão oficial.
Qualquer adição, remoção ou modificação de conteúdo deve ser feita primeiro nos
documentos em inglês. Posteriormente, quando possível, a mesma alteração deve
ser aplicada às traduções. Os mantenedores das traduções aceitam contribuições
que afetem puramente a atividade de tradução (por exemplo, novas traduções,
atualizações, correções).
As traduções buscam ser o mais precisas possível, mas não é possível mapear
diretamente uma língua em outra. Cada língua possui sua própria gramática e
cultura, portanto, a tradução de uma frase em inglês pode ser modificada para
se adaptar ao português. Por esse motivo, ao ler esta tradução, você poderá
encontrar algumas diferenças de forma, mas que transmitem a mensagem original.
Trabalhando com a comunidade de desenvolvimento
===============================================
As guias fundamentais para a interação com a comunidade de desenvolvimento do
kernel e sobre como ver seu trabalho integrado.
.. toctree::
:maxdepth: 1
Introdução <process/1.Intro>
Como começar <process/howto>
Requisitos mínimos <process/changes>
Conclave (Continuidade do projeto) <process/conclave>
Manuais dos mantenedores <process/maintainer-handbooks>
Processo do subsistema de rede (netdev) <process/maintainer-netdev>
Processo do subsistema SoC <process/maintainer-soc>
Conformidade de DTS para SoC <process/maintainer-soc-clean-dts>
Processo do subsistema KVM x86 <process/maintainer-kvm-x86>

View File

@ -0,0 +1,269 @@
.. SPDX-License-Identifier: GPL-2.0
Introdução
==========
Sumário
-------
O restante desta seção cobre o processo de desenvolvimento do kernel e os
tipos de frustração que os desenvolvedores e empresas podem encontrar pelo
caminho. Existem diversas razões que justificam a recomendação para que seja
feito o merge do código do kernel ao kernel principal ("mainline"), como
disponibilidade automática aos usuários, suporte da comunidade em diversas
formas, e a oportunidade de influenciar a direção do desenvolvimento do
kernel. Contribuições ao kernel Linux obrigatoriamente devem estar disponíveis
sob uma licença compatível com a GPL.
:ref:`development_process` apresenta o processo de desenvolvimento, o ciclo de
lançamento, e a mecânica da janela de merge. As várias fases no desenvolvimento
de patch, revisão, e ciclo de merge são explicadas. Algumas ferramentas e
listas de e-mail são discutidas. Desenvolvedores que queiram começar a
desenvolver o kernel são encorajados a buscar e corrigir bugs como exercício
inicial.
:ref:`development_early_stage` cobre os primeiros passos do processo de
desenvolvimento, com ênfase no envolvimento da comunidade de desenvolvedores o
mais cedo possível.
:ref:`development_coding` é sobre o processo de codificação; muitas armadilhas
já encontradas por outros desenvolvedores são discutidas. Alguns requisitos
para patches são explicados, e é feita uma introdução para algumas ferramentas
que podem ajudar a garantir que os patches de kernel estão corretos.
:ref:`development_posting` fala sobre o processo de envio de patches para
revisão. Para serem levados em consideração pela comunidade desenvolvedora, os
patches devem estar devidamente formatados e descritos, assim como devem estar
no lugar correto. Seguir os conselhos dessa seção pode ajudar na recepção
positiva do seu trabalho.
:ref:`development_followthrough` cobre o que acontece após o envio dos patches;
o trabalho ainda está longe de estar concluído. Trabalhar com os revisores é
parte crucial do processo de desenvolvimento; essa seção oferece dicas de como
evitar problemas nesse estágio importante. Desenvolvedores são alertados a não
presumir que o trabalho acabou após o merge do patch no "mainline".
:ref:`development_advancedtopics` introduz dois tópicos mais "avançados":
gerenciamento de patches com git e revisão de patches por outros.
:ref:`development_conclusion` conclui o documento com indicações de fontes com
mais informações sobre o desenvolvimento do kernel.
Sobre este documento
--------------------
O kernel Linux, com mais de 8 milhões de linhas de código e bem mais de 1000
contribuintes a cada lançamento ("release"), é um dos maiores e mais ativos
projetos de software livre em existência. Desde seu modesto início em 1991,
este kernel evoluiu para se tornar um dos melhores componentes de sistemas
operacionais, rodando em pequenos players de música digital, PCs de mesa, os
maiores supercomputadores em existência, e todos os outros tipos de sistema
entre eles. É robusto, eficiente, e uma solução escalável para quase toda
situação.
O crescimento do Linux trouxe o aumento no número de desenvolvedores (e
empresas) desejando participar no seu desenvolvimento. Fabricantes de hardware
querem garantir que o Linux suporte bem os seus produtos, tornando-os atrativos
para usuários Linux. Fabricantes de sistemas embarcados, que usam o Linux como
componente em um produto integrado, querem que o Linux seja tão capaz e
adequado quanto possível para a tarefa em questão. Distribuidores de software
que baseiam seus produtos em Linux têm claro interesse nas capacidades,
performance, e confiabilidade do kernel Linux. É também comum que usuários
finais queiram alterar o Linux para atender melhor suas necessidades.
Uma das características mais atrativas do Linux é sua facilidade de acesso a
esses desenvolvedores; qualquer um com as habilidades necessárias pode melhorar
o Linux e influenciar a direção do seu desenvolvimento. Produtos proprietários
não conseguem oferecer esse tipo de abertura, que é característico do processo
de software livre. O kernel é ainda mais acessível que a maioria dos outros
projetos de software livre. Um ciclo típico de três meses de desenvolvimento
do kernel pode envolver mais de 1000 desenvolvedores trabalhando para mais de
100 empresas (ou absolutamente nenhuma empresa).
Trabalhar com a comunidade de desenvolvimento do kernel não é uma tarefa árdua.
Contudo, muitos colaboradores potenciais passaram por dificuldades ao tentar
trabalhar no kernel. A comunidade evoluiu suas próprias formas de funcionamento
que permitem operar de forma fluida (e produzir um produto de alta qualidade)
em um ambiente em que milhares de linhas de código são alteradas todos os dias.
Não é surpresa que o processo de desenvolvimento do kernel Linux seja muito
diferente dos modelos de desenvolvimento proprietários.
O processo de desenvolvimento do kernel pode parecer estranho e intimidador
para novos desenvolvedores, mas existem bons motivos e uma sólida experiência
por trás disso. Um desenvolvedor que não entenda os caminhos próprios da
comunidade kernel (ou pior, que tente menosprezá-los ou contorná-los) terá uma
experiência frustrante pela frente. A comunidade de desenvolvimento ajuda
aqueles que tentam aprender, mas gasta pouco tempo com aqueles que não escutam
ou não ligam para o processo de desenvolvimento.
Espera-se que aqueles que leiam este documento sejam capazes de evitar essa
experiência frustrante. Há muito material aqui, mas o esforço envolvido na sua
leitura valerá a pena. A comunidade de desenvolvimento sempre necessita de
desenvolvedores que ajudem a melhorar o kernel; o texto a seguir deve ajudar
você - ou aqueles trabalhando para você - a se juntar à nossa comunidade.
Créditos
--------
Esse documento foi escrito por Jonathan Corbet, corbet@lwn.net. Aprimorado
pelos comentários de Johannes Berg, James Berry, Alex Chiang, Roland Dreier,
Randy Dunlap, Jake Edge, Jiri Kosina, Matt Mackall, Arthur Marsh, Amanda
McPherson, Andrew Morton, Andrew Price, Tsugikazu Shibata, e Jochen Voß.
Esse trabalho contou com o apoio da Linux Foundation; agradecimentos especiais
para Amanda McPherson, que viu o valor desse esforço e fez tudo acontecer.
A importância de levar o código até o "mainline"
-------------------------------------------------
Algumas empresas e desenvolvedores ocasionalmente se perguntam por que devem
se importar em aprender como trabalhar com a comunidade do kernel e ter seu
código no "mainline" (o kernel mantido por Linus Torvalds e usado como base
para os distribuidores Linux). No curto prazo, contribuir com o código pode
parecer um gasto evitável; parece mais fácil apenas manter o seu código à
parte e oferecer suporte direto aos usuários. A verdade é que manter código
fora da árvore principal ("out-of-tree") é uma falsa economia.
Para ilustrar os custos do código "out-of-tree", aqui estão alguns aspectos
relevantes do processo de desenvolvimento do kernel; a maioria será discutida
com mais detalhes adiante neste documento. Considere:
- Código integrado via merge ao "mainline" fica disponível para todos os
usuários Linux. Estará automaticamente presente em todas as distribuições
que o habilitarem. Não há necessidade de discos de armazenamento, downloads,
ou as complicações de dar suporte a múltiplas versões de variadas
distribuições; tudo simplesmente funciona, para o desenvolvedor e para o
usuário. Incorporação ao "mainline" resolve um grande número de problemas
de distribuição e suporte.
- Enquanto desenvolvedores do kernel se esforçam para manter uma interface
estável para o espaço do usuário, a API interna está em constante mudança.
A ausência de uma interface interna estável é uma escolha deliberada de
design; permite que sejam feitas melhorias fundamentais a qualquer tempo e
resulta em código de qualidade superior. Uma consequência dessa política é
que código "out-of-tree" precisa ser constantemente atualizado para que
continue funcionando com novos kernels. Manter código "out-of-tree" requer
significativo trabalho apenas para mantê-lo funcionando.
Por sua vez, código que está no "mainline" não precisa dessa manutenção,
resultado de uma regra simples que exige que qualquer desenvolvedor que
altere uma API, também conserte qualquer código que deixe de funcionar como
resultado da alteração. Código que teve o merge realizado no "mainline" tem
custo significativamente menor de manutenção.
- Além disso, código que está no kernel será muitas vezes melhorado por outros
desenvolvedores. Resultados surpreendentes podem surgir ao permitir que sua
comunidade de usuários e clientes melhore seu produto.
- Código do kernel está sujeito a revisão, tanto antes como depois do merge ao
"mainline". Independentemente das habilidades do desenvolvedor original, o
processo de revisão invariavelmente encontra maneiras de evoluí-lo. Bugs
severos e problemas de segurança são constantemente encontrados durante o
processo de revisão. Isso é especialmente válido para código desenvolvido em
ambiente isolado; tais códigos se beneficiam fortemente ao serem revistos por
outros desenvolvedores. Código "out-of-tree" é código de baixa qualidade.
- Participação no processo de desenvolvimento é a forma pela qual você pode
influenciar a direção do desenvolvimento do kernel. Usuários que se queixam
externamente são ouvidos, porém desenvolvedores ativos têm maior poder de
articulação - e a habilidade de implementar mudanças que façam o kernel
funcionar melhor para suas necessidades.
- Quando o código é mantido à parte, sempre existe a possibilidade de que
terceiros contribuam para uma implementação diferente de uma funcionalidade
parecida. Se isso acontecer, ter seu código integrado via merge se tornará
muito mais difícil - ao ponto de ser impossível. Você enfrentará duas
alternativas desagradáveis, (1) manter uma funcionalidade "out-of-tree"
indefinidamente ou (2) abandonar seu código e migrar seus usuários para a
versão na árvore principal ("in-tree").
- Contribuição de código é a ação fundamental que faz todo o processo
funcionar. Ao contribuir com seu código você pode adicionar nova
funcionalidade ao kernel e proporcionar capacidades e exemplos que podem ser
usados por outros desenvolvedores de kernel. Se você desenvolveu código para
o Linux (ou está pensando em desenvolver), você claramente tem interesse na
continuidade do sucesso dessa plataforma; contribuição de código é uma das
melhores maneiras de garantir esse sucesso.
Todos os argumentos acima se aplicam a qualquer código "out-of-tree", incluindo
código distribuído de maneira proprietária, em formato exclusivamente binário.
Existem fatores adicionais que devem ser levados em consideração antes de
qualquer distribuição de código de kernel apenas em binário, incluindo:
- As questões legais da distribuição de kernel proprietário são, no melhor dos
casos, confusas; muitos detentores de direitos autorais do kernel acreditam
que a maioria dos módulos binários são produtos derivados do kernel e que,
como resultado, sua distribuição é uma violação da Licença Pública Geral GNU
("GNU General Public License"), que será tratada com mais profundidade abaixo.
Este autor não é um advogado, e nada neste documento pode ser considerado
aconselhamento jurídico. O verdadeiro status de módulos privados ("closed
source") só pode ser determinado judicialmente. Independentemente disso, a
incerteza que cerca esses módulos existe.
- Os módulos binários aumentam consideravelmente a dificuldade de depuração de
problemas do kernel ("debugging"), a ponto de a maioria dos desenvolvedores
de kernel sequer tentar. Portanto, a distribuição de módulos exclusivamente
binários tornará mais difícil que os seus usuários recebam suporte.
- O suporte também é mais difícil para distribuidores de módulos exclusivamente
binários, que precisam fornecer uma versão do módulo para cada distribuição e
cada versão do kernel que desejam suportar. Dezenas de versões de um único
módulo podem ser necessárias para fornecer uma cobertura razoavelmente
abrangente, e seus usuários terão que atualizar seu módulo separadamente
sempre que atualizarem seu kernel.
- Tudo o que foi dito acima sobre revisão de código se aplica em dobro ao
código fechado. Como esse código não está disponível, ele não pode ter sido
revisado pela comunidade e, sem dúvida, terá sérios problemas.
Os fabricantes de sistemas embarcados, em particular, podem ser tentados a
ignorar grande parte do que foi dito nesta seção, acreditando que estão
lançando um produto autossuficiente que usa uma versão congelada do kernel e
não requer mais desenvolvimento após o lançamento. Esse argumento ignora o
valor de uma revisão de código abrangente e o valor de permitir que seus
usuários adicionem recursos ao seu produto. Mas esses produtos também têm uma
vida comercial limitada, após a qual uma nova versão deve ser lançada. Nesse
ponto, os fornecedores cujo código está no "mainline" e bem mantido estarão em
uma posição muito melhor para preparar o novo produto para o mercado
rapidamente.
Licenciamento
-------------
Código é submetido ao kernel do Linux sob diversas licenças, mas todo ele deve
ser compatível com a versão 2 da Licença Pública Geral GNU (GPLv2), que é a
licença que cobre a distribuição do kernel como um todo. Na prática, isso
significa que todas as contribuições de código são cobertas pela GPLv2 (com,
opcionalmente, uma linguagem que permita a distribuição sob versões posteriores
da GPL) ou pela licença BSD de três cláusulas. Quaisquer contribuições que não
sejam cobertas por uma licença compatível não serão aceitas no kernel.
A cessão de direitos autorais não é exigida (nem solicitada) para o código
contribuído para o kernel. Todo o código incorporado ao kernel principal mantém
sua titularidade original; como resultado, o kernel agora tem milhares de
proprietários.
Uma implicação dessa estrutura de propriedade é que qualquer tentativa de
alterar o licenciamento do kernel está fadada ao fracasso quase certo. Existem
poucos cenários práticos em que o acordo de todos os detentores de direitos
autorais poderia ser obtido (ou seu código removido do kernel). Portanto, em
particular, não há perspectiva de migração para a versão 3 da GPL em um futuro
próximo.
É imprescindível que todo o código contribuído para o kernel seja legitimamente
software livre. Por esse motivo, código de contribuidores sem identidade
conhecida ou contribuidores anônimos não será aceito. Todos os contribuidores
são obrigados a "assinar" seu código, declarando que ele pode ser distribuído
com o kernel sob a GPL. Código que não tenha sido licenciado como software
livre por seu proprietário, ou que apresente risco de criar problemas
relacionados a direitos autorais para o kernel (como código derivado de
esforços de engenharia reversa sem as devidas salvaguardas) não pode ser
contribuído.
Questões sobre direitos autorais são comuns em listas de discussão de
desenvolvimento Linux. Normalmente, essas perguntas recebem muitas respostas,
mas é importante lembrar que as pessoas que respondem a essas perguntas não são
advogados e não podem fornecer aconselhamento jurídico. Se você tiver dúvidas
jurídicas relacionadas ao código-fonte do Linux, não há substituto para
conversar com um advogado especializado nessa área. Confiar em respostas
obtidas em listas de discussão técnicas é arriscado.

View File

@ -0,0 +1,576 @@
.. SPDX-License-Identifier: GPL-2.0
Requisitos mínimos para compilar o Kernel
++++++++++++++++++++++++++++++++++++++++++
Introdução
===========
Este documento foi projetado para fornecer uma lista das versões mínimas
de software necessárias para executar a versão atual do kernel.
Este documento é originalmente baseado no meu arquivo 'Changes' para os kernels
2.0.x e portanto, deve créditos às mesmas pessoas que aquele arquivo (Jared
Mauch, Axel Boldt, Alessandro Sigala e inúmeros outros usuários em toda a rede).
Requisitos Mínimos Atuais
****************************
Atualize para pelo menos estas revisões de software antes de pensar que
encontrou um bug! Se não tiver certeza de qual versão está executando atualmente
, o comando sugerido deve lhe informar.
Novamente, tenha em mente que esta lista pressupõe que você já possui um kernel
Linux em execução funcional. Além disso, nem todas as ferramentas são
necessárias em todos os sistemas; obviamente, se você não possui nenhum hardware
PC Card por exemplo, provavelmente não precisará se preocupar com o pcmciautils.
====================== =============== ========================================
Programa Versão mínima Comando para verificar a versão
====================== =============== ========================================
GNU C 8.1 gcc --version
Clang/LLVM (optional) 15.0.0 clang --version
Rust (optional) 1.78.0 rustc --version
bindgen (optional) 0.65.1 bindgen --version
GNU make 4.0 make --version
bash 4.2 bash --version
binutils 2.30 ld -v
flex 2.5.35 flex --version
bison 2.0 bison --version
pahole 1.16 pahole --version
util-linux 2.10o mount --version
kmod 13 depmod -V
e2fsprogs 1.41.4 e2fsck -V
jfsutils 1.1.3 fsck.jfs -V
xfsprogs 2.6.0 xfs_db -V
squashfs-tools 4.0 mksquashfs -version
btrfs-progs 0.18 btrfs --version
pcmciautils 004 pccardctl -V
quota-tools 3.09 quota -V
PPP 2.4.0 pppd --version
nfs-utils 1.0.5 showmount --version
procps 3.2.0 ps --version
udev 081 udevd --version
grub 0.93 grub --version || grub-install --version
mcelog 0.6 mcelog --version
iptables 1.4.2 iptables -V
openssl & libcrypto 1.0.0 openssl version
bc 1.06.95 bc --version
Sphinx\ [#f1]_ 3.4.3 sphinx-build --version
GNU tar 1.28 tar --version
gtags (opcional) 6.6.5 gtags --version
mkimage (opcional) 2017.01 mkimage --version
Python 3.9.x python3 --version
GNU AWK (opcional) 5.1.0 gawk --version
====================== =============== ========================================
.. [#f1] O Sphinx é necessário apenas para gerar a documentação do Kernel.
Compilação do Kernel
*********************
GCC
---
Os requisitos da versão do gcc podem variar dependendo do tipo de CPU
do seu computador.
Clang/LLVM (opcional)
---------------------
A versão formal mais recente do clang e dos utilitários LLVM (de acordo com
releases.llvm.org <https://releases.llvm.org>_) é suportada para a compilação
de kernels. Versões anteriores não têm funcionamento garantido, e poderemos
remover do kernel soluções de contorno (workarounds) que eram utilizadas para
suportar versões mais antigas. Por favor, veja a documentação adicional em:
ref:Building Linux with Clang/LLVM <kbuild_llvm>.
Rust (opcional)
---------------
É necessária uma versão recente do compilador Rust.
Por favor, consulte Documentation/rust/quick-start.rst para obter instruções
sobre como atender aos requisitos de compilação do suporte a Rust. Em
particular, o alvo (target) rustavailable do Makefile é útil para verificar por
que a cadeia de ferramentas (toolchain) Rust pode não estar sendo detectada.
bindgen (opcional)
------------------
O ``bindgen`` é utilizado para gerar os vínculos (bindings) Rust para o lado C
do kernel. Ele depende da ``libclang``.
Make
----
Você precisará do GNU make 4.0 ou superior para compilar o kernel.
Bash
----
Alguns scripts bash são usados para a compilação do kernel.
É necessário o Bash 4.2 ou mais recente.
Binutils
--------
O binutils 2.30 ou mais recente é necessário para compilar o kernel.
pkg-config
----------
O sistema de compilação, a partir da versão 4.18, requer o pkg-config para
verificar as ferramentas kconfig instaladas e para determinar as configurações
de flags para uso em make {g,x}config. Anteriormente, o pkg-config já era
utilizado, mas não era verificado nem documentado.
Flex
----
Desde o Linux 4.16, o sistema de compilação gera analisadores léxicos durante a
compilação. Isso requer o flex 2.5.35 ou superior.
Bison
-----
Desde o Linux 4.16, o sistema de compilação gera analisadores sintáticos durante
a compilação. Isso requer o bison 2.0 ou superior
pahole
------
Desde o Linux 5.2, se CONFIG_DEBUG_INFO_BTF estiver selecionado, o sistema de
compilação gera BTF (BPF Type Format) a partir do DWARF no vmlinux, e um pouco
depois para os módulos do kernel também. Isso requer o pahole v1.16 ou superior.
Ele pode ser encontrado nos pacotes ``dwarves`` ou ``pahole`` das
distribuições, ou em https://fedorapeople.org/~acme/dwarves/.
Perl
----
Você precisará do perl 5 e dos seguintes módulos: Getopt::Long,
Getopt::Std, File::Basename e File::Find para compilar o kernel.
Python
------
Várias opções de configuração o exigem: ele é necessário para as configurações
padrão (defconfigs) de arm/arm64, CONFIG_LTO_CLANG, algumas configurações
opcionais de DRM, a ferramenta kernel-doc e a geração da documentação (Sphinx),
entre outros.
BC
--
Você precisará do bc para compilar kernels 3.10 ou superior.
OpenSSL
-------
A assinatura de módulos e a manipulação de certificados externos utilizam o
programa OpenSSL e a biblioteca de criptografia para realizar a criação de
chaves e a geração de assinaturas.
Você precisará do openssl para compilar kernels 3.7 e superiores se a assinatura
de módulos estiver habilitada. Você também precisará dos pacotes de
desenvolvimento do openssl para compilar kernels 4.3 e superiores.
Tar
---
O GNU tar é necessário caso você deseje habilitar o acesso aos cabeçalhos do
kernel via sysfs (CONFIG_IKHEADERS).
gtags / GNU GLOBAL (optional)
-----------------------------
A compilação do kernel requer o GNU GLOBAL versão 6.6.5 ou superior para gerar
arquivos de tags através de make gtags. Isso se deve ao uso da flag -C
(--directory) pelo gtags.
mkimage
-------
Esta ferramenta é utilizada ao gerar uma Flat Image Tree (FIT), comumente usada
em plataformas ARM. A ferramenta está disponível através do pacote u-boot-tools
ou pode ser compilada a partir do código-fonte do U-Boot. Veja as instruções em
https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux
GNU AWK
-------
O GNU AWK é necessário caso você deseje que a compilação do kernel gere dados de
intervalo de endereços para
módulos integrados (CONFIG_BUILTIN_MODULE_RANGES).
Utilitários de sistema
***********************
Mudanças de arquitetura
------------------------
O DevFS tornou-se obsoleto em favor do udev
(https://www.kernel.org/pub/linux/utils/kernel/hotplug/)
O suporte a UIDs de 32 bits já está implementado. Divirta-se!
A documentação das funções do Linux está migrando para a documentação embutida
(inline), por meio de comentários com formatação especial próximos às suas
definições no código-fonte. Esses comentários podem ser combinados com arquivos
ReST no diretório Documentation/ para criar uma documentação enriquecida, que
pode então ser convertida para arquivos PostScript, HTML, LaTeX, ePUB e PDF.
Para converter do formato ReST para o formato de sua escolha,você precisará do
Sphinx.
Util-linux
----------
Novas versões do util-linux oferecem suporte no fdisk para discos maiores,
suporte a novas opções para o mount, reconhecimento de mais tipos de partição e
outras funcionalidades interessantes. Você provavelmente vai querer atualizar.
Ksymoops
--------
Se o impensável acontecer e o seu kernel sofrer um oops, você pode precisar da
ferramenta ksymoops para decodificá-lo, mas na maioria dos casos, não será
necessário. É geralmente preferível compilar o kernel com CONFIG_KALLSYMS para
que ele produza dumps legíveis que possam ser usados no estado em que se
encontram (isso também gera uma saída melhor do que a do ksymoops).
Se por algum motivo o seu kernel não for compilado com CONFIG_KALLSYMS e você
não tiver como recompilar e reproduzir o oops com essa opção, você ainda poderá
decodificá-lo com o ksymoops.
Mkinitrd
--------
Estas mudanças no layout da árvore de arquivos /lib/modules também exigem que o
mkinitrd seja atualizado.
E2fsprogs
---------
A versão mais recente do e2fsprogs corrige diversos bugs no fsck e no debugfs.
Obviamente, é uma boa ideia atualizar.
JFSutils
--------
O pacote jfsutils contém os utilitários para o sistema de arquivos. Os seguintes
utilitários estão disponíveis:
- ``fsck.jfs`` - inicia a reprodução (replay) do log de transações, além de
verificar e reparar uma partição formatada em JFS.
- ``mkfs.jfs`` - cria uma partição formatada em JFS.
- Para o seu arquivo changes.rst, a tradução técnica adequada é:
Outros utilitários de sistema de arquivos também estão disponíveis neste pacote.
Xfsprogs
--------
A versão mais recente do ``xfsprogs`` contém os utilitários ``mkfs.xfs``,
``xfs_db`` e ``xfs_repair``, entre outros, para o sistema de arquivos XFS. Ele é
independente de arquitetura e qualquer versão a partir da 2.0.0 deve funcionar
corretamente com esta versão do código do kernel XFS (recomenda-se a
versão 2.6.0 ou posterior, devido a algumas melhorias significativas).
PCMCIAutils
-----------
O PCMCIAutils substitui o pcmcia-cs. Ele configura corretamente os sockets
PCMCIA na inicialização do sistema e carrega os módulos apropriados para
dispositivos PCMCIA de 16 bits, caso o kernel esteja modularizado e o subsistema
de hotplug seja utilizado.
Quota-tools
-----------
O suporte a UIDs e GIDs de 32 bits é necessário caso você deseje utilizar o
formato de cota versão 2 mais recente. O quota-tools versão 3.07 e superiores
possuem esse suporte. Utilize a versão recomendada ou superior da tabela acima.
Intel IA32 microcode
--------------------
Um driver foi adicionado para permitir a atualização do microcódigo Intel IA32,
acessível como um dispositivo de caracteres comum (misc). Se você não estiver
usando o udev, você poderá precisar de::
mkdir /dev/cpu
mknod /dev/cpu/microcode c 10 184
chmod 0644 /dev/cpu/microcode
Se você não estiver usando o udev, você poderá precisar executar os comandos
acima como root antes de poder usar isso. Você provavelmente também desejará
obter o utilitário de espaço de usuário ``microcode_ctl`` para utilizar em
conjunto com este driver.
udev
----
O udev é uma aplicação de espaço de usuário para popular o diretório /dev
dinamicamente, apenas com entradas para dispositivos de fat presentes no
sistema. O udev substitui a funcionalidade básica do devfs, permitindo ao mesmo
tempo a nomeação persistente de dispositivos.
FUSE
----
Necessita do libfuse 2.4.0 ou posterior. O mínimo absoluto é a versão 2.3.0,
mas as opções de montagem direct_io e kernel_cache não funcionarão.
Redes
******
Mudanças gerais
----------------
Caso você tenha necessidades avançadas de configuração de rede, você deve
provavelmente considerar o uso das ferramentas de rede do iproute2.
Filtro de Pacotes / NAT
------------------------
O código de filtragem de pacotes e NAT utiliza as mesmas ferramentas da série
anterior de kernels 2.4.x (iptables). Ele ainda inclui módulos de
retrocompatibilidade para o ipchains (estilo 2.2.x) e o ipfwadm (estilo 2.0.x).
PPP
---
O driver PPP foi reestruturado para suportar multilink e permitir que opere
sobre diversas camadas de mídia. Se você utiliza PPP, atualize o pppd para, no
mínimo, a versão 2.4.0.
Se você não estiver usando o udev, você deve possuir o arquivo de dispositivo
``/dev/ppp``, o qual pode ser criado por::
mknod /dev/ppp c 108 0
como root.
NFS-utils
---------
Em kernels antigos (2.4 e anteriores), o servidor NFS precisava conhecer
qualquer cliente que pretendesse acessar arquivos via NFS. Essa informação era
fornecida ao kernel pelo mountd quando o cliente montava o sistema de arquivos,
ou pelo exportfs na inicialização do sistema. O exportfs obtinha informações
sobre clientes ativos a partir de /var/lib/nfs/rmtab.
Esta abordagem é bastante frágil, pois depende da integridade do rmtab, o que
nem sempre é fácil, particularmente ao tentar implementar fail-over. Mesmo
quando o sistema está funcionando bem, o rmtab sofre com o acúmulo de muitas
entradas antigas que nunca são removidas.
Com kernels modernos, temos a opção de fazer o kernel informar ao mountd quando
recebe uma requisição de um host desconhecido, permitindo que o mountd forneça
as informações de exportação apropriadas ao kernel. Isso remove a dependência do
rmtab e significa que o kernel só precisa conhecer os clientes ativos no
momento.
Para habilitar esta nova funcionalidade, você precisa::
mount -t nfsd nfsd /proc/fs/nfsd
antes de executar o exportfs ou o mountd. Recomenda-se que todos os serviços NFS
sejam protegidos da internet em geral por um firewall, sempre que possível.
mcelog
------
Em kernels x86, o utilitário mcelog é necessário para processar e registrar
eventos de machine check quando opção CONFIG_X86_MCE está ativada. Eventos de
machine check são erros relatados pela CPU. O processamento desses eventos é
fortemente recomendado.
Documentação do Kernel
***********************
Sphinx
------
Por favor, consulte Documentation/doc-guide/sphinx.rst para detalhes sobre os
requisitos do Sphinx.
rustdoc
-------
O rustdoc é utilizado para gerar a documentação para código Rust. Por favor,
consulte Documentation/rust/general-information.rst para mais informações.
Obtendo software atualizado
============================
Compilação do kernel
**********************
gcc
---
- <ftp://ftp.gnu.org/gnu/gcc/>
Clang/LLVM
----------
- :ref:`Getting LLVM <getting_llvm>`.
Rust
----
- Documentation/rust/quick-start.rst.
bindgen
-------
- Documentation/rust/quick-start.rst.
Make
----
- <ftp://ftp.gnu.org/gnu/make/>
Bash
----
- <ftp://ftp.gnu.org/gnu/bash/>
Binutils
--------
- <https://www.kernel.org/pub/linux/devel/binutils/>
Flex
----
- <https://github.com/westes/flex/releases>
Bison
-----
- <ftp://ftp.gnu.org/gnu/bison/>
OpenSSL
-------
- <https://www.openssl.org/>
System utilities
****************
Util-linux
----------
- <https://www.kernel.org/pub/linux/utils/util-linux/>
Kmod
----
- <https://www.kernel.org/pub/linux/utils/kernel/kmod/>
- <https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git>
Ksymoops
--------
- <https://www.kernel.org/pub/linux/utils/kernel/ksymoops/v2.4/>
Mkinitrd
--------
- <https://code.launchpad.net/initrd-tools/main>
E2fsprogs
---------
- <https://www.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/>
- <https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/>
JFSutils
--------
- <https://jfs.sourceforge.net/>
Xfsprogs
--------
- <https://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git>
- <https://www.kernel.org/pub/linux/utils/fs/xfs/xfsprogs/>
Pcmciautils
-----------
- <https://www.kernel.org/pub/linux/utils/kernel/pcmcia/>
Quota-tools
-----------
- <https://sourceforge.net/projects/linuxquota/>
Intel P6 microcode
------------------
- <https://downloadcenter.intel.com/>
udev
----
- <https://www.freedesktop.org/software/systemd/man/udev.html>
FUSE
----
- <https://github.com/libfuse/libfuse/releases>
mcelog
------
- <https://www.mcelog.org/>
Redes
******
PPP
---
- <https://download.samba.org/pub/ppp/>
- <https://git.ozlabs.org/?p=ppp.git>
- <https://github.com/paulusmack/ppp/>
NFS-utils
---------
- <https://sourceforge.net/project/showfiles.php?group_id=14>
- <https://nfs.sourceforge.net/>
Iptables
--------
- <https://netfilter.org/projects/iptables/index.html>
Ip-route2
---------
- <https://www.kernel.org/pub/linux/utils/net/iproute2/>
OProfile
--------
- <https://oprofile.sf.net/download/>
Kernel documentation
********************
Sphinx
------
- <https://www.sphinx-doc.org/>

View File

@ -0,0 +1,40 @@
.. SPDX-License-Identifier: GPL-2.0
Continuidade do projeto do kernel Linux
=======================================
O projeto de desenvolvimento do kernel Linux é amplamente distribuído, com mais de
100 mantenedores, cada um trabalhando para manter as mudanças fluindo através de
seus próprios repositórios. A etapa final, no entanto, é centralizada, onde as
mudanças são puxadas para o repositório mainline. Isso é normalmente feito por
Linus Torvalds mas, como foi demonstrado pelo lançamento da versão 4.19 em 2018,
existem outros que podem realizar esse trabalho quando surge a necessidade.
Caso os mantenedores desse repositório se tornem indispostos ou incapazes de
realizar esse trabalho daqui em diante (incluindo a facilitação de uma transição),
o projeto precisará encontrar um ou mais substitutos sem demora. O processo pelo
qual isso será feito está listado abaixo. O $ORGANIZER é o último organizador do
Maintainer Summit ou o atual presidente do Conselho Consultivo Técnico (TAB) da
Linux Foundation (LF) como reserva.
- Em até 72 horas, o $ORGANIZER abrirá uma discussão com os convidados do
Maintainer Summit concluído mais recentemente. Uma reunião desses convidados e
do TAB, seja online ou presencial, será agendada o mais rápido possível de uma
forma que maximize o número de pessoas que possam participar.
- Se não houver ocorrido um Maintainer Summit nos últimos 15 meses, o conjunto de
convidados para esta reunião será determinado pelo TAB.
- Os convidados para esta reunião podem trazer outros mantenedores conforme
necessário.
- Esta reunião, presidida pelo $ORGANIZER, considerará opções para a gestão
contínua do repositório de nível superior do kernel, de forma consistente com
a expectativa de maximizar a saúde a longo prazo do projeto e de sua comunidade.
- Em até duas semanas, um representante deste grupo comunicará à comunidade em
geral, utilizando a lista de discussão ksummit@lists.linux.dev, quais serão os
próximos passos.
A Linux Foundation, conforme orientada pelo TAB, tomará as medidas necessárias
para apoiar e implementar este plano.

View File

@ -0,0 +1,637 @@
.. SPDX-License-Identifier: GPL-2.0
.. _pt_process_howto:
COMO FAZER o desenvolvimento do kernel Linux
============================================
Este é o documento definitivo sobre este tópico. Ele contém instruções
sobre como se tornar um desenvolvedor do kernel Linux e como aprender a
trabalhar com a comunidade de desenvolvimento do kernel Linux. Ele tenta
não conter nada relacionado aos aspectos técnicos da programação do kernel,
mas ajudará a apontar a direção certa para isso.
Se algo neste documento ficar desatualizado, por favor, envie patches para
o mantenedor deste arquivo, que está listado no final do documento.
Introdução
------------
Então, você quer aprender como se tornar um desenvolvedor do kernel Linux?
Ou o seu gerente lhe disse: "Vá escrever um driver Linux para este
dispositivo". O objetivo deste documento é ensinar tudo o que você precisa
saber para conseguir isso, descrevendo o processo pelo qual você deve passar
e oferecendo dicas sobre como trabalhar com a comunidade. Ele também tentará
explicar algumas das razões pelas quais a comunidade trabalha da forma que
trabalha.
O kernel é escrito principalmente em C, com algumas partes dependentes de
arquitetura escritas em assembly. Um bom entendimento de C é necessário para
o desenvolvimento do kernel. O conhecimento de Assembly (de qualquer
arquitetura) não é obrigatório, a menos que você planeje fazer
desenvolvimento de baixo nível para essa arquitetura específica. Embora não
sejam um substituto para uma formação sólida em C e/ou anos de experiência,
os seguintes livros são bons para, no mínimo, referência:
- "The C Programming Language" por Kernighan e Ritchie [Prentice Hall]
- "Practical C Programming" por Steve Oualline [O'Reilly]
- "C: A Reference Manual" por Harbison e Steele [Prentice Hall]
O kernel é escrito usando o GNU C e a GNU toolchain. Embora ele siga o
padrão ISO C11, ele utiliza uma série de extensões que não estão presentes
no padrão. O kernel é um ambiente C independente (freestanding), sem
dependência da biblioteca C padrão (libc), portanto, algumas partes do
padrão C não são suportadas. Divisões arbitrárias de "long long" e ponto
flutuante não são permitidas. Às vezes, pode ser difícil entender as
suposições que o kernel faz sobre a toolchain e as extensões que ele utiliza
e, infelizmente, não existe uma referência definitiva para elas. Por favor,
verifique as páginas de informações do gcc (`info gcc`) para obter algumas
informações sobre elas.
Por favor, lembre-se de que você está tentando aprender como trabalhar com a
comunidade de desenvolvimento existente. É um grupo diversificado de pessoas,
com altos padrões de codificação, estilo e procedimento. Esses padrões foram
criados ao longo do tempo com base no que se descobriu funcionar melhor para
uma equipe tão grande e geograficamente dispersa. Tente aprender o máximo
possível sobre esses padrões com antecedência, pois eles estão bem
documentados; não espere que as pessoas se adaptem a você ou à forma de fazer
as coisas da sua empresa.
Questões Legais
---------------
O código-fonte do kernel Linux é lançado sob a GPL. Por favor, veja o arquivo
COPYING no diretório principal da árvore de fontes. As regras de licenciamento
do kernel Linux e como usar os identificadores `SPDX <https://spdx.org/>`_ no
código-fonte estão descritas em :ref:`Documentation/process/license-rules.rst <kernel_licensing>`.
Se você tiver mais perguntas sobre a licença, por favor, entre em contato com
um advogado e não pergunte na lista de discussão do kernel Linux. As pessoas
nas listas de discussão não são advogados e você não deve confiar em suas
declarações sobre assuntos jurídicos.
Para perguntas e respostas comuns sobre a GPL, por favor, veja:
https://www.gnu.org/licenses/gpl-faq.html
Documentação
------------
A árvore de fontes do kernel Linux possui uma vasta gama de documentos que
são inestimáveis para aprender como interagir com a comunidade do kernel.
Quando novos recursos são adicionados ao kernel, recomenda-se que novos
arquivos de documentação também sejam adicionados explicando como usar o
recurso. Quando uma mudança no kernel faz com que a interface que o kernel
expõe para o espaço do usuário (userspace) mude, recomenda-se que você envie
a informação ou um patch para as páginas de manual explicando a mudança para
o mantenedor das páginas de manual em alx@kernel.org, e coloque em cópia (CC)
a lista linux-api@vger.kernel.org.
Aqui está uma lista de arquivos que estão na árvore de fontes do kernel e
que são de leitura obrigatória:
:ref:`Documentation/admin-guide/README.rst <readme>`
Este arquivo fornece um breve histórico sobre o kernel Linux e descreve
o que é necessário fazer para configurar e compilar o kernel. Pessoas
que são novas no kernel devem começar por aqui.
:doc:`changes`
Este arquivo fornece uma lista das versões mínimas de vários pacotes de
software que são necessários para compilar e executar o kernel com
sucesso.
:ref:`Documentation/process/coding-style.rst <codingstyle>`
Este documento descreve o estilo de codificação do kernel Linux e parte
da fundamentação por trás dele. Espera-se que todo código novo siga as
diretrizes deste documento. A maioria dos mantenedores apenas aceitará
patches se essas regras forem seguidas, e muitas pessoas apenas
revisarão o código se ele estiver no estilo adequado.
:ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
Este arquivo descreve em detalhes explícitos como criar e enviar
um patch com sucesso, incluindo (mas não limitado a):
- Conteúdo do e-mail
- Formato do e-mail
- Para quem enviá-lo
Seguir estas regras não garantirá o sucesso (já que todos os patches
estão sujeitos a um escrutínio de conteúdo e estilo), mas não segui-las
quase sempre o impedirá.
Outras excelentes descrições de como criar patches adequadamente são:
"O Patch Perfeito"
https://www.ozlabs.org/~akpm/stuff/tpp.txt
"Formato de Submissão de Patch do Kernel Linux"
https://web.archive.org/web/20180829112450/http://linux.yyz.us/patch-format.html
:ref:`Documentation/process/stable-api-nonsense.rst <stable_api_nonsense>`
Este arquivo descreve a justificativa por trás da decisão consciente de
não ter uma API estável dentro do kernel, incluindo pontos como:
- Camadas de adaptação (shim-layers) de subsistemas (para compatibilidade?)
- Portabilidade de drivers entre sistemas operacionais.
- Mitigação de mudanças rápidas dentro da árvore de fontes do kernel
(ou impedimento de mudanças rápidas).
Este documento é crucial para compreender a filosofia de desenvolvimento
do Linux e é muito importante para pessoas que estão migrando para o
Linux vindas do desenvolvimento em outros Sistemas Operacionais.
:ref:`Documentation/process/security-bugs.rst <securitybugs>`
Se você acredita ter encontrado um problema de segurança no kernel Linux,
por favor, siga os passos descritos neste documento para ajudar a
notificar os desenvolvedores do kernel e auxiliar na resolução do problema.
:ref:`Documentation/process/management-style.rst <managementstyle>`
Este documento descreve como os mantenedores do kernel Linux operam e o
ethos compartilhado por trás de suas metodologias. Esta é uma leitura
importante para qualquer pessoa nova no desenvolvimento do kernel (ou
para qualquer pessoa simplesmente curiosa sobre isso), pois resolve muitos
equívocos comuns e confusões sobre o comportamento único dos mantenedores
do kernel.
:ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`
Este arquivo descreve as regras sobre como ocorrem os lançamentos das
versões estáveis (stable) do kernel e o que fazer se você desejar que
uma alteração seja incluída em um desses lançamentos.
:ref:`Documentation/process/kernel-docs.rst <kernel_docs>`
Uma lista de documentação externa que pertence ao desenvolvimento do
kernel. Por favor, consulte esta lista caso não encontre o que está
procurando dentro da documentação interna do kernel.
:ref:`Documentation/process/applying-patches.rst <applying_patches>`
Uma boa introdução descrevendo exatamente o que é um patch e como
aplicá-lo aos diferentes ramos (branches) de desenvolvimento do kernel.
O kernel também possui um grande número de documentos que podem ser
gerados automaticamente a partir do próprio código-fonte ou de
marcações ReStructuredText (ReST), como esta. Isso inclui uma
descrição completa da API interna do kernel e regras sobre como
manipular o bloqueio (locking) corretamente.
Todos esses documentos podem ser gerados em formato PDF ou HTML ao
executar::
make pdfdocs
make htmldocs
respectivamente, a partir do diretório principal do código-fonte do kernel.
Os documentos que utilizam a marcação ReST serão gerados em
Documentation/output. Eles também podem ser gerados nos formatos
LaTeX e ePub com::
make latexdocs
make epubdocs
Como se tornar um desenvolvedor do kernel
------------------------------------------
Se você não sabe nada sobre o desenvolvimento do kernel Linux, você deve
consultar o projeto Linux KernelNewbies:
https://kernelnewbies.org
Ele consiste em uma lista de discussão útil onde você pode fazer quase
qualquer tipo de pergunta básica sobre o desenvolvimento do kernel
(certifique-se de pesquisar nos arquivos primeiro, antes de perguntar
algo que já foi respondido no passado). Ele também possui um canal de
IRC que você pode usar para fazer perguntas em tempo real, e muita
documentação útil para aprender sobre o desenvolvimento do kernel Linux.
O site possui informações básicas sobre a organização do código,
subsistemas e projetos atuais (tanto in-tree quanto out-of-tree).
Também descreve algumas informações logísticas básicas, como por exemplo,
como compilar um kernel e aplicar um patch.
Se você não sabe por onde começar, mas deseja procurar alguma tarefa
para iniciar sua integração na comunidade de desenvolvimento do kernel,
acesse o projeto Linux Kernel Janitor:
https://kernelnewbies.org/KernelJanitors
É um ótimo lugar para começar. Ele descreve uma lista de problemas
relativamente simples que precisam ser limpos e corrigidos dentro da
árvore de códigos-fonte do kernel Linux. Ao trabalhar com os
desenvolvedores responsáveis por este projeto, você aprenderá o básico
sobre como incluir seu patch na árvore do kernel Linux e,
possivelmente, será orientado sobre o que trabalhar em seguida, caso
ainda não tenha uma ideia.
Antes de fazer qualquer modificação real no código do kernel Linux, é
imperativo entender como o código em questão funciona. Para esse
propósito, nada é melhor do que lê-lo diretamente (a maioria das partes
complexas está bem comentada), talvez até com a ajuda de ferramentas
especializadas. Uma ferramenta particularmente recomendada é o projeto
Linux Cross-Reference, que é capaz de apresentar o código-fonte em um
formato de página web indexada e auto-referenciada. Um excelente
repositório atualizado do código do kernel pode ser encontrado em:
https://elixir.bootlin.com/
O processo de desenvolvimento
-----------------------------
O processo de desenvolvimento do kernel Linux consiste atualmente em algumas
"branches" (ramos) principais diferentes e muitos ramos de subsistemas
específicos. Esses diferentes ramos são:
- Árvore principal (mainline) do Linus
- Várias árvores estáveis com múltiplos números de versão principal
- Árvores específicas de subsistemas
- Árvore de testes de integração linux-next
Árvore principal (Mainline tree)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A árvore principal é mantida por Linus Torvalds e pode ser encontrada em
https://kernel.org ou no repositório. Seu processo de desenvolvimento é
o seguinte:
- Assim que um novo kernel é lançado, uma janela de duas semanas é aberta;
durante esse período, os mantenedores podem enviar grandes diffs para
Linus, geralmente patches que já foram incluídos na linux-next por algumas
semanas. A forma preferida de enviar grandes mudanças é usando o git
(a ferramenta de gerenciamento de código-fonte do kernel, mais informações
podem ser encontradas em https://git-scm.com/), mas patches simples
também são aceitos.
- Após duas semanas, um kernel -rc1 é lançado e o foco passa a ser tornar
o novo kernel o mais sólido possível. A maioria dos patches neste estágio
deve corrigir uma regressão. Bugs que sempre existiram não são regressões,
portanto, envie esses tipos de correções apenas se forem importantes.
Observe que um driver (ou sistema de arquivos) totalmente novo pode ser
aceito após o -rc1 porque não há risco de causar regressões com tal
mudança, desde que a alteração seja autocontida e não afete áreas fora do
código que está sendo adicionado. O git pode ser usado para enviar
patches para Linus após o lançamento do -rc1, mas os patches também
precisam ser enviados para uma lista de discussão pública para revisão.
- Um novo -rc é lançado sempre que Linus considerar que a árvore git atual
está em um estado razoavelmente estável e adequado para testes. O objetivo
é lançar um novo kernel -rc a cada semana.
- O processo continua até que o kernel seja considerado "pronto"; o
processo deve durar cerca de 6 semanas.
Vale a pena mencionar o que Andrew Morton escreveu na lista de discussão
do kernel Linux sobre os lançamentos do kernel:
*"Ninguém sabe quando um kernel será lançado, porque ele é
lançado de acordo com o status percebido dos bugs, não de acordo
com um cronograma pré-concebido."*
Várias árvores estáveis com múltiplos números de versão principal
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Kernels com versões de 3 partes são kernels -stable (estáveis). Eles
contêm correções relativamente pequenas e críticas para problemas de
segurança ou regressões significativas descobertas em um determinado
lançamento principal da árvore mainline. Cada lançamento em uma série
estável principal incrementa a terceira parte do número da versão,
mantendo as duas primeiras partes iguais.
Este é o ramo recomendado para usuários que desejam o kernel estável
mais recente e não estão interessados em ajudar a testar versões de
desenvolvimento ou experimentais.
As árvores estáveis são mantidas pela equipe "stable"
<stable@vger.kernel.org> e são lançadas conforme a necessidade exigir.
O período normal de lançamento é de aproximadamente duas semanas, mas
pode ser mais longo se não houver problemas urgentes. Por outro lado,
um problema relacionado à segurança pode fazer com que um lançamento
ocorra quase instantaneamente.
O arquivo :ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`
na árvore do kernel documenta quais tipos de mudanças são aceitáveis para
a árvore -stable e como o processo de lançamento funciona.
Árvores específicas de subsistemas
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Os mantenedores dos vários subsistemas do kernel — e também muitos
desenvolvedores de subsistemas do kernel — expõem seu estado atual de
desenvolvimento em repositórios de código-fonte. Dessa forma, outros
podem ver o que está acontecendo nas diferentes áreas do kernel. Em
áreas onde o desenvolvimento é rápido, um desenvolvedor pode ser
solicitado a basear suas submissões em tal árvore de subsistema do
kernel para que conflitos entre a submissão e outros trabalhos já em
andamento sejam evitados.
A maioria desses repositórios são árvores git, mas também existem outros
SCMs em uso, ou filas de patches sendo publicadas como séries quilt. Os
endereços desses repositórios de subsistemas estão listados no arquivo
MAINTAINERS. Muitos deles podem ser navegados em https://git.kernel.org/.
Antes que um patch proposto seja incluído em tal árvore de subsistema,
ele está sujeito a uma revisão que ocorre principalmente em listas de
discussão (veja a seção respectiva abaixo). Para vários subsistemas do
kernel, este processo de revisão é rastreado com a ferramenta patchwork.
O Patchwork oferece uma interface web que mostra as postagens de patches,
quaisquer comentários sobre um patch ou revisões feitas a ele, e os
mantenedores podem marcar os patches como "sob revisão", "aceitos" ou
"rejeitados". A maioria desses sites patchwork está listada em
https://patchwork.kernel.org/.
Árvore de testes de integração linux-next
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Antes que as atualizações das árvores de subsistemas sejam mescladas na
árvore mainline, elas precisam ser testadas quanto à integração. Para
este propósito, existe um repositório de testes especial no qual
praticamente todas as árvores de subsistemas são integradas (pulled)
quase diariamente:
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
Dessa forma, a linux-next oferece uma visão resumida do que se espera
que entre no kernel mainline no próximo período de mesclagem (merge
window). Testadores aventureiros são muito bem-vindos para testar a
linux-next em tempo de execução.
Relato de Bugs
--------------
O arquivo 'Documentation/admin-guide/reporting-issues.rst' no diretório
principal de códigos-fonte do kernel descreve como relatar um possível
bug no kernel e detalha que tipo de informação é necessária para os
desenvolvedores do kernel ajudarem a rastrear o problema.
Gerenciando relatos de bugs
---------------------------
Uma das melhores maneiras de colocar em prática suas habilidades de hacking
é corrigindo bugs relatados por outras pessoas. Você não apenas ajudará a
tornar o kernel mais estável, mas também aprenderá a resolver problemas do
mundo real, melhorará suas habilidades e outros desenvolvedores passarão a
notar sua presença. Corrigir bugs é uma das melhores formas de obter mérito
entre outros desenvolvedores, pois poucas pessoas gostam de gastar tempo
corrigindo bugs de terceiros.
Para trabalhar em relatos de bugs já existentes, encontre um subsistema no
qual você esteja interessado. Verifique no arquivo MAINTAINERS para onde
os bugs daquele subsistema são relatados; geralmente será uma lista de
discussão, raramente um rastreador de bugs (bugtracker). Pesquise nos
arquivos de mensagens do local indicado por relatos recentes e ajude onde
achar apropriado. Você também pode verificar o site
https://bugzilla.kernel.org para relatos de bugs; apenas alguns
subsistemas do kernel o utilizam ativamente para relato ou rastreamento,
entretanto, bugs de todo o kernel acabam sendo registrados lá.
Listas de discussão
-------------------
Como alguns dos documentos acima descrevem, a maioria dos desenvolvedores
do núcleo (core) do kernel participa da Linux Kernel Mailing List (LKML).
Detalhes sobre como se inscrever e cancelar a inscrição na lista podem
ser encontrados em:
https://subspace.kernel.org/subscribing.html
Existem arquivos de mensagens da lista na web em muitos lugares diferentes.
Use um mecanismo de busca para encontrar esses arquivos. Por exemplo:
https://lore.kernel.org/linux-kernel/
É altamente recomendável que você pesquise nos arquivos sobre o tópico que
deseja abordar antes de postar na lista. Muitas coisas já discutidas em
detalhes estão registradas apenas nos arquivos das listas de discussão.
A maioria dos subsistemas individuais do kernel também possui sua própria
lista de discussão separada, onde realizam seus esforços de desenvolvimento.
Consulte o arquivo MAINTAINERS para obter uma lista de quais são essas
listas para os diferentes grupos.
Muitas das listas estão hospedadas no kernel.org. Informações sobre elas
podem ser encontradas em:
https://subspace.kernel.org
Por favor, lembre-se de seguir bons hábitos de comportamento ao usar as
listas. Embora um pouco clichê, a URL a seguir possui algumas diretrizes
simples para interagir com a lista (ou qualquer outra lista):
https://subspace.kernel.org/etiquette.html
Se várias pessoas responderem ao seu e-mail, a lista de destinatários em
CC: pode se tornar bem grande. Não remova ninguém da lista CC: sem um
bom motivo, e não responda apenas para o endereço da lista. Acostume-se
a receber o e-mail duas vezes (um do remetente e outro da lista) e não
tente ajustar isso adicionando cabeçalhos de e-mail complexos; as pessoas
não gostarão disso.
Lembre-se de manter o contexto e a atribuição de suas respostas intactos;
mantenha as linhas do tipo "John Kernelhacker escreveu...:" no topo da
sua resposta e adicione seus comentários entre as seções citadas
individualmente, em vez de escrever tudo no topo do e-mail.
Se você adicionar patches ao seu e-mail, certifique-se de que sejam texto
puro legível, conforme declarado em
:ref:`Documentation/process/submitting-patches.rst <submittingpatches>`.
Os desenvolvedores do kernel não querem lidar com anexos ou patches
compactados; eles podem querer comentar linhas individuais do seu patch,
o que só funciona dessa forma. Certifique-se de usar um programa de
e-mail que não altere espaços e caracteres de tabulação (tabs). Um bom
primeiro teste é enviar o e-mail para si mesmo e tentar aplicar o seu
próprio patch. Se isso não funcionar, conserte seu programa de e-mail ou
troque-o até que funcione.
Acima de tudo, por favor, lembre-se de mostrar respeito aos outros
inscritos.
Trabalhando com a comunidade
----------------------------
O objetivo da comunidade do kernel é fornecer o melhor kernel possível.
Quando você envia um patch para aceitação, ele será revisado por seus
méritos técnicos e apenas por eles. Então, o que você deve esperar?
- críticas
- comentários
- solicitações de mudança
- solicitações de justificativa
- silêncio
Lembre-se, isso faz parte do processo de incluir seu patch no kernel.
Você deve ser capaz de aceitar críticas e comentários sobre seus patches,
avaliá-los em nível técnico e retrabalhar seus patches ou fornecer
raciocínios claros e concisos sobre o porquê de certas mudanças não
deverem ser feitas. Se não houver respostas à sua postagem, aguarde
alguns dias e tente novamente; às vezes, as coisas se perdem no enorme
volume de mensagens.
O que você não deve fazer?
- esperar que seu patch seja aceito sem questionamentos
- tornar-se defensivo
- ignorar comentários
- reenviar o patch sem fazer nenhuma das alterações solicitadas
Em uma comunidade que busca a melhor solução técnica possível, sempre
haverá opiniões divergentes sobre o quão benéfico é um patch. Você deve
ser cooperativo e estar disposto a adaptar sua ideia para que ela se
encaixe no kernel. Ou, pelo menos, estar disposto a provar que sua ideia
vale a pena. Lembre-se: estar errado é aceitável, desde que você esteja
disposto a trabalhar em direção a uma solução correta.
É normal que as respostas ao seu primeiro patch sejam apenas uma lista
de uma dúzia de coisas que você deve corrigir. Isso **não** implica que
seu patch não será aceito e **não** é algo pessoal contra você. Simplesmente
corrija todos os problemas apontados em seu patch e envie-o novamente.
Diferenças entre a comunidade do kernel e estruturas corporativas
-----------------------------------------------------------------
A comunidade do kernel trabalha de forma diferente da maioria dos ambientes
tradicionais de desenvolvimento corporativo. Aqui está uma lista de coisas
que você pode tentar fazer para evitar problemas:
Boas coisas a dizer em relação às suas mudanças propostas:
- "Isto resolve múltiplos problemas."
- "Isto remove 2000 linhas de código."
- "Aqui está um patch que explica o que estou tentando descrever."
- "Eu testei isso em 5 arquiteturas diferentes..."
- "Aqui está uma série de pequenos patches que..."
- "Isto aumenta a performance em máquinas comuns..."
Coisas ruins que você deve evitar dizer:
- "Nós fizemos desta forma no AIX/ptx/Solaris, portanto deve ser bom..."
- "Eu faço isso há 20 anos, então..."
- "Isto é necessário para minha empresa ganhar dinheiro."
- "Isto é para nossa linha de produtos Enterprise."
- "Aqui está meu documento de design de 1000 páginas que descreve minha ideia."
- "Estou trabalhando nisso há 6 meses..."
- "Aqui está um patch de 5000 linhas que..."
- "Eu reescrevi toda a bagunça atual, e aqui está..."
- "Eu tenho um prazo (deadline), e este patch precisa ser aplicado agora."
Outra forma em que a comunidade do kernel difere da maioria dos ambientes
tradicionais de engenharia de software é a natureza anônima da interação.
Um benefício de usar e-mail e IRC como as principais formas de comunicação
é a ausência de discriminação baseada em gênero ou raça. O ambiente de
trabalho do kernel Linux aceita mulheres e minorias porque tudo o que você
é, é um endereço de e-mail. O aspecto internacional também ajuda a nivelar
o campo de jogo porque você não pode adivinhar o gênero com base no nome
de uma pessoa. Um homem pode se chamar Andrea e uma mulher pode se chamar
Pat. A maioria das mulheres que trabalharam no kernel Linux e expressaram
uma opinião tiveram experiências positivas.
A barreira do idioma pode causar problemas para algumas pessoas que não
se sentem confortáveis com o inglês. Um bom domínio do idioma pode ser
necessário para transmitir ideias adequadamente nas listas de discussão,
por isso recomenda-se que você verifique seus e-mails para garantir que
façam sentido em inglês antes de enviá-los.
Divida suas alterações
----------------------
A comunidade do kernel Linux não aceita de bom grado grandes blocos de
código jogados de uma só vez. As mudanças precisam ser devidamente
introduzidas, discutidas e divididas em porções minúsculas e individuais.
Isso é quase o exato oposto do que as empresas costumam fazer. Sua proposta
também deve ser introduzida muito cedo no processo de desenvolvimento, para
que você possa receber feedback sobre o que está fazendo. Isso também permite
que a comunidade sinta que você está trabalhando com eles, e não simplesmente
usando-os como um depósito para sua funcionalidade. No entanto, não envie
50 e-mails de uma só vez para uma lista de discussão; sua série de patches
deve ser menor que isso quase sempre.
As razões para dividir as coisas são as seguintes:
1) Patches pequenos aumentam a probabilidade de serem aplicados, pois não
exigem muito tempo ou esforço para verificar sua correção. Um patch de
5 linhas pode ser aplicado por um mantenedor com apenas um olhar rápido.
No entanto, um patch de 500 linhas pode levar horas para ser revisado
(o tempo que leva é exponencialmente proporcional ao tamanho do patch,
ou algo assim).
Patches pequenos também tornam muito fácil a depuração (debug) quando
algo dá errado. É muito mais fácil reverter patches um por um do que
dissecar um patch muito grande após ele ter sido aplicado (e quebrado algo).
2) É importante não apenas enviar patches pequenos, mas também reescrever
e simplificar (ou simplesmente reordenar) os patches antes de submetê-los.
Aqui está uma analogia do desenvolvedor do kernel Al Viro:
*"Pense em um professor corrigindo o dever de casa de um aluno de
matemática. O professor não quer ver as tentativas e erros do aluno
antes de chegar à solução. Ele quer ver a resposta mais limpa e
elegante. Um bom aluno sabe disso e nunca enviaria seu trabalho
intermediário antes da solução final.*
*O mesmo vale para o desenvolvimento do kernel. Os mantenedores e
revisores não querem ver o processo de pensamento por trás da solução
do problema que se está resolvendo. Eles querem ver uma solução
simples e elegante."*
Pode ser desafiador manter o equilíbrio entre apresentar uma solução
elegante e trabalhar em conjunto com a comunidade discutindo seu trabalho
inacabado. Portanto, é bom entrar no processo cedo para obter feedback e
melhorar seu trabalho, mas também manter suas alterações em pequenos blocos
que possam ser aceitos, mesmo quando sua tarefa completa ainda não esteja
pronta para inclusão.
Também entenda que não é aceitável enviar patches para inclusão que estejam
inacabados e que serão "consertados mais tarde".
Justifique sua alteração
------------------------
Além de dividir seus patches, é muito importante que você deixe a comunidade
Linux saber por que eles deveriam adicionar essa mudança. Novas
funcionalidades devem ser justificadas como necessárias e úteis.
Documente sua alteração
-----------------------
Ao enviar seus patches, preste atenção especial ao que você diz no texto
do seu e-mail. Essas informações se tornarão as informações do ChangeLog
para o patch e serão preservadas para que todos vejam para sempre. Elas
devem descrever o patch completamente, contendo:
- por que a mudança é necessária
- a abordagem geral de design no patch
- detalhes de implementação
- resultados de testes
Para mais detalhes sobre como tudo isso deve ser, por favor, veja a seção
ChangeLog do documento:
"O Patch Perfeito"
https://www.ozlabs.org/~akpm/stuff/tpp.txt
Todas essas coisas às vezes são muito difíceis de fazer. Pode levar anos
para aperfeiçoar essas práticas (se é que é possível). É um processo
contínuo de melhoria que exige muita paciência e determinação. Mas não
desista, é possível. Muitos fizeram isso antes, e cada um teve que começar
exatamente onde você está agora.
----------
Agradecimentos a Paolo Ciarrocchi, que permitiu que a seção "Processo de
Desenvolvimento" (https://lwn.net/Articles/94386/) fosse baseada em um
texto que ele escreveu, e a Randy Dunlap e Gerrit Huizenga por parte da
lista de coisas que você deve ou não dizer. Também agradecemos a Pat Mochel,
Hanna Linder, Randy Dunlap, Kay Sievers, Vojtech Pavlik, Jan Kara,
Josh Boyer, Kees Cook, Andrew Morton, Andi Kleen, Vadim Lobanov, Jesper Juhl,
Adrian Bunk, Keri Harris, Frans Pop, David A. Wheeler, Junio Hamano,
Michael Kerrisk e Alex Shepard por suas revisões, comentários e contribuições.
Sem a ajuda deles, este documento não teria sido possível.
Mantenedor: Greg Kroah-Hartman <greg@kroah.com>

View File

@ -0,0 +1,18 @@
.. SPDX-License-Identifier: GPL-2.0
Notas sobre o processo de desenvolvimento de subsistemas e mantenedores
=======================================================================
O propósito deste documento é fornecer informações específicas de
subsistemas que são suplementares ao manual geral do processo de
desenvolvimento.
Conteúdos:
.. toctree::
:numbered:
:maxdepth: 2
maintainer-netdev
maintainer-soc
maintainer-soc-clean-dts

View File

@ -0,0 +1,435 @@
.. SPDX-License-Identifier: GPL-2.0
KVM x86
=======
Prefácio
--------
O KVM se esforça para ser uma comunidade acolhedora; as contribuições de
recém-chegados são valorizadas e incentivadas. Por favor, não se sinta
desanimado ou intimidado pela extensão deste documento e pelas muitas
regras/diretrizes que ele contém. Todo mundo comete erros e todo mundo já foi um
novato em algum momento. Desde que você faça um esforço honesto para seguir as
diretrizes do KVM x86, seja receptivo ao feedback e aprenda com os erros que
cometer, você será recebido de braços abertos, não com tochas e forquilhas.
(TL;DR)
--------
Testes são obrigatórios. Seja consistente com os estilos e padrões estabelecidos.
Árvores
-------
O KVM x86 está atualmente em um período de transição: deixando de fazer parte da
árvore principal do KVM para se tornar "apenas mais uma arquitetura KVM". Como tal,
o KVM x86 está dividido entre a árvore principal do KVM,
``git.kernel.org/pub/scm/virt/kvm/kvm.git``, e uma árvore específica para KVM x86,
``github.com/kvm-x86/linux.git``.
De modo geral, as correções (fixes) para o ciclo atual são aplicadas diretamente
na árvore principal do KVM, enquanto todo o desenvolvimento para o próximo ciclo
é roteado através da árvore do KVM x86. No caso improvável de uma correção para o
ciclo atual ser roteada através da árvore do KVM x86, ela será aplicada à branch
``fixes`` antes de seguir para a árvore principal do KVM.
Note que espera-se que este período de transição dure bastante tempo, ou seja,
será o status quo em um futuro próximo.
Branches
~~~~~~~~
A árvore do KVM x86 é organizada em múltiplas branches de tópicos (topic
branches). O objetivo de usar branches de tópicos mais granulares é facilitar o
acompanhamento de uma área específica de desenvolvimento e limitar os danos
colaterais de erros humanos e/ou commits com bugs; por exemplo, descartar o
commit HEAD de uma branch de tópico não tem impacto nos hashes SHA1 de outros
commits em andamento, e a necessidade de rejeitar um pull request devido a bugs
atrasa apenas aquela branch de tópico específica.
Todas as branches de tópicos, exceto a ``next`` e a ``fixes``, são incorporadas
na ``next`` via um "Cthulhu merge" conforme a necessidade, ou seja, sempre que
uma branch de tópico é atualizada. Como resultado, force pushes para a branch
``next`` são comuns.
Ciclo de Vida
~~~~~~~~~~~~~
As correções (fixes) destinadas ao lançamento atual, também conhecido como
mainline, são normalmente aplicadas diretamente na árvore principal do KVM, ou
seja, não passam pela árvore do KVM x86.
As mudanças destinadas ao próximo lançamento são roteadas através da árvore do
KVM x86. Pull requests (do KVM x86 para o KVM principal) são enviados para cada
branch de tópico do KVM x86, normalmente na semana anterior à abertura da janela
de merge por Linus, por exemplo, na semana seguinte ao rc7 para lançamentos
"normais". Se tudo correr bem, as branches de tópicos são incorporadas ao pull
request principal do KVM enviado durante a janela de merge de Linus.
A árvore do KVM x86 não possui sua própria janela de merge oficial, mas há um
"soft close" (fechamento flexível) por volta do rc5 para novos recursos, e um
"soft close" por volta do rc6 para correções (para o próximo lançamento; veja
acima para correções destinadas ao lançamento atual).
Cronograma
----------
As submissões são normalmente revisadas e aplicadas em ordem FIFO (primeiro a
entrar, primeiro a sair), com alguma margem de manobra para o tamanho de uma
série, patches que estão "cache hot", etc. Correções (fixes), especialmente para
o lançamento atual e/ou árvores estáveis (stable trees), têm prioridade na fila.
Patches que serão aceitos através de uma árvore não-KVM (mais frequentemente
através da árvore "tip") e/ou que possuam outros "acks"/revisões também ganham
certa prioridade.
Note que a grande maioria das revisões é feita entre o rc1 e o rc6,
aproximadamente. O período entre o rc6 e o próximo rc1 é usado para colocar
outras tarefas em dia, ou seja, o "silêncio de rádio" durante este período não é
incomum.
Pings para obter uma atualização de status são bem-vindos, mas tenha em mente o
tempo do ciclo de lançamento atual e tenha expectativas realistas. Se você está
dando um ping para aceitação — ou seja, não apenas para feedback ou uma
atualização — por favor, faça tudo o que puder, dentro do razoável, para garantir
que seus patches estejam prontos para o merge! Pings em séries que quebram o
build ou falham em testes resultam em mantenedores infelizes!
Desenvolvimento
---------------
Árvore/Branch Base
~~~~~~~~~~~~~~~~~~
Correções destinadas ao lançamento atual, também conhecido como mainline, devem
ser baseadas em ``git://git.kernel.org/pub/scm/virt/kvm/kvm.git master``. Note
que as correções não garantem inclusão automática no lançamento atual. Não
existe uma regra única, mas tipicamente apenas correções para bugs que sejam
urgentes, críticos e/ou que tenham sido introduzidos no lançamento atual devem
ser destinadas ao lançamento atual.
Todo o restante deve ser baseado em ``kvm-x86/next``, ou seja, não há
necessidade de selecionar uma branch de tópico específica como base. Se houver
conflitos e/ou dependências entre as branches de tópicos, é trabalho do
mantenedor resolvê-los.
A única exceção ao uso da ``kvm-x86/next`` como base é se um patch/série for uma
série multi-arquitetura (multi-arch), ou seja, possuir modificações não triviais
no código comum do KVM e/ou possuir mudanças mais do que superficiais no código
de outras arquiteturas. Patches/séries multi-arquitetura devem, em vez disso,
ser baseados em um ponto comum e estável no histórico do KVM, por exemplo, o
release candidate no qual a ``kvm-x86 next`` se baseia. Se você não tiver
certeza se um patch/série é verdadeiramente multi-arquitetura, erre pelo lado da
cautela e trate-o como tal, ou seja, use uma base comum.
Estilo de Codificação
~~~~~~~~~~~~~~~~~~~~~
Quando se trata de estilo, nomenclatura, padrões, etc., a consistência é a
prioridade número um no KVM x86. Se tudo mais falhar, siga o que já existe.
Com algumas ressalvas listadas abaixo, siga o estilo de codificação preferido
dos mantenedores da árvore "tip" (:ref:`maintainer-tip-coding-style`), já que
patches/séries frequentemente tocam tanto arquivos do KVM quanto arquivos x86
não-KVM, ou seja, atraem a atenção de mantenedores do KVM *e* da árvore "tip".
O uso de "reverse fir tree" (árvore de abeto invertida), também conhecido como
"árvore de Natal invertida", para declarações de variáveis não é estritamente
obrigatório, embora ainda seja preferido.
Exceto por alguns casos excepcionais, não use comentários kernel-doc para
funções. A grande maioria das funções "públicas" do KVM não são verdadeiramente
públicas, pois se destinam apenas ao consumo interno do KVM (há planos para
privatizar os headers e exports do KVM para reforçar isso).
Comentários
~~~~~~~~~~~
Escreva comentários usando o modo imperativo e evite pronomes. Use comentários
para fornecer uma visão geral de alto nível do código e/ou para explicar por
que o código faz o que faz. Não reitere o que o código faz literalmente; deixe
o código falar por si mesmo. Se o código em si for inescrutável, comentários
não ajudarão.
Referências ao SDM e ao APM
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Grande parte da base de código do KVM está diretamente ligada ao comportamento
arquitetural definido no Manual de Desenvolvimento de Software (SDM) da Intel e
no Manual do Programador de Arquitetura (APM) da AMD. O uso de "Intel SDM" e
"AMD APM", ou até mesmo apenas "SDM" ou "APM", sem contexto adicional, é
perfeitamente aceitável.
Não faça referência a seções, tabelas, figuras, etc., por número, especialmente
em comentários. Em vez disso, se necessário (veja abaixo), copie e cole o trecho
relevante e referencie seções/tabelas/figuras pelo nome. Os layouts do SDM e do
APM mudam constantemente e, portanto, os números/rótulos não são estáveis.
De modo geral, não faça referência explícita nem copie e cole do SDM ou do APM
em comentários. Com poucas exceções, o KVM *deve* respeitar o comportamento
arquitetural; portanto, subentende-se que o comportamento do KVM está emulando o
comportamento do SDM e/ou do APM. Note que fazer referência ao SDM/APM em
changelogs para justificar a mudança e fornecer contexto é perfeitamente
aceitável e incentivado.
Shortlog
~~~~~~~~
O formato de prefixo preferencial é ``KVM: <topic>:``, onde ``<topic>`` é um dos
seguintes::
- x86
- x86/mmu
- x86/pmu
- x86/xen
- selftests
- SVM
- nSVM
- VMX
- nVMX
**NÃO use x86/kvm!** ``x86/kvm`` é usado exclusivamente para mudanças no Linux
como convidado (guest) de um KVM, ou seja, para ``arch/x86/kernel/kvm.c``. Não
use nomes de arquivos ou caminhos completos de arquivos como prefixo do
assunto/shortlog.
Note que estes não se alinham com as branches de tópicos (as branches de tópicos
se preocupam muito mais com conflitos de código).
Todos os nomes são sensíveis a maiúsculas e minúsculas! ``KVM: x86:`` é bom,
``kvm: vmx:`` não é.
Comece com letra maiúscula a primeira palavra da descrição condensada do patch,
mas omita a pontuação final. Ex.::
KVM: x86: Fix a null pointer dereference in function_xyz()
e não::
kvm: x86: fix a null pointer dereference in function_xyz.
Se um patch tocar em múltiplos tópicos, suba na árvore conceitual para encontrar
o primeiro pai comum (que geralmente é apenas ``x86``). Em caso de dúvida,
``git log caminho/do/arquivo`` deve fornecer uma dica razoável.
Novos tópicos surgem ocasionalmente, mas, por favor, inicie uma discussão na
lista se desejar propor a introdução de um novo tópico; ou seja, não aja por
conta própria.
Veja :ref:`the_canonical_patch_format` para mais informações, com uma ressalva:
não trate o limite de 70-75 caracteres como um limite absoluto e rígido. Em
vez disso, use 75 caracteres como um limite firme, mas não rígido, e use 80
caracteres como um limite intransponível. Ou seja, permita que o shortlog
ultrapasse alguns caracteres do limite padrão se você tiver um bom motivo para
fazê-lo.
Changelog
~~~~~~~~~
O mais importante: escreva os changelogs usando o modo imperativo e evite o uso
de pronomes.
Veja :ref:`describe_changes` para mais informações, com uma ressalva: comece com
uma breve descrição das mudanças reais e, em seguida, apresente o contexto e o
histórico. Note! Esta ordem entra em conflito direto com a abordagem preferida
da árvore "tip"! Por favor, siga o estilo preferido da árvore "tip" ao enviar
patches que visam primariamente o código de arch/x86 que _NÃO_ seja código KVM.
Declarar o que um patch faz antes de mergulhar nos detalhes é preferido pelo KVM
x86 por vários motivos. Primeiro e mais importante, qual código está sendo
realmente alterado é, reconhecidamente, a informação mais importante e,
portanto, essa informação deve ser fácil de encontrar. Changelogs que escondem
"o que está mudando de fato" em uma única linha após 3 ou mais parágrafos de
histórico tornam muito difícil encontrar essa informação.
Para uma revisão inicial, pode-se argumentar que "o que está quebrado" é mais
importante, mas para uma leitura rápida de logs e arqueologia do git, os
detalhes minuciosos importam cada vez menos. Por exemplo, ao fazer uma série de
"git blame", os detalhes de cada mudança ao longo do caminho são inúteis; os
detalhes só importam para o culpado. Fornecer "o que mudou" facilita determinar
rapidamente se um commit pode ou não ser de interesse.
Outro benefício de declarar "o que está mudando" primeiro é que quase sempre é
possível declarar "o que está mudando" em uma única frase. Por outro lado,
exceto pelos bugs mais simples, todos exigem várias frases ou parágrafos para
descrever totalmente o problema. Se tanto "o que está mudando" quanto "qual é o
bug" forem super curtos, a ordem não importa. Mas se um for mais curto (quase
sempre o "o que está mudando"), então cobrir o mais curto primeiro é vantajoso
porque é menos inconveniente para leitores/revisores que têm uma preferência de
ordenação estrita. Ex: ter que pular uma frase para chegar ao contexto é menos
doloroso do que ter que pular três parágrafos para chegar ao "o que está
mudando".
Correções (Fixes)
~~~~~~~~~~~~~~~~~
Se uma mudança corrige um bug do KVM/kernel, adicione uma tag Fixes:, mesmo que
a mudança não precise ser portada (backported) para kernels estáveis, e mesmo
que a mudança corrija um bug em uma versão mais antiga.
Por outro lado, se uma correção realmente precisar de backport, marque
explicitamente o patch com "Cc: stable@vger.kernel.org" (embora o e-mail em si
não precise enviar cópia para a lista stable); o KVM x86 opta por não realizar
o backport automático de tags Fixes: por padrão. Alguns patches selecionados
automaticamente são portados, mas exigem aprovação explícita do mantenedor
(pesquise por MANUALSEL).
Referências a Funções
~~~~~~~~~~~~~~~~~~~~~
Quando uma função for mencionada em um comentário, changelog ou shortlog (ou em
qualquer outro lugar, aliás), use o formato ``nome_da_funcao()``. Os parênteses
fornecem contexto e removem a ambiguidade da referência.
Testes
------
No mínimo, *todos* os patches de uma série devem compilar sem erros para
KVM_INTEL=m, KVM_AMD=m e KVM_WERROR=y. Compilar cada combinação possível de
Kconfigs não é viável, mas quanto mais, melhor. KVM_SMM, KVM_XEN, PROVE_LOCKING
e X86_64 são opções (knobs) particularmente interessantes para se testar.
A execução de KVM selftests e KVM-unit-tests também é obrigatória (e, para
afirmar o óbvio, os testes precisam passar). A única exceção é para mudanças
que tenham probabilidade insignificante de afetar o comportamento em tempo de
execução, por exemplo, patches que apenas modificam comentários. Sempre que
possível e relevante, o teste tanto em Intel quanto em AMD é fortemente
preferido. A inicialização de uma VM real é incentivada, mas não obrigatória.
Para mudanças que tocam o código de shadow paging do KVM, executar com o TDP
(EPT/NPT) desabilitado é obrigatório. Para mudanças que afetam o código comum da
MMU do KVM, a execução com o TDP desabilitado é fortemente incentivada. Para
todas as outras mudanças, se o código sendo modificado depender de e/ou
interagir com um parâmetro de módulo (module param), o teste com as
configurações relevantes é obrigatório.
Note que o KVM selftests e o KVM-unit-tests possuem falhas conhecidas. Se você
suspeitar que uma falha não se deve às suas alterações, verifique se a *exata
mesma* falha ocorre com e sem as suas mudanças.
Mudanças que tocam a documentação em reStructuredText, ou seja, arquivos .rst,
devem compilar o htmldocs de forma limpa, ou seja, sem novos avisos (warnings)
ou erros.
Se você não puder testar totalmente uma mudança, por exemplo, devido à falta de
hardware, declare claramente qual nível de teste você foi capaz de realizar,
por exemplo, na cover letter (carta de apresentação).
Novos Recursos
~~~~~~~~~~~~~~
Com uma exceção, novos recursos *devem* vir acompanhados de cobertura de testes.
Testes específicos do KVM não são estritamente obrigatórios, por exemplo, se a
cobertura for fornecida ao executar uma VM convidada (guest) suficientemente
habilitada, ou ao executar um selftest de kernel relacionado em uma VM, mas
testes dedicados do KVM são preferidos em todos os casos. Casos de teste
negativos, em particular, são obrigatórios para a habilitação de novos recursos
de hardware, já que fluxos de erro e exceção raramente são exercitados
simplesmente ao executar uma VM.
A única exceção a esta regra é se o KVM estiver simplesmente anunciando suporte
para um recurso via KVM_GET_SUPPORTED_CPUID, ou seja, para instruções/recursos
que o KVM não pode impedir um convidado de usar e para os quais não há uma
habilitação real.
Note que "novos recursos" não significa apenas "novos recursos de hardware"!
Novos recursos que não podem ser bem validados usando os KVM selftests e/ou
KVM-unit-tests existentes devem vir acompanhados de testes.
Enviar o desenvolvimento de novos recursos sem testes para obter feedback
antecipado é mais do que bem-vindo, mas tais submissões devem ser marcadas como
RFC, e a carta de apresentação (cover letter) deve declarar claramente que tipo
de feedback é solicitado/esperado. Não abuse do processo de RFC; as RFCs
normalmente não receberão uma revisão profunda.
Correções de Bugs
~~~~~~~~~~~~~~~~~
Exceto por bugs "óbvios" encontrados por inspeção, as correções devem vir
acompanhadas de um reprodutor (reproducer) para o bug que está sendo corrigido.
Em muitos casos, o reprodutor é implícito, por exemplo, para erros de build e
falhas de teste, mas ainda assim deve estar claro para os leitores o que está
quebrado e como verificar a correção. Alguma margem de manobra é dada para
bugs encontrados através de cargas de trabalho ou testes não públicos, mas a
disponibilização de testes de regressão para tais bugs é fortemente preferida.
Em geral, testes de regressão são preferidos para qualquer bug que não seja
trivial de ser atingido. Por exemplo, mesmo que o bug tenha sido originalmente
encontrado por um fuzzer como o syzkaller, um teste de regressão direcionado
pode ser justificável se o bug exigir que se atinja uma condição de corrida do
tipo "uma em um milhão".
Note que os bugs do KVM raramente são urgentes *e* não triviais de reproduzir.
Pergunte a si mesmo se um bug é realmente o fim do mundo antes de enviar uma
correção sem um reprodutor.
Postagem
--------
Links
~~~~~
Não faça referência explícita a relatórios de bugs, versões anteriores de um
patch/série, etc., através de cabeçalhos ``In-Reply-To:``. O uso de
``In-Reply-To:`` torna-se uma bagunça infernal para grandes séries e/ou quando
o número de versões aumenta, e o ``In-Reply-To:`` é inútil para qualquer
pessoa que não tenha a mensagem original, por exemplo, se alguém não estava
em cópia (Cc) no relatório do bug ou se a lista de destinatários mudar entre
as versões.
Para vincular a um relatório de bug, versão anterior ou qualquer coisa de
interesse, use links do lore. Para referenciar versão(ões) anterior(es), de modo
geral, não inclua um Link: no changelog, pois não há necessidade de registrar o
histórico no git; ou seja, coloque o link na carta de apresentação (cover
letter) ou na seção que o git ignora. Forneça um Link: formal para relatórios
de bugs e/ou discussões que levaram ao patch. O contexto de por que uma mudança
foi feita é altamente valioso para futuros leitores.
Base do Git (Git Base)
~~~~~~~~~~~~~~~~~~~~~~
Se você estiver usando o git versão 2.9.0 ou posterior (Googlers, isso inclui
todos vocês!), use ``git format-patch`` com a flag ``--base`` para incluir
automaticamente as informações da árvore base nos patches gerados.
Note que ``--base=auto`` funciona conforme o esperado se, e somente se, o
upstream de uma branch estiver definido para a branch de tópico base; por
exemplo, ele fará a coisa errada se o seu upstream estiver definido para o seu
repositório pessoal para fins de backup. Uma solução "auto" alternativa é
derivar os nomes das suas branches de desenvolvimento com base no seu tópico
KVM x86 e alimentar isso no ``--base``. Por exemplo,
``x86/pmu/minha_branch`` e, em seguida, escrever um pequeno wrapper para
extrair ``pmu`` do nome da branch atual para resultar em ``--base=x/pmu``, onde
``x`` é o nome que seu repositório usa para rastrear o remoto do KVM x86.
Postagem Conjunta de Testes
~~~~~~~~~~~~~~~~~~~~~~~~~~~
KVM selftests que estão associados a mudanças no KVM, por exemplo, testes de
regressão para correções de bugs, devem ser postados junto com as mudanças do
KVM como uma única série. As regras padrão do kernel para bissecção (bisection)
se aplicam, ou seja, mudanças no KVM que resultem em falhas de teste devem ser
ordenadas após as atualizações dos selftests e, vice-versa, novos testes que
falhem devido a bugs do KVM devem ser ordenados após as correções do KVM.
KVM-unit-tests devem *sempre* ser postados separadamente. Ferramentas, como o
b4 am, não sabem que o KVM-unit-tests é um repositório separado e ficam
confusas quando os patches de uma série se aplicam a árvores diferentes. Para
vincular os patches do KVM-unit-tests aos patches do KVM, poste primeiro as
mudanças do KVM e, em seguida, forneça um link do lore para o patch/série do
KVM no(s) patch(es) do KVM-unit-tests.
Notificações
------------
Quando um patch/série é oficialmente aceito, um e-mail de notificação será
enviado em resposta à postagem original (carta de apresentação para séries de
múltiplos patches). A notificação incluirá a árvore e a branch de tópico,
juntamente com os SHA1s dos commits dos patches aplicados.
Se um subconjunto de patches for aplicado, isso será claramente declarado na
notificação. A menos que seja dito o contrário, subentende-se que quaisquer
patches na série que não foram aceitos precisam de mais trabalho e devem ser
enviados em uma nova versão.
Se, por algum motivo, um patch for descartado após ter sido oficialmente
aceito, uma resposta será enviada ao e-mail de notificação explicando o porquê
do descarte, bem como os próximos passos.
Estabilidade de SHA1
~~~~~~~~~~~~~~~~~~~~
Os SHA1s não têm garantia de serem 100% estáveis até que cheguem na árvore do
Linus! Um SHA1 é *geralmente* estável uma vez que a notificação tenha sido
enviada, mas imprevistos acontecem. Na maioria dos casos, uma atualização no
e-mail de notificação será fornecida se o SHA1 de um patch aplicado mudar. No
entanto, em alguns cenários, por exemplo, se todas as branches do KVM x86
precisarem de rebase, as notificações individuais não serão enviadas.
Vulnerabilidades
----------------
Bugs que podem ser explorados pelo convidado (guest) para atacar o hospedeiro
(host) (kernel ou espaço do usuário), ou que podem ser explorados por uma VM
aninhada (nested) contra o *seu* próprio hospedeiro (L2 atacando L1), são de
interesse particular para o KVM. Por favor, siga o protocolo em
:ref:`securitybugs` se você suspeitar que um bug possa levar a um escape,
vazamento de dados, etc.

View File

@ -0,0 +1,596 @@
.. SPDX-License-Identifier: GPL-2.0
=====================================
Subsistema de Rede do Linux (netdev)
=====================================
tl;dr
-----
- **Direcione seu patch para uma árvore** use ``[PATCH net]``para correções
ou ``[PATCH net-next]`` para novas funcionalidades.
- **Tag Fixes** para correções, a tag ``Fixes:`` é obrigatória,
independentemente da árvore de destino.
- **Tamanho da série** não envie séries grandes (> 15 patches);divida-as em
partes menores.
- **Intervalo de envio** não reenvie seus patches dentro de um período de 24
horas.
- **Reverse xmas tree** organize as declarações de variáveis locais da mais
longa para a mais curta.
netdev
------
A **netdev** é a lista de discussão para todos os assuntos do Linux relacionados
a rede. Isso inclui qualquer item encontrado em ``net/`` (ex: código principal
como IPv6) e em ``drivers/net`` (ex: drivers específicos de hardware) na árvore
de diretórios do Linux.
Note que alguns subsistemas (ex: drivers de rede sem fio/wireless), que possuem
um alto volume de tráfego, possuem suas próprias listas de discussão e árvores
específicas.
Como muitas outras listas de discussão do Linux, a lista netdev é hospedada no
`kernel.org <https://www.kernel.org/>`_, com arquivos disponíveis em
https://lore.kernel.org/netdev/.
À exceção dos subsistemas mencionados anteriormente, todo o desenvolvimento de
rede do Linux (ex: RFCs, revisões, comentários, etc.) ocorre na **netdev**.
Ciclo de Desenvolvimento
------------------------
Aqui está um pouco de informação contextual sobre a cadência de desenvolvimento
do Linux. Cada nova versão (release) inicia-se com uma "janela de mesclagem"
(*merge window*) de duas semanas, onde os mantenedores principais enviam suas
novas implementações para o Linus para incorporação na árvore principal
(*mainline tree*).
Após as duas semanas, a janela de mesclagem é fechada e a versão é
nomeada/etiquetada como ``-rc1``. Nenhuma funcionalidade nova é incorporada à
árvore principal após isso -- espera-se apenas correções (*fixes*) para o
conteúdo da rc1.
Após cerca de uma semana coletando correções para a rc1, a rc2 é lançada. Isso
se repete semanalmente até a rc7 (tipicamente; às vezes rc6 se o ritmo estiver
calmo, ou rc8 se houver muita instabilidade); uma semana após a última vX.Y-rcN
ser concluída, a versão oficial vX.Y é lançada.
Para descobrir em que ponto do ciclo estamos agora - carregue a página da
mainline (Linus) aqui:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
e observe o topo da seção de "tags". Se for rc1, estamos no início do ciclo
de desenvolvimento. Se a rc7 foi marcada há uma semana, então um lançamento
é provavelmente iminente. Se a tag mais recente for uma tag de lançamento
final (sem o sufixo ``-rcN``) - muito provavelmente estamos em uma janela de
mesclagem (*merge window*) e o ``net-next`` está fechado.
Árvores git e fluxo de patches
------------------------------
Existem duas árvores de rede (repositórios git) em jogo. Ambas são coordenadas
por David Miller, o mantenedor principal de rede. Há a árvore ``net``e a árvore
``net-next``. Como você provavelmente pode adivinhar pelos nomes, a árvore
``net`` é para correções de código existente já na árvore mainline de Linus, e a
``net-next`` é para onde o novo código vai para o lançamento futuro.
Você pode encontrar as árvores aqui:
- https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
- https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
Relacionando isso ao desenvolvimento do kernel: no início da janela de mesclagem
(*merge window*) de 2 semanas, a árvore ``net-next`` será fechada, sem novas
mudanças ou funcionalidades. O conteúdo novo acumulado nas últimas 10 semanas
será passado para a mainline/Linus via um *pull request* para a vX.Y ao mesmo
tempo, a árvore ``net`` começará a acumular correções para este conteúdo enviado
relacionado à vX.Y.
Um anúncio indicando quando a ``net-next`` foi fechada é geralmente enviado para
a netdev, mas sabendo o que foi dito acima, você pode prever isso com
antecedência.
.. warning::
Não envie novo conteúdo para a ``net-next`` para a netdev durante o período
em que a árvore ``net-next`` estiver fechada.
Patches RFC enviados apenas para revisão são obviamente bem-vindos a qualquer
momento (use ``--subject-prefix='RFC net-next'`` com ``git format-patch``).
Pouco depois das duas semanas terem passado (e a vX.Y-rc1 ser lançada), a árvore
para a ``net-next`` reabre para coletar conteúdo para o próximo lançamento
(vX.Y+1).
Se você não estiver inscrito na netdev e/ou simplesmente não tiver certeza se a
``net-next`` já reabriu, basta verificar o link do repositório git da
``net-next`` acima para quaisquer novos *commits* relacionados à rede. Você
também pode verificar o seguinte site para o status atual:
https://netdev.bots.linux.dev/net-next.html
A árvore ``net`` continua a coletar correções para o conteúdo da vX.Y e é
enviada de volta para Linus em intervalos regulares (~semanais). Isso significa
que o foco da ``net`` é a estabilização e correções de bugs.
Finalmente, a vX.Y é lançada e todo o ciclo recomeça.
Revisão de patches da netdev
----------------------------
Status do patch
~~~~~~~~~~~~~~~
O status de um patch pode ser verificado olhando a fila principal do patchwork
para a netdev:
https://patchwork.kernel.org/project/netdevbpf/list/
O campo "State" informará exatamente onde as coisas estão com o seu patch:
================= ============================================================
Estado do patch Descrição
================= ============================================================
New, Under review revisão pendente, o patch está na fila do mantenedor
para revisão; os dois estados são usados alternadamente
(dependendo do co-mantenedor exato que estiver lidando
com o patchwork no momento)
Accepted o patch foi aplicado à árvore de rede apropriada,
isso é geralmente definido de forma automática pelo pw-bot
Needs ACK aguardando um "ack" de um especialista da área
ou testes
Changes requested o patch não passou na revisão, espera-se uma nova
revisão com mudanças apropriadas no código e na mensagem
de commit
Rejected o patch foi rejeitado e não se espera uma nova
revisão
Not applicable espera-se que o patch seja aplicado fora do
subsistema de rede
Awaiting upstream o patch deve ser revisado e tratado pelo sub-mantenedor
apropriado, que o enviará para as árvores de rede;
patches definidos como ``Awaiting upstream`` no patchwork
da netdev geralmente permanecerão neste estado,
independentemente de o sub-mantenedor ter solicitado
mudanças, aceito ou rejeitado o patch
Deferred o patch precisa ser reenviado mais tarde, geralmente
devido a alguma dependência ou porque foi enviado para
uma árvore fechada
Superseded uma nova versão do patch foi enviada, geralmente
definido pelo pw-bot
RFC não deve ser aplicado, geralmente não está na
fila de revisão do mantenedor; o pw-bot pode definir
patches para este estado automaticamente com base nas
tags do assunto
================= ============================================================
Os patches são indexados pelo cabeçalho ``Message-ID`` dos e-mails que os
transportaram; portanto, se você tiver problemas para encontrar seu patch,
anexe o valor do ``Message-ID`` à URL acima.
Atualizando o status do patch
-----------------------------
Colaboradores e revisores não têm permissões para atualizar o estado do patch
diretamente no patchwork. O Patchwork não expõe muitas informações sobre o
histórico do estado dos patches; portanto, ter várias pessoas atualizando o
estado leva a confusões.
Em vez de delegar permissões do patchwork, a netdev usa um robô de e-mail
simples (bot) que procura por comandos/linhas especiais dentro dos e-mails
enviados para a lista de discussão. Por exemplo, para marcar uma série como
Mudanças Solicitadas (*Changes Requested*), é necessário enviar a seguinte
linha em qualquer lugar na thread do e-mail::
pw-bot: changes-requested
Como resultado, o bot definirá toda a série como Mudanças Solicitadas. Isso
pode ser útil quando o autor descobre um bug em sua própria série e deseja
evitar que ela seja aplicada.
O uso do bot é totalmente opcional; em caso de dúvida, ignore completamente a
existência dele. Os mantenedores classificarão e atualizarão o estado dos
patches por conta própria. Nenhum e-mail deve ser enviado à lista com o
propósito principal de se comunicar com o bot; os comandos do bot devem ser
vistos como metadados.
O uso do bot é restrito aos autores dos patches (o cabeçalho ``From:`` no envio
do patch e no comando deve coincidir!), mantenedores do código modificado de
acordo com o arquivo MAINTAINERS (novamente, o ``From:`` deve coincidir
com a entrada no MAINTAINERS) e alguns revisores seniores.
O bot registra sua atividade aqui:
https://netdev.bots.linux.dev/pw-bot.html
Prazos de revisão
~~~~~~~~~~~~~~~~~
De modo geral, os patches são triados rapidamente (em menos de 48h). Mas
seja paciente; se o seu patch estiver ativo no patchwork (ou seja, listado
na lista de patches do projeto), as chances de ele ter sido esquecido são
próximas de zero.
O alto volume de desenvolvimento na netdev faz com que os revisores encerrem
discussões de forma relativamente rápida. É muito improvável que novos
comentários e respostas cheguem após uma semana de silêncio. Se um
patch não estiver mais ativo no patchwork e a thread ficar inativa por mais de
uma semana - esclareça os próximos passos e/ou envie a próxima versão.
Especificamente para envios de RFC, se ninguém responder em uma semana ou os
revisores perderam o envio ou não têm opiniões fortes a respeito. Se o código
estiver pronto, reenvie como um PATCH.
E-mails dizendo apenas "ping" ou "bump" são considerados rudes. Se você não
conseguir identificar o status do patch pelo patchwork ou onde a discussão
parou - descreva sua melhor suposição e pergunte se ela está correta. Por
exemplo::
Não entendo quais são os próximos passos. A Pessoa X parece estar descontente
com A; devo fazer B e enviar novamente os patches?
.. _Solicitações de mudanças:
Mudanças solicitadas
~~~~~~~~~~~~~~~~~~~~
Patches marcados como ``Changes Requested`` precisam ser revisados. A nova
versão deve vir com um registro de alterações (changelog),
preferencialmente incluindo links para as postagens anteriores, por exemplo::
[PATCH net-next v3] net: faz as vacas dizerem "muuu"
Mesmo os usuários que não bebem leite apreciam ouvir as vacas dizendo
"muuu".
A quantidade de mugidos dependerá da taxa de pacotes, portanto, deve
corresponder muito bem ao ciclo diurno.
Signed-off-by: Joe Defarmer <joe@barn.org>
---
v3:
- adicionada uma nota sobre a flutuação do mugido conforme a hora
do dia na
mensagem de commit
v2: https://lore.kernel.org/netdev/123themessageid@barn.org/
- corrigido argumento ausente na kernel doc para netif_is_bovine()
- corrigido vazamento de memória (memory leak) em
netdev_register_cow()
v1: https://lore.kernel.org/netdev/456getstheclicks@barn.org/
A mensagem de commit deve ser revisada para responder a quaisquer perguntas que
os revisores tenham feito em discussões anteriores. Ocasionalmente, a
atualização da mensagem de commit será a única mudança na nova versão.
Reenvios parciais
~~~~~~~~~~~~~~~~~
Por favor, sempre reenvie a série completa de patches e certifique-se de
numerar seus patches de forma que fique claro que este é o conjunto mais
recente e completo de patches que pode ser aplicado. Não tente reenviar apenas
os patches que foram alterados.
Lidando com patches aplicados incorretamente
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ocasionalmente, uma série de patches é aplicada antes de receber feedback
crítico, ou a versão errada de uma série é aplicada.
Não é possível fazer o patch desaparecer uma vez que ele foi enviado (pushed);
o histórico de commits nas árvores netdev é imutável. Por favor, envie versões
incrementais sobre o que foi mesclado para corrigir os patches da maneira que
eles ficariam se a sua série de patches mais recente fosse mesclada.
Em casos onde uma reversão completa (revert) é necessária, a reversão deve ser
enviada como um patch para a lista com uma mensagem de commit explicando os
problemas técnicos com o commit revertido. Reversões devem ser usadas como
último recurso, quando a mudança original está completamente errada; correções
incrementais são preferidas.
Árvore estável
~~~~~~~~~~~~~~
Embora antigamente as submissões para a netdev não devessem carregar tags
explícitas ``CC: stable@vger.kernel.org``, esse não é mais o caso hoje em dia.
Por favor, siga as regras padrão de estabilidade em
``Documentation/process/stable-kernel-rules.rst``, e certifique-se de incluir as
tags Fixes apropriadas!
Correções de segurança
~~~~~~~~~~~~~~~~~~~~~~
Não envie e-mails diretamente para os mantenedores da netdev se você acha que
descobriu um bug que possa ter possíveis implicações de segurança. O atual
mantenedor da netdev tem solicitado consistentemente que as pessoas usem as
listas de discussão e não entrem em contato diretamente. Se você não estiver
de acordo com isso, considere enviar um e-mail para security@kernel.org ou
ler sobre http://oss-security.openwall.org/wiki/mailing-lists/distros como
possíveis mecanismos alternativos.
Envio conjunto de mudanças em componentes de espaço do usuário
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
O código de espaço do usuário (*user space*) que exercita funcionalidades do
kernel deve ser enviado juntamente com os patches do kernel. Isso dá aos
revisores a chance de ver como qualquer nova interface é usada e quão
bem ela funciona.
Quando as ferramentas de espaço do usuário residem no próprio repositório do
kernel, todas as alterações devem geralmente vir em uma única série. Se a série
se tornar muito grande ou se o projeto de espaço do usuário não for revisado na
netdev, inclua um link para um repositório público onde os patches de espaço do
usuário possam ser vistos.
No caso de ferramentas de espaço do usuário residirem em um repositório
separado, mas serem revisadas na netdev (por exemplo, patches para ferramentas
``iproute2``), os patches do kernel e do espaço do usuário devem formar séries
(threads) separadas quando postados na lista de discussão, por exemplo::
[PATCH net-next 0/3] net: carta de apresentação de alguma funcionalidade
└─ [PATCH net-next 1/3] net: preparação para alguma funcionalidade
└─ [PATCH net-next 2/3] net: implementação de alguma funcionalidade
└─ [PATCH net-next 3/3] selftest: net: alguma funcionalidade
[PATCH iproute2-next] ip: adiciona suporte para alguma funcionalidade
A postagem em uma única thread é desencorajada porque confunde o patchwork
(a partir da versão 2.2.2 do patchwork).
Envio conjunto de selftests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Os selftests devem fazer parte da mesma série que as mudanças de código.
Especificamente para correções, tanto a mudança de código quanto o teste
relacionado devem ir para a mesma árvore (os testes podem não ter uma tag
Fixes, o que é esperado). Misturar mudanças de código e mudanças de teste em
um único commit é desencorajado.
Preparando as mudanças
----------------------
Atenção aos detalhes é importante. Releia seu próprio trabalho como se você
fosse o revisor. Você pode começar usando o ``checkpatch.pl``, talvez até com
a flag ``--strict``. Mas não seja robótico e irracional ao fazer isso. Se sua
mudança for uma correção de bug, certifique-se de que seu log de commit indique
o sintoma visível para o usuário final, a razão subjacente de por que isso
acontece e, se necessário, explique por que a correção proposta é a melhor
maneira de resolver as coisas. Não corrompa espaços em branco e, como é comum,
não use recuos incorretos em argumentos de função que abrangem várias linhas.
Se for o seu primeiro patch, envie-o para si mesmo por e-mail para que você
possa testar a aplicação em uma árvore sem patches para confirmar que a
infraestrutura não o danificou.
Finalmente, volte e leia ``Documentation/process/submitting-patches.rst``
para ter certeza de que não está repetindo algum erro comum documentado lá.
Indicando a árvore de destino
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Para ajudar os mantenedores e os bots de CI, você deve marcar explicitamente
qual árvore seu patch tem como alvo. Supondo que você use git, utilize a flag
de prefixo::
git format-patch --subject-prefix='PATCH net-next' inicio..fim
Use ``net`` em vez de ``net-next`` (sempre em letras minúsculas) no comando
acima para conteúdos de correção de bugs da árvore ``net``.
Dividindo o trabalho em patches
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Coloque-se no lugar do revisor. Cada patch é lido separadamente e, portanto,
deve constituir um passo compreensível em direção ao seu objetivo declarado.
Evite enviar séries com mais de 15 patches. Séries maiores levam mais tempo
para serem revisadas, pois os revisores adiarão a análise até encontrarem um
grande bloco de tempo disponível. Uma série pequena pode ser revisada em pouco
tempo, então os mantenedores simplesmente a revisam de imediato. Como resultado,
uma sequência de séries menores é mesclada mais rapidamente e com melhor
cobertura de revisão. Reenviar séries grandes também aumenta o tráfego na lista
de discussão.
Limitar patches pendentes na lista de discussão
-----------------------------------------------
Evite ter mais de 15 patches, em todas as séries, pendentes de revisão na lista
de discussão para uma única árvore. Em outras palavras, um máximo de 15 patches
sob revisão na ``net`` e um máximo de 15 patches sob revisão na ``net-next``.
Este limite tem o objetivo de focar o esforço do desenvolvedor nos testes dos
patches antes da revisão upstream, auxiliando a qualidade das submissões
upstream e aliviando a carga sobre os revisores.
Ordenação de variáveis locais ("árvore invertida", "RCS")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A netdev tem uma convenção para ordenar variáveis locais em funções. Ordene as
linhas de declaração de variáveis da mais longa para a mais curta, por exemplo::
struct scatterlist *sg;
struct sk_buff *skb;
int err, i;
Se houver dependências entre as variáveis que impeçam a ordenação, mova a
inicialização para fora da linha de declaração.
Precedência de formatação
~~~~~~~~~~~~~~~~~~~~~~~~~
Ao trabalhar em código existente que utiliza formatação não padrão, faça com
que seu código siga as diretrizes mais recentes, para que, eventualmente,
todo o código no domínio da netdev esteja no formato preferido.
Uso de construções gerenciadas por dispositivo e cleanup.h
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Historicamente, a netdev permanece cética em relação às promessas de todas as
APIs de "auto-limpeza" (auto-cleanup), incluindo até mesmo os auxiliares
``devm_``. Eles não são o estilo preferido de implementação, apenas um estilo
aceitável.
O uso de ``guard()`` é desencorajado em qualquer função com mais de 20 linhas;
``scoped_guard()`` é considerado mais legível. O uso de lock/unlock normal
ainda é (levemente) preferido.
Construções de limpeza de baixo nível (como ``__free()``) podem ser usadas ao
construir APIs e auxiliares, especialmente iteradores com escopo. No entanto, o
uso direto de ``__free()`` dentro do núcleo de rede (networking core) e drivers
é desencorajado. Orientações semelhantes se aplicam à declaração de variáveis
no meio da função.
Patches de limpeza (Clean-up patches)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A netdev desencoraja patches que realizam limpezas simples que não estejam no
contexto de outro trabalho. Por exemplo:
* Tratar avisos do ``checkpatch.pl`` e outros avisos triviais de estilo de
codificação
* Tratar problemas de Ordenação de variáveis locais
* Conversões para APIs gerenciadas por dispositivo (auxiliares ``devm_``)
Isso ocorre porque se considera que a agitação (*churn*) que tais mudanças
produzem tem um custo maior do que o valor de tais limpezas.
Por outro lado, correções de ortografia e gramática não são desencorajadas.
Reenviando após a revisão
~~~~~~~~~~~~~~~~~~~~~~~~~
Aguarde pelo menos 24 horas entre as postagens. Isso garantirá que revisores de
todas as localizações geográficas tenham a chance de se manifestar. Não espere
muito tempo (semanas) entre as postagens, pois isso tornará mais difícil para
os revisores lembrarem de todo o contexto.
Certifique-se de tratar todo o feedback em sua nova postagem. Não envie uma
nova versão do código se a discussão sobre a versão anterior ainda estiver em
andamento, a menos que seja instruído diretamente por um revisor.
A nova versão dos patches deve ser postada como uma thread separada, não como
uma resposta à postagem anterior. O registro de alterações (changelog) deve
incluir um link para a postagem anterior (veja :ref:`Solicitações
de mudanças`).
Testes
------
Nível de teste esperado
~~~~~~~~~~~~~~~~~~~~~~~
No mínimo, suas alterações devem passar por uma compilação ``allyesconfig`` e
uma ``allmodconfig`` com ``W=1`` definido, sem novos avisos ou falhas.
O ideal é que você tenha feito testes em tempo de execução específicos para sua
alteração, e que a série de patches contenha um conjunto de selftests do kernel
para ``tools/testing/selftests/net`` ou usando o framework KUnit.
Espera-se que você teste suas alterações no topo da árvore de rede relevante
(``net`` ou ``net-next``) e não, por exemplo, em uma árvore estável ou na
``linux-next``.
Verificações do patchwork
~~~~~~~~~~~~~~~~~~~~~~~~~
As verificações (*checks*) no patchwork são, em sua maioria, wrappers simples
em torno de scripts existentes do kernel; as fontes estão disponíveis em:
https://github.com/linux-netdev/nipa/tree/master/tests
**Não** envie seus patches apenas para executá-los nas verificações. Você deve
garantir que seus patches estejam prontos, testando-os localmente antes de
postar na lista de discussão. A instância do bot de build do patchwork fica
sobrecarregada com muita facilidade e a netdev@vger realmente não precisa de
mais tráfego se pudermos evitar.
netdevsim
~~~~~~~~~
O ``netdevsim`` é um driver de teste que pode ser usado para exercitar APIs de
configuração de driver sem a necessidade de hardware compatível. Mock-ups e
testes baseados no ``netdevsim`` são fortemente encorajados ao adicionar novas
APIs, mas o ``netdevsim`` em si **não** é considerado um caso de uso/usuário.
Você também deve implementar as novas APIs em um driver real.
Não damos garantias de que o ``netdevsim`` mudará no futuro de uma forma que
quebraria o que normalmente seria considerado uAPI. O ``netdevsim`` é reservado
apenas para uso por testes upstream, portanto, quaisquer novos recursos do
``netdevsim`` devem ser acompanhados de selftests em ``tools/testing/selftests/``.
Status de suporte para drivers
------------------------------
.. note:
Os requisitos a seguir aplicam-se apenas a drivers de NIC Ethernet.
A netdev define requisitos adicionais para drivers que desejam adquirir o status
``Supported`` (Suportado) no arquivo MAINTAINERS. Drivers ``Supported`` devem
executar todos os testes de driver upstream e relatar os resultados duas vezes
por dia. Drivers que não cumprirem este requisito devem usar o status
``Maintained`` (Mantido). Atualmente, não há diferença na forma como os drivers
``Supported`` e ``Maintained`` são tratados no upstream.
As regras exatas que um driver deve seguir para adquirir o status ``Supported``:
1. Deve executar todos os testes sob os alvos ``drivers/net`` e
``drivers/net/hw`` dos selftests do Linux. A execução e o relato
de testes privados / internos também são bem-vindos, mas os testes
upstream são obrigatórios.
2. A frequência mínima de execução é uma vez a cada 12 horas. Deve
testar o branch designado a partir do feed de branches selecionado.
Observe que os branches são construídos automaticamente e estão
expostos à postagem intencional de patches maliciosos; portanto,
os sistemas de teste devem ser isolados.
3. Drivers que suportam múltiplas gerações de dispositivos devem
testar pelo menos um dispositivo de cada geração. Um manifesto do
ambiente de teste (*testbed manifest* - formato exato a definir)
deve descrever os modelos de dispositivos testados.
4. Os testes devem ser executados de forma confiável; se múltiplos
branches forem ignorados ou se os testes falharem devido a problemas
no ambiente de execução, o status ``Supported`` será retirado.
5. Falhas nos testes devido a bugs no driver ou no próprio teste,
ou falta de suporte para a funcionalidade que o teste visa, *não*
são motivo para a perda do status ``Supported``.
O CI da netdev manterá uma página oficial de dispositivos suportados, listando
seus resultados de testes recentes.
O mantenedor do driver pode providenciar para que outra pessoa execute o teste;
não há exigência de que a pessoa listada como mantenedora (ou seu empregador)
seja responsável pela execução dos testes. Colaborações entre
fornecedores, hospedagem de CI no GitHub (GH CI), outros repositórios sob o
linux-netdev, etc., são muito bem-vindas.
Veja https://github.com/linux-netdev/nipa/wiki para mais informações sobre o CI
da netdev. Sinta-se à vontade para entrar em contato com os mantenedores ou com
a lista para quaisquer dúvidas.
Orientações para revisores
--------------------------
Revisar patches de outras pessoas na lista é altamente incentivado,
independentemente do nível de experiência. Para orientações gerais e dicas
úteis, consulte `revisão de tópicos avançados de desenvolvimento`.
É seguro assumir que os mantenedores da netdev conhecem a comunidade e o nível
de experiência dos revisores. Os revisores não devem se preocupar com o fato de
seus comentários impedirem ou desviarem o fluxo de patches. Revisores menos
experientes são fortemente incentivados a fazer uma revisão mais aprofundada das
submissões e não focar exclusivamente em questões triviais ou subjetivas, como
formatação de código, tags, etc.
Depoimentos / feedback
----------------------
Algumas empresas utilizam o feedback de colegas em revisões de desempenho de
funcionários. Sinta-se à vontade para solicitar feedback dos mantenedores da
netdev, especialmente se você dedica uma quantidade significativa de tempo
revisando código e se esforça além do esperado para melhorar a infraestrutura
compartilhada.
O feedback deve ser solicitado por você, o colaborador, e será sempre
compartilhado com você (mesmo que você solicite que ele seja enviado ao seu
gerente).

View File

@ -0,0 +1,28 @@
.. SPDX-License-Identifier: GPL-2.0
=====================================================
Plataformas SoC com Requisitos de Conformidade de DTS
=====================================================
Visão Geral
-----------
As plataformas SoC ou subarquiteturas devem seguir todas as regras de
Documentation/process/maintainer-soc.rst. Este documento, referenciado em
MAINTAINERS, impõe requisitos adicionais listados abaixo.
Conformidade Estrita com DT Schema de DTS e dtc
-----------------------------------------------
Nenhuma alteração nos arquivos de origem do Devicetree da plataforma SoC
(arquivos DTS) deve introduzir novos avisos de ``make dtbs_check W=1``.
Avisos em um novo DTS de placa, que sejam resultado de problemas em um
arquivo DTSI incluído, são considerados avisos existentes, não novos.
Para séries divididas entre árvores diferentes (vínculos de DT seguem pela
árvore do subsistema de drivers), os avisos no linux-next são decisivos.
Os mantenedores da plataforma possuem automação implementada que deve
apontar quaisquer novos avisos.
Se um commit que introduz novos avisos for aceito de alguma forma, os
problemas resultantes deverão ser corrigidos em um tempo razoável
(por exemplo, dentro de um ciclo de lançamento) ou o commit será revertido.

View File

@ -0,0 +1,222 @@
.. SPDX-License-Identifier: GPL-2.0
==============
Subsistema SoC
==============
Visão Geral
-----------
O subsistema SoC é um local de agregação para códigos específicos de SoC
System on Chip). Os principais componentes do subsistema são:
* Devicetrees (DTS) para ARM de 32 e 64 bits e RISC-V.
* Arquivos de placa (board files) ARM de 32 bits (arch/arm/mach*).
* Defconfigs ARM de 32 e 64 bits.
* Drivers específicos de SoC em diversas arquiteturas, em particular para ARM de
* 32 e 64 bits, RISC-V e Loongarch.
Estes "drivers específicos de SoC" não incluem drivers de clock, GPIO, etc., que
possuem outros mantenedores de alto nível. O diretório ``drivers/soc/`` é
geralmente destinado a drivers internos do kernel que são usados por outros
drivers para fornecer funcionalidades específicas do SoC, como identificar uma
revisão do chip ou fazer a interface com domínios de energia.
O subsistema SoC também serve como um local intermediário para alterações em
``drivers/bus``, ``drivers/firmware``, ``drivers/reset`` e ``drivers/memory``.
A adição de novas plataformas, ou a remoção de existentes, geralmente passa pela
árvore SoC como um branch dedicado cobrindo múltiplos subsistemas.
A árvore principal do SoC está hospedada no git.kernel.org:
https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/
Mantenedores
------------
Claramente, esta é uma gama bastante ampla de tópicos, que nenhuma pessoa, ou
mesmo um pequeno grupo de pessoas, é capaz de manter. Em vez disso, o
subsistema SoC é composto por muitos submantenedores (mantenedores de
plataforma), cada um cuidando de plataformas individuais e subdiretórios de
drivers.
Nesse sentido, "plataforma" geralmente se refere a uma série de SoCs de um
determinado fornecedor, por exemplo, a série de SoCs Tegra da Nvidia. Muitos
submantenedores operam em nível de fornecedor, sendo responsáveis por várias
linhas de produtos. Por diversos motivos, incluindo aquisições ou diferentes
unidades de negócios em uma empresa, as coisas variam significativamente aqui.
Os diversos submantenedores estão documentados no arquivo ``MAINTAINERS``.
A maioria desses submantenedores possui suas próprias árvores onde preparam os
patches, enviando pull requests para a árvore SoC principal. Essas árvores são
geralmente, mas nem sempre, listadas em ``MAINTAINERS``.
O que a árvore SoC não é, contudo, é um local para alterações de código
específicas da arquitetura. Cada arquitetura possui seus próprios mantenedores
que são responsáveis pelos detalhes arquiteturais, erratas de CPU e afins.
Submetendo Patches para um Determinado SoC
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Todos os patches típicos relacionados à plataforma devem ser enviados por meio
dos submantenedores de SoC (mantenedores específicos da plataforma). Isso inclui
também alterações em defconfigs por plataforma ou compartilhadas. Note que
``scripts/get_maintainer.pl`` pode não fornecer os endereços corretos para a
defconfig compartilhada; portanto, ignore sua saída e crie manualmente a lista
de CC baseada no arquivo ``MAINTAINERS`` ou use algo como
``scripts/get_maintainer.pl -f drivers/soc/FOO/``.
Submetendo Patches para os Mantenedores Principais de SoC
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Os mantenedores principais de SoC podem ser contatados via o alias
soc@kernel.org apenas nos seguintes casos:
1. Não existem mantenedores específicos para a plataforma.
2. Os mantenedores específicos da plataforma não respondem.
3. Introdução de uma plataforma SoC completamente nova. Tal trabalho de novo SoC
deve ser enviado primeiro para as listas de discussão comuns, indicadas por
``scripts/get_maintainer.pl``, para revisão da comunidade. Após uma revisão
positiva da comunidade, o trabalho deve ser enviado para soc@kernel.org em
um único conjunto de patches (*patchset*) contendo a nova entrada em
``arch/foo/Kconfig``, arquivos DTS, entrada no arquivo ``MAINTAINERS`` e,
opcionalmente, drivers iniciais com seus respectivos bindings de Devicetree.
A entrada no arquivo ``MAINTAINERS`` deve listar os novos mantenedores
específicos da plataforma, que serão responsáveis por lidar com os patches
da plataforma de agora em diante.
Note que o endereço soc@kernel.org geralmente não é o local para discutir os
patches; portanto, o trabalho enviado para este endereço já deve ser
considerado aceitável pela comunidade.
Informações para (novos) Submantenedores
----------------------------------------
À medida que novas plataformas surgem, elas frequentemente trazem consigo novos
submantenedores, muitos dos quais trabalham para o fornecedor do silício e podem
não estar familiarizados com o processo.
Estabilidade da ABI do Devicetree
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Talvez um dos pontos mais importantes a destacar é que os *dt-bindings*
documentam a ABI entre o devicetree e o kernel. Por favor, leia
``Documentation/devicetree/bindings/ABI.rst``.
Se estiverem sendo feitas alterações em um DTS que sejam incompatíveis com
kernels antigos, o patch do DTS não deve ser aplicado até que o driver seja, ou
em um momento apropriado posterior. Mais importante ainda, quaisquer alterações
incompatíveis devem ser claramente apontadas na descrição do patch e no pull
request, juntamente com o impacto esperado nos usuários existentes, como
bootloaders ou outros sistemas operacionais.
Dependências de Branch de Driver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Um problema comum é a sincronização de alterações entre drivers de dispositivos
e arquivos de devicetree. Mesmo que uma alteração seja compatível em ambas as
direções, isso pode exigir a coordenação de como as mudanças são mescladas
através de diferentes árvores de mantenedores.
Geralmente, o branch que inclui uma alteração de driver também incluirá a
mudança correspondente na descrição do binding do devicetree, para garantir que
sejam, de fato, compatíveis. Isso significa que o branch do devicetree pode
acabar causando avisos na etapa ``make dtbs_check``. Se uma alteração de
devicetree depender de adições ausentes em um arquivo de cabeçalho em
``include/dt-bindings/``, ela falhará na etapa ``make dtbs`` e não será mesclada.
Existem várias maneiras de lidar com isso:
* Evite definir macros personalizadas em ``include/dt-bindings/`` para constantes
de hardware que podem ser derivadas de um datasheet -- macros de binding em
arquivos de cabeçalho devem ser usadas apenas como último recurso, se não
houver uma maneira natural de definir um binding.
* Use valores literais no arquivo devicetree em vez de macros, mesmo quando um
cabeçalho for necessário, e altere-os para a representação nomeada em um
lançamento posterior.
* Adie as alterações do devicetree para um lançamento após o binding e o driver
já terem sido mesclados.
* Altere os bindings em um branch imutável compartilhado que seja usado como
base tanto para a alteração do driver quanto para as alterações do devicetree.
* Adicione definições duplicadas no arquivo devicetree protegidas por uma seção
``#ifndef``, removendo-as em um lançamento posterior.
Convenção de Nomenclatura de Devicetree
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
O esquema geral de nomenclatura para arquivos de devicetree é o seguinte. Os
aspectos de uma plataforma que são definidos no nível do SoC, como núcleos de
CPU, são contidos em um arquivo nomeado ``$soc.dtsi``, por exemplo,
``jh7100.dtsi``. Detalhes de integração, que variam de placa para placa, são
descritos em ``$soc-$board.dts``. Um exemplo disso é
``jh7100-beaglev-starlight.dts``. Frequentemente, muitas placas são variações
de um mesmo tema, e é comum haver arquivos intermediários, como
``jh7100-common.dtsi``, que ficam entre os arquivos ``$soc.dtsi`` e
``$soc-$board.dts``, contendo as descrições de hardware comum.
Algumas plataformas também possuem *System on Modules* (SoM), contendo um SoC,
que são então integrados em diversas placas diferentes. Para essas plataformas,
``$soc-$som.dtsi`` e ``$soc-$som-$board.dts`` são típicos.
Os diretórios geralmente são nomeados após o fornecedor do SoC no momento de sua
inclusão, o que leva a alguns nomes de diretórios históricos na árvore.
Validando Arquivos de Devicetree
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``make dtbs_check`` pode ser usado para validar se os arquivos de devicetree
estão em conformidade com os *dt-bindings* que descrevem a ABI. Por favor, leia
a seção "Running checks" de ``Documentation/devicetree/bindings/writing-schema.rst``
para mais informações sobre a validação de devicetrees.
Para novas plataformas, ou adições a plataformas existentes, ``make dtbs_check``
não deve adicionar nenhum aviso (*warning*) novo. Para SoCs RISC-V e Samsung, é
exigido que ``make dtbs_check W=1`` não adicione nenhum novo aviso.
Se houver qualquer dúvida sobre uma alteração de devicetree, entre em contato
com os mantenedores de devicetree.
Branches e Pull Requests
~~~~~~~~~~~~~~~~~~~~~~~~
Assim como a árvore SoC principal possui vários branches, espera-se que os
submantenedores façam o mesmo. Alterações de drivers, defconfig e devicetree
devem ser todas divididas em branches separados e aparecer em pull requests
distintos para os mantenedores de SoC. Cada branch deve ser utilizável por si só
e evitar regressões originadas de dependências em outros branches.
Pequenos conjuntos de patches também podem ser enviados como e-mails separados
para soc@kernel.org, agrupados nas mesmas categorias.
Se as alterações não se encaixarem nos padrões normais, pode haver branches de
nível superior adicionais, por exemplo, para uma reformulação em toda a árvore
(*treewide rework*) ou a adição de novas plataformas SoC, incluindo arquivos dts
e drivers.
Branches com muitas alterações podem se beneficiar ao serem divididos em
branches de tópicos separados, mesmo que acabem sendo mesclados no mesmo branch
da árvore SoC. Um exemplo aqui seria um branch para correções de avisos de
devicetree, um para uma reformulação e um para placas recém-adicionadas.
Outra forma comum de dividir as alterações é enviar um pull request antecipado
com a maioria das mudanças em algum momento entre rc1 e rc4, seguido por um ou
mais pull requests menores no final do ciclo, que podem adicionar alterações
tardias ou resolver problemas identificados durante os testes do primeiro
conjunto.
Embora não haja um prazo limite para pull requests tardios, ajuda enviar apenas
branches pequenos à medida que o tempo se aproxima da janela de mesclagem
(*merge window*).
Pull requests para correções de bugs (*bugfixes*) da versão atual podem ser
enviados a qualquer momento, mas, novamente, ter múltiplos branches menores é
melhor do que tentar combinar muitos patches em um único pull request.
A linha de assunto de um pull request deve começar com "[GIT PULL]" e ser feita
usando uma tag assinada, em vez de um branch. Esta tag deve conter uma breve
descrição resumindo as alterações no pull request. Para mais detalhes sobre o
envio de pull requests, consulte ``Documentation/maintainer/pull-requests.rst``.

View File

@ -336,7 +336,8 @@ https://sparse.wiki.kernel.org/index.php/Main_Page si su distribución no lo
empaqueta); luego, puede ejecutarse en el código agregando "C=1" a su
comando make.
La herramienta "Coccinelle" (http://coccinelle.lip6.fr/) puede encontrar
La herramienta "Coccinelle" (https://coccinelle.gitlabpages.inria.fr/website/)
puede encontrar
una amplia variedad de posibles problemas de codificación; también puede
proponer correcciones para esos problemas. Bastantes "parches semánticos"
para el kernel se han empaquetado en el directorio scripts/coccinelle;

View File

@ -30,7 +30,7 @@ más sencilla.
Algunos subsistemas y árboles de mantenimiento cuentan con información
adicional sobre su flujo de trabajo y expectativas, consulte
:ref:`Documentation/process/maintainer-handbooks.rst <maintainer_handbooks_main>`.
Documentation/process/maintainer-handbooks.rst.
Obtenga el código fuente actual
--------------------------------

View File

@ -198,9 +198,9 @@ Esta es la lista parcial de llamadas:
- yield_task(...)
Esta función es básicamente desencolar, seguido por encolar, a menos que
sysctl compat_yield esté activado; en ese caso, sitúa la entidad a gestionar
en la parte más hacia la derecha del árbol rojo-negro.
Esta función cede la CPU desplazando la posición de la tarea actualmente
en ejecución hacia atrás en la cola de ejecución, para que otras tareas
ejecutables sean planificadas primero.
- check_preempt_curr(...)

View File

@ -154,7 +154,7 @@ Smatch和Coccinelle的强项
Coccinelle可能是最容易写检查的。它在预处理器之前工作所以用Coccinelle
检查宏中的错误更容易。Coccinelle还能为你创建补丁这是其他工具无法做到的。
例如用Coccinelle你可以从 ``kmalloc_array(x, size, GFP_KERNEL)``
例如用Coccinelle你可以从 ``kmalloc(x * size, GFP_KERNEL)``
``kmalloc_array(x, size, GFP_KERNEL)`` 进行大规模转换,这真的很
有用。如果你只是创建一个Smatch警告并试图把转换的工作推给维护者他们会很
恼火。你将不得不为每个警告争论是否真的可以溢出。

View File

@ -23,21 +23,18 @@
总览
----
内核开发人员使用一个松散的基于时间的发布过程,每两到三个月发布一次新的主要
内核版本。最近的发布历史记录如下:
内核开发使用一个松散的、基于时间的滚动发布rolling release开发模型。
一个新的主内核发行版本(作为示例,我们将其称为 9.x [1]_ 大约每两到三个月
发布一次,它带来了新特性、内部 API 的更改等。一个典型的版本包含大约 13,000
个变更集changesets涉及几十万行代码的修改。最近的发行版本及其日期可以
在这里找到
`维基百科 <https://en.wikipedia.org/wiki/Linux_kernel_version_history>`_
====== =================
5.0 2019年3月3日
5.1 2019年5月5日
5.2 2019年7月7日
5.3 2019年9月15日
5.4 2019年11月24日
5.5 2020年1月6日
====== =================
每个5.x版本都是一个主要的内核版本具有新特性、内部API更改等等。一个典型的5.x
版本包含大约13000个变更集变更了几十万行代码。因此5.x是Linux内核开发的前
沿;内核使用滚动开发模型,不断集成重大变化。
.. [1] 严格来说Linux 内核并不采用语义化版本号方案,而是将 9.x 这一组数字
作为一个整体来标识主发行版本号。对于每一个版本x 都会递增,但只有
当 x 被认为足够大时9 才会递增例如Linux 5.0 是紧随 Linux 4.20
之后发布的)。
对于每个版本的补丁合并,遵循一个相对简单的规则。在每个开发周期的开头,“合并
窗口”被打开。这时,被认为足够稳定(并且被开发社区接受)的代码被合并到主线内
@ -48,8 +45,8 @@
提前收集、测试和分级的。稍后将详细描述该过程的工作方式。)
合并窗口持续大约两周。在这段时间结束时Linus Torvalds将声明窗口已关闭
释放第一个“rc”内核。例如对于目标为5.6的内核,在合并窗口结束时发生的释放
将被称为5.6-rc1。-rc1 版本是一个信号,表示合并新特性的时间已经过去,稳定下一
释放第一个“rc”内核。例如对于目标为9.x的内核,在合并窗口结束时发生的释放
将被称为9.x-rc1。-rc1 版本是一个信号,表示合并新特性的时间已经过去,稳定下一
个内核的时间已经到来。
在接下来的6到10周内只有修复问题的补丁才应该提交给主线。有时会允许更大的
@ -84,11 +81,14 @@
开发人员的目标是在稳定发布之前修复所有已知的回归。在现实世界中,这种完美是
很难实现的;在这种规模的项目中,变数太多了。需要说明的是,延迟最终版本只会
使问题变得更糟;等待下一个合并窗口的更改将变多,导致下次出现更多的回归错误。
因此大多数5.x内核都有一些已知的回归错误不过希望没有一个是严重的。
因此,大多数内核发布时都会带有一部分已知的回归问题,不过希望它们都不是严重
的问题。
一旦一个稳定的版本发布,它的持续维护工作就被移交给“稳定团队”,目前由
Greg Kroah-Hartman领导。稳定团队将使用5.x.y编号方案不定期地发布稳定版本的
更新。要合入更新版本补丁必须1修复一个重要的缺陷2已经合并到
Greg Kroah-Hartman领导。稳定团队将使用9.x.y编号方案不定期地发布稳定版本的
更新。
要合入更新版本补丁必须1修复一个重要的缺陷2已经合并到
下一个开发版本主线中。内核通常会在其初始版本后的一个以上的开发周期内收到
稳定版更新。例如5.2内核的历史如下2019年
@ -105,17 +105,10 @@ Greg Kroah-Hartman领导。稳定团队将使用5.x.y编号方案不定期地发
5.2.21是5.2版本的最终稳定更新。
有些内核被指定为“长期”内核;它们将得到更长时间的支持。在本文中,当前的长期
内核及其维护者是
有些内核被指定为“长期”内核;它们将得到更长时间的支持。请参考以下链接
获取当前长期支持内核版本及其维护者的列表
====== ================================ ================
3.16 Ben Hutchings (长期稳定内核)
4.4 Greg Kroah-Hartman & Sasha Levin (长期稳定内核)
4.9 Greg Kroah-Hartman & Sasha Levin
4.14 Greg Kroah-Hartman & Sasha Levin
4.19 Greg Kroah-Hartman & Sasha Levin
5.4 Greg Kroah-Hartman & Sasha Levin
====== ================================ ================
https://www.kernel.org/category/releases.html
长期支持内核的选择纯粹是维护人员是否有需求和时间来维护该版本的问题。
目前还没有为即将发布的任何特定版本提供长期支持的已知计划。
@ -320,7 +313,8 @@ Quilt 是一个补丁管理系统,而不是源代码管理系统。它不会
没有完成家庭作业的人感到不耐烦。
- 避免顶部回复(把你的答案放在你要回复的引文上面的做法)。这会让你的回答更难
理解,印象也很差。
理解,印象也很差,详细请查看
:ref:`Documentation/process/submitting-patches.rst <interleaved_replies>`
- 在正确的邮件列表发问。linux-kernel 可能是通用的讨论场所,但它不是寻找所有
子系统开发人员的最佳场所。

View File

@ -216,7 +216,7 @@ Documentation/fault-injection/fault-injection.rst。
可以在 https://sparse.wiki.kernel.org/index.php/Main_page 找到),
然后可以通过在make命令中添加“C=1”在代码上运行它。
“Coccinelle”工具 :ref:`http://coccinelle.lip6.fr/ <devtools_coccinelle>`
“Coccinelle”工具 :ref:`https://coccinelle.gitlabpages.inria.fr/website/ <devtools_coccinelle>`
能够发现各种潜在的编码问题;它还可以为这些问题提出修复方案。在
scripts/coccinelle目录下已经打包了相当多的内核“语义补丁”运行
“make coccicheck”将运行这些语义补丁并报告发现的任何问题。有关详细信息请参阅

View File

@ -19,9 +19,10 @@
============= ================ ==============================================
架构 支持水平 限制因素
============= ================ ==============================================
``arm64`` Maintained 只有小端序
``arm`` Maintained 仅 ARMv7 小端序。
``arm64`` Maintained 仅小端序。
``loongarch`` Maintained \-
``riscv`` Maintained 只有 ``riscv64``
``um`` Maintained 只有 ``x86_64``
``x86`` Maintained 只有 ``x86_64``
``riscv`` Maintained ``riscv64``,且仅限 LLVM/Clang。
``um`` Maintained \-
``x86`` Maintained ``x86_64``
============= ================ ==============================================

View File

@ -37,6 +37,73 @@
像内核其他部分的 ``clang-format`` 一样, ``rustfmt`` 在单个文件上工作,并且不需要
内核配置。有时,它甚至可以与破碎的代码一起工作。
导入
~~~~
``rustfmt`` 默认会以一种在合并和变基时容易产生冲突的方式格式化导入,因为在某些情况下
它会将多个条目合并到同一行。例如:
.. code-block:: rust
// Do not use this style.
use crate::{
example1,
example2::{example3, example4, example5},
example6, example7,
example8::example9,
};
相反,内核使用如下所示的垂直布局:
.. code-block:: rust
use crate::{
example1,
example2::{
example3,
example4,
example5, //
},
example6,
example7,
example8::example9, //
};
也就是说,每个条目占一行,只要列表中有多个条目就使用花括号。
末尾的空注释可以保留这种格式。不仅如此, ``rustfmt`` 在添加空注释后实际上会将导入重
新格式化为垂直布局。也就是说,可以通过对如下输入运行 ``rustfmt`` 来轻松地将原始示例
重新格式化为预期的风格:
.. code-block:: rust
// Do not use this style.
use crate::{
example1,
example2::{example3, example4, example5, //
},
example6, example7,
example8::example9, //
};
末尾的空注释适用于嵌套导入(如上所示)以及单条目导入——这有助于最小化补丁系列中的差
异:
.. code-block:: rust
use crate::{
example1, //
};
末尾的空注释可以放在花括号内的任何一行中,但建议放在最后一个条目上,因为这让人联想到其
他格式化工具中的末尾逗号。有时在补丁系列中由于列表的变更,避免多次移动注释可能更简单。
在某些情况下可能需要例外处理,即以上都不是硬性规则。也有一些代码尚未迁移到这种风格,但
请不要引入其他风格的代码。
最终目标是让 ``rustfmt`` 在稳定版本中自动支持这种格式化风格(或类似的风格),而无需
末尾的空注释。因此,在某个时候,目标是移除这些注释。
注释
----
@ -77,6 +144,16 @@
// ...
}
这适用于公共和私有项目。这增加了与公共项目的一致性,允许在更改可见性时减少涉及的更改,
并允许我们将来也为私有项目生成文档。换句话说,如果为私有项目编写了文档,那么仍然应该使
``///`` 。例如:
.. code-block:: rust
/// My private function.
// TODO: ...
fn f() {}
一种特殊的注释是 ``// SAFETY:`` 注释。这些注释必须出现在每个 ``unsafe`` 块之前,它们
解释了为什么该块内的代码是正确/健全的,即为什么它在任何情况下都不会触发未定义行为,例如:
@ -131,27 +208,27 @@ https://commonmark.org/help/
这个例子展示了一些 ``rustdoc`` 的特性和内核中遵循的一些惯例:
- 第一段必须是一个简单的句子,简要地描述被记录的项目的作用。进一步的解释必须放在额
外的段落中。
- 第一段必须是一个简单的句子,简要地描述被记录的项目的作用。进一步的解释必须放在额
外的段落中。
- 不安全的函数必须在 ``# Safety`` 部分记录其安全前提条件。
- 不安全的函数必须在 ``# Safety`` 部分记录其安全前提条件。
- 虽然这里没有显示,但如果一个函数可能会恐慌,那么必须在 ``# Panics`` 部分描述发
生这种情况的条件。
- 虽然这里没有显示,但如果一个函数可能会恐慌,那么必须在 ``# Panics`` 部分描述发
生这种情况的条件。
请注意,恐慌应该是非常少见的,只有在有充分理由的情况下才会使用。几乎在所有的情况下,
都应该使用一个可失败的方法,通常是返回一个 ``Result``
请注意,恐慌应该是非常少见的,只有在有充分理由的情况下才会使用。几乎在所有的情况下,
都应该使用一个可失败的方法,通常是返回一个 ``Result``
- 如果提供使用实例对读者有帮助的话,必须写在一个叫做``# Examples``的部分。
- 如果提供使用实例对读者有帮助的话,必须写在一个叫做``# Examples``的部分。
- Rust项目函数、类型、常量……必须有适当的链接(``rustdoc`` 会自动创建一个
链接)。
- Rust项目函数、类型、常量……必须有适当的链接(``rustdoc`` 会自动创建一个
链接)。
- 任何 ``unsafe`` 的代码块都必须在前面加上一个 ``// SAFETY:`` 的注释,描述里面
的代码为什么是正确的。
- 任何 ``unsafe`` 的代码块都必须在前面加上一个 ``// SAFETY:`` 的注释,描述里面
的代码为什么是正确的。
虽然有时原因可能看起来微不足道,但写这些注释不仅是记录已经考虑到的问题的好方法,
最重要的是,它提供了一种知道没有额外隐含约束的方法。
虽然有时原因可能看起来微不足道,但写这些注释不仅是记录已经考虑到的问题的好方法,
最重要的是,它提供了一种知道没有额外隐含约束的方法。
要了解更多关于如何编写Rust和拓展功能的文档请看看 ``rustdoc`` 这本书,网址是:
@ -170,6 +247,22 @@ https://commonmark.org/help/
/// [`struct mutex`]: srctree/include/linux/mutex.h
C FFI 类型
----------
Rust 内核代码使用类型别名(如 ``c_int``)来引用 C 类型(如 ``int``),这些别名可
以直接从 ``kernel`` 预导入prelude中获取。请不要使用 ``core::ffi`` 中的别
名——它们可能无法映射到正确的类型。
这些别名通常应该直接通过其标识符引用,即作为单段路径。例如:
.. code-block:: rust
fn f(p: *const c_char) -> c_int {
// ...
}
命名
----
@ -202,3 +295,144 @@ Rust内核代码遵循通常的Rust命名空间:
也就是说, ``GPIO_LINE_DIRECTION_IN`` 的等价物将被称为 ``gpio::LineDirection::In``
特别是,它不应该被命名为 ``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``
代码检查提示Lints
---------------------
在 Rust 中,可以在局部 ``allow`` 特定的警告诊断信息、代码检查提示lint
使编译器忽略给定函数、模块、代码块等中给定警告的实例。
这类似于 C 中的 ``#pragma GCC diagnostic push`` + ``ignored`` + ``pop``
[#]_
.. code-block:: c
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static void f(void) {}
#pragma GCC diagnostic pop
.. [#] 在这个特定情况下,可以使用内核的 ``__{always,maybe}_unused`` 属性
C23 的 ``[[maybe_unused]]``);然而,此示例旨在反映下文讨论的 Rust 中
的等效代码检查提示。
但要简洁得多:
.. code-block:: rust
#[allow(dead_code)]
fn f() {}
凭借这一点,可以更方便地默认启用更多诊断(即在 ``W=`` 级别之外)。特别是那些可能有
一些误报但在其他方面非常有用的诊断,保持启用可以捕获潜在的错误。
在此基础上Rust 提供了 ``expect`` 属性,更进一步。如果警告没有产生,它会让编译器
发出警告。例如,以下代码将确保当 ``f()`` 在某处被调用时,我们必须移除该属性:
.. code-block:: rust
#[expect(dead_code)]
fn f() {}
如果我们不这样做,编译器会发出警告::
warning: this lint expectation is unfulfilled
--> x.rs:3:10
|
3 | #[expect(dead_code)]
| ^^^^^^^^^
|
= note: `#[warn(unfulfilled_lint_expectations)]` on by default
这意味着 ``expect`` 不会在不需要时被遗忘,这可能发生在以下几种情况中:
- 开发过程中添加的临时属性。
- 编译器、Clippy 或自定义工具中代码检查提示的改进可能消除误报。
- 当代码检查提示不再需要时,因为预期它会在某个时候被移除,例如上面的
``dead_code`` 示例。
这也增加了剩余 ``allow`` 的可见性,并减少了误用的可能性。
因此,优先使用 ``expect`` 而不是 ``allow``,除非:
- 条件编译在某些情况下触发警告,在其他情况下不触发。
如果与总的相比,只有少数情况触发(或不触发)警告,那么可以考虑使用条件
``expect``(即 ``cfg_attr(..., expect(...))``)。否则,使用 ``allow``
能更简单。
- 在宏内部,不同的调用可能会创建在某些情况下触发警告而在其他情况下不触发的展开代码。
- 当代码可能在某些架构上触发警告但在其他架构上不触发时,例如到 C FFI 类型的 ``as``
转换。
作为一个更详细的示例,考虑以下程序:
.. code-block:: rust
fn g() {}
fn main() {
#[cfg(CONFIG_X)]
g();
}
这里,如果 ``CONFIG_X`` 未设置,函数 ``g()`` 是死代码。我们可以在这里使用
``expect`` 吗?
.. code-block:: rust
#[expect(dead_code)]
fn g() {}
fn main() {
#[cfg(CONFIG_X)]
g();
}
如果 ``CONFIG_X`` 被设置,这将产生代码检查提示,因为在该配置中它不是死代码。因
此,在这种情况下,我们不能直接使用 ``expect``
一个简单的可能性是使用 ``allow``
.. code-block:: rust
#[allow(dead_code)]
fn g() {}
fn main() {
#[cfg(CONFIG_X)]
g();
}
另一种方法是使用条件 ``expect``
.. code-block:: rust
#[cfg_attr(not(CONFIG_X), expect(dead_code))]
fn g() {}
fn main() {
#[cfg(CONFIG_X)]
g();
}
这将确保如果有人在某处引入了对 ``g()`` 的另一个调用(例如无条件的),那么将会被发现
它不再是死代码。然而, ``cfg_attr`` 比简单的 ``allow`` 更复杂。
因此,当涉及多个配置或者代码检查提示可能由于非局部更改(如 ``dead_code``)而触发
时,使用条件 ``expect`` 可能不值得。
有关 Rust 中诊断的更多信息,请参阅:
https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html
错误处理
--------
有关 Rust for Linux 特定错误处理的背景和指南,请参阅:
https://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust

View File

@ -12,16 +12,6 @@ Rust
与内核中的Rust有关的文档。若要开始在内核中使用Rust请阅读 quick-start.rst 指南。
Rust 实验
---------
Rust 支持在 v6.1 版本中合并到主线,以帮助确定 Rust 作为一种语言是否适合内核,
即是否值得进行权衡。
目前Rust 支持主要面向对 Rust 支持感兴趣的内核开发人员和维护者,
以便他们可以开始处理抽象和驱动程序,并帮助开发基础设施和工具。
如果您是终端用户,请注意,目前没有适合或旨在生产使用的内置驱动程序或模块,
并且 Rust 支持仍处于开发/实验阶段,尤其是对于特定内核配置。
代码文档
--------
@ -50,10 +40,3 @@ Rust 支持在 v6.1 版本中合并到主线,以帮助确定 Rust 作为一种
testing
你还可以在 :doc:`../../../process/kernel-docs` 中找到 Rust 的学习材料。
.. only:: subproject and html
Indices
=======
* :ref:`genindex`

View File

@ -13,16 +13,138 @@
本文介绍了如何开始使用Rust进行内核开发。
安装内核开发所需的 Rust 工具链有几种方式。一种简单的方式是使用 Linux 发行版的软件包
(如果它们合适的话)——下面的第一节解释了这种方法。这种方法的一个优势是,通常发行版会
匹配 Rust 和 Clang 所使用的 LLVM。
另一种方式是使用 `kernel.org <https://kernel.org/pub/tools/llvm/rust/>`_ 上提
供的预构建稳定版本的 LLVM+Rust。这些与 :ref:`获取 LLVM <zh_cn_getting_llvm>` 中的精
简快速 LLVM 工具链相同,并添加了 Rust for Linux 支持的 Rust 版本。提供了两套工具
链:"最新 LLVM" 和 "匹配 LLVM"(请参阅链接了解更多信息)。
或者,接下来的两个 "依赖" 章节将解释每个组件以及如何通过 ``rustup``、Rust 的独立
安装程序或从源码构建来安装它们。
本文档的其余部分解释了有关如何入门的其他方面。
发行版
------
Arch Linux
**********
Arch Linux 提供较新的 Rust 版本,因此通常开箱即用,例如::
pacman -S rust rust-src rust-bindgen
Debian
******
Debian 13Trixie以及 Testing 和 Debian UnstableSid提供较新的 Rust 版
本,因此通常开箱即用,例如::
apt install rustc rust-src bindgen rustfmt rust-clippy
Fedora Linux
************
Fedora Linux 提供较新的 Rust 版本,因此通常开箱即用,例如::
dnf install rust rust-src bindgen-cli rustfmt clippy
Gentoo Linux
************
Gentoo Linux尤其是 testing 分支)提供较新的 Rust 版本,因此通常开箱即用,
例如::
USE='rust-src rustfmt clippy' emerge dev-lang/rust dev-util/bindgen
可能需要设置 ``LIBCLANG_PATH``
Nix
***
Nixunstable 频道)提供较新的 Rust 版本,因此通常开箱即用,例如::
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
nativeBuildInputs = with pkgs; [ rustc rust-bindgen rustfmt clippy ];
RUST_LIB_SRC = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
}
openSUSE
********
openSUSE Slowroll 和 openSUSE Tumbleweed 提供较新的 Rust 版本,因此通常开箱
即用,例如::
zypper install rust rust1.79-src rust-bindgen clang
Ubuntu
******
25.04
~~~~~
最新的 Ubuntu 版本提供较新的 Rust 版本,因此通常开箱即用,例如::
apt install rustc rust-src bindgen rustfmt rust-clippy
此外,需要设置 ``RUST_LIB_SRC``,例如::
RUST_LIB_SRC=/usr/src/rustc-$(rustc --version | cut -d' ' -f2)/library
为方便起见,可以将 ``RUST_LIB_SRC`` 导出到全局环境中。
24.04 LTS 及更早版本
~~~~~~~~~~~~~~~~~~~~
虽然 Ubuntu 24.04 LTS 及更早版本仍然提供较新的 Rust 版本,但它们需要一些额外的配
置,使用带版本号的软件包,例如::
apt install rustc-1.80 rust-1.80-src bindgen-0.65 rustfmt-1.80 \
rust-1.80-clippy
ln -s /usr/lib/rust-1.80/bin/rustfmt /usr/bin/rustfmt-1.80
ln -s /usr/lib/rust-1.80/bin/clippy-driver /usr/bin/clippy-driver-1.80
这些软件包都不会将其工具设置为默认值;因此应该显式指定它们,例如::
make LLVM=1 RUSTC=rustc-1.80 RUSTDOC=rustdoc-1.80 RUSTFMT=rustfmt-1.80 \
CLIPPY_DRIVER=clippy-driver-1.80 BINDGEN=bindgen-0.65
或者,修改 ``PATH`` 变量将 Rust 1.80 的二进制文件放在前面,并将 ``bindgen``
置为默认值,例如::
PATH=/usr/lib/rust-1.80/bin:$PATH
update-alternatives --install /usr/bin/bindgen bindgen \
/usr/bin/bindgen-0.65 100
update-alternatives --set bindgen /usr/bin/bindgen-0.65
使用带版本号的软件包时需要设置 ``RUST_LIB_SRC``,例如::
RUST_LIB_SRC=/usr/src/rustc-$(rustc-1.80 --version | cut -d' ' -f2)/library
为方便起见,可以将 ``RUST_LIB_SRC`` 导出到全局环境中。
此外, ``bindgen-0.65`` 在较新的版本24.04 LTS 和 24.10)中可用,但在更早的版
20.04 LTS 和 22.04 LTS中可能不可用因此可能需要手动构建 ``bindgen``
(请参见下文)。
构建依赖
--------
本节描述了如何获取构建所需的工具。
其中一些依赖也许可以从Linux发行版中获得包名可能是 ``rustc`` , ``rust-src`` ,
``rust-bindgen`` 等。然而,在写这篇文章的时候,它们很可能还不够新,除非发行版跟踪最
新的版本。
为了方便检查是否满足要求,可以使用以下目标::
make LLVM=1 rustavailable
@ -34,15 +156,14 @@
rustc
*****
需要一个特定版本的Rust编译器。较新的版本可能会也可能不会工作因为就目前而言内核依赖
于一些不稳定的Rust特性。
需要一个较新版本的Rust编译器。
如果使用的是 ``rustup`` ,请进入内核编译目录(或者用 ``--path=<build-dir>`` 参数
``设置`` sub-command)运行::
``设置`` sub-command),例如运行::
rustup override set $(scripts/min-tool-version.sh rustc)
rustup override set stable
+这将配置你的工作目录使用正确版本的 ``rustc``,而不影响你的默认工具链。
这将配置你的工作目录使用给定版本的 ``rustc``,而不影响你的默认工具链。
请注意覆盖应用当前的工作目录(和它的子目录)。
@ -54,7 +175,7 @@ rustc
Rust标准库源代码
****************
Rust标准库的源代码是必需的因为构建系统会交叉编译 ``core`` ``alloc``
Rust标准库的源代码是必需的因为构建系统会交叉编译 ``core``
如果正在使用 ``rustup`` ,请运行::
@ -64,10 +185,10 @@ Rust标准库的源代码是必需的因为构建系统会交叉编译 ``core
否则如果使用独立的安装程序可以将Rust源码树下载到安装工具链的文件夹中::
curl -L "https://static.rust-lang.org/dist/rust-src-$(scripts/min-tool-version.sh rustc).tar.gz" |
tar -xzf - -C "$(rustc --print sysroot)/lib" \
"rust-src-$(scripts/min-tool-version.sh rustc)/rust-src/lib/" \
--strip-components=3
curl -L "https://static.rust-lang.org/dist/rust-src-$(rustc --version | cut -d' ' -f2).tar.gz" |
tar -xzf - -C "$(rustc --print sysroot)/lib" \
"rust-src-$(rustc --version | cut -d' ' -f2)/rust-src/lib/" \
--strip-components=3
在这种情况下以后升级Rust编译器版本需要手动更新这个源代码树这可以通过移除
``$(rustc --print sysroot)/lib/rustlib/src/rust`` ,然后重新执行上
@ -97,24 +218,21 @@ Linux发行版中可能会有合适的包所以最好先检查一下。
bindgen
*******
内核的C端绑定是在构建时使用 ``bindgen`` 工具生成的。这需要特定的版本。
内核的C端绑定是在构建时使用 ``bindgen`` 工具生成的。
通过以下方式安装它(注意,这将从源码下载并构建该工具)::
例如,通过以下方式安装它(注意,这将从源码下载并构建该工具)::
cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen-cli
cargo install --locked bindgen-cli
``bindgen`` 需要找到合适的 ``libclang`` 才能工作。如果没有找到(或者找到的
``libclang`` 与应该使用的 ``libclang`` 不同),则可以使用 ``clang-sys``
理解的环境变量Rust绑定创建的 ``bindgen`` 用来访问 ``libclang``:
``bindgen`` 使用 ``clang-sys`` crate 来查找合适的 ``libclang`` (可以静态链
接、动态链接或在运行时加载)。默认情况下,上面的 ``cargo`` 命令会生成一个在运行时
加载 ``libclang````bindgen`` 二进制文件。如果没有找到(或者应该使用与找到的
不同的 ``libclang``),可以调整该过程,例如使用 ``LIBCLANG_PATH`` 环境变量。详
情请参阅 ``clang-sys`` 的文档:
https://github.com/KyleMayes/clang-sys#linking
* ``LLVM_CONFIG_PATH`` 可以指向一个 ``llvm-config`` 可执行文件。
* 或者 ``LIBCLANG_PATH`` 可以指向 ``libclang`` 共享库或包含它的目录。
* 或者 ``CLANG_PATH`` 可以指向 ``clang`` 可执行文件。
详情请参阅 ``clang-sys`` 的文档:
https://github.com/KyleMayes/clang-sys#environment-variables
开发依赖
@ -151,18 +269,6 @@ clippy
独立的安装程序也带有 ``clippy``
cargo
*****
``cargo`` 是Rust的本地构建系统。目前需要它来运行测试因为它被用来构建一个自定义的标准
库,其中包含了内核中自定义 ``alloc`` 所提供的设施。测试可以使用 ``rusttest`` Make 目标
来运行。
如果使用的是 ``rustup`` ,所有的配置文件都已经安装了该工具,因此不需要再做什么。
独立的安装程序也带有 ``cargo``
rustdoc
*******
@ -223,7 +329,7 @@ Rust支持CONFIG_RUST需要在 ``General setup`` 菜单中启用。在其
如果使用的是GDB/Binutils而Rust符号没有被demangled原因是工具链还不支持Rust的新v0
mangling方案。有几个办法可以解决
- 安装一个较新的版本GDB >= 10.2, Binutils >= 2.36)。
- 安装一个较新的版本GDB >= 10.2, Binutils >= 2.36)。
- 一些版本的GDB例如vanilla GDB 10.1)能够使用嵌入在调试信息(``CONFIG_DEBUG_INFO``)
中的pre-demangled的名字。
- 一些版本的GDB例如vanilla GDB 10.1)能够使用嵌入在调试信息(``CONFIG_DEBUG_INFO``)
中的pre-demangled的名字。

View File

@ -144,8 +144,8 @@ array
- yield_task(...)
这个函数的行为基本上是出队紧接着入队除非compat_yield sysctl被开启。在那种情况下
它将调度实体放在红黑树的最右端
此函数通过将当前任务在运行队列中的位置后移来让出 CPU
使得其他可运行的任务优先被调度
- wakeup_preempt(...)

View File

@ -33,7 +33,7 @@ Linux內核6.x版本 <http://kernel.org/>
雖然Linux最初是爲32位的x86 PC機386或更高版本開發的但今天它也能運行在
至少Compaq Alpha AXP、Sun SPARC與UltraSPARC、Motorola 68000、PowerPC、
PowerPC64、ARM、Hitachi SuperH、Cell、IBM S/390、MIPS、HP PA-RISC、Intel
PowerPC64、ARM、Hitachi SuperH、Cell、IBM S/390、MIPS、HP PA-RISC、Intel
IA-64、DEC VAX、AMD x86-64 Xtensa和ARC架構上。
Linux很容易移植到大多數通用的32位或64位體系架構只要它們有一個分頁內存管理

View File

@ -219,7 +219,7 @@ Documentation/fault-injection/fault-injection.rst。
可以在 https://sparse.wiki.kernel.org/index.php/Main_page 找到),
然後可以通過在make命令中添加“C=1”在代碼上運行它。
“Coccinelle”工具 :ref:`http://coccinelle.lip6.fr/ <devtools_coccinelle>`
“Coccinelle”工具 :ref:`https://coccinelle.gitlabpages.inria.fr/website/ <devtools_coccinelle>`
能夠發現各種潛在的編碼問題;它還可以爲這些問題提出修復方案。在
scripts/coccinelle目錄下已經打包了相當多的內核“語義補丁”運行
“make coccicheck”將運行這些語義補丁並報告發現的任何問題。有關詳細信息請參閱

View File

@ -7688,8 +7688,9 @@ M: Mauro Carvalho Chehab <mchehab@kernel.org>
L: linux-doc@vger.kernel.org
S: Maintained
F: Documentation/sphinx/
F: tools/lib/python/*
F: tools/docs/
F: tools/lib/python/*
F: tools/unittests/*
DOCUMENTATION/ITALIAN
M: Federico Vaga <federico.vaga@vaga.pv.it>
@ -14774,7 +14775,6 @@ F: Documentation/memory-barriers.txt
F: tools/memory-model/
LINUX-NEXT TREE
M: Stephen Rothwell <sfr@canb.auug.org.au>
M: Mark Brown <broonie@kernel.org>
L: linux-next@vger.kernel.org
S: Supported
@ -21014,6 +21014,12 @@ S: Maintained
F: drivers/pnp/
F: include/linux/pnp.h
PORTUGUESE (BRAZILIAN) TRANSLATION
M: Daniel Pereira <danielmaraboo@gmail.com>
L: linux-doc@vger.kernel.org
S: Maintained
F: Documentation/translations/pt_BR/
PORTWELL EC DRIVER
M: Yen-Chi Huang <jesse.huang@portwell.com.tw>
L: platform-driver-x86@vger.kernel.org

View File

@ -7,7 +7,7 @@
BEGIN {
usage = "If some fields are empty or look unusual you may have an old version.\n"
usage = usage "Compare to the current minimal requirements in Documentation/Changes.\n"
usage = usage "Compare to the current minimal requirements in Documentation/process/changes.rst\n"
print usage
system("uname -a")
@ -17,37 +17,58 @@ BEGIN {
libc = "libc[.]so[.][0-9]+$"
libcpp = "(libg|stdc)[+]+[.]so([.][0-9]+)+$"
printversion("bash", version("bash --version"))
printversion("bc", version("bc --version"))
printversion("bindgen", version("bindgen --version"))
printversion("binutils", version("ld -v"))
printversion("bison", version("bison --version"))
printversion("btrfs-progs", version("btrfs --version"))
printversion("Clang", version("clang --version"))
printversion("Console-tools", version("loadkeys -V"))
printversion("Dynamic linker (ldd)", version("ldd --version"))
printversion("e2fsprogs", version("e2fsck -V"))
printversion("flex", version("flex --version"))
printversion("gdb", version("gdb -version"))
printversion("GNU awk", version("gawk --version"))
printversion("GNU C", version("gcc -dumpversion"))
printversion("GNU Make", version("make --version"))
printversion("Binutils", version("ld -v"))
printversion("Util-linux", version("mount --version"))
printversion("Mount", version("mount --version"))
printversion("Module-init-tools", version("depmod -V"))
printversion("E2fsprogs", version("tune2fs"))
printversion("Jfsutils", version("fsck.jfs -V"))
printversion("Xfsprogs", version("xfs_db -V"))
printversion("Pcmciautils", version("pccardctl -V"))
printversion("Pcmcia-cs", version("cardmgr -V"))
printversion("Quota-tools", version("quota -V"))
printversion("PPP", version("pppd --version"))
printversion("GNU make", version("make --version"))
printversion("GNU tar", version("tar --version"))
printversion("GRUB2", version("grub2-install --version"))
printversion("GRUB", version("grub-install --version"))
printversion("gtags", version("gtags --version"))
printversion("iptables", version("iptables -V"))
printversion("Isdn4k-utils", version("isdnctrl"))
printversion("Nfs-utils", version("showmount --version"))
printversion("Bison", version("bison --version"))
printversion("Flex", version("flex --version"))
printversion("jfsutils", version("fsck.jfs -V"))
printversion("Kbd", version("loadkeys -V"))
printversion("kmod", version("kmod -V"))
while ("ldconfig -p 2>/dev/null" | getline > 0)
if ($NF ~ libc || $NF ~ libcpp)
if (!seen[ver = version("readlink " $NF)]++)
printversion("Linux C" ($NF ~ libcpp? "++" : "") " Library", ver)
printversion("Dynamic linker (ldd)", version("ldd --version"))
printversion("Procps", version("ps --version"))
printversion("mcelog", version("mcelog --version"))
printversion("mkimage", version("mkimage --version"))
printversion("Module-init-tools", version("depmod -V"))
printversion("Mount", version("mount --version"))
printversion("Net-tools", version("ifconfig --version"))
printversion("Kbd", version("loadkeys -V"))
printversion("Console-tools", version("loadkeys -V"))
printversion("nfs-utils", version("showmount --version"))
printversion("openssl", version("openssl version"))
printversion("pahole", version("pahole --version"))
printversion("Pcmcia-cs", version("cardmgr -V"))
printversion("pcmciautils", version("pccardctl -V"))
printversion("PPP", version("pppd --version"))
printversion("procps", version("ps --version"))
printversion("Python", version("python3 -V"))
printversion("quota-tools", version("quota -V"))
printversion("Rust", version("rustc --version"))
printversion("Sh-utils", version("expr --v"))
printversion("Udev", version("udevadm --version"))
printversion("Sphinx", version("sphinx-build --version"))
printversion("squashfs-tools", version("mksquashfs -version"))
printversion("udev", version("udevadm --version"))
printversion("util-linux", version("mount --version"))
printversion("Wireless-tools", version("iwconfig --version"))
printversion("xfsprogs", version("xfs_db -V"))
while ("sort /proc/modules" | getline > 0) {
mods = mods sep $1

View File

@ -13,6 +13,8 @@ The usage is as follows:
This will print all the files that need to be updated or translated in the zh_CN locale.
- tools/docs/checktransupdate.py Documentation/translations/zh_CN/dev-tools/testing-overview.rst
This will only print the status of the specified file.
- tools/docs/checktransupdate.py Documentation/translations/zh_CN/dev-tools
This will print the status of all files under the directory.
The output is something like:
Documentation/dev-tools/kfence.rst
@ -76,11 +78,11 @@ def get_origin_from_trans_smartly(origin_path, t_from_head):
(2) Update the translation through commit HASH (TITLE)
"""
# catch flag for 12-bit commit hash
HASH = r'([0-9a-f]{12})'
hash_re = r'([0-9a-f]{12})'
# pattern 1: contains "update to commit HASH"
pat_update_to = re.compile(rf'update to commit {HASH}')
pat_update_to = re.compile(rf'update to commit {hash_re}')
# pattern 2: contains "Update the translation through commit HASH"
pat_update_translation = re.compile(rf'Update the translation through commit {HASH}')
pat_update_translation = re.compile(rf'Update the translation through commit {hash_re}')
origin_commit_hash = None
for line in t_from_head["message"]:
@ -131,7 +133,7 @@ def check_per_file(file_path):
opath = get_origin_path(file_path)
if not os.path.isfile(opath):
logging.error("Cannot find the origin path for {file_path}")
logging.error("Cannot find the origin path for %s", file_path)
return
o_from_head = get_latest_commit_from(opath, "HEAD")
@ -262,7 +264,7 @@ def main():
help='Set the logging file (default: checktransupdate.log)')
parser.add_argument(
"files", nargs="*", help="Files to check, if not specified, check all files"
"files", nargs="*", help="Files or directories to check, if not specified, check all files"
)
args = parser.parse_args()
@ -293,6 +295,16 @@ def main():
if args.print_missing_translations:
logging.info(os.path.relpath(os.path.abspath(file), linux_path))
logging.info("No translation in the locale of %s\n", args.locale)
else:
# check if the files are directories or files
new_files = []
for file in files:
if os.path.isfile(file):
new_files.append(file)
elif os.path.isdir(file):
# for directories, list all files in the directory and its subfolders
new_files.extend(list_files_with_excluding_folders(file, [], "rst"))
files = new_files
files = list(map(lambda x: os.path.relpath(os.path.abspath(x), linux_path), files))

508
tools/docs/kdoc_diff Executable file
View File

@ -0,0 +1,508 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
# Copyright(c) 2026: Mauro Carvalho Chehab <mchehab@kernel.org>.
#
# pylint: disable=R0903,R0912,R0913,R0914,R0915,R0917
"""
docdiff - Check differences between kerneldoc output between two different
commits.
Examples
--------
Compare the kerneldoc output between the last two 5.15 releases::
$ kdoc_diff v6.18..v6.19
Both outputs are cached
Force a complete documentation scan and clean any previous cache from
6.19 to the current HEAD::
$ kdoc_diff 6.19.. --full --clean
Check differences only on a single driver since origin/main::
$ kdoc_diff origin/main drivers/media
Generate an YAML file and use it to check for regressions::
$ kdoc_diff HEAD~ drivers/media --regression
"""
import os
import sys
import argparse
import subprocess
import shutil
import re
import signal
from glob import iglob
SRC_DIR = os.path.dirname(os.path.realpath(__file__))
WORK_DIR = os.path.abspath(os.path.join(SRC_DIR, "../.."))
KDOC_BINARY = os.path.join(SRC_DIR, "kernel-doc")
KDOC_PARSER_TEST = os.path.join(WORK_DIR, "tools/unittests/test_kdoc_parser.py")
CACHE_DIR = ".doc_diff_cache"
YAML_NAME = "out.yaml"
DIR_NAME = {
"full": os.path.join(CACHE_DIR, "full"),
"partial": os.path.join(CACHE_DIR, "partial"),
"no-cache": os.path.join(CACHE_DIR, "no_cache"),
"tmp": os.path.join(CACHE_DIR, "__tmp__"),
}
class GitHelper:
"""Handles all Git operations"""
def __init__(self, work_dir=None):
self.work_dir = work_dir
def is_inside_repository(self):
"""Check if we're inside a Git repository"""
try:
output = subprocess.check_output(["git", "rev-parse",
"--is-inside-work-tree"],
cwd=self.work_dir,
stderr=subprocess.STDOUT,
universal_newlines=True)
return output.strip() == "true"
except subprocess.CalledProcessError:
return False
def is_valid_commit(self, commit_hash):
"""
Validate that a ref (branch, tag, commit hash, etc.) can be
resolved to a commit.
"""
try:
subprocess.check_output(["git", "rev-parse", commit_hash],
cwd=self.work_dir,
stderr=subprocess.STDOUT)
return True
except subprocess.CalledProcessError:
return False
def get_short_hash(self, commit_hash):
"""Get short commit hash"""
try:
return subprocess.check_output(["git", "rev-parse", "--short",
commit_hash],
cwd=self.work_dir,
stderr=subprocess.STDOUT,
universal_newlines=True).strip()
except subprocess.CalledProcessError:
return ""
def has_uncommitted_changes(self):
"""Check for uncommitted changes"""
try:
subprocess.check_output(["git", "diff-index",
"--quiet", "HEAD", "--"],
cwd=self.work_dir,
stderr=subprocess.STDOUT)
return False
except subprocess.CalledProcessError:
return True
def get_current_branch(self):
"""Get current branch name"""
return subprocess.check_output(["git", "branch", "--show-current"],
cwd=self.work_dir,
universal_newlines=True).strip()
def checkout_commit(self, commit_hash, quiet=True):
"""Checkout a commit safely"""
args = ["git", "checkout", "-f"]
if quiet:
args.append("-q")
args.append(commit_hash)
try:
subprocess.check_output(args, cwd=self.work_dir,
stderr=subprocess.STDOUT)
# Double-check if branch actually switched
branch = self.get_short_hash("HEAD")
if commit_hash != branch:
raise RuntimeError(f"Branch changed to '{branch}' instead of '{commit_hash}'")
return True
except subprocess.CalledProcessError as e:
print(f"ERROR: Failed to checkout {commit_hash}: {e}",
file=sys.stderr)
return False
class CacheManager:
"""Manages persistent cache directories"""
def __init__(self, work_dir):
self.work_dir = work_dir
def initialize(self):
"""Create cache directories if they don't exist"""
for dir_path in DIR_NAME.values():
abs_path = os.path.join(self.work_dir, dir_path)
if not os.path.exists(abs_path):
os.makedirs(abs_path, exist_ok=True, mode=0o755)
def get_commit_cache(self, commit_hash, path):
"""Generate cache path for a commit"""
hash_short = GitHelper(self.work_dir).get_short_hash(commit_hash)
if not hash_short:
hash_short = commit_hash
return os.path.join(path, hash_short)
class KernelDocRunner:
"""Runs kernel-doc documentation generator"""
def __init__(self, work_dir, kdoc_binary):
self.work_dir = work_dir
self.kdoc_binary = kdoc_binary
self.kdoc_files = None
def find_kdoc_references(self):
"""Find all files marked with kernel-doc:: directives"""
if self.kdoc_files:
print("Using cached Kdoc refs")
return self.kdoc_files
print("Finding kernel-doc entries in Documentation...")
files = os.path.join(self.work_dir, 'Documentation/**/*.rst')
pattern = re.compile(r"^\.\.\s+kernel-doc::\s*(\S+)")
kdoc_files = set()
for file_path in iglob(files, recursive=True):
try:
with open(file_path, 'r', encoding='utf-8') as fp:
for line in fp:
match = pattern.match(line.strip())
if match:
kdoc_files.add(match.group(1))
except OSError:
continue
self.kdoc_files = list(kdoc_files)
return self.kdoc_files
def gen_yaml(self, yaml_file, kdoc_files):
"""Runs kernel-doc to generate a yaml file with man and rst."""
cmd = [self.kdoc_binary, "--man", "--rst", "--yaml", yaml_file]
cmd += kdoc_files
print(f"YAML regression test file will be stored at: {yaml_file}")
try:
subprocess.check_call(cmd, cwd=self.work_dir,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError:
return False
return True
def run_unittest(self, yaml_file):
"""Run unit tests with the generated yaml file"""
cmd = [KDOC_PARSER_TEST, "-q", "--yaml", yaml_file]
result = subprocess.run(cmd, cwd=self.work_dir)
if result.returncode:
print("To check for problems, try to run it again with -v\n")
print("Use -k <regex> to filter results\n\n\t$", end="")
print(" ".join(cmd) + "\n")
return True
def normal_run(self, tmp_dir, output_dir, kdoc_files):
"""Generate man, rst and errors, storing them at tmp_dir."""
os.makedirs(tmp_dir, exist_ok=True)
try:
with open(os.path.join(tmp_dir, "man.log"), "w", encoding="utf-8") as out:
subprocess.check_call([self.kdoc_binary, "--man"] + kdoc_files,
cwd=self.work_dir,
stdout=out, stderr=subprocess.DEVNULL)
with open(os.path.join(tmp_dir, "rst.log"), "w", encoding="utf-8") as out:
with open(os.path.join(tmp_dir, "err.log"), "w", encoding="utf-8") as err:
subprocess.check_call([self.kdoc_binary, "--rst"] + kdoc_files,
cwd=self.work_dir,
stdout=out, stderr=err)
except subprocess.CalledProcessError:
return False
if output_dir:
os.replace(tmp_dir, output_dir)
return True
def run(self, commit_hash, tmp_dir, output_dir, kdoc_files, is_regression,
is_end):
"""Run kernel-doc on its several ways"""
if not kdoc_files:
raise RuntimeError("No kernel-doc references found")
git_helper = GitHelper(self.work_dir)
if not git_helper.checkout_commit(commit_hash, quiet=True):
raise RuntimeError(f"ERROR: can't checkout commit {commit_hash}")
print(f"Processing {commit_hash}...")
if not is_regression:
return self.normal_run(tmp_dir, output_dir, kdoc_files)
yaml_file = os.path.join(tmp_dir, YAML_NAME)
if not is_end:
return self.gen_yaml(yaml_file, kdoc_files)
return self.run_unittest(yaml_file)
class DiffManager:
"""Compare documentation output directories with an external diff."""
def __init__(self, diff_tool="diff", diff_args=None):
self.diff_tool = diff_tool
# default: unified, no context, ignore whitespace changes
self.diff_args = diff_args or ["-u0", "-w"]
def diff_directories(self, dir1, dir2):
"""Compare two directories using an external diff."""
print(f"\nDiffing {dir1} and {dir2}:")
dir1_files = set()
dir2_files = set()
has_diff = False
for root, _, files in os.walk(dir1):
for file in files:
dir1_files.add(os.path.relpath(os.path.join(root, file), dir1))
for root, _, files in os.walk(dir2):
for file in files:
dir2_files.add(os.path.relpath(os.path.join(root, file), dir2))
common_files = sorted(dir1_files & dir2_files)
for file in common_files:
f1 = os.path.join(dir1, file)
f2 = os.path.join(dir2, file)
cmd = [self.diff_tool] + self.diff_args + [f1, f2]
try:
result = subprocess.run(
cmd, capture_output=True, text=True, check=False
)
if result.stdout:
has_diff = True
print(f"\n{file}")
print(result.stdout, end="")
except FileNotFoundError:
print(f"ERROR: {self.diff_tool} not found")
sys.exit(1)
# Show files that exist only in one directory
only_in_dir1 = dir1_files - dir2_files
only_in_dir2 = dir2_files - dir1_files
if only_in_dir1 or only_in_dir2:
has_diff = True
print("\nDifferential files:")
for f in sorted(only_in_dir1):
print(f" - {f} (only in {dir1})")
for f in sorted(only_in_dir2):
print(f" + {f} (only in {dir2})")
if not has_diff:
print("\nNo differences between those two commits")
class SignalHandler():
"""Signal handler class."""
def restore(self, force_exit=False):
"""Restore original HEAD state."""
if self.restored:
return
print(f"Restoring original branch: {self.original_head}")
try:
subprocess.check_call(
["git", "checkout", "-f", self.original_head],
cwd=self.git_helper.work_dir,
stderr=subprocess.STDOUT,
)
except subprocess.CalledProcessError as e:
print(f"Failed to restore: {e}", file=sys.stderr)
for sig, handler in self.old_handler.items():
signal.signal(sig, handler)
self.restored = True
if force_exit:
sys.exit(1)
def signal_handler(self, sig, _):
"""Handle interrupt signals."""
print(f"\nSignal {sig} received. Restoring original state...")
self.restore(force_exit=True)
def __enter__(self):
"""Allow using it via with command."""
for sig in [signal.SIGINT, signal.SIGTERM]:
self.old_handler[sig] = signal.getsignal(sig)
signal.signal(sig, self.signal_handler)
return self
def __exit__(self, *args):
"""Restore signals at the end of with block."""
self.restore()
def __init__(self, git_helper, original_head):
self.git_helper = git_helper
self.original_head = original_head
self.old_handler = {}
self.restored = False
def parse_commit_range(value):
"""Handle a commit range."""
if ".." not in value:
begin = value
end = "HEAD"
else:
begin, _, end = value.partition("..")
if not end:
end = "HEAD"
if not begin:
raise argparse.ArgumentTypeError("Need a commit begginning")
print(f"Range: {begin} to {end}")
return begin, end
def main():
"""Main code"""
parser = argparse.ArgumentParser(description="Compare kernel documentation between commits")
parser.add_argument("commits", type=parse_commit_range,
help="commit range like old..new")
parser.add_argument("files", nargs="*",
help="files to process if supplied the --full flag is ignored")
parser.add_argument("--full", "-f", action="store_true",
help="Force a full scan of Documentation/*")
parser.add_argument("--regression", "-r", action="store_true",
help="Use YAML format to check for regressions")
parser.add_argument("--work-dir", "-w", default=WORK_DIR,
help="work dir (default: %(default)s)")
parser.add_argument("--clean", "-c", action="store_true",
help="Clean caches")
args = parser.parse_args()
if args.files and args.full:
raise argparse.ArgumentError(args.full,
"cannot combine '--full' with an explicit file list")
work_dir = os.path.abspath(args.work_dir)
# Initialize cache
cache = CacheManager(work_dir)
cache.initialize()
# Validate git repository
git_helper = GitHelper(work_dir)
if not git_helper.is_inside_repository():
raise RuntimeError("Must run inside Git repository")
old_commit, new_commit = args.commits
old_commit = git_helper.get_short_hash(old_commit)
new_commit = git_helper.get_short_hash(new_commit)
# Validate commits
for commit in [old_commit, new_commit]:
if not git_helper.is_valid_commit(commit):
raise RuntimeError(f"Commit '{commit}' does not exist")
# Check for uncommitted changes
if git_helper.has_uncommitted_changes():
raise RuntimeError("Uncommitted changes present. Commit or stash first.")
runner = KernelDocRunner(git_helper.work_dir, KDOC_BINARY)
# Get files to be parsed
cache_msg = " (results will be cached)"
if args.full:
kdoc_files = ["."]
diff_type = "full"
print(f"Parsing all files at {work_dir}")
if not args.files:
diff_type = "partial"
kdoc_files = runner.find_kdoc_references()
print(f"Parsing files with kernel-doc markups at {work_dir}/Documentation")
else:
diff_type = "no-cache"
cache_msg = ""
kdoc_files = args.files
tmp_dir = DIR_NAME["tmp"]
out_path = DIR_NAME[diff_type]
if not args.regression:
print(f"Output will be stored at: {out_path}{cache_msg}")
# Just in case - should never happen in practice
if not kdoc_files:
raise argparse.ArgumentError(args.files,
"No kernel-doc references found")
original_head = git_helper.get_current_branch()
old_cache = cache.get_commit_cache(old_commit, out_path)
new_cache = cache.get_commit_cache(new_commit, out_path)
with SignalHandler(git_helper, original_head):
if args.clean or diff_type == "no-cache":
for cache_dir in [old_cache, new_cache]:
if cache_dir and os.path.exists(cache_dir):
shutil.rmtree(cache_dir)
if args.regression or not os.path.exists(old_cache):
old_success = runner.run(old_commit, tmp_dir, old_cache, kdoc_files,
args.regression, False)
else:
old_success = True
if args.regression or not os.path.exists(new_cache):
new_success = runner.run(new_commit, tmp_dir, new_cache, kdoc_files,
args.regression, True)
else:
new_success = True
if not (old_success and new_success):
raise RuntimeError("Failed to generate documentation")
if not args.regression:
diff_manager = DiffManager()
diff_manager.diff_directories(old_cache, new_cache)
if __name__ == "__main__":
main()

View File

@ -210,7 +210,6 @@ def main():
help="Enable debug messages")
parser.add_argument("-M", "-modulename", "--modulename",
default="Kernel API",
help="Allow setting a module name at the output.")
parser.add_argument("-l", "-enable-lineno", "--enable_lineno",
@ -241,11 +240,9 @@ def main():
help=EXPORT_FILE_DESC)
#
# Output format mutually-exclusive group
# Output format
#
out_group = parser.add_argument_group("Output format selection (mutually exclusive)")
out_fmt = out_group.add_mutually_exclusive_group()
out_fmt = parser.add_argument_group("Output format selection (mutually exclusive)")
out_fmt.add_argument("-m", "-man", "--man", action="store_true",
help="Output troff manual page format.")
@ -254,6 +251,12 @@ def main():
out_fmt.add_argument("-N", "-none", "--none", action="store_true",
help="Do not output documentation, only warnings.")
out_fmt.add_argument("-y", "--yaml-file", "--yaml",
help="Stores kernel-doc output on a yaml file.")
out_fmt.add_argument("-k", "--kdoc-item", "--kdoc", action="store_true",
help="Store KdocItem inside yaml file. Ued together with --yaml.")
#
# Output selection mutually-exclusive group
#
@ -324,14 +327,42 @@ def main():
from kdoc.kdoc_files import KernelFiles # pylint: disable=C0415
from kdoc.kdoc_output import RestFormat, ManFormat # pylint: disable=C0415
if args.man:
out_style = ManFormat(modulename=args.modulename)
elif args.none:
yaml_content = set()
if args.yaml_file:
out_style = None
if args.man:
yaml_content |= {"man"}
if args.rst:
yaml_content |= {"rst"}
if args.kdoc_item or not yaml_content:
yaml_content |= {"KdocItem"}
else:
out_style = RestFormat()
n_outputs = 0
if args.man:
out_style = ManFormat(modulename=args.modulename)
n_outputs += 1
if args.none:
out_style = None
n_outputs += 1
if args.rst or n_outputs == 0:
n_outputs += 1
out_style = RestFormat()
if n_outputs > 1:
parser.error("Those arguments are muttually exclusive: --man, --rst, --none, except when generating a YAML file.")
elif not n_outputs:
out_style = RestFormat()
kfiles = KernelFiles(verbose=args.verbose,
yaml_file=args.yaml_file, yaml_content=yaml_content,
out_style=out_style, werror=args.werror,
wreturn=args.wreturn, wshort_desc=args.wshort_desc,
wcontents_before_sections=args.wcontents_before_sections)

View File

@ -238,7 +238,12 @@ class SphinxBuilder:
self.latexopts = os.environ.get("LATEXOPTS", "")
if not verbose:
verbose = bool(os.environ.get("KBUILD_VERBOSE", "") != "")
try:
verbose = bool(int(os.environ.get("KBUILD_VERBOSE", 0)))
except ValueError:
# Handles an eventual case where verbosity is not a number
# like KBUILD_VERBOSE=""
verbose = False
if verbose is not None:
self.verbose = verbose
@ -576,7 +581,6 @@ class SphinxBuilder:
"""
re_kernel_doc = re.compile(r"^\.\.\s+kernel-doc::\s*(\S+)")
re_man = re.compile(r'^\.TH "[^"]*" (\d+) "([^"]*)"')
if docs_dir == src_dir:
#
@ -616,8 +620,7 @@ class SphinxBuilder:
fp = None
try:
for line in result.stdout.split("\n"):
match = re_man.match(line)
if not match:
if not line.startswith(".TH"):
if fp:
fp.write(line + '\n')
continue
@ -625,7 +628,11 @@ class SphinxBuilder:
if fp:
fp.close()
fname = f"{output_dir}/{match.group(2)}.{match.group(1)}"
# Use shlex here, as it handles well parameters with commas
args = shlex.split(line)
fname = f"{args[1]}.{args[2]}"
fname = fname.replace("/", " ")
fname = f"{output_dir}/{fname}"
if self.verbose:
print(f"Creating {fname}")

View File

@ -8,14 +8,14 @@
"""
Interacts with the POSIX jobserver during the Kernel build time.
A "normal" jobserver task, like the one initiated by a make subrocess would do:
A "normal" jobserver task, like the one initiated by a make subprocess would do:
- open read/write file descriptors to communicate with the job server;
- ask for one slot by calling::
claim = os.read(reader, 1)
- when the job finshes, call::
- when the job finishes, call::
os.write(writer, b"+") # os.write(writer, claim)

View File

@ -0,0 +1,662 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
# Copyright(c) 2025: Mauro Carvalho Chehab <mchehab@kernel.org>.
"""
Regular expression ancillary classes.
Those help caching regular expressions and do matching for kernel-doc.
Please notice that the code here may rise exceptions to indicate bad
usage inside kdoc to indicate problems at the replace pattern.
Other errors are logged via log instance.
"""
import logging
import re
from copy import copy
from .kdoc_re import KernRe
log = logging.getLogger(__name__)
def tokenizer_set_log(logger, prefix = ""):
"""
Replace the modulelevel logger with a LoggerAdapter that
prepends *prefix* to every message.
"""
global log
class PrefixAdapter(logging.LoggerAdapter):
"""
Ancillary class to set prefix on all message logs.
"""
def process(self, msg, kwargs):
return f"{prefix}{msg}", kwargs
# Wrap the provided logger in our adapter
log = PrefixAdapter(logger, {"prefix": prefix})
class CToken():
"""
Data class to define a C token.
"""
# Tokens that can be used by the parser. Works like an C enum.
COMMENT = 0 #: A standard C or C99 comment, including delimiter.
STRING = 1 #: A string, including quotation marks.
CHAR = 2 #: A character, including apostophes.
NUMBER = 3 #: A number.
PUNC = 4 #: A puntuation mark: / ``,`` / ``.``.
BEGIN = 5 #: A begin character: ``{`` / ``[`` / ``(``.
END = 6 #: A end character: ``}`` / ``]`` / ``)``.
CPP = 7 #: A preprocessor macro.
HASH = 8 #: The hash character - useful to handle other macros.
OP = 9 #: A C operator (add, subtract, ...).
STRUCT = 10 #: A ``struct`` keyword.
UNION = 11 #: An ``union`` keyword.
ENUM = 12 #: A ``struct`` keyword.
TYPEDEF = 13 #: A ``typedef`` keyword.
NAME = 14 #: A name. Can be an ID or a type.
SPACE = 15 #: Any space characters, including new lines
ENDSTMT = 16 #: End of an statement (``;``).
BACKREF = 17 #: Not a valid C sequence, but used at sub regex patterns.
MISMATCH = 255 #: an error indicator: should never happen in practice.
# Dict to convert from an enum interger into a string.
_name_by_val = {v: k for k, v in dict(vars()).items() if isinstance(v, int)}
# Dict to convert from string to an enum-like integer value.
_name_to_val = {k: v for v, k in _name_by_val.items()}
@staticmethod
def to_name(val):
"""Convert from an integer value from CToken enum into a string"""
return CToken._name_by_val.get(val, f"UNKNOWN({val})")
@staticmethod
def from_name(name):
"""Convert a string into a CToken enum value"""
if name in CToken._name_to_val:
return CToken._name_to_val[name]
return CToken.MISMATCH
def __init__(self, kind, value=None, pos=0,
brace_level=0, paren_level=0, bracket_level=0):
self.kind = kind
self.value = value
self.pos = pos
self.level = (bracket_level, paren_level, brace_level)
def __repr__(self):
name = self.to_name(self.kind)
if isinstance(self.value, str):
value = '"' + self.value + '"'
else:
value = self.value
return f"CToken(CToken.{name}, {value}, {self.pos}, {self.level})"
#: Regexes to parse C code, transforming it into tokens.
RE_SCANNER_LIST = [
#
# Note that \s\S is different than .*, as it also catches \n
#
(CToken.COMMENT, r"//[^\n]*|/\*[\s\S]*?\*/"),
(CToken.STRING, r'"(?:\\.|[^"\\])*"'),
(CToken.CHAR, r"'(?:\\.|[^'\\])'"),
(CToken.NUMBER, r"0[xX][\da-fA-F]+[uUlL]*|0[0-7]+[uUlL]*|"
r"\d+(?:\.\d*)?(?:[eE][+-]?\d+)?[fFlL]*"),
(CToken.ENDSTMT, r"(?:\s+;|;)"),
(CToken.PUNC, r"[,\.]"),
(CToken.BEGIN, r"[\[\(\{]"),
(CToken.END, r"[\]\)\}]"),
(CToken.CPP, r"#\s*(?:define|include|ifdef|ifndef|if|else|elif|endif|undef|pragma)\b"),
(CToken.HASH, r"#"),
(CToken.OP, r"\+\+|\-\-|\->|==|\!=|<=|>=|&&|\|\||<<|>>|\+=|\-=|\*=|/=|%="
r"|&=|\|=|\^=|[=\+\-\*/%<>&\|\^~!\?\:]"),
(CToken.STRUCT, r"\bstruct\b"),
(CToken.UNION, r"\bunion\b"),
(CToken.ENUM, r"\benum\b"),
(CToken.TYPEDEF, r"\btypedef\b"),
(CToken.NAME, r"[A-Za-z_]\w*"),
(CToken.SPACE, r"\s+"),
(CToken.BACKREF, r"\\\d+"),
(CToken.MISMATCH,r"."),
]
def fill_re_scanner(token_list):
"""Ancillary routine to convert RE_SCANNER_LIST into a finditer regex"""
re_tokens = []
for kind, pattern in token_list:
name = CToken.to_name(kind)
re_tokens.append(f"(?P<{name}>{pattern})")
return KernRe("|".join(re_tokens), re.MULTILINE | re.DOTALL)
#: Handle C continuation lines.
RE_CONT = KernRe(r"\\\n")
RE_COMMENT_START = KernRe(r'/\*\s*')
#: tokenizer regex. Will be filled at the first CTokenizer usage.
RE_SCANNER = fill_re_scanner(RE_SCANNER_LIST)
class CTokenizer():
"""
Scan C statements and definitions and produce tokens.
When converted to string, it drops comments and handle public/private
values, respecting depth.
"""
# This class is inspired and follows the basic concepts of:
# https://docs.python.org/3/library/re.html#writing-a-tokenizer
def __init__(self, source=None):
"""
Create a regular expression to handle RE_SCANNER_LIST.
While I generally don't like using regex group naming via:
(?P<name>...)
in this particular case, it makes sense, as we can pick the name
when matching a code via RE_SCANNER.
"""
#
# Store logger to allow parser classes to re-use it
#
global log
self.log = log
self.tokens = []
if not source:
return
if isinstance(source, list):
self.tokens = source
return
#
# While we could just use _tokenize directly via interator,
# As we'll need to use the tokenizer several times inside kernel-doc
# to handle macro transforms, cache the results on a list, as
# re-using it is cheaper than having to parse everytime.
#
for tok in self._tokenize(source):
self.tokens.append(tok)
def _tokenize(self, source):
"""
Iterator that parses ``source``, splitting it into tokens, as defined
at ``self.RE_SCANNER_LIST``.
The interactor returns a CToken class object.
"""
# Handle continuation lines. Note that kdoc_parser already has a
# logic to do that. Still, let's keep it for completeness, as we might
# end re-using this tokenizer outsize kernel-doc some day - or we may
# eventually remove from there as a future cleanup.
source = RE_CONT.sub("", source)
brace_level = 0
paren_level = 0
bracket_level = 0
for match in RE_SCANNER.finditer(source):
kind = CToken.from_name(match.lastgroup)
pos = match.start()
value = match.group()
if kind == CToken.MISMATCH:
log.error(f"Unexpected token '{value}' on pos {pos}:\n\t'{source}'")
elif kind == CToken.BEGIN:
if value == '(':
paren_level += 1
elif value == '[':
bracket_level += 1
else: # value == '{'
brace_level += 1
elif kind == CToken.END:
if value == ')' and paren_level > 0:
paren_level -= 1
elif value == ']' and bracket_level > 0:
bracket_level -= 1
elif brace_level > 0: # value == '}'
brace_level -= 1
yield CToken(kind, value, pos,
brace_level, paren_level, bracket_level)
def __str__(self):
out=""
show_stack = [True]
for i, tok in enumerate(self.tokens):
if tok.kind == CToken.BEGIN:
show_stack.append(show_stack[-1])
elif tok.kind == CToken.END:
prev = show_stack[-1]
if len(show_stack) > 1:
show_stack.pop()
if not prev and show_stack[-1]:
#
# Try to preserve indent
#
out += "\t" * (len(show_stack) - 1)
out += str(tok.value)
continue
elif tok.kind == CToken.COMMENT:
comment = RE_COMMENT_START.sub("", tok.value)
if comment.startswith("private:"):
show_stack[-1] = False
show = False
elif comment.startswith("public:"):
show_stack[-1] = True
continue
if not show_stack[-1]:
continue
if i < len(self.tokens) - 1:
next_tok = self.tokens[i + 1]
# Do some cleanups before ";"
if tok.kind == CToken.SPACE and next_tok.kind == CToken.ENDSTMT:
continue
if tok.kind == CToken.ENDSTMT and next_tok.kind == tok.kind:
continue
out += str(tok.value)
return out
class CTokenArgs:
"""
Ancillary class to help using backrefs from sub matches.
If the highest backref contain a "+" at the last element,
the logic will be greedy, picking all other delims.
This is needed to parse struct_group macros with end with ``MEMBERS...``.
"""
def __init__(self, sub_str):
self.sub_groups = set()
self.max_group = -1
self.greedy = None
for m in KernRe(r'\\(\d+)([+]?)').finditer(sub_str):
group = int(m.group(1))
if m.group(2) == "+":
if self.greedy and self.greedy != group:
raise ValueError("There are multiple greedy patterns!")
self.greedy = group
self.sub_groups.add(group)
self.max_group = max(self.max_group, group)
if self.greedy:
if self.greedy != self.max_group:
raise ValueError("Greedy pattern is not the last one!")
sub_str = KernRe(r'(\\\d+)[+]').sub(r"\1", sub_str)
self.sub_str = sub_str
self.sub_tokeninzer = CTokenizer(sub_str)
def groups(self, new_tokenizer):
r"""
Create replacement arguments for backrefs like:
``\0``, ``\1``, ``\2``, ... ``\{number}``
It also accepts a ``+`` character to the highest backref, like
``\4+``. When used, the backref will be greedy, picking all other
arguments afterwards.
The logic is smart enough to only go up to the maximum required
argument, even if there are more.
If there is a backref for an argument above the limit, it will
raise an exception. Please notice that, on C, square brackets
don't have any separator on it. Trying to use ``\1``..``\n`` for
brackets also raise an exception.
"""
level = (0, 0, 0)
if self.max_group < 0:
return level, []
tokens = new_tokenizer.tokens
#
# Fill \0 with the full token contents
#
groups_list = [ [] ]
if 0 in self.sub_groups:
inner_level = 0
for i in range(0, len(tokens)):
tok = tokens[i]
if tok.kind == CToken.BEGIN:
inner_level += 1
#
# Discard first begin
#
if not groups_list[0]:
continue
elif tok.kind == CToken.END:
inner_level -= 1
if inner_level < 0:
break
if inner_level:
groups_list[0].append(tok)
if not self.max_group:
return level, groups_list
delim = None
#
# Ignore everything before BEGIN. The value of begin gives the
# delimiter to be used for the matches
#
for i in range(0, len(tokens)):
tok = tokens[i]
if tok.kind == CToken.BEGIN:
if tok.value == "{":
delim = ";"
elif tok.value == "(":
delim = ","
else:
self.log.error(fr"Can't handle \1..\n on {sub_str}")
level = tok.level
break
pos = 1
groups_list.append([])
inner_level = 0
for i in range(i + 1, len(tokens)):
tok = tokens[i]
if tok.kind == CToken.BEGIN:
inner_level += 1
if tok.kind == CToken.END:
inner_level -= 1
if inner_level < 0:
break
if tok.kind in [CToken.PUNC, CToken.ENDSTMT] and delim == tok.value:
pos += 1
if self.greedy and pos > self.max_group:
pos -= 1
else:
groups_list.append([])
if pos > self.max_group:
break
continue
groups_list[pos].append(tok)
if pos < self.max_group:
log.error(fr"{self.sub_str} groups are up to {pos} instead of {self.max_group}")
return level, groups_list
def tokens(self, new_tokenizer):
level, groups = self.groups(new_tokenizer)
new = CTokenizer()
for tok in self.sub_tokeninzer.tokens:
if tok.kind == CToken.BACKREF:
group = int(tok.value[1:])
for group_tok in groups[group]:
new_tok = copy(group_tok)
new_level = [0, 0, 0]
for i in range(0, len(level)):
new_level[i] = new_tok.level[i] + level[i]
new_tok.level = tuple(new_level)
new.tokens += [ new_tok ]
else:
new.tokens += [ tok ]
return new.tokens
class CMatch:
"""
Finding nested delimiters is hard with regular expressions. It is
even harder on Python with its normal re module, as there are several
advanced regular expressions that are missing.
This is the case of this pattern::
'\\bSTRUCT_GROUP(\\(((?:(?>[^)(]+)|(?1))*)\\))[^;]*;'
which is used to properly match open/close parentheses of the
string search STRUCT_GROUP(),
Add a class that counts pairs of delimiters, using it to match and
replace nested expressions.
The original approach was suggested by:
https://stackoverflow.com/questions/5454322/python-how-to-match-nested-parentheses-with-regex
Although I re-implemented it to make it more generic and match 3 types
of delimiters. The logic checks if delimiters are paired. If not, it
will ignore the search string.
"""
def __init__(self, regex, delim="("):
self.regex = KernRe("^" + regex + r"\b")
self.start_delim = delim
def _search(self, tokenizer):
"""
Finds paired blocks for a regex that ends with a delimiter.
The suggestion of using finditer to match pairs came from:
https://stackoverflow.com/questions/5454322/python-how-to-match-nested-parentheses-with-regex
but I ended using a different implementation to align all three types
of delimiters and seek for an initial regular expression.
The algorithm seeks for open/close paired delimiters and places them
into a stack, yielding a start/stop position of each match when the
stack is zeroed.
The algorithm should work fine for properly paired lines, but will
silently ignore end delimiters that precede a start delimiter.
This should be OK for kernel-doc parser, as unaligned delimiters
would cause compilation errors. So, we don't need to raise exceptions
to cover such issues.
"""
start = None
started = False
import sys
stack = []
for i, tok in enumerate(tokenizer.tokens):
if start is None:
if tok.kind == CToken.NAME and self.regex.match(tok.value):
start = i
stack.append((start, tok.level))
started = False
continue
if not started:
if tok.kind == CToken.SPACE:
continue
if tok.kind == CToken.BEGIN and tok.value == self.start_delim:
started = True
continue
# Name only token without BEGIN/END
if i > start:
i -= 1
yield start, i
start = None
if tok.kind == CToken.END and tok.level == stack[-1][1]:
start, level = stack.pop()
yield start, i
start = None
#
# If an END zeroing levels is not there, return remaining stuff
# This is meant to solve cases where the caller logic might be
# picking an incomplete block.
#
if start and stack:
if started:
s = str(tokenizer)
log.warning(f"can't find a final end at {s}")
yield start, len(tokenizer.tokens)
def search(self, source):
"""
This is similar to re.search:
It matches a regex that it is followed by a delimiter,
returning occurrences only if all delimiters are paired.
"""
if isinstance(source, CTokenizer):
tokenizer = source
is_token = True
else:
tokenizer = CTokenizer(source)
is_token = False
for start, end in self._search(tokenizer):
new_tokenizer = CTokenizer(tokenizer.tokens[start:end + 1])
if is_token:
yield new_tokenizer
else:
yield str(new_tokenizer)
def sub(self, sub_str, source, count=0):
"""
This is similar to re.sub:
It matches a regex that it is followed by a delimiter,
replacing occurrences only if all delimiters are paired.
if the sub argument contains::
r'\0'
it will work just like re: it places there the matched paired data
with the delimiter stripped.
If count is different than zero, it will replace at most count
items.
"""
if isinstance(source, CTokenizer):
is_token = True
tokenizer = source
else:
is_token = False
tokenizer = CTokenizer(source)
# Detect if sub_str contains sub arguments
args_match = CTokenArgs(sub_str)
new_tokenizer = CTokenizer()
pos = 0
n = 0
#
# NOTE: the code below doesn't consider overlays at sub.
# We may need to add some extra unit tests to check if those
# would cause problems. When replacing by "", this should not
# be a problem, but other transformations could be problematic
#
for start, end in self._search(tokenizer):
new_tokenizer.tokens += tokenizer.tokens[pos:start]
new = CTokenizer(tokenizer.tokens[start:end + 1])
new_tokenizer.tokens += args_match.tokens(new)
pos = end + 1
n += 1
if count and n >= count:
break
new_tokenizer.tokens += tokenizer.tokens[pos:]
if not is_token:
return str(new_tokenizer)
return new_tokenizer
def __repr__(self):
"""
Returns a displayable version of the class init.
"""
return f'CMatch("{self.regex.regex.pattern}")'

Some files were not shown because too many files have changed in this diff Show More