mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
A handful of obvious fixes that wandered in during the merge window.
-----BEGIN PGP SIGNATURE----- iQFDBAABCAAtFiEEIw+MvkEiF49krdp9F0NaE2wMflgFAl81p3sPHGNvcmJldEBs d24ubmV0AAoJEBdDWhNsDH5YTDAH/i+boeUlQsiobPcnfF7jxjQWd2wy9GVT6y7k RQsifOIIsJZB8DN/ChYbeFemtnn495HaIrwN4QvQss82A2NpaGYCRR8D4vncqLHL 1K36JLHE/5dOFvaKUvAVIquEcwuyvmRNU0Bbyz/3kzNUf8KkovDzoJ7xZ/2n/fev hksn3RChj1osJNViSGBkHEjF6NJ46gzNtbt4mW88/jDZNCENK7rZQWbwUvrvZ4ze B1LfMFYuZhm6s4sooBxO6y2njuzmKLoykM9MQFr5PXLuexHTcMlS5mpHVqvQsJ8l 70G2zXZiGUwxboC1YW7aRUEhkASVsXTb077zOVYXWY6duUqWVFs= =tuId -----END PGP SIGNATURE----- Merge tag 'docs-5.9-2' of git://git.lwn.net/linux Pull documentation fixes from Jonathan Corbet: "A handful of obvious fixes that wandered in during the merge window" * tag 'docs-5.9-2' of git://git.lwn.net/linux: Documentation/locking/locktypes: fix the typo doc/zh_CN: resolve undefined label warning in admin-guide index doc/zh_CN: fix title heading markup in admin-guide cpu-load docs: remove the 2.6 "Upgrading I2C Drivers" guide docs: Correct the release date of 5.2 stable mailmap: Update comments for with format and more detalis docs: cdrom: Fix a typo and rst markup Doc: admin-guide: use correct legends in kernel-parameters.txt Documentation/features: refresh RISC-V arch support files documentation: coccinelle: Improve command example for make C={1,2} Core-api: Documentation: Replace deprecated :c:func: Usage Dev-tools: Documentation: Replace deprecated :c:func: Usage Filesystems: Documentation: Replace deprecated :c:func: Usage docs: trace: fix a typo
This commit is contained in:
commit
dddcbc139e
9
.mailmap
9
.mailmap
@ -2,11 +2,16 @@
|
||||
# This list is used by git-shortlog to fix a few botched name translations
|
||||
# in the git archive, either because the author's full name was messed up
|
||||
# and/or not always written the same way, making contributions from the
|
||||
# same person appearing not to be so or badly displayed.
|
||||
# same person appearing not to be so or badly displayed. Also allows for
|
||||
# old email addresses to map to new email addresses.
|
||||
#
|
||||
# For format details, see "MAPPING AUTHORS" in "man git-shortlog".
|
||||
#
|
||||
# Please keep this list dictionary sorted.
|
||||
#
|
||||
# This comment is parsed by git-shortlog:
|
||||
# repo-abbrev: /pub/scm/linux/kernel/git/
|
||||
#
|
||||
|
||||
Aaron Durbin <adurbin@google.com>
|
||||
Adam Oldham <oldhamca@gmail.com>
|
||||
Adam Radford <aradford@gmail.com>
|
||||
|
@ -724,7 +724,7 @@
|
||||
memory region [offset, offset + size] for that kernel
|
||||
image. If '@offset' is omitted, then a suitable offset
|
||||
is selected automatically.
|
||||
[KNL, x86_64] select a region under 4G first, and
|
||||
[KNL, X86-64] Select a region under 4G first, and
|
||||
fall back to reserve region above 4G when '@offset'
|
||||
hasn't been specified.
|
||||
See Documentation/admin-guide/kdump/kdump.rst for further details.
|
||||
@ -737,14 +737,14 @@
|
||||
Documentation/admin-guide/kdump/kdump.rst for an example.
|
||||
|
||||
crashkernel=size[KMG],high
|
||||
[KNL, x86_64] range could be above 4G. Allow kernel
|
||||
[KNL, X86-64] range could be above 4G. Allow kernel
|
||||
to allocate physical memory region from top, so could
|
||||
be above 4G if system have more than 4G ram installed.
|
||||
Otherwise memory region will be allocated below 4G, if
|
||||
available.
|
||||
It will be ignored if crashkernel=X is specified.
|
||||
crashkernel=size[KMG],low
|
||||
[KNL, x86_64] range under 4G. When crashkernel=X,high
|
||||
[KNL, X86-64] range under 4G. When crashkernel=X,high
|
||||
is passed, kernel could allocate physical memory region
|
||||
above 4G, that cause second kernel crash on system
|
||||
that require some amount of low memory, e.g. swiotlb
|
||||
@ -1427,7 +1427,7 @@
|
||||
|
||||
gamma= [HW,DRM]
|
||||
|
||||
gart_fix_e820= [X86_64] disable the fix e820 for K8 GART
|
||||
gart_fix_e820= [X86-64] disable the fix e820 for K8 GART
|
||||
Format: off | on
|
||||
default: on
|
||||
|
||||
@ -1814,7 +1814,7 @@
|
||||
Format: 0 | 1
|
||||
Default set by CONFIG_INIT_ON_FREE_DEFAULT_ON.
|
||||
|
||||
init_pkru= [x86] Specify the default memory protection keys rights
|
||||
init_pkru= [X86] Specify the default memory protection keys rights
|
||||
register contents for all processes. 0x55555554 by
|
||||
default (disallow access to all but pkey 0). Can
|
||||
override in debugfs after boot.
|
||||
@ -1822,7 +1822,7 @@
|
||||
inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver
|
||||
Format: <irq>
|
||||
|
||||
int_pln_enable [x86] Enable power limit notification interrupt
|
||||
int_pln_enable [X86] Enable power limit notification interrupt
|
||||
|
||||
integrity_audit=[IMA]
|
||||
Format: { "0" | "1" }
|
||||
@ -1840,7 +1840,7 @@
|
||||
bypassed by not enabling DMAR with this option. In
|
||||
this case, gfx device will use physical address for
|
||||
DMA.
|
||||
forcedac [x86_64]
|
||||
forcedac [X86-64]
|
||||
With this option iommu will not optimize to look
|
||||
for io virtual address below 32-bit forcing dual
|
||||
address cycle on pci bus for cards supporting greater
|
||||
@ -1925,7 +1925,7 @@
|
||||
strict regions from userspace.
|
||||
relaxed
|
||||
|
||||
iommu= [x86]
|
||||
iommu= [X86]
|
||||
off
|
||||
force
|
||||
noforce
|
||||
@ -1935,8 +1935,8 @@
|
||||
merge
|
||||
nomerge
|
||||
soft
|
||||
pt [x86]
|
||||
nopt [x86]
|
||||
pt [X86]
|
||||
nopt [X86]
|
||||
nobypass [PPC/POWERNV]
|
||||
Disable IOMMU bypass, using IOMMU for PCI devices.
|
||||
|
||||
@ -2079,21 +2079,21 @@
|
||||
|
||||
iucv= [HW,NET]
|
||||
|
||||
ivrs_ioapic [HW,X86_64]
|
||||
ivrs_ioapic [HW,X86-64]
|
||||
Provide an override to the IOAPIC-ID<->DEVICE-ID
|
||||
mapping provided in the IVRS ACPI table. For
|
||||
example, to map IOAPIC-ID decimal 10 to
|
||||
PCI device 00:14.0 write the parameter as:
|
||||
ivrs_ioapic[10]=00:14.0
|
||||
|
||||
ivrs_hpet [HW,X86_64]
|
||||
ivrs_hpet [HW,X86-64]
|
||||
Provide an override to the HPET-ID<->DEVICE-ID
|
||||
mapping provided in the IVRS ACPI table. For
|
||||
example, to map HPET-ID decimal 0 to
|
||||
PCI device 00:14.0 write the parameter as:
|
||||
ivrs_hpet[0]=00:14.0
|
||||
|
||||
ivrs_acpihid [HW,X86_64]
|
||||
ivrs_acpihid [HW,X86-64]
|
||||
Provide an override to the ACPI-HID:UID<->DEVICE-ID
|
||||
mapping provided in the IVRS ACPI table. For
|
||||
example, to map UART-HID:UID AMD0020:0 to
|
||||
@ -2370,7 +2370,7 @@
|
||||
lapic [X86-32,APIC] Enable the local APIC even if BIOS
|
||||
disabled it.
|
||||
|
||||
lapic= [x86,APIC] "notscdeadline" Do not use TSC deadline
|
||||
lapic= [X86,APIC] "notscdeadline" Do not use TSC deadline
|
||||
value for LAPIC timer one-shot implementation. Default
|
||||
back to the programmable timer unit in the LAPIC.
|
||||
|
||||
@ -3188,12 +3188,12 @@
|
||||
register save and restore. The kernel will only save
|
||||
legacy floating-point registers on task switch.
|
||||
|
||||
nohugeiomap [KNL,x86,PPC] Disable kernel huge I/O mappings.
|
||||
nohugeiomap [KNL,X86,PPC] Disable kernel huge I/O mappings.
|
||||
|
||||
nosmt [KNL,S390] Disable symmetric multithreading (SMT).
|
||||
Equivalent to smt=1.
|
||||
|
||||
[KNL,x86] Disable symmetric multithreading (SMT).
|
||||
[KNL,X86] Disable symmetric multithreading (SMT).
|
||||
nosmt=force: Force disable SMT, cannot be undone
|
||||
via the sysfs control file.
|
||||
|
||||
@ -3955,7 +3955,7 @@
|
||||
pt. [PARIDE]
|
||||
See Documentation/admin-guide/blockdev/paride.rst.
|
||||
|
||||
pti= [X86_64] Control Page Table Isolation of user and
|
||||
pti= [X86-64] Control Page Table Isolation of user and
|
||||
kernel address spaces. Disabling this feature
|
||||
removes hardening, but improves performance of
|
||||
system calls and interrupts.
|
||||
@ -3967,7 +3967,7 @@
|
||||
|
||||
Not specifying this option is equivalent to pti=auto.
|
||||
|
||||
nopti [X86_64]
|
||||
nopti [X86-64]
|
||||
Equivalent to pti=off
|
||||
|
||||
pty.legacy_count=
|
||||
|
@ -557,7 +557,7 @@ phase. Currently, the capabilities are any of::
|
||||
CDC_DRIVE_STATUS /* driver implements drive status */
|
||||
|
||||
The capability flag is declared *const*, to prevent drivers from
|
||||
accidentally tampering with the contents. The capability fags actually
|
||||
accidentally tampering with the contents. The capability flags actually
|
||||
inform `cdrom.c` of what the driver can do. If the drive found
|
||||
by the driver does not have the capability, is can be masked out by
|
||||
the *cdrom_device_info* variable *mask*. For instance, the SCSI CD-ROM
|
||||
@ -736,7 +736,7 @@ Description of routines in `cdrom.c`
|
||||
|
||||
Only a few routines in `cdrom.c` are exported to the drivers. In this
|
||||
new section we will discuss these, as well as the functions that `take
|
||||
over' the CD-ROM interface to the kernel. The header file belonging
|
||||
over` the CD-ROM interface to the kernel. The header file belonging
|
||||
to `cdrom.c` is called `cdrom.h`. Formerly, some of the contents of this
|
||||
file were placed in the file `ucdrom.h`, but this file has now been
|
||||
merged back into `cdrom.h`.
|
||||
|
@ -20,48 +20,48 @@ only ID allocation, and as a result is much more memory-efficient.
|
||||
IDR usage
|
||||
=========
|
||||
|
||||
Start by initialising an IDR, either with :c:func:`DEFINE_IDR`
|
||||
for statically allocated IDRs or :c:func:`idr_init` for dynamically
|
||||
Start by initialising an IDR, either with DEFINE_IDR()
|
||||
for statically allocated IDRs or idr_init() for dynamically
|
||||
allocated IDRs.
|
||||
|
||||
You can call :c:func:`idr_alloc` to allocate an unused ID. Look up
|
||||
the pointer you associated with the ID by calling :c:func:`idr_find`
|
||||
and free the ID by calling :c:func:`idr_remove`.
|
||||
You can call idr_alloc() to allocate an unused ID. Look up
|
||||
the pointer you associated with the ID by calling idr_find()
|
||||
and free the ID by calling idr_remove().
|
||||
|
||||
If you need to change the pointer associated with an ID, you can call
|
||||
:c:func:`idr_replace`. One common reason to do this is to reserve an
|
||||
idr_replace(). One common reason to do this is to reserve an
|
||||
ID by passing a ``NULL`` pointer to the allocation function; initialise the
|
||||
object with the reserved ID and finally insert the initialised object
|
||||
into the IDR.
|
||||
|
||||
Some users need to allocate IDs larger than ``INT_MAX``. So far all of
|
||||
these users have been content with a ``UINT_MAX`` limit, and they use
|
||||
:c:func:`idr_alloc_u32`. If you need IDs that will not fit in a u32,
|
||||
idr_alloc_u32(). If you need IDs that will not fit in a u32,
|
||||
we will work with you to address your needs.
|
||||
|
||||
If you need to allocate IDs sequentially, you can use
|
||||
:c:func:`idr_alloc_cyclic`. The IDR becomes less efficient when dealing
|
||||
idr_alloc_cyclic(). The IDR becomes less efficient when dealing
|
||||
with larger IDs, so using this function comes at a slight cost.
|
||||
|
||||
To perform an action on all pointers used by the IDR, you can
|
||||
either use the callback-based :c:func:`idr_for_each` or the
|
||||
iterator-style :c:func:`idr_for_each_entry`. You may need to use
|
||||
:c:func:`idr_for_each_entry_continue` to continue an iteration. You can
|
||||
also use :c:func:`idr_get_next` if the iterator doesn't fit your needs.
|
||||
either use the callback-based idr_for_each() or the
|
||||
iterator-style idr_for_each_entry(). You may need to use
|
||||
idr_for_each_entry_continue() to continue an iteration. You can
|
||||
also use idr_get_next() if the iterator doesn't fit your needs.
|
||||
|
||||
When you have finished using an IDR, you can call :c:func:`idr_destroy`
|
||||
When you have finished using an IDR, you can call idr_destroy()
|
||||
to release the memory used by the IDR. This will not free the objects
|
||||
pointed to from the IDR; if you want to do that, use one of the iterators
|
||||
to do it.
|
||||
|
||||
You can use :c:func:`idr_is_empty` to find out whether there are any
|
||||
You can use idr_is_empty() to find out whether there are any
|
||||
IDs currently allocated.
|
||||
|
||||
If you need to take a lock while allocating a new ID from the IDR,
|
||||
you may need to pass a restrictive set of GFP flags, which can lead
|
||||
to the IDR being unable to allocate memory. To work around this,
|
||||
you can call :c:func:`idr_preload` before taking the lock, and then
|
||||
:c:func:`idr_preload_end` after the allocation.
|
||||
you can call idr_preload() before taking the lock, and then
|
||||
idr_preload_end() after the allocation.
|
||||
|
||||
.. kernel-doc:: include/linux/idr.h
|
||||
:doc: idr sync
|
||||
|
@ -175,13 +175,20 @@ For example, to check drivers/net/wireless/ one may write::
|
||||
make coccicheck M=drivers/net/wireless/
|
||||
|
||||
To apply Coccinelle on a file basis, instead of a directory basis, the
|
||||
following command may be used::
|
||||
C variable is used by the makefile to select which files to work with.
|
||||
This variable can be used to run scripts for the entire kernel, a
|
||||
specific directory, or for a single file.
|
||||
|
||||
make C=1 CHECK="scripts/coccicheck"
|
||||
For example, to check drivers/bluetooth/bfusb.c, the value 1 is
|
||||
passed to the C variable to check files that make considers
|
||||
need to be compiled.::
|
||||
|
||||
To check only newly edited code, use the value 2 for the C flag, i.e.::
|
||||
make C=1 CHECK=scripts/coccicheck drivers/bluetooth/bfusb.o
|
||||
|
||||
make C=2 CHECK="scripts/coccicheck"
|
||||
The value 2 is passed to the C variable to check files regardless of
|
||||
whether they need to be compiled or not.::
|
||||
|
||||
make C=2 CHECK=scripts/coccicheck drivers/bluetooth/bfusb.o
|
||||
|
||||
In these modes, which work on a file basis, there is no information
|
||||
about semantic patches displayed, and no commit message proposed.
|
||||
|
@ -316,7 +316,7 @@ driver as a loadable kernel module kgdbwait will not do anything.
|
||||
Kernel parameter: ``kgdbcon``
|
||||
-----------------------------
|
||||
|
||||
The ``kgdbcon`` feature allows you to see :c:func:`printk` messages inside gdb
|
||||
The ``kgdbcon`` feature allows you to see printk() messages inside gdb
|
||||
while gdb is connected to the kernel. Kdb does not make use of the kgdbcon
|
||||
feature.
|
||||
|
||||
@ -432,7 +432,7 @@ This is a quick example of how to use kdb.
|
||||
``ps`` Displays only the active processes
|
||||
``ps A`` Shows all the processes
|
||||
``summary`` Shows kernel version info and memory usage
|
||||
``bt`` Get a backtrace of the current process using :c:func:`dump_stack`
|
||||
``bt`` Get a backtrace of the current process using dump_stack()
|
||||
``dmesg`` View the kernel syslog buffer
|
||||
``go`` Continue the system
|
||||
=========== =================================================================
|
||||
@ -724,7 +724,7 @@ The kernel debugger is organized into a number of components:
|
||||
The arch-specific portion implements:
|
||||
|
||||
- contains an arch-specific trap catcher which invokes
|
||||
:c:func:`kgdb_handle_exception` to start kgdb about doing its work
|
||||
kgdb_handle_exception() to start kgdb about doing its work
|
||||
|
||||
- translation to and from gdb specific packet format to :c:type:`pt_regs`
|
||||
|
||||
@ -769,7 +769,7 @@ The kernel debugger is organized into a number of components:
|
||||
config. Later run ``modprobe kdb_hello`` and the next time you
|
||||
enter the kdb shell, you can run the ``hello`` command.
|
||||
|
||||
- The implementation for :c:func:`kdb_printf` which emits messages directly
|
||||
- The implementation for kdb_printf() which emits messages directly
|
||||
to I/O drivers, bypassing the kernel log.
|
||||
|
||||
- SW / HW breakpoint management for the kdb shell
|
||||
@ -875,7 +875,7 @@ kernel when ``CONFIG_KDB_KEYBOARD=y`` is set in the kernel configuration.
|
||||
The core polled keyboard driver for PS/2 type keyboards is in
|
||||
``drivers/char/kdb_keyboard.c``. This driver is hooked into the debug core
|
||||
when kgdboc populates the callback in the array called
|
||||
:c:type:`kdb_poll_funcs[]`. The :c:func:`kdb_get_kbd_char` is the top-level
|
||||
:c:type:`kdb_poll_funcs[]`. The kdb_get_kbd_char() is the top-level
|
||||
function which polls hardware for single character input.
|
||||
|
||||
kgdboc and kms
|
||||
@ -887,10 +887,10 @@ that you have a video driver which has a frame buffer console and atomic
|
||||
kernel mode setting support.
|
||||
|
||||
Every time the kernel debugger is entered it calls
|
||||
:c:func:`kgdboc_pre_exp_handler` which in turn calls :c:func:`con_debug_enter`
|
||||
kgdboc_pre_exp_handler() which in turn calls con_debug_enter()
|
||||
in the virtual console layer. On resuming kernel execution, the kernel
|
||||
debugger calls :c:func:`kgdboc_post_exp_handler` which in turn calls
|
||||
:c:func:`con_debug_leave`.
|
||||
debugger calls kgdboc_post_exp_handler() which in turn calls
|
||||
con_debug_leave().
|
||||
|
||||
Any video driver that wants to be compatible with the kernel debugger
|
||||
and the atomic kms callbacks must implement the ``mode_set_base_atomic``,
|
||||
|
@ -23,7 +23,7 @@
|
||||
| openrisc: | TODO |
|
||||
| parisc: | TODO |
|
||||
| powerpc: | ok |
|
||||
| riscv: | TODO |
|
||||
| riscv: | ok |
|
||||
| s390: | ok |
|
||||
| sh: | ok |
|
||||
| sparc: | ok |
|
||||
|
@ -23,7 +23,7 @@
|
||||
| openrisc: | TODO |
|
||||
| parisc: | TODO |
|
||||
| powerpc: | ok |
|
||||
| riscv: | TODO |
|
||||
| riscv: | ok |
|
||||
| s390: | TODO |
|
||||
| sh: | ok |
|
||||
| sparc: | TODO |
|
||||
|
@ -23,7 +23,7 @@
|
||||
| openrisc: | ok |
|
||||
| parisc: | TODO |
|
||||
| powerpc: | ok |
|
||||
| riscv: | TODO |
|
||||
| riscv: | ok |
|
||||
| s390: | ok |
|
||||
| sh: | ok |
|
||||
| sparc: | ok |
|
||||
|
@ -23,7 +23,7 @@
|
||||
| openrisc: | TODO |
|
||||
| parisc: | TODO |
|
||||
| powerpc: | ok |
|
||||
| riscv: | TODO |
|
||||
| riscv: | ok |
|
||||
| s390: | TODO |
|
||||
| sh: | TODO |
|
||||
| sparc: | ok |
|
||||
|
@ -10,27 +10,27 @@ Details
|
||||
The journalling layer is easy to use. You need to first of all create a
|
||||
journal_t data structure. There are two calls to do this dependent on
|
||||
how you decide to allocate the physical media on which the journal
|
||||
resides. The :c:func:`jbd2_journal_init_inode` call is for journals stored in
|
||||
filesystem inodes, or the :c:func:`jbd2_journal_init_dev` call can be used
|
||||
resides. The jbd2_journal_init_inode() call is for journals stored in
|
||||
filesystem inodes, or the jbd2_journal_init_dev() call can be used
|
||||
for journal stored on a raw device (in a continuous range of blocks). A
|
||||
journal_t is a typedef for a struct pointer, so when you are finally
|
||||
finished make sure you call :c:func:`jbd2_journal_destroy` on it to free up
|
||||
finished make sure you call jbd2_journal_destroy() on it to free up
|
||||
any used kernel memory.
|
||||
|
||||
Once you have got your journal_t object you need to 'mount' or load the
|
||||
journal file. The journalling layer expects the space for the journal
|
||||
was already allocated and initialized properly by the userspace tools.
|
||||
When loading the journal you must call :c:func:`jbd2_journal_load` to process
|
||||
When loading the journal you must call jbd2_journal_load() to process
|
||||
journal contents. If the client file system detects the journal contents
|
||||
does not need to be processed (or even need not have valid contents), it
|
||||
may call :c:func:`jbd2_journal_wipe` to clear the journal contents before
|
||||
calling :c:func:`jbd2_journal_load`.
|
||||
may call jbd2_journal_wipe() to clear the journal contents before
|
||||
calling jbd2_journal_load().
|
||||
|
||||
Note that jbd2_journal_wipe(..,0) calls
|
||||
:c:func:`jbd2_journal_skip_recovery` for you if it detects any outstanding
|
||||
transactions in the journal and similarly :c:func:`jbd2_journal_load` will
|
||||
call :c:func:`jbd2_journal_recover` if necessary. I would advise reading
|
||||
:c:func:`ext4_load_journal` in fs/ext4/super.c for examples on this stage.
|
||||
jbd2_journal_skip_recovery() for you if it detects any outstanding
|
||||
transactions in the journal and similarly jbd2_journal_load() will
|
||||
call jbd2_journal_recover() if necessary. I would advise reading
|
||||
ext4_load_journal() in fs/ext4/super.c for examples on this stage.
|
||||
|
||||
Now you can go ahead and start modifying the underlying filesystem.
|
||||
Almost.
|
||||
@ -39,57 +39,57 @@ You still need to actually journal your filesystem changes, this is done
|
||||
by wrapping them into transactions. Additionally you also need to wrap
|
||||
the modification of each of the buffers with calls to the journal layer,
|
||||
so it knows what the modifications you are actually making are. To do
|
||||
this use :c:func:`jbd2_journal_start` which returns a transaction handle.
|
||||
this use jbd2_journal_start() which returns a transaction handle.
|
||||
|
||||
:c:func:`jbd2_journal_start` and its counterpart :c:func:`jbd2_journal_stop`,
|
||||
jbd2_journal_start() and its counterpart jbd2_journal_stop(),
|
||||
which indicates the end of a transaction are nestable calls, so you can
|
||||
reenter a transaction if necessary, but remember you must call
|
||||
:c:func:`jbd2_journal_stop` the same number of times as
|
||||
:c:func:`jbd2_journal_start` before the transaction is completed (or more
|
||||
jbd2_journal_stop() the same number of times as
|
||||
jbd2_journal_start() before the transaction is completed (or more
|
||||
accurately leaves the update phase). Ext4/VFS makes use of this feature to
|
||||
simplify handling of inode dirtying, quota support, etc.
|
||||
|
||||
Inside each transaction you need to wrap the modifications to the
|
||||
individual buffers (blocks). Before you start to modify a buffer you
|
||||
need to call :c:func:`jbd2_journal_get_create_access()` /
|
||||
:c:func:`jbd2_journal_get_write_access()` /
|
||||
:c:func:`jbd2_journal_get_undo_access()` as appropriate, this allows the
|
||||
need to call jbd2_journal_get_create_access() /
|
||||
jbd2_journal_get_write_access() /
|
||||
jbd2_journal_get_undo_access() as appropriate, this allows the
|
||||
journalling layer to copy the unmodified
|
||||
data if it needs to. After all the buffer may be part of a previously
|
||||
uncommitted transaction. At this point you are at last ready to modify a
|
||||
buffer, and once you are have done so you need to call
|
||||
:c:func:`jbd2_journal_dirty_metadata`. Or if you've asked for access to a
|
||||
jbd2_journal_dirty_metadata(). Or if you've asked for access to a
|
||||
buffer you now know is now longer required to be pushed back on the
|
||||
device you can call :c:func:`jbd2_journal_forget` in much the same way as you
|
||||
might have used :c:func:`bforget` in the past.
|
||||
device you can call jbd2_journal_forget() in much the same way as you
|
||||
might have used bforget() in the past.
|
||||
|
||||
A :c:func:`jbd2_journal_flush` may be called at any time to commit and
|
||||
A jbd2_journal_flush() may be called at any time to commit and
|
||||
checkpoint all your transactions.
|
||||
|
||||
Then at umount time , in your :c:func:`put_super` you can then call
|
||||
:c:func:`jbd2_journal_destroy` to clean up your in-core journal object.
|
||||
Then at umount time , in your put_super() you can then call
|
||||
jbd2_journal_destroy() to clean up your in-core journal object.
|
||||
|
||||
Unfortunately there a couple of ways the journal layer can cause a
|
||||
deadlock. The first thing to note is that each task can only have a
|
||||
single outstanding transaction at any one time, remember nothing commits
|
||||
until the outermost :c:func:`jbd2_journal_stop`. This means you must complete
|
||||
until the outermost jbd2_journal_stop(). This means you must complete
|
||||
the transaction at the end of each file/inode/address etc. operation you
|
||||
perform, so that the journalling system isn't re-entered on another
|
||||
journal. Since transactions can't be nested/batched across differing
|
||||
journals, and another filesystem other than yours (say ext4) may be
|
||||
modified in a later syscall.
|
||||
|
||||
The second case to bear in mind is that :c:func:`jbd2_journal_start` can block
|
||||
The second case to bear in mind is that jbd2_journal_start() can block
|
||||
if there isn't enough space in the journal for your transaction (based
|
||||
on the passed nblocks param) - when it blocks it merely(!) needs to wait
|
||||
for transactions to complete and be committed from other tasks, so
|
||||
essentially we are waiting for :c:func:`jbd2_journal_stop`. So to avoid
|
||||
deadlocks you must treat :c:func:`jbd2_journal_start` /
|
||||
:c:func:`jbd2_journal_stop` as if they were semaphores and include them in
|
||||
essentially we are waiting for jbd2_journal_stop(). So to avoid
|
||||
deadlocks you must treat jbd2_journal_start() /
|
||||
jbd2_journal_stop() as if they were semaphores and include them in
|
||||
your semaphore ordering rules to prevent
|
||||
deadlocks. Note that :c:func:`jbd2_journal_extend` has similar blocking
|
||||
behaviour to :c:func:`jbd2_journal_start` so you can deadlock here just as
|
||||
easily as on :c:func:`jbd2_journal_start`.
|
||||
deadlocks. Note that jbd2_journal_extend() has similar blocking
|
||||
behaviour to jbd2_journal_start() so you can deadlock here just as
|
||||
easily as on jbd2_journal_start().
|
||||
|
||||
Try to reserve the right number of blocks the first time. ;-). This will
|
||||
be the maximum number of blocks you are going to touch in this
|
||||
@ -116,8 +116,8 @@ called after each transaction commit. You can also use
|
||||
that need processing when the transaction commits.
|
||||
|
||||
JBD2 also provides a way to block all transaction updates via
|
||||
:c:func:`jbd2_journal_lock_updates()` /
|
||||
:c:func:`jbd2_journal_unlock_updates()`. Ext4 uses this when it wants a
|
||||
jbd2_journal_lock_updates() /
|
||||
jbd2_journal_unlock_updates(). Ext4 uses this when it wants a
|
||||
window with a clean and stable fs for a moment. E.g.
|
||||
|
||||
::
|
||||
|
@ -62,7 +62,6 @@ Legacy documentation
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
upgrading-clients
|
||||
old-module-parameters
|
||||
|
||||
.. only:: subproject and html
|
||||
|
@ -1,285 +0,0 @@
|
||||
=================================================
|
||||
Upgrading I2C Drivers to the new 2.6 Driver Model
|
||||
=================================================
|
||||
|
||||
Ben Dooks <ben-linux@fluff.org>
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This guide outlines how to alter existing Linux 2.6 client drivers from
|
||||
the old to the new binding methods.
|
||||
|
||||
|
||||
Example old-style driver
|
||||
------------------------
|
||||
|
||||
::
|
||||
|
||||
struct example_state {
|
||||
struct i2c_client client;
|
||||
....
|
||||
};
|
||||
|
||||
static struct i2c_driver example_driver;
|
||||
|
||||
static unsigned short ignore[] = { I2C_CLIENT_END };
|
||||
static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
|
||||
|
||||
I2C_CLIENT_INSMOD;
|
||||
|
||||
static int example_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||
{
|
||||
struct example_state *state;
|
||||
struct device *dev = &adap->dev; /* to use for dev_ reports */
|
||||
int ret;
|
||||
|
||||
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
|
||||
if (state == NULL) {
|
||||
dev_err(dev, "failed to create our state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
example->client.addr = addr;
|
||||
example->client.flags = 0;
|
||||
example->client.adapter = adap;
|
||||
|
||||
i2c_set_clientdata(&state->i2c_client, state);
|
||||
strscpy(client->i2c_client.name, "example", sizeof(client->i2c_client.name));
|
||||
|
||||
ret = i2c_attach_client(&state->i2c_client);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to attach client\n");
|
||||
kfree(state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev = &state->i2c_client.dev;
|
||||
|
||||
/* rest of the initialisation goes here. */
|
||||
|
||||
dev_info(dev, "example client created\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int example_detach(struct i2c_client *client)
|
||||
{
|
||||
struct example_state *state = i2c_get_clientdata(client);
|
||||
|
||||
i2c_detach_client(client);
|
||||
kfree(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int example_attach_adapter(struct i2c_adapter *adap)
|
||||
{
|
||||
return i2c_probe(adap, &addr_data, example_attach);
|
||||
}
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "example",
|
||||
.pm = &example_pm_ops,
|
||||
},
|
||||
.attach_adapter = example_attach_adapter,
|
||||
.detach_client = example_detach,
|
||||
};
|
||||
|
||||
|
||||
Updating the client
|
||||
-------------------
|
||||
|
||||
The new style binding model will check against a list of supported
|
||||
devices and their associated address supplied by the code registering
|
||||
the busses. This means that the driver .attach_adapter and
|
||||
.detach_client methods can be removed, along with the addr_data,
|
||||
as follows::
|
||||
|
||||
- static struct i2c_driver example_driver;
|
||||
|
||||
- static unsigned short ignore[] = { I2C_CLIENT_END };
|
||||
- static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END };
|
||||
|
||||
- I2C_CLIENT_INSMOD;
|
||||
|
||||
- static int example_attach_adapter(struct i2c_adapter *adap)
|
||||
- {
|
||||
- return i2c_probe(adap, &addr_data, example_attach);
|
||||
- }
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
- .attach_adapter = example_attach_adapter,
|
||||
- .detach_client = example_detach,
|
||||
}
|
||||
|
||||
Add the probe and remove methods to the i2c_driver, as so::
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
+ .probe = example_probe,
|
||||
+ .remove = example_remove,
|
||||
}
|
||||
|
||||
Change the example_attach method to accept the new parameters
|
||||
which include the i2c_client that it will be working with::
|
||||
|
||||
- static int example_attach(struct i2c_adapter *adap, int addr, int kind)
|
||||
+ static int example_probe(struct i2c_client *client,
|
||||
+ const struct i2c_device_id *id)
|
||||
|
||||
Change the name of example_attach to example_probe to align it with the
|
||||
i2c_driver entry names. The rest of the probe routine will now need to be
|
||||
changed as the i2c_client has already been setup for use.
|
||||
|
||||
The necessary client fields have already been setup before
|
||||
the probe function is called, so the following client setup
|
||||
can be removed::
|
||||
|
||||
- example->client.addr = addr;
|
||||
- example->client.flags = 0;
|
||||
- example->client.adapter = adap;
|
||||
-
|
||||
- strscpy(client->i2c_client.name, "example", sizeof(client->i2c_client.name));
|
||||
|
||||
The i2c_set_clientdata is now::
|
||||
|
||||
- i2c_set_clientdata(&state->client, state);
|
||||
+ i2c_set_clientdata(client, state);
|
||||
|
||||
The call to i2c_attach_client is no longer needed, if the probe
|
||||
routine exits successfully, then the driver will be automatically
|
||||
attached by the core. Change the probe routine as so::
|
||||
|
||||
- ret = i2c_attach_client(&state->i2c_client);
|
||||
- if (ret < 0) {
|
||||
- dev_err(dev, "failed to attach client\n");
|
||||
- kfree(state);
|
||||
- return ret;
|
||||
- }
|
||||
|
||||
|
||||
Remove the storage of 'struct i2c_client' from the 'struct example_state'
|
||||
as we are provided with the i2c_client in our example_probe. Instead we
|
||||
store a pointer to it for when it is needed.
|
||||
|
||||
::
|
||||
|
||||
struct example_state {
|
||||
- struct i2c_client client;
|
||||
+ struct i2c_client *client;
|
||||
|
||||
the new i2c client as so::
|
||||
|
||||
- struct device *dev = &adap->dev; /* to use for dev_ reports */
|
||||
+ struct device *dev = &i2c_client->dev; /* to use for dev_ reports */
|
||||
|
||||
And remove the change after our client is attached, as the driver no
|
||||
longer needs to register a new client structure with the core::
|
||||
|
||||
- dev = &state->i2c_client.dev;
|
||||
|
||||
In the probe routine, ensure that the new state has the client stored
|
||||
in it::
|
||||
|
||||
static int example_probe(struct i2c_client *i2c_client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct example_state *state;
|
||||
struct device *dev = &i2c_client->dev;
|
||||
int ret;
|
||||
|
||||
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
|
||||
if (state == NULL) {
|
||||
dev_err(dev, "failed to create our state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
+ state->client = i2c_client;
|
||||
|
||||
Update the detach method, by changing the name to _remove and
|
||||
to delete the i2c_detach_client call. It is possible that you
|
||||
can also remove the ret variable as it is not needed for any
|
||||
of the core functions.
|
||||
|
||||
::
|
||||
|
||||
- static int example_detach(struct i2c_client *client)
|
||||
+ static int example_remove(struct i2c_client *client)
|
||||
{
|
||||
struct example_state *state = i2c_get_clientdata(client);
|
||||
|
||||
- i2c_detach_client(client);
|
||||
|
||||
And finally ensure that we have the correct ID table for the i2c-core
|
||||
and other utilities::
|
||||
|
||||
+ struct i2c_device_id example_idtable[] = {
|
||||
+ { "example", 0 },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(i2c, example_idtable);
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "example",
|
||||
},
|
||||
+ .id_table = example_ids,
|
||||
|
||||
|
||||
Our driver should now look like this::
|
||||
|
||||
struct example_state {
|
||||
struct i2c_client *client;
|
||||
....
|
||||
};
|
||||
|
||||
static int example_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct example_state *state;
|
||||
struct device *dev = &client->dev;
|
||||
|
||||
state = kzalloc(sizeof(struct example_state), GFP_KERNEL);
|
||||
if (state == NULL) {
|
||||
dev_err(dev, "failed to create our state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
state->client = client;
|
||||
i2c_set_clientdata(client, state);
|
||||
|
||||
/* rest of the initialisation goes here. */
|
||||
|
||||
dev_info(dev, "example client created\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int example_remove(struct i2c_client *client)
|
||||
{
|
||||
struct example_state *state = i2c_get_clientdata(client);
|
||||
|
||||
kfree(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_device_id example_idtable[] = {
|
||||
{ "example", 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, example_idtable);
|
||||
|
||||
static struct i2c_driver example_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "example",
|
||||
.pm = &example_pm_ops,
|
||||
},
|
||||
.id_table = example_idtable,
|
||||
.probe = example_probe,
|
||||
.remove = example_remove,
|
||||
};
|
@ -10,7 +10,7 @@ Introduction
|
||||
============
|
||||
|
||||
The kernel provides a variety of locking primitives which can be divided
|
||||
into two categories:
|
||||
into three categories:
|
||||
|
||||
- Sleeping locks
|
||||
- CPU local locks
|
||||
|
@ -113,7 +113,7 @@ than one development cycle past their initial release. So, for example, the
|
||||
5.2 kernel's history looked like this (all dates in 2019):
|
||||
|
||||
============== ===============================
|
||||
September 15 5.2 stable release
|
||||
July 7 5.2 stable release
|
||||
July 14 5.2.1
|
||||
July 21 5.2.2
|
||||
July 26 5.2.3
|
||||
|
@ -58,7 +58,7 @@ Bus and Subdevices
|
||||
|
||||
For each Intel TH device in the system a bus of its own is
|
||||
created and assigned an id number that reflects the order in which TH
|
||||
devices were emumerated. All TH subdevices (devices on intel_th bus)
|
||||
devices were enumerated. All TH subdevices (devices on intel_th bus)
|
||||
begin with this id: 0-gth, 0-msc0, 0-msc1, 0-pti, 0-sth, which is
|
||||
followed by device's name and an optional index.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
=======
|
||||
========
|
||||
CPU 负载
|
||||
=======
|
||||
========
|
||||
|
||||
Linux通过``/proc/stat``和``/proc/uptime``导出各种信息,用户空间工具
|
||||
如top(1)使用这些信息计算系统花费在某个特定状态的平均时间。
|
||||
|
@ -1,6 +1,6 @@
|
||||
.. include:: ../disclaimer-zh_CN.rst
|
||||
|
||||
:Original: :ref:`Documentation/admin-guide/index.rst`
|
||||
:Original: :doc:`../../../admin-guide/index`
|
||||
:Translator: Alex Shi <alex.shi@linux.alibaba.com>
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user