mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
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:
commit
5181afcdf9
|
|
@ -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).
|
||||
|
|
|
|||
357
Documentation/admin-guide/cpu-isolation.rst
Normal file
357
Documentation/admin-guide/cpu-isolation.rst
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)).
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
47
Documentation/admin-guide/sysctl/crypto.rst
Normal file
47
Documentation/admin-guide/sysctl/crypto.rst
Normal 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_)
|
||||
52
Documentation/admin-guide/sysctl/debug.rst
Normal file
52
Documentation/admin-guide/sysctl/debug.rst
Normal 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_)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
31
Documentation/admin-guide/sysctl/xen.rst
Normal file
31
Documentation/admin-guide/sysctl/xen.rst
Normal 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.
|
||||
|
|
@ -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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -9,3 +9,4 @@ IRQs
|
|||
irq-affinity
|
||||
irq-domain
|
||||
irqflags-tracing
|
||||
managed_irq
|
||||
|
|
|
|||
116
Documentation/core-api/irq/managed_irq.rst
Normal file
116
Documentation/core-api/irq/managed_irq.rst
Normal 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.
|
||||
|
||||
Affinity‑managed 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 affinity‑managed 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 re‑enabled.
|
||||
|
||||
Implementation
|
||||
--------------
|
||||
|
||||
Devices must provide per‑instance interrupts, such as per‑I/O‑queue interrupts
|
||||
for storage devices like NVMe. The driver allocates interrupt vectors with the
|
||||
required affinity settings using struct irq_affinity. For MSI‑X 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
|
||||
sub‑parameter of the isolcpus boot option specifies a CPU mask that managed
|
||||
interrupts should attempt to avoid. This isolation is best‑effort 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 interrupt’s affinity mask.
|
||||
This means that if all non‑isolated 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 MSI‑X 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 MSI‑X 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 5–7 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.
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
==================
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
-------------------------------
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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 !
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
| mips: | ok |
|
||||
| nios2: | TODO |
|
||||
| openrisc: | TODO |
|
||||
| parisc: | TODO |
|
||||
| parisc: | ok |
|
||||
| powerpc: | ok |
|
||||
| riscv: | ok |
|
||||
| s390: | ok |
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
| mips: | ok |
|
||||
| nios2: | TODO |
|
||||
| openrisc: | TODO |
|
||||
| parisc: | TODO |
|
||||
| parisc: | ok |
|
||||
| powerpc: | ok |
|
||||
| riscv: | ok |
|
||||
| s390: | ok |
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. _maintainer_handbooks_main:
|
||||
|
||||
Subsystem and maintainer tree specific development process notes
|
||||
================================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(...)
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ all_languages = {
|
|||
'it_IT': 'Italian',
|
||||
'ja_JP': 'Japanese',
|
||||
'ko_KR': 'Korean',
|
||||
'pt_BR': 'Portuguese (Brazilian)',
|
||||
'sp_SP': 'Spanish',
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
====================
|
||||
|
||||
|
|
|
|||
|
|
@ -11,3 +11,5 @@ Python libraries
|
|||
feat
|
||||
kdoc
|
||||
kabi
|
||||
|
||||
unittest
|
||||
|
|
|
|||
|
|
@ -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
|
||||
======
|
||||
|
|
|
|||
|
|
@ -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
|
||||
======
|
||||
|
|
|
|||
|
|
@ -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
|
||||
======
|
||||
|
|
|
|||
|
|
@ -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
|
||||
======
|
||||
|
|
|
|||
|
|
@ -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
|
||||
======
|
||||
|
|
|
|||
|
|
@ -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
|
||||
------
|
||||
|
|
|
|||
|
|
@ -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
|
||||
======
|
||||
|
|
|
|||
|
|
@ -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
|
||||
======
|
||||
|
|
|
|||
24
Documentation/tools/unittest.rst
Normal file
24
Documentation/tools/unittest.rst
Normal 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:
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
11
Documentation/translations/pt_BR/disclaimer-pt_BR.rst
Normal file
11
Documentation/translations/pt_BR/disclaimer-pt_BR.rst
Normal 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.
|
||||
77
Documentation/translations/pt_BR/index.rst
Normal file
77
Documentation/translations/pt_BR/index.rst
Normal 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>
|
||||
269
Documentation/translations/pt_BR/process/1.Intro.rst
Normal file
269
Documentation/translations/pt_BR/process/1.Intro.rst
Normal 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.
|
||||
576
Documentation/translations/pt_BR/process/changes.rst
Normal file
576
Documentation/translations/pt_BR/process/changes.rst
Normal 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/>
|
||||
40
Documentation/translations/pt_BR/process/conclave.rst
Normal file
40
Documentation/translations/pt_BR/process/conclave.rst
Normal 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.
|
||||
637
Documentation/translations/pt_BR/process/howto.rst
Normal file
637
Documentation/translations/pt_BR/process/howto.rst
Normal 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>
|
||||
|
|
@ -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
|
||||
435
Documentation/translations/pt_BR/process/maintainer-kvm-x86.rst
Normal file
435
Documentation/translations/pt_BR/process/maintainer-kvm-x86.rst
Normal 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.
|
||||
596
Documentation/translations/pt_BR/process/maintainer-netdev.rst
Normal file
596
Documentation/translations/pt_BR/process/maintainer-netdev.rst
Normal 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).
|
||||
|
|
@ -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.
|
||||
222
Documentation/translations/pt_BR/process/maintainer-soc.rst
Normal file
222
Documentation/translations/pt_BR/process/maintainer-soc.rst
Normal 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``.
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
--------------------------------
|
||||
|
|
|
|||
|
|
@ -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(...)
|
||||
|
||||
|
|
|
|||
|
|
@ -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警告,并试图把转换的工作推给维护者,他们会很
|
||||
恼火。你将不得不为每个警告争论是否真的可以溢出。
|
||||
|
|
|
|||
|
|
@ -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 可能是通用的讨论场所,但它不是寻找所有
|
||||
子系统开发人员的最佳场所。
|
||||
|
|
|
|||
|
|
@ -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”将运行这些语义补丁并报告发现的任何问题。有关详细信息,请参阅
|
||||
|
|
|
|||
|
|
@ -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``。
|
||||
============= ================ ==============================================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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 13(Trixie)以及 Testing 和 Debian Unstable(Sid)提供较新的 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
|
||||
***
|
||||
|
||||
Nix(unstable 频道)提供较新的 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的名字。
|
||||
|
|
|
|||
|
|
@ -144,8 +144,8 @@ array)。
|
|||
|
||||
- yield_task(...)
|
||||
|
||||
这个函数的行为基本上是出队,紧接着入队,除非compat_yield sysctl被开启。在那种情况下,
|
||||
它将调度实体放在红黑树的最右端。
|
||||
此函数通过将当前任务在运行队列中的位置后移来让出 CPU,
|
||||
使得其他可运行的任务优先被调度。
|
||||
|
||||
- wakeup_preempt(...)
|
||||
|
||||
|
|
|
|||
|
|
@ -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位體系架構,只要它們有一個分頁內存管理
|
||||
|
|
|
|||
|
|
@ -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”將運行這些語義補丁並報告發現的任何問題。有關詳細信息,請參閱
|
||||
|
|
|
|||
10
MAINTAINERS
10
MAINTAINERS
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
508
tools/docs/kdoc_diff
Executable 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 kernel‑doc output between two different
|
||||
commits.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Compare the kernel‑doc 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()
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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}")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
662
tools/lib/python/kdoc/c_lex.py
Normal file
662
tools/lib/python/kdoc/c_lex.py
Normal 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 module‑level 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
Loading…
Reference in New Issue
Block a user