Merge tag 'v5.9' into next
Sync up with mainline to bring in the latest DTS files.
This commit is contained in:
@@ -80,6 +80,7 @@ ForEachMacros:
|
||||
- 'ax25_uid_for_each'
|
||||
- '__bio_for_each_bvec'
|
||||
- 'bio_for_each_bvec'
|
||||
- 'bio_for_each_bvec_all'
|
||||
- 'bio_for_each_integrity_vec'
|
||||
- '__bio_for_each_segment'
|
||||
- 'bio_for_each_segment'
|
||||
@@ -110,6 +111,7 @@ ForEachMacros:
|
||||
- 'css_for_each_descendant_pre'
|
||||
- 'device_for_each_child_node'
|
||||
- 'dma_fence_chain_for_each'
|
||||
- 'do_for_each_ftrace_op'
|
||||
- 'drm_atomic_crtc_for_each_plane'
|
||||
- 'drm_atomic_crtc_state_for_each_plane'
|
||||
- 'drm_atomic_crtc_state_for_each_plane_state'
|
||||
@@ -135,6 +137,7 @@ ForEachMacros:
|
||||
- 'for_each_active_dev_scope'
|
||||
- 'for_each_active_drhd_unit'
|
||||
- 'for_each_active_iommu'
|
||||
- 'for_each_aggr_pgid'
|
||||
- 'for_each_available_child_of_node'
|
||||
- 'for_each_bio'
|
||||
- 'for_each_board_func_rsrc'
|
||||
@@ -233,6 +236,7 @@ ForEachMacros:
|
||||
- 'for_each_node_state'
|
||||
- 'for_each_node_with_cpus'
|
||||
- 'for_each_node_with_property'
|
||||
- 'for_each_nonreserved_multicast_dest_pgid'
|
||||
- 'for_each_of_allnodes'
|
||||
- 'for_each_of_allnodes_from'
|
||||
- 'for_each_of_cpu_node'
|
||||
@@ -255,6 +259,7 @@ ForEachMacros:
|
||||
- 'for_each_pci_dev'
|
||||
- 'for_each_pci_msi_entry'
|
||||
- 'for_each_pcm_streams'
|
||||
- 'for_each_physmem_range'
|
||||
- 'for_each_populated_zone'
|
||||
- 'for_each_possible_cpu'
|
||||
- 'for_each_present_cpu'
|
||||
@@ -264,6 +269,8 @@ ForEachMacros:
|
||||
- 'for_each_process_thread'
|
||||
- 'for_each_property_of_node'
|
||||
- 'for_each_registered_fb'
|
||||
- 'for_each_requested_gpio'
|
||||
- 'for_each_requested_gpio_in_range'
|
||||
- 'for_each_reserved_mem_region'
|
||||
- 'for_each_rtd_codec_dais'
|
||||
- 'for_each_rtd_codec_dais_rollback'
|
||||
@@ -277,12 +284,17 @@ ForEachMacros:
|
||||
- 'for_each_sg'
|
||||
- 'for_each_sg_dma_page'
|
||||
- 'for_each_sg_page'
|
||||
- 'for_each_sgtable_dma_page'
|
||||
- 'for_each_sgtable_dma_sg'
|
||||
- 'for_each_sgtable_page'
|
||||
- 'for_each_sgtable_sg'
|
||||
- 'for_each_sibling_event'
|
||||
- 'for_each_subelement'
|
||||
- 'for_each_subelement_extid'
|
||||
- 'for_each_subelement_id'
|
||||
- '__for_each_thread'
|
||||
- 'for_each_thread'
|
||||
- 'for_each_unicast_dest_pgid'
|
||||
- 'for_each_wakeup_source'
|
||||
- 'for_each_zone'
|
||||
- 'for_each_zone_zonelist'
|
||||
@@ -463,6 +475,7 @@ ForEachMacros:
|
||||
- 'v4l2_m2m_for_each_src_buf'
|
||||
- 'v4l2_m2m_for_each_src_buf_safe'
|
||||
- 'virtio_device_for_each_vq'
|
||||
- 'while_for_each_ftrace_op'
|
||||
- 'xa_for_each'
|
||||
- 'xa_for_each_marked'
|
||||
- 'xa_for_each_range'
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
*.tab.[ch]
|
||||
*.tar
|
||||
*.xz
|
||||
*.zst
|
||||
Module.symvers
|
||||
modules.builtin
|
||||
modules.order
|
||||
@@ -56,6 +57,7 @@ modules.order
|
||||
/linux
|
||||
/vmlinux
|
||||
/vmlinux.32
|
||||
/vmlinux.symvers
|
||||
/vmlinux-gdb.py
|
||||
/vmlinuz
|
||||
/System.map
|
||||
@@ -142,6 +144,9 @@ x509.genkey
|
||||
/allrandom.config
|
||||
/allyes.config
|
||||
|
||||
# Kconfig savedefconfig output
|
||||
/defconfig
|
||||
|
||||
# Kdevelop4
|
||||
*.kdev4
|
||||
|
||||
|
||||
@@ -2,37 +2,47 @@
|
||||
# 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>
|
||||
Adrian Bunk <bunk@stusta.de>
|
||||
Adriana Reus <adi.reus@gmail.com> <adriana.reus@intel.com>
|
||||
Adrian Bunk <bunk@stusta.de>
|
||||
Alan Cox <alan@lxorguk.ukuu.org.uk>
|
||||
Alan Cox <root@hraefn.swansea.linux.org.uk>
|
||||
Aleksey Gorelov <aleksey_gorelov@phoenix.com>
|
||||
Aleksandar Markovic <aleksandar.markovic@mips.com> <aleksandar.markovic@imgtec.com>
|
||||
Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@intel.com>
|
||||
Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@linaro.org>
|
||||
Aleksey Gorelov <aleksey_gorelov@phoenix.com>
|
||||
Alexander Lobakin <alobakin@pm.me> <alobakin@dlink.ru>
|
||||
Alexander Lobakin <alobakin@pm.me> <alobakin@marvell.com>
|
||||
Alexander Lobakin <alobakin@pm.me> <bloodyreaper@yandex.ru>
|
||||
Alexandre Belloni <alexandre.belloni@bootlin.com> <alexandre.belloni@free-electrons.com>
|
||||
Alexei Starovoitov <ast@kernel.org> <ast@plumgrid.com>
|
||||
Alexei Starovoitov <ast@kernel.org> <alexei.starovoitov@gmail.com>
|
||||
Alexei Starovoitov <ast@kernel.org> <ast@fb.com>
|
||||
Alexei Starovoitov <ast@kernel.org> <ast@plumgrid.com>
|
||||
Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@intel.com>
|
||||
Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@linaro.org>
|
||||
Al Viro <viro@ftp.linux.org.uk>
|
||||
Al Viro <viro@zenIV.linux.org.uk>
|
||||
Andi Kleen <ak@linux.intel.com> <ak@suse.de>
|
||||
Andi Shyti <andi@etezian.org> <andi.shyti@samsung.com>
|
||||
Andreas Herrmann <aherrman@de.ibm.com>
|
||||
Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com>
|
||||
Andrew Morton <akpm@linux-foundation.org>
|
||||
Andrew Murray <amurray@thegoodpenguin.co.uk> <andrew.murray@arm.com>
|
||||
Andrew Murray <amurray@thegoodpenguin.co.uk> <amurray@embedded-bits.co.uk>
|
||||
Andrew Murray <amurray@thegoodpenguin.co.uk> <andrew.murray@arm.com>
|
||||
Andrew Vasquez <andrew.vasquez@qlogic.com>
|
||||
Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com>
|
||||
Andy Adamson <andros@citi.umich.edu>
|
||||
Antoine Tenart <antoine.tenart@free-electrons.com>
|
||||
Antoine Tenart <atenart@kernel.org> <antoine.tenart@bootlin.com>
|
||||
Antoine Tenart <atenart@kernel.org> <antoine.tenart@free-electrons.com>
|
||||
Antonio Ospite <ao2@ao2.it> <ao2@amarulasolutions.com>
|
||||
Archit Taneja <archit@ti.com>
|
||||
Ard Biesheuvel <ardb@kernel.org> <ard.biesheuvel@linaro.org>
|
||||
@@ -40,40 +50,42 @@ Arnaud Patard <arnaud.patard@rtp-net.org>
|
||||
Arnd Bergmann <arnd@arndb.de>
|
||||
Axel Dyks <xl@xlsigned.net>
|
||||
Axel Lin <axel.lin@gmail.com>
|
||||
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com>
|
||||
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@sandisk.com>
|
||||
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com>
|
||||
Ben Gardner <bgardner@wabtec.com>
|
||||
Ben M Cahill <ben.m.cahill@intel.com>
|
||||
Björn Steinbrink <B.Steinbrink@gmx.de>
|
||||
Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@bootlin.com>
|
||||
Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@free-electrons.com>
|
||||
Boris Brezillon <bbrezillon@kernel.org> <b.brezillon.dev@gmail.com>
|
||||
Boris Brezillon <bbrezillon@kernel.org> <b.brezillon@overkiz.com>
|
||||
Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@bootlin.com>
|
||||
Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@free-electrons.com>
|
||||
Brian Avery <b.avery@hp.com>
|
||||
Brian King <brking@us.ibm.com>
|
||||
Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com>
|
||||
Changbin Du <changbin.du@intel.com> <changbin.du@intel.com>
|
||||
Chao Yu <chao@kernel.org> <chao2.yu@samsung.com>
|
||||
Chao Yu <chao@kernel.org> <yuchao0@huawei.com>
|
||||
Christoph Hellwig <hch@lst.de>
|
||||
Christophe Ricard <christophe.ricard@gmail.com>
|
||||
Christoph Hellwig <hch@lst.de>
|
||||
Corey Minyard <minyard@acm.org>
|
||||
Damian Hobson-Garcia <dhobsong@igel.co.jp>
|
||||
Daniel Borkmann <daniel@iogearbox.net> <dborkman@redhat.com>
|
||||
Daniel Borkmann <daniel@iogearbox.net> <dborkmann@redhat.com>
|
||||
Daniel Borkmann <daniel@iogearbox.net> <danborkmann@googlemail.com>
|
||||
Daniel Borkmann <daniel@iogearbox.net> <danborkmann@iogearbox.net>
|
||||
Daniel Borkmann <daniel@iogearbox.net> <daniel.borkmann@tik.ee.ethz.ch>
|
||||
Daniel Borkmann <daniel@iogearbox.net> <danborkmann@googlemail.com>
|
||||
Daniel Borkmann <daniel@iogearbox.net> <dborkmann@redhat.com>
|
||||
Daniel Borkmann <daniel@iogearbox.net> <dborkman@redhat.com>
|
||||
Daniel Borkmann <daniel@iogearbox.net> <dxchgb@gmail.com>
|
||||
David Brownell <david-b@pacbell.net>
|
||||
David Woodhouse <dwmw2@shinybook.infradead.org>
|
||||
Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@mips.com>
|
||||
Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@imgtec.com>
|
||||
Dengcheng Zhu <dzhu@wavecomp.com> <dczhu@mips.com>
|
||||
Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@gmail.com>
|
||||
Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@imgtec.com>
|
||||
Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@mips.com>
|
||||
<dev.kurt@vandijck-laurijssen.be> <kurt.van.dijck@eia.be>
|
||||
Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
|
||||
Dmitry Safonov <0x7f454c46@gmail.com> <dsafonov@virtuozzo.com>
|
||||
Dmitry Safonov <0x7f454c46@gmail.com> <d.safonov@partner.samsung.com>
|
||||
Dmitry Safonov <0x7f454c46@gmail.com> <dima@arista.com>
|
||||
Dmitry Safonov <0x7f454c46@gmail.com> <d.safonov@partner.samsung.com>
|
||||
Dmitry Safonov <0x7f454c46@gmail.com> <dsafonov@virtuozzo.com>
|
||||
Domen Puncer <domen@coderock.org>
|
||||
Douglas Gilbert <dougg@torque.net>
|
||||
Ed L. Cashin <ecashin@coraid.com>
|
||||
@@ -84,51 +96,65 @@ Felix Kuhling <fxkuehl@gmx.de>
|
||||
Felix Moeller <felix@derklecks.de>
|
||||
Filipe Lautert <filipe@icewall.org>
|
||||
Franck Bui-Huu <vagabon.xyz@gmail.com>
|
||||
Frank Rowand <frowand.list@gmail.com> <frowand@mvista.com>
|
||||
Frank Rowand <frowand.list@gmail.com> <frank.rowand@am.sony.com>
|
||||
Frank Rowand <frowand.list@gmail.com> <frank.rowand@sonymobile.com>
|
||||
Frank Rowand <frowand.list@gmail.com> <frowand@mvista.com>
|
||||
Frank Zago <fzago@systemfabricworks.com>
|
||||
Gao Xiang <xiang@kernel.org> <gaoxiang25@huawei.com>
|
||||
Gao Xiang <xiang@kernel.org> <hsiangkao@aol.com>
|
||||
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@de.ibm.com>
|
||||
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <gerald.schaefer@de.ibm.com>
|
||||
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@linux.vnet.ibm.com>
|
||||
Greg Kroah-Hartman <greg@echidna.(none)>
|
||||
Greg Kroah-Hartman <gregkh@suse.de>
|
||||
Greg Kroah-Hartman <greg@kroah.com>
|
||||
Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com>
|
||||
Gregory CLEMENT <gregory.clement@bootlin.com> <gregory.clement@free-electrons.com>
|
||||
Gustavo Padovan <gustavo@las.ic.unicamp.br>
|
||||
Gustavo Padovan <padovan@profusion.mobi>
|
||||
Hanjun Guo <guohanjun@huawei.com> <hanjun.guo@linaro.org>
|
||||
Heiko Carstens <hca@linux.ibm.com> <h.carstens@de.ibm.com>
|
||||
Heiko Carstens <hca@linux.ibm.com> <heiko.carstens@de.ibm.com>
|
||||
Henk Vergonet <Henk.Vergonet@gmail.com>
|
||||
Henrik Kretzschmar <henne@nachtwindheim.de>
|
||||
Henrik Rydberg <rydberg@bitmath.org>
|
||||
Herbert Xu <herbert@gondor.apana.org.au>
|
||||
Jacob Shin <Jacob.Shin@amd.com>
|
||||
Jaegeuk Kim <jaegeuk@kernel.org> <jaegeuk@google.com>
|
||||
Jaegeuk Kim <jaegeuk@kernel.org> <jaegeuk@motorola.com>
|
||||
Jaegeuk Kim <jaegeuk@kernel.org> <jaegeuk.kim@samsung.com>
|
||||
Jaegeuk Kim <jaegeuk@kernel.org> <jaegeuk@motorola.com>
|
||||
Jakub Kicinski <kuba@kernel.org> <jakub.kicinski@netronome.com>
|
||||
James Bottomley <jejb@mulgrave.(none)>
|
||||
James Bottomley <jejb@titanic.il.steeleye.com>
|
||||
James E Wilson <wilson@specifix.com>
|
||||
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
|
||||
James Hogan <jhogan@kernel.org> <james@albanarts.com>
|
||||
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
|
||||
James Ketrenos <jketreno@io.(none)>
|
||||
Jan Glauber <jan.glauber@gmail.com> <jang@de.ibm.com>
|
||||
Jan Glauber <jan.glauber@gmail.com> <jang@linux.vnet.ibm.com>
|
||||
Jan Glauber <jan.glauber@gmail.com> <jglauber@cavium.com>
|
||||
Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com>
|
||||
Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com>
|
||||
Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com>
|
||||
Javi Merino <javi.merino@kernel.org> <javi.merino@arm.com>
|
||||
<javier@osg.samsung.com> <javier.martinez@collabora.co.uk>
|
||||
Javi Merino <javi.merino@kernel.org> <javi.merino@arm.com>
|
||||
Jayachandran C <c.jayachandran@gmail.com> <jayachandranc@netlogicmicro.com>
|
||||
Jayachandran C <c.jayachandran@gmail.com> <jchandra@broadcom.com>
|
||||
Jayachandran C <c.jayachandran@gmail.com> <jchandra@digeo.com>
|
||||
Jayachandran C <c.jayachandran@gmail.com> <jnair@caviumnetworks.com>
|
||||
Jean Tourrilhes <jt@hpl.hp.com>
|
||||
<jean-philippe@linaro.org> <jean-philippe.brucker@arm.com>
|
||||
Jean Tourrilhes <jt@hpl.hp.com>
|
||||
Jeff Garzik <jgarzik@pretzel.yyz.us>
|
||||
Jeff Layton <jlayton@kernel.org> <jlayton@redhat.com>
|
||||
Jeff Layton <jlayton@kernel.org> <jlayton@poochiereds.net>
|
||||
Jeff Layton <jlayton@kernel.org> <jlayton@primarydata.com>
|
||||
Jeff Layton <jlayton@kernel.org> <jlayton@redhat.com>
|
||||
Jens Axboe <axboe@suse.de>
|
||||
Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
|
||||
Jiri Slaby <jirislaby@kernel.org> <jirislaby@gmail.com>
|
||||
Jiri Slaby <jirislaby@kernel.org> <jslaby@novell.com>
|
||||
Jiri Slaby <jirislaby@kernel.org> <jslaby@suse.com>
|
||||
Jiri Slaby <jirislaby@kernel.org> <jslaby@suse.cz>
|
||||
Jiri Slaby <jirislaby@kernel.org> <xslaby@fi.muni.cz>
|
||||
Johan Hovold <johan@kernel.org> <jhovold@gmail.com>
|
||||
Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
|
||||
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
|
||||
@@ -144,29 +170,37 @@ Juha Yrjola <juha.yrjola@solidboot.com>
|
||||
Julien Thierry <julien.thierry.kdev@gmail.com> <julien.thierry@arm.com>
|
||||
Kamil Konieczny <k.konieczny@samsung.com> <k.konieczny@partner.samsung.com>
|
||||
Kay Sievers <kay.sievers@vrfy.org>
|
||||
Kees Cook <keescook@chromium.org> <kees.cook@canonical.com>
|
||||
Kees Cook <keescook@chromium.org> <keescook@google.com>
|
||||
Kees Cook <keescook@chromium.org> <kees@outflux.net>
|
||||
Kees Cook <keescook@chromium.org> <kees@ubuntu.com>
|
||||
Kenneth W Chen <kenneth.w.chen@intel.com>
|
||||
Konstantin Khlebnikov <koct9i@gmail.com> <khlebnikov@yandex-team.ru>
|
||||
Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com>
|
||||
Koushik <raghavendra.koushik@neterion.com>
|
||||
Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski@samsung.com>
|
||||
Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski.k@gmail.com>
|
||||
Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski@samsung.com>
|
||||
Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
Leonardo Bras <leobras.c@gmail.com> <leonardo@linux.ibm.com>
|
||||
Leonid I Ananiev <leonid.i.ananiev@intel.com>
|
||||
Leon Romanovsky <leon@kernel.org> <leon@leon.nu>
|
||||
Leon Romanovsky <leon@kernel.org> <leonro@mellanox.com>
|
||||
Leonid I Ananiev <leonid.i.ananiev@intel.com>
|
||||
Leon Romanovsky <leon@kernel.org> <leonro@nvidia.com>
|
||||
Linas Vepstas <linas@austin.ibm.com>
|
||||
Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@web.de>
|
||||
Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@ascom.ch>
|
||||
Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org>
|
||||
Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@web.de>
|
||||
<linux-hardening@vger.kernel.org> <kernel-hardening@lists.openwall.com>
|
||||
Li Yang <leoyang.li@nxp.com> <leoli@freescale.com>
|
||||
Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org>
|
||||
Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com>
|
||||
Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com>
|
||||
Marc Zyngier <maz@kernel.org> <marc.zyngier@arm.com>
|
||||
Marcin Nowakowski <marcin.nowakowski@mips.com> <marcin.nowakowski@imgtec.com>
|
||||
Marc Zyngier <maz@kernel.org> <marc.zyngier@arm.com>
|
||||
Mark Brown <broonie@sirena.org.uk>
|
||||
Mark Yao <markyao0591@gmail.com> <mark.yao@rock-chips.com>
|
||||
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com>
|
||||
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@ginzinger.com>
|
||||
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@puri.sm>
|
||||
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com>
|
||||
Mathieu Othacehe <m.othacehe@gmail.com>
|
||||
Matthew Wilcox <willy@infradead.org> <matthew.r.wilcox@intel.com>
|
||||
Matthew Wilcox <willy@infradead.org> <matthew@wil.cx>
|
||||
@@ -176,22 +210,25 @@ Matthew Wilcox <willy@infradead.org> <willy@debian.org>
|
||||
Matthew Wilcox <willy@infradead.org> <willy@linux.intel.com>
|
||||
Matthew Wilcox <willy@infradead.org> <willy@parisc-linux.org>
|
||||
Matthieu CASTET <castet.matthieu@free.fr>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@brturbo.com.br>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <maurochehab@gmail.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@infradead.org>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@redhat.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <m.chehab@samsung.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@osg.samsung.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@s-opensource.com>
|
||||
Matt Ranostay <matt.ranostay@konsulko.com> <matt@ranostay.consulting>
|
||||
Matt Ranostay <mranostay@gmail.com> Matthew Ranostay <mranostay@embeddedalley.com>
|
||||
Matt Ranostay <mranostay@gmail.com> <matt.ranostay@intel.com>
|
||||
Matt Ranostay <matt.ranostay@konsulko.com> <matt@ranostay.consulting>
|
||||
Matt Redfearn <matt.redfearn@mips.com> <matt.redfearn@imgtec.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <maurochehab@gmail.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@brturbo.com.br>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@infradead.org>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@osg.samsung.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@redhat.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <m.chehab@samsung.com>
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@s-opensource.com>
|
||||
Maxime Ripard <mripard@kernel.org> <maxime.ripard@bootlin.com>
|
||||
Maxime Ripard <mripard@kernel.org> <maxime.ripard@free-electrons.com>
|
||||
Mayuresh Janorkar <mayur@ti.com>
|
||||
Michael Buesch <m@bues.ch>
|
||||
Michel Dänzer <michel@tungstengraphics.com>
|
||||
Mike Rapoport <rppt@kernel.org> <mike@compulab.co.il>
|
||||
Mike Rapoport <rppt@kernel.org> <mike.rapoport@gmail.com>
|
||||
Mike Rapoport <rppt@kernel.org> <rppt@linux.ibm.com>
|
||||
Miodrag Dinic <miodrag.dinic@mips.com> <miodrag.dinic@imgtec.com>
|
||||
Miquel Raynal <miquel.raynal@bootlin.com> <miquel.raynal@free-electrons.com>
|
||||
Mitesh shah <mshah@teja.com>
|
||||
@@ -215,13 +252,13 @@ Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
|
||||
Patrick Mochel <mochel@digitalimplant.org>
|
||||
Paul Burton <paulburton@kernel.org> <paul.burton@imgtec.com>
|
||||
Paul Burton <paulburton@kernel.org> <paul.burton@mips.com>
|
||||
Paul E. McKenney <paulmck@kernel.org> <paul.mckenney@linaro.org>
|
||||
Paul E. McKenney <paulmck@kernel.org> <paulmck@linux.ibm.com>
|
||||
Paul E. McKenney <paulmck@kernel.org> <paulmck@linux.vnet.ibm.com>
|
||||
Paul E. McKenney <paulmck@kernel.org> <paul.mckenney@linaro.org>
|
||||
Paul E. McKenney <paulmck@kernel.org> <paulmck@us.ibm.com>
|
||||
Peter A Jonsson <pj@ludd.ltu.se>
|
||||
Peter Oruba <peter@oruba.de>
|
||||
Peter Oruba <peter.oruba@amd.com>
|
||||
Peter Oruba <peter@oruba.de>
|
||||
Pratyush Anand <pratyush.anand@gmail.com> <pratyush.anand@st.com>
|
||||
Praveen BP <praveenbp@ti.com>
|
||||
Punit Agrawal <punitagrawal@gmail.com> <punit.agrawal@arm.com>
|
||||
@@ -234,21 +271,23 @@ Ralf Baechle <ralf@linux-mips.org>
|
||||
Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
|
||||
Randy Dunlap <rdunlap@infradead.org> <rdunlap@xenotime.net>
|
||||
Rémi Denis-Courmont <rdenis@simphalempin.com>
|
||||
Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
|
||||
Ricardo Ribalda <ribalda@kernel.org> <ricardo@ribalda.com>
|
||||
Ricardo Ribalda <ribalda@kernel.org> Ricardo Ribalda Delgado <ribalda@kernel.org>
|
||||
Ricardo Ribalda <ribalda@kernel.org> <ricardo.ribalda@gmail.com>
|
||||
Ross Zwisler <zwisler@kernel.org> <ross.zwisler@linux.intel.com>
|
||||
Rudolf Marek <R.Marek@sh.cvut.cz>
|
||||
Rui Saraiva <rmps@joel.ist.utl.pt>
|
||||
Sachin P Sant <ssant@in.ibm.com>
|
||||
Sarangdhar Joshi <spjoshi@codeaurora.org>
|
||||
Sakari Ailus <sakari.ailus@linux.intel.com> <sakari.ailus@iki.fi>
|
||||
Sam Ravnborg <sam@mars.ravnborg.org>
|
||||
Santosh Shilimkar <ssantosh@kernel.org>
|
||||
Santosh Shilimkar <santosh.shilimkar@oracle.org>
|
||||
Santosh Shilimkar <ssantosh@kernel.org>
|
||||
Sarangdhar Joshi <spjoshi@codeaurora.org>
|
||||
Sascha Hauer <s.hauer@pengutronix.de>
|
||||
S.Çağlar Onur <caglar@pardus.org.tr>
|
||||
Sakari Ailus <sakari.ailus@linux.intel.com> <sakari.ailus@iki.fi>
|
||||
Sean Nyekjaer <sean@geanix.com> <sean.nyekjaer@prevas.dk>
|
||||
Sebastian Reichel <sre@kernel.org> <sre@debian.org>
|
||||
Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk>
|
||||
Sebastian Reichel <sre@kernel.org> <sre@debian.org>
|
||||
Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de>
|
||||
Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com>
|
||||
Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com>
|
||||
@@ -259,19 +298,23 @@ Simon Arlott <simon@octiron.net> <simon@fire.lp0.eu>
|
||||
Simon Kelley <simon@thekelleys.org.uk>
|
||||
Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
|
||||
Stephen Hemminger <shemminger@osdl.org>
|
||||
Steve Wise <larrystevenwise@gmail.com> <swise@chelsio.com>
|
||||
Steve Wise <larrystevenwise@gmail.com> <swise@opengridcomputing.com>
|
||||
Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
|
||||
Subhash Jadavani <subhashj@codeaurora.org>
|
||||
Sudeep Holla <sudeep.holla@arm.com> Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
|
||||
Sumit Semwal <sumit.semwal@ti.com>
|
||||
Takashi YOSHII <takashi.yoshii.zj@renesas.com>
|
||||
Tejun Heo <htejun@gmail.com>
|
||||
Thomas Graf <tgraf@suug.ch>
|
||||
Thomas Pedersen <twp@codeaurora.org>
|
||||
Tiezhu Yang <yangtiezhu@loongson.cn> <kernelpatch@126.com>
|
||||
Todor Tomov <todor.too@gmail.com> <todor.tomov@linaro.org>
|
||||
Tony Luck <tony.luck@intel.com>
|
||||
TripleX Chung <xxx.phy@gmail.com> <zhongyu@18mail.cn>
|
||||
TripleX Chung <xxx.phy@gmail.com> <triplex@zh-kernel.org>
|
||||
TripleX Chung <xxx.phy@gmail.com> <zhongyu@18mail.cn>
|
||||
Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com>
|
||||
Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws>
|
||||
Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
|
||||
Uwe Kleine-König <ukl@pengutronix.de>
|
||||
Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
|
||||
@@ -279,22 +322,16 @@ Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
|
||||
Vinod Koul <vkoul@kernel.org> <vinod.koul@intel.com>
|
||||
Vinod Koul <vkoul@kernel.org> <vinod.koul@linux.intel.com>
|
||||
Vinod Koul <vkoul@kernel.org> <vkoul@infradead.org>
|
||||
Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com>
|
||||
Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com>
|
||||
Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com>
|
||||
Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com>
|
||||
Vivien Didelot <vivien.didelot@gmail.com> <vivien.didelot@savoirfairelinux.com>
|
||||
Vlad Dogaru <ddvlad@gmail.com> <vlad.dogaru@intel.com>
|
||||
Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com>
|
||||
Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@parallels.com>
|
||||
Takashi YOSHII <takashi.yoshii.zj@renesas.com>
|
||||
Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com>
|
||||
WeiXiong Liao <gmpy.liaowx@gmail.com> <liaoweixiong@allwinnertech.com>
|
||||
Will Deacon <will@kernel.org> <will.deacon@arm.com>
|
||||
Wolfram Sang <wsa@kernel.org> <wsa@the-dreams.de>
|
||||
Wolfram Sang <wsa@kernel.org> <w.sang@pengutronix.de>
|
||||
Wolfram Sang <wsa@kernel.org> <wsa@the-dreams.de>
|
||||
Yakir Yang <kuankuan.y@gmail.com> <ykk@rock-chips.com>
|
||||
Yusuke Goda <goda.yusuke@renesas.com>
|
||||
Gustavo Padovan <gustavo@las.ic.unicamp.br>
|
||||
Gustavo Padovan <padovan@profusion.mobi>
|
||||
Changbin Du <changbin.du@intel.com> <changbin.du@intel.com>
|
||||
Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com>
|
||||
Steve Wise <larrystevenwise@gmail.com> <swise@chelsio.com>
|
||||
Steve Wise <larrystevenwise@gmail.com> <swise@opengridcomputing.com>
|
||||
|
||||
@@ -34,7 +34,7 @@ S: Romania
|
||||
|
||||
N: Mark Adler
|
||||
E: madler@alumni.caltech.edu
|
||||
W: http://alumnus.caltech.edu/~madler/
|
||||
W: https://alumnus.caltech.edu/~madler/
|
||||
D: zlib decompression
|
||||
|
||||
N: Monalisa Agrawal
|
||||
@@ -62,7 +62,7 @@ S: United Kingdom
|
||||
|
||||
N: Werner Almesberger
|
||||
E: werner@almesberger.net
|
||||
W: http://www.almesberger.net/
|
||||
W: https://www.almesberger.net/
|
||||
D: dosfs, LILO, some fd features, ATM, various other hacks here and there
|
||||
S: Buenos Aires
|
||||
S: Argentina
|
||||
@@ -96,7 +96,7 @@ S: USA
|
||||
|
||||
N: Erik Andersen
|
||||
E: andersen@codepoet.org
|
||||
W: http://www.codepoet.org/
|
||||
W: https://www.codepoet.org/
|
||||
P: 1024D/30D39057 1BC4 2742 E885 E4DE 9301 0C82 5F9B 643E 30D3 9057
|
||||
D: Maintainer of ide-cd and Uniform CD-ROM driver,
|
||||
D: ATAPI CD-Changer support, Major 2.1.x CD-ROM update.
|
||||
@@ -114,7 +114,7 @@ S: Canada K2P 0X3
|
||||
|
||||
N: H. Peter Anvin
|
||||
E: hpa@zytor.com
|
||||
W: http://www.zytor.com/~hpa/
|
||||
W: https://www.zytor.com/~hpa/
|
||||
P: 2047/2A960705 BA 03 D3 2C 14 A8 A8 BD 1E DF FE 69 EE 35 BD 74
|
||||
D: Author of the SYSLINUX boot loader, maintainer of the linux.* news
|
||||
D: hierarchy and the Linux Device List; various kernel hacks
|
||||
@@ -124,7 +124,7 @@ S: USA
|
||||
|
||||
N: Andrea Arcangeli
|
||||
E: andrea@suse.de
|
||||
W: http://www.kernel.org/pub/linux/kernel/people/andrea/
|
||||
W: https://www.kernel.org/pub/linux/kernel/people/andrea/
|
||||
P: 1024D/68B9CB43 13D9 8355 295F 4823 7C49 C012 DFA1 686E 68B9 CB43
|
||||
P: 1024R/CB4660B9 CC A0 71 81 F4 A0 63 AC C0 4B 81 1D 8C 15 C8 E5
|
||||
D: Parport hacker
|
||||
@@ -339,7 +339,7 @@ S: Haifa, Israel
|
||||
|
||||
N: Johannes Berg
|
||||
E: johannes@sipsolutions.net
|
||||
W: http://johannes.sipsolutions.net/
|
||||
W: https://johannes.sipsolutions.net/
|
||||
P: 4096R/7BF9099A C0EB C440 F6DA 091C 884D 8532 E0F3 73F3 7BF9 099A
|
||||
D: powerpc & 802.11 hacker
|
||||
|
||||
@@ -376,7 +376,7 @@ D: Original author of the Linux networking code
|
||||
|
||||
N: Anton Blanchard
|
||||
E: anton@samba.org
|
||||
W: http://samba.org/~anton/
|
||||
W: https://samba.org/~anton/
|
||||
P: 1024/8462A731 4C 55 86 34 44 59 A7 99 2B 97 88 4A 88 9A 0D 97
|
||||
D: sun4 port, Sparc hacker
|
||||
|
||||
@@ -509,7 +509,7 @@ S: Sweden
|
||||
|
||||
N: Paul Bristow
|
||||
E: paul@paulbristow.net
|
||||
W: http://paulbristow.net/linux/idefloppy.html
|
||||
W: https://paulbristow.net/linux/idefloppy.html
|
||||
D: Maintainer of IDE/ATAPI floppy driver
|
||||
|
||||
N: Stefano Brivio
|
||||
@@ -518,7 +518,7 @@ D: Broadcom B43 driver
|
||||
|
||||
N: Dominik Brodowski
|
||||
E: linux@brodo.de
|
||||
W: http://www.brodo.de/
|
||||
W: https://www.brodo.de/
|
||||
P: 1024D/725B37C6 190F 3E77 9C89 3B6D BECD 46EE 67C3 0308 725B 37C6
|
||||
D: parts of CPUFreq code, ACPI bugfixes, PCMCIA rewrite, cpufrequtils
|
||||
S: Tuebingen, Germany
|
||||
@@ -865,7 +865,7 @@ D: Promise DC4030VL caching HD controller drivers
|
||||
|
||||
N: Todd J. Derr
|
||||
E: tjd@fore.com
|
||||
W: http://www.wordsmith.org/~tjd
|
||||
W: https://www.wordsmith.org/~tjd
|
||||
D: Random console hacks and other miscellaneous stuff
|
||||
S: 3000 FORE Drive
|
||||
S: Warrendale, Pennsylvania 15086
|
||||
@@ -894,8 +894,8 @@ S: USA
|
||||
|
||||
N: Matt Domsch
|
||||
E: Matt_Domsch@dell.com
|
||||
W: http://www.dell.com/linux
|
||||
W: http://domsch.com/linux
|
||||
W: https://www.dell.com/linux
|
||||
W: https://domsch.com/linux
|
||||
D: Linux/IA-64
|
||||
D: Dell PowerEdge server, SCSI layer, misc drivers, and other patches
|
||||
S: Dell Inc.
|
||||
@@ -992,7 +992,7 @@ S: USA
|
||||
|
||||
N: Randy Dunlap
|
||||
E: rdunlap@infradead.org
|
||||
W: http://www.infradead.org/~rdunlap/
|
||||
W: https://www.infradead.org/~rdunlap/
|
||||
D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers
|
||||
D: x86 SMP, ACPI, bootflag hacking
|
||||
D: documentation, builds
|
||||
@@ -1157,7 +1157,7 @@ S: Germany
|
||||
|
||||
N: Jeremy Fitzhardinge
|
||||
E: jeremy@goop.org
|
||||
W: http://www.goop.org/~jeremy
|
||||
W: https://www.goop.org/~jeremy
|
||||
D: author of userfs filesystem
|
||||
D: Improved mmap and munmap handling
|
||||
D: General mm minor tidyups
|
||||
@@ -1460,7 +1460,7 @@ S: The Netherlands
|
||||
|
||||
N: Oliver Hartkopp
|
||||
E: oliver.hartkopp@volkswagen.de
|
||||
W: http://www.volkswagen.de
|
||||
W: https://www.volkswagen.de
|
||||
D: Controller Area Network (network layer core)
|
||||
S: Brieffach 1776
|
||||
S: 38436 Wolfsburg
|
||||
@@ -1599,13 +1599,13 @@ S: Germany
|
||||
|
||||
N: Kenji Hollis
|
||||
E: kenji@bitgate.com
|
||||
W: http://www.bitgate.com/
|
||||
W: https://www.bitgate.com/
|
||||
D: Berkshire PC Watchdog Driver
|
||||
D: Small/Industrial Driver Project
|
||||
|
||||
N: Nick Holloway
|
||||
E: Nick.Holloway@pyrites.org.uk
|
||||
W: http://www.pyrites.org.uk/
|
||||
W: https://www.pyrites.org.uk/
|
||||
P: 1024/36115A04 F4E1 3384 FCFD C055 15D6 BA4C AB03 FBF8 3611 5A04
|
||||
D: Occasional Linux hacker...
|
||||
S: (ask for current address)
|
||||
@@ -1655,7 +1655,7 @@ S: USA
|
||||
|
||||
N: Harald Hoyer
|
||||
E: harald@redhat.com
|
||||
W: http://www.harald-hoyer.de
|
||||
W: https://www.harald-hoyer.de
|
||||
D: ip_masq_quake
|
||||
D: md boot support
|
||||
S: Am Strand 5
|
||||
@@ -1856,7 +1856,7 @@ E: kas@fi.muni.cz
|
||||
D: Author of the COSA/SRP sync serial board driver.
|
||||
D: Port of the syncppp.c from the 2.0 to the 2.1 kernel.
|
||||
P: 1024/D3498839 0D 99 A7 FB 20 66 05 D7 8B 35 FC DE 05 B1 8A 5E
|
||||
W: http://www.fi.muni.cz/~kas/
|
||||
W: https://www.fi.muni.cz/~kas/
|
||||
S: c/o Faculty of Informatics, Masaryk University
|
||||
S: Botanicka' 68a
|
||||
S: 602 00 Brno
|
||||
@@ -2017,7 +2017,7 @@ S: Prague, Czech Republic
|
||||
|
||||
N: Gene Kozin
|
||||
E: 74604.152@compuserve.com
|
||||
W: http://www.sangoma.com
|
||||
W: https://www.sangoma.com
|
||||
D: WAN Router & Sangoma WAN drivers
|
||||
S: Sangoma Technologies Inc.
|
||||
S: 7170 Warden Avenue, Unit 2
|
||||
@@ -2112,7 +2112,7 @@ D: Original author of software suspend
|
||||
|
||||
N: Jaroslav Kysela
|
||||
E: perex@perex.cz
|
||||
W: http://www.perex.cz
|
||||
W: https://www.perex.cz
|
||||
D: Original Author and Maintainer for HP 10/100 Mbit Network Adapters
|
||||
D: ISA PnP
|
||||
S: Sindlovy Dvory 117
|
||||
@@ -2316,7 +2316,7 @@ S: Finland
|
||||
|
||||
N: Daniel J. Maas
|
||||
E: dmaas@dcine.com
|
||||
W: http://www.maasdigital.com
|
||||
W: https://www.maasdigital.com
|
||||
D: dv1394
|
||||
|
||||
N: Hamish Macdonald
|
||||
@@ -2647,7 +2647,7 @@ D: bug fixes, documentation, minor hackery
|
||||
|
||||
N: Paul Moore
|
||||
E: paul@paul-moore.com
|
||||
W: http://www.paul-moore.com
|
||||
W: https://www.paul-moore.com
|
||||
D: NetLabel, SELinux, audit
|
||||
|
||||
N: James Morris
|
||||
@@ -2786,7 +2786,7 @@ N: David C. Niemi
|
||||
E: niemi@tux.org
|
||||
W: http://www.tux.org/~niemi/
|
||||
D: Assistant maintainer of Mtools, fdutils, and floppy driver
|
||||
D: Administrator of Tux.Org Linux Server, http://www.tux.org
|
||||
D: Administrator of Tux.Org Linux Server, https://www.tux.org
|
||||
S: 2364 Old Trail Drive
|
||||
S: Reston, Virginia 20191
|
||||
S: USA
|
||||
@@ -2850,7 +2850,7 @@ S: USA
|
||||
|
||||
N: Mikulas Patocka
|
||||
E: mikulas@artax.karlin.mff.cuni.cz
|
||||
W: http://artax.karlin.mff.cuni.cz/~mikulas/
|
||||
W: https://artax.karlin.mff.cuni.cz/~mikulas/
|
||||
P: 1024/BB11D2D5 A0 F1 28 4A C4 14 1E CF 92 58 7A 8F 69 BC A4 D3
|
||||
D: Read/write HPFS filesystem
|
||||
S: Weissova 8
|
||||
@@ -2872,7 +2872,7 @@ D: RFC2385 Support for TCP
|
||||
|
||||
N: Barak A. Pearlmutter
|
||||
E: bap@cs.unm.edu
|
||||
W: http://www.cs.unm.edu/~bap/
|
||||
W: https://www.cs.unm.edu/~bap/
|
||||
P: 512/602D785D 9B A1 83 CD EE CB AD 93 20 C6 4C B7 F5 E9 60 D4
|
||||
D: Author of mark-and-sweep GC integrated by Alan Cox
|
||||
S: Computer Science Department
|
||||
@@ -3035,7 +3035,7 @@ S: United Kingdom
|
||||
|
||||
N: Daniel Quinlan
|
||||
E: quinlan@pathname.com
|
||||
W: http://www.pathname.com/~quinlan/
|
||||
W: https://www.pathname.com/~quinlan/
|
||||
D: FSSTND coordinator; FHS editor
|
||||
D: random Linux documentation, patches, and hacks
|
||||
S: 4390 Albany Drive #41A
|
||||
@@ -3104,14 +3104,16 @@ W: http://www.qsl.net/dl1bke/
|
||||
D: Generic Z8530 driver, AX.25 DAMA slave implementation
|
||||
D: Several AX.25 hacks
|
||||
|
||||
N: Ricardo Ribalda Delgado
|
||||
E: ricardo.ribalda@gmail.com
|
||||
N: Ricardo Ribalda
|
||||
E: ribalda@kernel.org
|
||||
W: http://ribalda.com
|
||||
D: PLX USB338x driver
|
||||
D: PCA9634 driver
|
||||
D: Option GTM671WFS
|
||||
D: Fintek F81216A
|
||||
D: AD5761 iio driver
|
||||
D: TI DAC7612 driver
|
||||
D: Sony IMX214 driver
|
||||
D: Various kernel hacks
|
||||
S: Qtechnology A/S
|
||||
S: Valby Langgade 142
|
||||
@@ -3128,7 +3130,7 @@ S: France
|
||||
|
||||
N: Rik van Riel
|
||||
E: riel@redhat.com
|
||||
W: http://www.surriel.com/
|
||||
W: https://www.surriel.com/
|
||||
D: Linux-MM site, Documentation/admin-guide/sysctl/*, swap/mm readaround
|
||||
D: kswapd fixes, random kernel hacker, rmap VM,
|
||||
D: nl.linux.org administrator, minor scheduler additions
|
||||
@@ -3244,7 +3246,7 @@ S: Germany
|
||||
|
||||
N: Paul `Rusty' Russell
|
||||
E: rusty@rustcorp.com.au
|
||||
W: http://ozlabs.org/~rusty
|
||||
W: https://ozlabs.org/~rusty
|
||||
D: Ruggedly handsome.
|
||||
D: netfilter, ipchains with Michael Neuling.
|
||||
S: 52 Moore St
|
||||
@@ -3367,7 +3369,7 @@ S: Germany
|
||||
|
||||
N: Robert Schwebel
|
||||
E: robert@schwebel.de
|
||||
W: http://www.schwebel.de
|
||||
W: https://www.schwebel.de
|
||||
D: Embedded hacker and book author,
|
||||
D: AMD Elan support for Linux
|
||||
S: Pengutronix
|
||||
@@ -3543,7 +3545,7 @@ S: Australia
|
||||
N: Henrik Storner
|
||||
E: storner@image.dk
|
||||
W: http://www.image.dk/~storner/
|
||||
W: http://www.sslug.dk/
|
||||
W: https://www.sslug.dk/
|
||||
D: Configure script: Invented tristate for module-configuration
|
||||
D: vfat/msdos integration, kerneld docs, Linux promotion
|
||||
D: Miscellaneous bug-fixes
|
||||
@@ -3577,7 +3579,7 @@ S: USA
|
||||
|
||||
N: Eugene Surovegin
|
||||
E: ebs@ebshome.net
|
||||
W: http://kernel.ebshome.net/
|
||||
W: https://kernel.ebshome.net/
|
||||
P: 1024D/AE5467F1 FF22 39F1 6728 89F6 6E6C 2365 7602 F33D AE54 67F1
|
||||
D: Embedded PowerPC 4xx: EMAC, I2C, PIC and random hacks/fixes
|
||||
S: Sunnyvale, California 94085
|
||||
@@ -3607,7 +3609,7 @@ S: France
|
||||
|
||||
N: Urs Thuermann
|
||||
E: urs.thuermann@volkswagen.de
|
||||
W: http://www.volkswagen.de
|
||||
W: https://www.volkswagen.de
|
||||
D: Controller Area Network (network layer core)
|
||||
S: Brieffach 1776
|
||||
S: 38436 Wolfsburg
|
||||
@@ -3654,7 +3656,7 @@ S: Canada K2L 1S2
|
||||
|
||||
N: Andrew Tridgell
|
||||
E: tridge@samba.org
|
||||
W: http://samba.org/tridge/
|
||||
W: https://samba.org/tridge/
|
||||
D: dosemu, networking, samba
|
||||
S: 3 Ballow Crescent
|
||||
S: MacGregor A.C.T 2615
|
||||
@@ -3892,7 +3894,7 @@ D: The Linux Support Team Erlangen
|
||||
N: David Weinehall
|
||||
E: tao@acc.umu.se
|
||||
P: 1024D/DC47CA16 7ACE 0FB0 7A74 F994 9B36 E1D1 D14E 8526 DC47 CA16
|
||||
W: http://www.acc.umu.se/~tao/
|
||||
W: https://www.acc.umu.se/~tao/
|
||||
D: v2.0 kernel maintainer
|
||||
D: Fixes for the NE/2-driver
|
||||
D: Miscellaneous MCA-support
|
||||
@@ -3917,7 +3919,7 @@ S: USA
|
||||
N: Harald Welte
|
||||
E: laforge@netfilter.org
|
||||
P: 1024D/30F48BFF DBDE 6912 8831 9A53 879B 9190 5DA5 C655 30F4 8BFF
|
||||
W: http://gnumonks.org/users/laforge
|
||||
W: https://gnumonks.org/users/laforge
|
||||
D: netfilter: new nat helper infrastructure
|
||||
D: netfilter: ULOG, ECN, DSCP target
|
||||
D: netfilter: TTL match
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
What: /sys/devices/system/cpu/cpuidle/current_governor_ro
|
||||
Date: April, 2020
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
current_governor_ro shows current using cpuidle governor, but read only.
|
||||
with the update that cpuidle governor can be changed at runtime in default,
|
||||
both current_governor and current_governor_ro co-exist under
|
||||
/sys/devices/system/cpu/cpuidle/ file, it's duplicate so make
|
||||
current_governor_ro obselete.
|
||||
@@ -0,0 +1,22 @@
|
||||
These files allow sending arbitrary IPC commands to the PMC/SCU which
|
||||
may be dangerous. These will be removed eventually and should not be
|
||||
used in any new applications.
|
||||
|
||||
What: /sys/bus/platform/devices/INT34D2:00/simplecmd
|
||||
Date: Jun 2015
|
||||
KernelVersion: 4.1
|
||||
Contact: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
Description: This interface allows userspace to send an arbitrary
|
||||
IPC command to the PMC/SCU.
|
||||
|
||||
Format: %d %d where first number is command and
|
||||
second number is subcommand.
|
||||
|
||||
What: /sys/bus/platform/devices/INT34D2:00/northpeak
|
||||
Date: Jun 2015
|
||||
KernelVersion: 4.1
|
||||
Contact: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
Description: This interface allows userspace to enable and disable
|
||||
Northpeak through the PMC/SCU.
|
||||
|
||||
Format: %u.
|
||||
@@ -54,7 +54,7 @@ Date: October 2002
|
||||
Contact: Linux Memory Management list <linux-mm@kvack.org>
|
||||
Description:
|
||||
Provides information about the node's distribution and memory
|
||||
utilization. Similar to /proc/meminfo, see Documentation/filesystems/proc.txt
|
||||
utilization. Similar to /proc/meminfo, see Documentation/filesystems/proc.rst
|
||||
|
||||
What: /sys/devices/system/node/nodeX/numastat
|
||||
Date: October 2002
|
||||
|
||||
@@ -1,41 +1,47 @@
|
||||
What: sys/bus/dsa/devices/dsa<m>/cdev_major
|
||||
What: /sys/bus/dsa/devices/dsa<m>/version
|
||||
Date: Apr 15, 2020
|
||||
KernelVersion: 5.8.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The hardware version number.
|
||||
|
||||
What: /sys/bus/dsa/devices/dsa<m>/cdev_major
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The major number that the character device driver assigned to
|
||||
this device.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/errors
|
||||
What: /sys/bus/dsa/devices/dsa<m>/errors
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The error information for this device.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/max_batch_size
|
||||
What: /sys/bus/dsa/devices/dsa<m>/max_batch_size
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The largest number of work descriptors in a batch.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/max_work_queues_size
|
||||
What: /sys/bus/dsa/devices/dsa<m>/max_work_queues_size
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The maximum work queue size supported by this device.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/max_engines
|
||||
What: /sys/bus/dsa/devices/dsa<m>/max_engines
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The maximum number of engines supported by this device.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/max_groups
|
||||
What: /sys/bus/dsa/devices/dsa<m>/max_groups
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The maximum number of groups can be created under this device.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/max_tokens
|
||||
What: /sys/bus/dsa/devices/dsa<m>/max_tokens
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
@@ -44,7 +50,7 @@ Description: The total number of bandwidth tokens supported by this device.
|
||||
implementation, and these resources are allocated by engines to
|
||||
support operations.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/max_transfer_size
|
||||
What: /sys/bus/dsa/devices/dsa<m>/max_transfer_size
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
@@ -52,57 +58,57 @@ Description: The number of bytes to be read from the source address to
|
||||
perform the operation. The maximum transfer size is dependent on
|
||||
the workqueue the descriptor was submitted to.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/max_work_queues
|
||||
What: /sys/bus/dsa/devices/dsa<m>/max_work_queues
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The maximum work queue number that this device supports.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/numa_node
|
||||
What: /sys/bus/dsa/devices/dsa<m>/numa_node
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The numa node number for this device.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/op_cap
|
||||
What: /sys/bus/dsa/devices/dsa<m>/op_cap
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The operation capability bit mask specify the operation types
|
||||
supported by the this device.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/state
|
||||
What: /sys/bus/dsa/devices/dsa<m>/state
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The state information of this device. It can be either enabled
|
||||
or disabled.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/group<m>.<n>
|
||||
What: /sys/bus/dsa/devices/dsa<m>/group<m>.<n>
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The assigned group under this device.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/engine<m>.<n>
|
||||
What: /sys/bus/dsa/devices/dsa<m>/engine<m>.<n>
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The assigned engine under this device.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/wq<m>.<n>
|
||||
What: /sys/bus/dsa/devices/dsa<m>/wq<m>.<n>
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The assigned work queue under this device.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/configurable
|
||||
What: /sys/bus/dsa/devices/dsa<m>/configurable
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: To indicate if this device is configurable or not.
|
||||
|
||||
What: sys/bus/dsa/devices/dsa<m>/token_limit
|
||||
What: /sys/bus/dsa/devices/dsa<m>/token_limit
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
@@ -110,19 +116,19 @@ Description: The maximum number of bandwidth tokens that may be in use at
|
||||
one time by operations that access low bandwidth memory in the
|
||||
device.
|
||||
|
||||
What: sys/bus/dsa/devices/wq<m>.<n>/group_id
|
||||
What: /sys/bus/dsa/devices/wq<m>.<n>/group_id
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The group id that this work queue belongs to.
|
||||
|
||||
What: sys/bus/dsa/devices/wq<m>.<n>/size
|
||||
What: /sys/bus/dsa/devices/wq<m>.<n>/size
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The work queue size for this work queue.
|
||||
|
||||
What: sys/bus/dsa/devices/wq<m>.<n>/type
|
||||
What: /sys/bus/dsa/devices/wq<m>.<n>/type
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
@@ -130,20 +136,20 @@ Description: The type of this work queue, it can be "kernel" type for work
|
||||
queue usages in the kernel space or "user" type for work queue
|
||||
usages by applications in user space.
|
||||
|
||||
What: sys/bus/dsa/devices/wq<m>.<n>/cdev_minor
|
||||
What: /sys/bus/dsa/devices/wq<m>.<n>/cdev_minor
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The minor number assigned to this work queue by the character
|
||||
device driver.
|
||||
|
||||
What: sys/bus/dsa/devices/wq<m>.<n>/mode
|
||||
What: /sys/bus/dsa/devices/wq<m>.<n>/mode
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The work queue mode type for this work queue.
|
||||
|
||||
What: sys/bus/dsa/devices/wq<m>.<n>/priority
|
||||
What: /sys/bus/dsa/devices/wq<m>.<n>/priority
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
@@ -151,20 +157,20 @@ Description: The priority value of this work queue, it is a vlue relative to
|
||||
other work queue in the same group to control quality of service
|
||||
for dispatching work from multiple workqueues in the same group.
|
||||
|
||||
What: sys/bus/dsa/devices/wq<m>.<n>/state
|
||||
What: /sys/bus/dsa/devices/wq<m>.<n>/state
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The current state of the work queue.
|
||||
|
||||
What: sys/bus/dsa/devices/wq<m>.<n>/threshold
|
||||
What: /sys/bus/dsa/devices/wq<m>.<n>/threshold
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The number of entries in this work queue that may be filled
|
||||
via a limited portal.
|
||||
|
||||
What: sys/bus/dsa/devices/engine<m>.<n>/group_id
|
||||
What: /sys/bus/dsa/devices/engine<m>.<n>/group_id
|
||||
Date: Oct 25, 2019
|
||||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
What: /sys/devices/platform/firmware\:zynqmp-firmware/ggs*
|
||||
Date: March 2020
|
||||
KernelVersion: 5.6
|
||||
Contact: "Jolly Shah" <jollys@xilinx.com>
|
||||
Description:
|
||||
Read/Write PMU global general storage register value,
|
||||
GLOBAL_GEN_STORAGE{0:3}.
|
||||
Global general storage register that can be used
|
||||
by system to pass information between masters.
|
||||
|
||||
The register is reset during system or power-on
|
||||
resets. Three registers are used by the FSBL and
|
||||
other Xilinx software products: GLOBAL_GEN_STORAGE{4:6}.
|
||||
|
||||
Usage:
|
||||
# cat /sys/devices/platform/firmware\:zynqmp-firmware/ggs0
|
||||
# echo <value> > /sys/devices/platform/firmware\:zynqmp-firmware/ggs0
|
||||
|
||||
Example:
|
||||
# cat /sys/devices/platform/firmware\:zynqmp-firmware/ggs0
|
||||
# echo 0x1234ABCD > /sys/devices/platform/firmware\:zynqmp-firmware/ggs0
|
||||
|
||||
Users: Xilinx
|
||||
|
||||
What: /sys/devices/platform/firmware\:zynqmp-firmware/pggs*
|
||||
Date: March 2020
|
||||
KernelVersion: 5.6
|
||||
Contact: "Jolly Shah" <jollys@xilinx.com>
|
||||
Description:
|
||||
Read/Write PMU persistent global general storage register
|
||||
value, PERS_GLOB_GEN_STORAGE{0:3}.
|
||||
Persistent global general storage register that
|
||||
can be used by system to pass information between
|
||||
masters.
|
||||
|
||||
This register is only reset by the power-on reset
|
||||
and maintains its value through a system reset.
|
||||
Four registers are used by the FSBL and other Xilinx
|
||||
software products: PERS_GLOB_GEN_STORAGE{4:7}.
|
||||
Register is reset only by a POR reset.
|
||||
|
||||
Usage:
|
||||
# cat /sys/devices/platform/firmware\:zynqmp-firmware/pggs0
|
||||
# echo <value> > /sys/devices/platform/firmware\:zynqmp-firmware/pggs0
|
||||
|
||||
Example:
|
||||
# cat /sys/devices/platform/firmware\:zynqmp-firmware/pggs0
|
||||
# echo 0x1234ABCD > /sys/devices/platform/firmware\:zynqmp-firmware/pggs0
|
||||
|
||||
Users: Xilinx
|
||||
|
||||
What: /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope
|
||||
Date: March 2020
|
||||
KernelVersion: 5.6
|
||||
Contact: "Jolly Shah" <jollys@xilinx.com>
|
||||
Description:
|
||||
This sysfs interface allows to set the shutdown scope for the
|
||||
next shutdown request. When the next shutdown is performed, the
|
||||
platform specific portion of PSCI-system_off can use the chosen
|
||||
shutdown scope.
|
||||
|
||||
Following are available shutdown scopes(subtypes):
|
||||
|
||||
subsystem: Only the APU along with all of its peripherals
|
||||
not used by other processing units will be
|
||||
shut down. This may result in the FPD power
|
||||
domain being shut down provided that no other
|
||||
processing unit uses FPD peripherals or DRAM.
|
||||
ps_only: The complete PS will be shut down, including the
|
||||
RPU, PMU, etc. Only the PL domain (FPGA)
|
||||
remains untouched.
|
||||
system: The complete system/device is shut down.
|
||||
|
||||
Usage:
|
||||
# cat /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope
|
||||
# echo <scope> > /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope
|
||||
|
||||
Example:
|
||||
# cat /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope
|
||||
# echo "subsystem" > /sys/devices/platform/firmware\:zynqmp-firmware/shutdown_scope
|
||||
|
||||
Users: Xilinx
|
||||
|
||||
What: /sys/devices/platform/firmware\:zynqmp-firmware/health_status
|
||||
Date: March 2020
|
||||
KernelVersion: 5.6
|
||||
Contact: "Jolly Shah" <jollys@xilinx.com>
|
||||
Description:
|
||||
This sysfs interface allows to set the health status. If PMUFW
|
||||
is compiled with CHECK_HEALTHY_BOOT, it will check the healthy
|
||||
bit on FPD WDT expiration. If healthy bit is set by a user
|
||||
application running in Linux, PMUFW will do APU only restart. If
|
||||
healthy bit is not set during FPD WDT expiration, PMUFW will do
|
||||
system restart.
|
||||
|
||||
Usage:
|
||||
Set healthy bit
|
||||
# echo 1 > /sys/devices/platform/firmware\:zynqmp-firmware/health_status
|
||||
|
||||
Unset healthy bit
|
||||
# echo 0 > /sys/devices/platform/firmware\:zynqmp-firmware/health_status
|
||||
|
||||
Users: Xilinx
|
||||
@@ -206,3 +206,20 @@ Description: This file exposes the firmware version of burnable voltage
|
||||
regulator devices.
|
||||
|
||||
The file is read only.
|
||||
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld1_pn
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld2_pn
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld3_pn
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld4_pn
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld1_version_min
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld2_version_min
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld3_version_min
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld4_version_min
|
||||
Date: July 2020
|
||||
KernelVersion: 5.9
|
||||
Contact: Vadim Pasternak <vadimpmellanox.com>
|
||||
Description: These files show with which CPLD part numbers and minor
|
||||
versions have been burned CPLD devices equipped on a
|
||||
system.
|
||||
|
||||
The files are read only.
|
||||
|
||||
+6
@@ -325,6 +325,12 @@ KernelVersion: 2.6
|
||||
Contact: speakup@linux-speakup.org
|
||||
Description: Gets or sets the pitch of the synthesizer. The range is 0-9.
|
||||
|
||||
What: /sys/accessibility/speakup/soft/inflection
|
||||
KernelVersion: 5.8
|
||||
Contact: speakup@linux-speakup.org
|
||||
Description: Gets or sets the inflection of the synthesizer, i.e. the pitch
|
||||
range. The range is 0-9.
|
||||
|
||||
What: /sys/accessibility/speakup/soft/punct
|
||||
KernelVersion: 2.6
|
||||
Contact: speakup@linux-speakup.org
|
||||
@@ -37,4 +37,4 @@ when changes are made.
|
||||
|
||||
The following CEC error injection implementations exist:
|
||||
|
||||
- Documentation/media/uapi/cec/cec-pin-error-inj.rst
|
||||
- Documentation/userspace-api/media/cec/cec-pin-error-inj.rst
|
||||
|
||||
@@ -8,6 +8,25 @@ Description: Sets the device address to be used for read or write through
|
||||
only when the IOMMU is disabled.
|
||||
The acceptable value is a string that starts with "0x"
|
||||
|
||||
What: /sys/kernel/debug/habanalabs/hl<n>/clk_gate
|
||||
Date: May 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: oded.gabbay@gmail.com
|
||||
Description: Allow the root user to disable/enable in runtime the clock
|
||||
gating mechanism in Gaudi. Due to how Gaudi is built, the
|
||||
clock gating needs to be disabled in order to access the
|
||||
registers of the TPC and MME engines. This is sometimes needed
|
||||
during debug by the user and hence the user needs this option.
|
||||
The user can supply a bitmask value, each bit represents
|
||||
a different engine to disable/enable its clock gating feature.
|
||||
The bitmask is composed of 20 bits:
|
||||
0 - 7 : DMA channels
|
||||
8 - 11 : MME engines
|
||||
12 - 19 : TPC engines
|
||||
The bit's location of a specific engine can be determined
|
||||
using (1 << GAUDI_ENGINE_ID_*). GAUDI_ENGINE_ID_* values
|
||||
are defined in uapi habanalabs.h file in enum gaudi_engine_id
|
||||
|
||||
What: /sys/kernel/debug/habanalabs/hl<n>/command_buffers
|
||||
Date: Jan 2019
|
||||
KernelVersion: 5.1
|
||||
@@ -150,3 +169,10 @@ KernelVersion: 5.1
|
||||
Contact: oded.gabbay@gmail.com
|
||||
Description: Displays a list with information about all the active virtual
|
||||
address mappings per ASID
|
||||
|
||||
What: /sys/kernel/debug/habanalabs/hl<n>/stop_on_err
|
||||
Date: Mar 2020
|
||||
KernelVersion: 5.6
|
||||
Contact: oded.gabbay@gmail.com
|
||||
Description: Sets the stop-on_error option for the device engines. Value of
|
||||
"0" is for disable, otherwise enable.
|
||||
|
||||
@@ -33,7 +33,7 @@ Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump debug registers from the HPRE.
|
||||
Only available for PF.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/qm_regs
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/regs
|
||||
Date: Sep 2019
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump debug registers from the QM.
|
||||
@@ -44,14 +44,97 @@ What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/current_q
|
||||
Date: Sep 2019
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: One QM may contain multiple queues. Select specific queue to
|
||||
show its debug registers in above qm_regs.
|
||||
show its debug registers in above regs.
|
||||
Only available for PF.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/clear_enable
|
||||
Date: Sep 2019
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: QM debug registers(qm_regs) read clear control. 1 means enable
|
||||
Description: QM debug registers(regs) read clear control. 1 means enable
|
||||
register read clear, otherwise 0.
|
||||
Writing to this file has no functional effect, only enable or
|
||||
disable counters clear after reading of these registers.
|
||||
Only available for PF.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/err_irq
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of invalid interrupts for
|
||||
QM task completion.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/aeq_irq
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of QM async event queue interrupts.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/abnormal_irq
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of interrupts for QM abnormal event.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/create_qp_err
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of queue allocation errors.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/mb_err
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of failed QM mailbox commands.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/qm/status
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the status of the QM.
|
||||
Four states: initiated, started, stopped and closed.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/send_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of sent requests.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/recv_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of received requests.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/send_busy_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of requests sent
|
||||
with returning busy.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/send_fail_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of completed but error requests.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/invalid_req_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of invalid requests being received.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/overtime_thrhld
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Set the threshold time for counting the request which is
|
||||
processed longer than the threshold.
|
||||
0: disable(default), 1: 1 microsecond.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
What: /sys/kernel/debug/hisi_hpre/<bdf>/hpre_dfx/over_thrhld_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of time out requests.
|
||||
Available for both PF and VF, and take no other effect on HPRE.
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
What: /sys/kernel/debug/hisi_sec/<bdf>/sec_dfx
|
||||
Date: Oct 2019
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the debug registers of SEC cores.
|
||||
Only available for PF.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec/<bdf>/clear_enable
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/clear_enable
|
||||
Date: Oct 2019
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Enabling/disabling of clear action after reading
|
||||
@@ -12,7 +6,7 @@ Description: Enabling/disabling of clear action after reading
|
||||
0: disable, 1: enable.
|
||||
Only available for PF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec/<bdf>/current_qm
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/current_qm
|
||||
Date: Oct 2019
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: One SEC controller has one PF and multiple VFs, each function
|
||||
@@ -20,24 +14,100 @@ Description: One SEC controller has one PF and multiple VFs, each function
|
||||
qm refers to.
|
||||
Only available for PF.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec/<bdf>/qm/qm_regs
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/qm_regs
|
||||
Date: Oct 2019
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump of QM related debug registers.
|
||||
Available for PF and VF in host. VF in guest currently only
|
||||
has one debug register.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec/<bdf>/qm/current_q
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/current_q
|
||||
Date: Oct 2019
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: One QM of SEC may contain multiple queues. Select specific
|
||||
queue to show its debug registers in above 'qm_regs'.
|
||||
queue to show its debug registers in above 'regs'.
|
||||
Only available for PF.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec/<bdf>/qm/clear_enable
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/clear_enable
|
||||
Date: Oct 2019
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Enabling/disabling of clear action after reading
|
||||
the SEC's QM debug registers.
|
||||
0: disable, 1: enable.
|
||||
Only available for PF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/err_irq
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of invalid interrupts for
|
||||
QM task completion.
|
||||
Available for both PF and VF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/aeq_irq
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of QM async event queue interrupts.
|
||||
Available for both PF and VF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/abnormal_irq
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of interrupts for QM abnormal event.
|
||||
Available for both PF and VF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/create_qp_err
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of queue allocation errors.
|
||||
Available for both PF and VF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/mb_err
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of failed QM mailbox commands.
|
||||
Available for both PF and VF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/qm/status
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the status of the QM.
|
||||
Four states: initiated, started, stopped and closed.
|
||||
Available for both PF and VF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/send_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of sent requests.
|
||||
Available for both PF and VF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/recv_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of received requests.
|
||||
Available for both PF and VF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/send_busy_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of requests sent with returning busy.
|
||||
Available for both PF and VF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/err_bd_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of BD type error requests
|
||||
to be received.
|
||||
Available for both PF and VF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/invalid_req_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of invalid requests being received.
|
||||
Available for both PF and VF, and take no other effect on SEC.
|
||||
|
||||
What: /sys/kernel/debug/hisi_sec2/<bdf>/sec_dfx/done_flag_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of completed but marked error requests
|
||||
to be received.
|
||||
Available for both PF and VF, and take no other effect on SEC.
|
||||
|
||||
@@ -26,7 +26,7 @@ Description: One ZIP controller has one PF and multiple VFs, each function
|
||||
has a QM. Select the QM which below qm refers to.
|
||||
Only available for PF.
|
||||
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/qm/qm_regs
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/qm/regs
|
||||
Date: Nov 2018
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump of QM related debug registers.
|
||||
@@ -37,14 +37,78 @@ What: /sys/kernel/debug/hisi_zip/<bdf>/qm/current_q
|
||||
Date: Nov 2018
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: One QM may contain multiple queues. Select specific queue to
|
||||
show its debug registers in above qm_regs.
|
||||
show its debug registers in above regs.
|
||||
Only available for PF.
|
||||
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/qm/clear_enable
|
||||
Date: Nov 2018
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: QM debug registers(qm_regs) read clear control. 1 means enable
|
||||
Description: QM debug registers(regs) read clear control. 1 means enable
|
||||
register read clear, otherwise 0.
|
||||
Writing to this file has no functional effect, only enable or
|
||||
disable counters clear after reading of these registers.
|
||||
Only available for PF.
|
||||
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/qm/err_irq
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of invalid interrupts for
|
||||
QM task completion.
|
||||
Available for both PF and VF, and take no other effect on ZIP.
|
||||
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/qm/aeq_irq
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of QM async event queue interrupts.
|
||||
Available for both PF and VF, and take no other effect on ZIP.
|
||||
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/qm/abnormal_irq
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of interrupts for QM abnormal event.
|
||||
Available for both PF and VF, and take no other effect on ZIP.
|
||||
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/qm/create_qp_err
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of queue allocation errors.
|
||||
Available for both PF and VF, and take no other effect on ZIP.
|
||||
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/qm/mb_err
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the number of failed QM mailbox commands.
|
||||
Available for both PF and VF, and take no other effect on ZIP.
|
||||
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/qm/status
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the status of the QM.
|
||||
Four states: initiated, started, stopped and closed.
|
||||
Available for both PF and VF, and take no other effect on ZIP.
|
||||
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/zip_dfx/send_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of sent requests.
|
||||
Available for both PF and VF, and take no other effect on ZIP.
|
||||
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/zip_dfx/recv_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of received requests.
|
||||
Available for both PF and VF, and take no other effect on ZIP.
|
||||
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/zip_dfx/send_busy_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of requests received
|
||||
with returning busy.
|
||||
Available for both PF and VF, and take no other effect on ZIP.
|
||||
|
||||
What: /sys/kernel/debug/hisi_zip/<bdf>/zip_dfx/err_bd_cnt
|
||||
Date: Apr 2020
|
||||
Contact: linux-crypto@vger.kernel.org
|
||||
Description: Dump the total number of BD type error requests
|
||||
to be received.
|
||||
Available for both PF and VF, and take no other effect on ZIP.
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
What: /sys/kernel/debug/turris-mox-rwtm/do_sign
|
||||
Date: Jun 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Description: (W) Message to sign with the ECDSA private key stored in
|
||||
device's OTP. The message must be exactly 64 bytes (since
|
||||
this is intended for SHA-512 hashes).
|
||||
(R) The resulting signature, 136 bytes. This contains the R and
|
||||
S values of the ECDSA signature, both in big-endian format.
|
||||
@@ -56,6 +56,17 @@ Description: The /dev/kmsg character device node provides userspace access
|
||||
seek after the last record available at the time
|
||||
the last SYSLOG_ACTION_CLEAR was issued.
|
||||
|
||||
Other seek operations or offsets are not supported because of
|
||||
the special behavior this device has. The device allows to read
|
||||
or write only whole variable length messages (records) that are
|
||||
stored in a ring buffer.
|
||||
|
||||
Because of the non-standard behavior also the error values are
|
||||
non-standard. -ESPIPE is returned for non-zero offset. -EINVAL
|
||||
is returned for other operations, e.g. SEEK_CUR. This behavior
|
||||
and values are historical and could not be modified without the
|
||||
risk of breaking userspace.
|
||||
|
||||
The output format consists of a prefix carrying the syslog
|
||||
prefix including priority and facility, the 64 bit message
|
||||
sequence number and the monotonic timestamp in microseconds,
|
||||
|
||||
@@ -11,7 +11,7 @@ Description:
|
||||
Additionally, the fields Pss_Anon, Pss_File and Pss_Shmem
|
||||
are not present in /proc/pid/smaps. These fields represent
|
||||
the sum of the Pss field of each type (anon, file, shmem).
|
||||
For more details, see Documentation/filesystems/proc.txt
|
||||
For more details, see Documentation/filesystems/proc.rst
|
||||
and the procfs man page.
|
||||
|
||||
Typical output looks like this:
|
||||
|
||||
@@ -273,6 +273,24 @@ Description:
|
||||
device ("host-aware" or "host-managed" zone model). For regular
|
||||
block devices, the value is always 0.
|
||||
|
||||
What: /sys/block/<disk>/queue/max_active_zones
|
||||
Date: July 2020
|
||||
Contact: Niklas Cassel <niklas.cassel@wdc.com>
|
||||
Description:
|
||||
For zoned block devices (zoned attribute indicating
|
||||
"host-managed" or "host-aware"), the sum of zones belonging to
|
||||
any of the zone states: EXPLICIT OPEN, IMPLICIT OPEN or CLOSED,
|
||||
is limited by this value. If this value is 0, there is no limit.
|
||||
|
||||
What: /sys/block/<disk>/queue/max_open_zones
|
||||
Date: July 2020
|
||||
Contact: Niklas Cassel <niklas.cassel@wdc.com>
|
||||
Description:
|
||||
For zoned block devices (zoned attribute indicating
|
||||
"host-managed" or "host-aware"), the sum of zones belonging to
|
||||
any of the zone states: EXPLICIT OPEN or IMPLICIT OPEN,
|
||||
is limited by this value. If this value is 0, there is no limit.
|
||||
|
||||
What: /sys/block/<disk>/queue/chunk_sectors
|
||||
Date: September 2016
|
||||
Contact: Hannes Reinecke <hare@suse.com>
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
What: /sys/block/rnbd<N>/rnbd/unmap_device
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: To unmap a volume, "normal" or "force" has to be written to:
|
||||
/sys/block/rnbd<N>/rnbd/unmap_device
|
||||
|
||||
When "normal" is used, the operation will fail with EBUSY if any process
|
||||
is using the device. When "force" is used, the device is also unmapped
|
||||
when device is in use. All I/Os that are in progress will fail.
|
||||
|
||||
Example:
|
||||
|
||||
# echo "normal" > /sys/block/rnbd0/rnbd/unmap_device
|
||||
|
||||
What: /sys/block/rnbd<N>/rnbd/state
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: The file contains the current state of the block device. The state file
|
||||
returns "open" when the device is successfully mapped from the server
|
||||
and accepting I/O requests. When the connection to the server gets
|
||||
disconnected in case of an error (e.g. link failure), the state file
|
||||
returns "closed" and all I/O requests submitted to it will fail with -EIO.
|
||||
|
||||
What: /sys/block/rnbd<N>/rnbd/session
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RNBD uses RTRS session to transport the data between client and
|
||||
server. The entry "session" contains the name of the session, that
|
||||
was used to establish the RTRS session. It's the same name that
|
||||
was passed as server parameter to the map_device entry.
|
||||
|
||||
What: /sys/block/rnbd<N>/rnbd/mapping_path
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Contains the path that was passed as "device_path" to the map_device
|
||||
operation.
|
||||
|
||||
What: /sys/block/rnbd<N>/rnbd/access_mode
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Contains the device access mode: ro, rw or migration.
|
||||
@@ -0,0 +1,104 @@
|
||||
What: /sys/bus/event_source/devices/dfl_fmeX/format
|
||||
Date: April 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: Wu Hao <hao.wu@intel.com>
|
||||
Description: Read-only. Attribute group to describe the magic bits
|
||||
that go into perf_event_attr.config for a particular pmu.
|
||||
(See ABI/testing/sysfs-bus-event_source-devices-format).
|
||||
|
||||
Each attribute under this group defines a bit range of the
|
||||
perf_event_attr.config. All supported attributes are listed
|
||||
below.
|
||||
|
||||
event = "config:0-11" - event ID
|
||||
evtype = "config:12-15" - event type
|
||||
portid = "config:16-23" - event source
|
||||
|
||||
For example,
|
||||
|
||||
fab_mmio_read = "event=0x06,evtype=0x02,portid=0xff"
|
||||
|
||||
It shows this fab_mmio_read is a fabric type (0x02) event with
|
||||
0x06 local event id for overall monitoring (portid=0xff).
|
||||
|
||||
What: /sys/bus/event_source/devices/dfl_fmeX/cpumask
|
||||
Date: April 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: Wu Hao <hao.wu@intel.com>
|
||||
Description: Read-only. This file always returns cpu which the PMU is bound
|
||||
for access to all fme pmu performance monitoring events.
|
||||
|
||||
What: /sys/bus/event_source/devices/dfl_fmeX/events
|
||||
Date: April 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: Wu Hao <hao.wu@intel.com>
|
||||
Description: Read-only. Attribute group to describe performance monitoring
|
||||
events specific to fme. Each attribute in this group describes
|
||||
a single performance monitoring event supported by this fme pmu.
|
||||
The name of the file is the name of the event.
|
||||
(See ABI/testing/sysfs-bus-event_source-devices-events).
|
||||
|
||||
All supported performance monitoring events are listed below.
|
||||
|
||||
Basic events (evtype=0x00)
|
||||
|
||||
clock = "event=0x00,evtype=0x00,portid=0xff"
|
||||
|
||||
Cache events (evtype=0x01)
|
||||
|
||||
cache_read_hit = "event=0x00,evtype=0x01,portid=0xff"
|
||||
cache_read_miss = "event=0x01,evtype=0x01,portid=0xff"
|
||||
cache_write_hit = "event=0x02,evtype=0x01,portid=0xff"
|
||||
cache_write_miss = "event=0x03,evtype=0x01,portid=0xff"
|
||||
cache_hold_request = "event=0x05,evtype=0x01,portid=0xff"
|
||||
cache_data_write_port_contention =
|
||||
"event=0x06,evtype=0x01,portid=0xff"
|
||||
cache_tag_write_port_contention =
|
||||
"event=0x07,evtype=0x01,portid=0xff"
|
||||
cache_tx_req_stall = "event=0x08,evtype=0x01,portid=0xff"
|
||||
cache_rx_req_stall = "event=0x09,evtype=0x01,portid=0xff"
|
||||
cache_eviction = "event=0x0a,evtype=0x01,portid=0xff"
|
||||
|
||||
Fabric events (evtype=0x02)
|
||||
|
||||
fab_pcie0_read = "event=0x00,evtype=0x02,portid=0xff"
|
||||
fab_pcie0_write = "event=0x01,evtype=0x02,portid=0xff"
|
||||
fab_pcie1_read = "event=0x02,evtype=0x02,portid=0xff"
|
||||
fab_pcie1_write = "event=0x03,evtype=0x02,portid=0xff"
|
||||
fab_upi_read = "event=0x04,evtype=0x02,portid=0xff"
|
||||
fab_upi_write = "event=0x05,evtype=0x02,portid=0xff"
|
||||
fab_mmio_read = "event=0x06,evtype=0x02,portid=0xff"
|
||||
fab_mmio_write = "event=0x07,evtype=0x02,portid=0xff"
|
||||
fab_port_pcie0_read = "event=0x00,evtype=0x02,portid=?"
|
||||
fab_port_pcie0_write = "event=0x01,evtype=0x02,portid=?"
|
||||
fab_port_pcie1_read = "event=0x02,evtype=0x02,portid=?"
|
||||
fab_port_pcie1_write = "event=0x03,evtype=0x02,portid=?"
|
||||
fab_port_upi_read = "event=0x04,evtype=0x02,portid=?"
|
||||
fab_port_upi_write = "event=0x05,evtype=0x02,portid=?"
|
||||
fab_port_mmio_read = "event=0x06,evtype=0x02,portid=?"
|
||||
fab_port_mmio_write = "event=0x07,evtype=0x02,portid=?"
|
||||
|
||||
VTD events (evtype=0x03)
|
||||
|
||||
vtd_port_read_transaction = "event=0x00,evtype=0x03,portid=?"
|
||||
vtd_port_write_transaction = "event=0x01,evtype=0x03,portid=?"
|
||||
vtd_port_devtlb_read_hit = "event=0x02,evtype=0x03,portid=?"
|
||||
vtd_port_devtlb_write_hit = "event=0x03,evtype=0x03,portid=?"
|
||||
vtd_port_devtlb_4k_fill = "event=0x04,evtype=0x03,portid=?"
|
||||
vtd_port_devtlb_2m_fill = "event=0x05,evtype=0x03,portid=?"
|
||||
vtd_port_devtlb_1g_fill = "event=0x06,evtype=0x03,portid=?"
|
||||
|
||||
VTD SIP events (evtype=0x04)
|
||||
|
||||
vtd_sip_iotlb_4k_hit = "event=0x00,evtype=0x04,portid=0xff"
|
||||
vtd_sip_iotlb_2m_hit = "event=0x01,evtype=0x04,portid=0xff"
|
||||
vtd_sip_iotlb_1g_hit = "event=0x02,evtype=0x04,portid=0xff"
|
||||
vtd_sip_slpwc_l3_hit = "event=0x03,evtype=0x04,portid=0xff"
|
||||
vtd_sip_slpwc_l4_hit = "event=0x04,evtype=0x04,portid=0xff"
|
||||
vtd_sip_rcc_hit = "event=0x05,evtype=0x04,portid=0xff"
|
||||
vtd_sip_iotlb_4k_miss = "event=0x06,evtype=0x04,portid=0xff"
|
||||
vtd_sip_iotlb_2m_miss = "event=0x07,evtype=0x04,portid=0xff"
|
||||
vtd_sip_iotlb_1g_miss = "event=0x08,evtype=0x04,portid=0xff"
|
||||
vtd_sip_slpwc_l3_miss = "event=0x09,evtype=0x04,portid=0xff"
|
||||
vtd_sip_slpwc_l4_miss = "event=0x0a,evtype=0x04,portid=0xff"
|
||||
vtd_sip_rcc_miss = "event=0x0b,evtype=0x04,portid=0xff"
|
||||
@@ -22,6 +22,34 @@ Description:
|
||||
Exposes the "version" field of the 24x7 catalog. This is also
|
||||
extractable from the provided binary "catalog" sysfs entry.
|
||||
|
||||
What: /sys/devices/hv_24x7/interface/sockets
|
||||
Date: May 2020
|
||||
Contact: Linux on PowerPC Developer List <linuxppc-dev@lists.ozlabs.org>
|
||||
Description: read only
|
||||
This sysfs interface exposes the number of sockets present in the
|
||||
system.
|
||||
|
||||
What: /sys/devices/hv_24x7/interface/chipspersocket
|
||||
Date: May 2020
|
||||
Contact: Linux on PowerPC Developer List <linuxppc-dev@lists.ozlabs.org>
|
||||
Description: read only
|
||||
This sysfs interface exposes the number of chips per socket
|
||||
present in the system.
|
||||
|
||||
What: /sys/devices/hv_24x7/interface/coresperchip
|
||||
Date: May 2020
|
||||
Contact: Linux on PowerPC Developer List <linuxppc-dev@lists.ozlabs.org>
|
||||
Description: read only
|
||||
This sysfs interface exposes the number of cores per chip
|
||||
present in the system.
|
||||
|
||||
What: /sys/devices/hv_24x7/cpumask
|
||||
Date: July 2020
|
||||
Contact: Linux on PowerPC Developer List <linuxppc-dev@lists.ozlabs.org>
|
||||
Description: read only
|
||||
This sysfs file exposes the cpumask which is designated to make
|
||||
HCALLs to retrieve hv-24x7 pmu event counter data.
|
||||
|
||||
What: /sys/bus/event_source/devices/hv_24x7/event_descs/<event-name>
|
||||
Date: February 2014
|
||||
Contact: Linux on PowerPC Developer List <linuxppc-dev@lists.ozlabs.org>
|
||||
|
||||
@@ -1569,7 +1569,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_concentrationX_voc_raw
|
||||
KernelVersion: 4.3
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Raw (unscaled no offset etc.) percentage reading of a substance.
|
||||
Raw (unscaled no offset etc.) reading of a substance. Units
|
||||
after application of scale and offset are percents.
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_resistance_raw
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_resistanceX_raw
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibbias
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibbias
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibbias
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibbias
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibbias
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibbias
|
||||
KernelVersion: 5.8
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Hardware applied calibration offset (assumed to fix production
|
||||
inaccuracies). Values represent a real physical offset expressed
|
||||
in SI units (m/s^2 for accelerometer and rad/s for gyroscope).
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_accel_calibbias_available
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_calibbias_available
|
||||
KernelVersion: 5.8
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Range of available values for hardware offset. Values in SI
|
||||
units (m/s^2 for accelerometer and rad/s for gyroscope).
|
||||
@@ -0,0 +1,10 @@
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_proximity_nearlevel
|
||||
Date: March 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Near level for proximity sensors. This is a single integer
|
||||
value that tells user space when an object should be
|
||||
considered close to the device. If the value read from the
|
||||
sensor is above or equal to the value in this file an object
|
||||
should typically be considered near.
|
||||
@@ -0,0 +1,34 @@
|
||||
What: /sys/bus/iio/devices/iio:deviceX/calibration_auto_enable
|
||||
Date: June 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Contaminants build-up in the measurement chamber or optical
|
||||
elements deterioration leads to sensor drift.
|
||||
|
||||
One can compensate for sensor drift by using automatic self
|
||||
calibration procedure (asc).
|
||||
|
||||
Writing 1 or 0 to this attribute will respectively activate or
|
||||
deactivate asc.
|
||||
|
||||
Upon reading current asc status is returned.
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/calibration_forced_value
|
||||
Date: June 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Contaminants build-up in the measurement chamber or optical
|
||||
elements deterioration leads to sensor drift.
|
||||
|
||||
One can compensate for sensor drift by using forced
|
||||
recalibration (frc). This is useful in case there's known
|
||||
co2 reference available nearby the sensor.
|
||||
|
||||
Picking value from the range [400 1 2000] and writing it to the
|
||||
sensor will set frc.
|
||||
|
||||
Upon reading current frc value is returned. Note that after
|
||||
power cycling default value (i.e 400) is returned even though
|
||||
internally sensor had recalibrated itself.
|
||||
@@ -0,0 +1,10 @@
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_proximity3_comb_raw
|
||||
Date: February 2019
|
||||
KernelVersion: 5.6
|
||||
Contact: Daniel Campello <campello@chromium.org>
|
||||
Description:
|
||||
Proximity measurement indicating that some object is
|
||||
near the combined sensor. The combined sensor presents
|
||||
proximity measurements constructed by hardware by
|
||||
combining measurements taken from a given set of
|
||||
physical sensors.
|
||||
@@ -1,14 +1,14 @@
|
||||
What: /sys/bus/most/devices/.../description
|
||||
What: /sys/bus/most/devices/<dev>/description
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
Provides information about the interface type and the physical
|
||||
location of the device. Hardware attached via USB, for instance,
|
||||
Provides information about the physical location of the
|
||||
device. Hardware attached via USB, for instance,
|
||||
might return <1-1.1:1.0>
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../interface
|
||||
What: /sys/bus/most/devices/<dev>/interface
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -16,7 +16,7 @@ Description:
|
||||
Indicates the type of peripheral interface the device uses.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci
|
||||
What: /sys/bus/most/devices/<dev>/dci
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -26,7 +26,7 @@ Description:
|
||||
write the controller's DCI registers.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/arb_address
|
||||
What: /sys/bus/most/devices/<dev>/dci/arb_address
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -35,7 +35,7 @@ Description:
|
||||
application wants to read from or write to.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/arb_value
|
||||
What: /sys/bus/most/devices/<dev>/dci/arb_value
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -44,7 +44,7 @@ Description:
|
||||
is stored in arb_address.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/mep_eui48_hi
|
||||
What: /sys/bus/most/devices/<dev>/dci/mep_eui48_hi
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -52,7 +52,7 @@ Description:
|
||||
This is used to check and configure the MAC address.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/mep_eui48_lo
|
||||
What: /sys/bus/most/devices/<dev>/dci/mep_eui48_lo
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -60,7 +60,7 @@ Description:
|
||||
This is used to check and configure the MAC address.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/mep_eui48_mi
|
||||
What: /sys/bus/most/devices/<dev>/dci/mep_eui48_mi
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -68,7 +68,7 @@ Description:
|
||||
This is used to check and configure the MAC address.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/mep_filter
|
||||
What: /sys/bus/most/devices/<dev>/dci/mep_filter
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -76,7 +76,7 @@ Description:
|
||||
This is used to check and configure the MEP filter address.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/mep_hash0
|
||||
What: /sys/bus/most/devices/<dev>/dci/mep_hash0
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -84,7 +84,7 @@ Description:
|
||||
This is used to check and configure the MEP hash table.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/mep_hash1
|
||||
What: /sys/bus/most/devices/<dev>/dci/mep_hash1
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -92,7 +92,7 @@ Description:
|
||||
This is used to check and configure the MEP hash table.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/mep_hash2
|
||||
What: /sys/bus/most/devices/<dev>/dci/mep_hash2
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -100,7 +100,7 @@ Description:
|
||||
This is used to check and configure the MEP hash table.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/mep_hash3
|
||||
What: /sys/bus/most/devices/<dev>/dci/mep_hash3
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -108,7 +108,7 @@ Description:
|
||||
This is used to check and configure the MEP hash table.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/ni_state
|
||||
What: /sys/bus/most/devices/<dev>/dci/ni_state
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -116,7 +116,7 @@ Description:
|
||||
Indicates the current network interface state.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/node_address
|
||||
What: /sys/bus/most/devices/<dev>/dci/node_address
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -124,7 +124,7 @@ Description:
|
||||
Indicates the current node address.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/node_position
|
||||
What: /sys/bus/most/devices/<dev>/dci/node_position
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -132,7 +132,7 @@ Description:
|
||||
Indicates the current node position.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/packet_bandwidth
|
||||
What: /sys/bus/most/devices/<dev>/dci/packet_bandwidth
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -140,7 +140,7 @@ Description:
|
||||
Indicates the configured packet bandwidth.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../dci/sync_ep
|
||||
What: /sys/bus/most/devices/<dev>/dci/sync_ep
|
||||
Date: June 2016
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -149,7 +149,7 @@ Description:
|
||||
endpoint.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
@@ -160,91 +160,92 @@ Description:
|
||||
configure it.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/available_datatypes
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/available_datatypes
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
Indicates the data types the current channel can transport.
|
||||
Indicates the data types the channel can transport.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/available_directions
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/available_directions
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
Indicates the directions the current channel is capable of.
|
||||
Indicates the directions the channel is capable of.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/number_of_packet_buffers
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/number_of_packet_buffers
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
Indicates the number of packet buffers the current channel can
|
||||
Indicates the number of packet buffers the channel can
|
||||
handle.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/number_of_stream_buffers
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/number_of_stream_buffers
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
Indicates the number of streaming buffers the current channel can
|
||||
Indicates the number of streaming buffers the channel can
|
||||
handle.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/size_of_packet_buffer
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/size_of_packet_buffer
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
Indicates the size of a packet buffer the current channel can
|
||||
Indicates the size of a packet buffer the channel can
|
||||
handle.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/size_of_stream_buffer
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/size_of_stream_buffer
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
Indicates the size of a streaming buffer the current channel can
|
||||
Indicates the size of a streaming buffer the channel can
|
||||
handle.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/set_number_of_buffers
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/set_number_of_buffers
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
This is to configure the number of buffers of the current channel.
|
||||
This is to read back the configured number of buffers of
|
||||
the channel.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/set_buffer_size
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/set_buffer_size
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
This is to configure the size of a buffer of the current channel.
|
||||
This is to read back the configured buffer size of the channel.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/set_direction
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/set_direction
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
This is to configure the direction of the current channel.
|
||||
This is to read back the configured direction of the channel.
|
||||
The following strings will be accepted:
|
||||
'dir_tx',
|
||||
'dir_rx'
|
||||
'tx',
|
||||
'rx'
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/set_datatype
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/set_datatype
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
This is to configure the data type of the current channel.
|
||||
This is to read back the configured data type of the channel.
|
||||
The following strings will be accepted:
|
||||
'control',
|
||||
'async',
|
||||
@@ -252,30 +253,31 @@ Description:
|
||||
'isoc_avp'
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/set_subbuffer_size
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/set_subbuffer_size
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
This is to configure the subbuffer size of the current channel.
|
||||
This is to read back the configured subbuffer size of
|
||||
the channel.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/set_packets_per_xact
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/set_packets_per_xact
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
This is to configure the number of packets per transaction of
|
||||
the current channel. This is only needed network interface
|
||||
controller is attached via USB.
|
||||
This is to read back the configured number of packets per
|
||||
transaction of the channel. This is only applicable when
|
||||
connected via USB.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/devices/.../<channel>/channel_starving
|
||||
What: /sys/bus/most/devices/<dev>/<channel>/channel_starving
|
||||
Date: March 2017
|
||||
KernelVersion: 4.15
|
||||
Contact: Christian Gromm <christian.gromm@microchip.com>
|
||||
Description:
|
||||
Indicates whether current channel ran out of buffers.
|
||||
Indicates whether channel ran out of buffers.
|
||||
Users:
|
||||
|
||||
What: /sys/bus/most/drivers/most_core/components
|
||||
|
||||
@@ -202,6 +202,25 @@ Description:
|
||||
functions. See the section named 'NVDIMM Root Device _DSMs' in
|
||||
the ACPI specification.
|
||||
|
||||
What: /sys/bus/nd/devices/ndbusX/nfit/firmware_activate_noidle
|
||||
Date: Apr, 2020
|
||||
KernelVersion: v5.8
|
||||
Contact: linux-nvdimm@lists.01.org
|
||||
Description:
|
||||
(RW) The Intel platform implementation of firmware activate
|
||||
support exposes an option let the platform force idle devices in
|
||||
the system over the activation event, or trust that the OS will
|
||||
do it. The safe default is to let the platform force idle
|
||||
devices since the kernel is already in a suspend state, and on
|
||||
the chance that a driver does not properly quiesce bus-mastering
|
||||
after a suspend callback the platform will handle it. However,
|
||||
the activation might abort if, for example, platform firmware
|
||||
determines that the activation time exceeds the max PCI-E
|
||||
completion timeout. Since the platform does not know whether the
|
||||
OS is running the activation from a suspend context it aborts,
|
||||
but if the system owner trusts driver suspend callback to be
|
||||
sufficient then 'firmware_activation_noidle' can be
|
||||
enabled to bypass the activation abort.
|
||||
|
||||
What: /sys/bus/nd/devices/regionX/nfit/range_index
|
||||
Date: Jun, 2015
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
The libnvdimm sub-system implements a common sysfs interface for
|
||||
platform nvdimm resources. See Documentation/driver-api/nvdimm/.
|
||||
@@ -0,0 +1,8 @@
|
||||
What: /sys/bus/tee/devices/optee-ta-<uuid>/
|
||||
Date: May 2020
|
||||
KernelVersion 5.8
|
||||
Contact: op-tee@lists.trustedfirmware.org
|
||||
Description:
|
||||
OP-TEE bus provides reference to registered drivers under this directory. The <uuid>
|
||||
matches Trusted Application (TA) driver and corresponding TA in secure OS. Drivers
|
||||
are free to create needed API under optee-ta-<uuid> directory.
|
||||
@@ -0,0 +1,54 @@
|
||||
What: /sys/bus/nd/devices/nmemX/papr/flags
|
||||
Date: Apr, 2020
|
||||
KernelVersion: v5.8
|
||||
Contact: linuxppc-dev <linuxppc-dev@lists.ozlabs.org>, linux-nvdimm@lists.01.org,
|
||||
Description:
|
||||
(RO) Report flags indicating various states of a
|
||||
papr-pmem NVDIMM device. Each flag maps to a one or
|
||||
more bits set in the dimm-health-bitmap retrieved in
|
||||
response to H_SCM_HEALTH hcall. The details of the bit
|
||||
flags returned in response to this hcall is available
|
||||
at 'Documentation/powerpc/papr_hcalls.rst' . Below are
|
||||
the flags reported in this sysfs file:
|
||||
|
||||
* "not_armed" : Indicates that NVDIMM contents will not
|
||||
survive a power cycle.
|
||||
* "flush_fail" : Indicates that NVDIMM contents
|
||||
couldn't be flushed during last
|
||||
shut-down event.
|
||||
* "restore_fail": Indicates that NVDIMM contents
|
||||
couldn't be restored during NVDIMM
|
||||
initialization.
|
||||
* "encrypted" : NVDIMM contents are encrypted.
|
||||
* "smart_notify": There is health event for the NVDIMM.
|
||||
* "scrubbed" : Indicating that contents of the
|
||||
NVDIMM have been scrubbed.
|
||||
* "locked" : Indicating that NVDIMM contents cant
|
||||
be modified until next power cycle.
|
||||
|
||||
What: /sys/bus/nd/devices/nmemX/papr/perf_stats
|
||||
Date: May, 2020
|
||||
KernelVersion: v5.9
|
||||
Contact: linuxppc-dev <linuxppc-dev@lists.ozlabs.org>, linux-nvdimm@lists.01.org,
|
||||
Description:
|
||||
(RO) Report various performance stats related to papr-scm NVDIMM
|
||||
device. Each stat is reported on a new line with each line
|
||||
composed of a stat-identifier followed by it value. Below are
|
||||
currently known dimm performance stats which are reported:
|
||||
|
||||
* "CtlResCt" : Controller Reset Count
|
||||
* "CtlResTm" : Controller Reset Elapsed Time
|
||||
* "PonSecs " : Power-on Seconds
|
||||
* "MemLife " : Life Remaining
|
||||
* "CritRscU" : Critical Resource Utilization
|
||||
* "HostLCnt" : Host Load Count
|
||||
* "HostSCnt" : Host Store Count
|
||||
* "HostSDur" : Host Store Duration
|
||||
* "HostLDur" : Host Load Duration
|
||||
* "MedRCnt " : Media Read Count
|
||||
* "MedWCnt " : Media Write Count
|
||||
* "MedRDur " : Media Read Duration
|
||||
* "MedWDur " : Media Write Duration
|
||||
* "CchRHCnt" : Cache Read Hit Count
|
||||
* "CchWHCnt" : Cache Write Hit Count
|
||||
* "FastWCnt" : Fast Write Count
|
||||
@@ -18,3 +18,13 @@ Description:
|
||||
devices to opt-out of driver binding using a driver_override
|
||||
name such as "none". Only a single driver may be specified in
|
||||
the override, there is no support for parsing delimiters.
|
||||
|
||||
What: /sys/bus/platform/devices/.../numa_node
|
||||
Date: June 2020
|
||||
Contact: Barry Song <song.bao.hua@hisilicon.com>
|
||||
Description:
|
||||
This file contains the NUMA node to which the platform device
|
||||
is attached. It won't be visible if the node is unknown. The
|
||||
value comes from an ACPI _PXM method or a similar firmware
|
||||
source. Initial users for this file would be devices like
|
||||
arm smmu which are populated by arm64 acpi_iort.
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
What: /sys/bus/soundwire/devices/sdw-master-N/revision
|
||||
/sys/bus/soundwire/devices/sdw-master-N/clk_stop_modes
|
||||
/sys/bus/soundwire/devices/sdw-master-N/clk_freq
|
||||
/sys/bus/soundwire/devices/sdw-master-N/clk_gears
|
||||
/sys/bus/soundwire/devices/sdw-master-N/default_col
|
||||
/sys/bus/soundwire/devices/sdw-master-N/default_frame_rate
|
||||
/sys/bus/soundwire/devices/sdw-master-N/default_row
|
||||
/sys/bus/soundwire/devices/sdw-master-N/dynamic_shape
|
||||
/sys/bus/soundwire/devices/sdw-master-N/err_threshold
|
||||
/sys/bus/soundwire/devices/sdw-master-N/max_clk_freq
|
||||
|
||||
Date: April 2020
|
||||
|
||||
Contact: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Bard Liao <yung-chuan.liao@linux.intel.com>
|
||||
Vinod Koul <vkoul@kernel.org>
|
||||
|
||||
Description: SoundWire Master-N DisCo properties.
|
||||
These properties are defined by MIPI DisCo Specification
|
||||
for SoundWire. They define various properties of the Master
|
||||
and are used by the bus to configure the Master. clk_stop_modes
|
||||
is a bitmask for simplifications and combines the
|
||||
clock-stop-mode0 and clock-stop-mode1 properties.
|
||||
@@ -0,0 +1,91 @@
|
||||
What: /sys/bus/soundwire/devices/sdw:.../dev-properties/mipi_revision
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/wake_capable
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/test_mode_capable
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/clk_stop_mode1
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/simple_clk_stop_capable
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/clk_stop_timeout
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/ch_prep_timeout
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/reset_behave
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/high_PHY_capable
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/paging_support
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/bank_delay_support
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/p15_behave
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/master_count
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/source_ports
|
||||
/sys/bus/soundwire/devices/sdw:.../dev-properties/sink_ports
|
||||
|
||||
Date: May 2020
|
||||
|
||||
Contact: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Bard Liao <yung-chuan.liao@linux.intel.com>
|
||||
Vinod Koul <vkoul@kernel.org>
|
||||
|
||||
Description: SoundWire Slave DisCo properties.
|
||||
These properties are defined by MIPI DisCo Specification
|
||||
for SoundWire. They define various properties of the
|
||||
SoundWire Slave and are used by the bus to configure
|
||||
the Slave
|
||||
|
||||
|
||||
What: /sys/bus/soundwire/devices/sdw:.../dp0/max_word
|
||||
/sys/bus/soundwire/devices/sdw:.../dp0/min_word
|
||||
/sys/bus/soundwire/devices/sdw:.../dp0/words
|
||||
/sys/bus/soundwire/devices/sdw:.../dp0/BRA_flow_controlled
|
||||
/sys/bus/soundwire/devices/sdw:.../dp0/simple_ch_prep_sm
|
||||
/sys/bus/soundwire/devices/sdw:.../dp0/imp_def_interrupts
|
||||
|
||||
Date: May 2020
|
||||
|
||||
Contact: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Bard Liao <yung-chuan.liao@linux.intel.com>
|
||||
Vinod Koul <vkoul@kernel.org>
|
||||
|
||||
Description: SoundWire Slave Data Port-0 DisCo properties.
|
||||
These properties are defined by MIPI DisCo Specification
|
||||
for the SoundWire. They define various properties of the
|
||||
Data port 0 are used by the bus to configure the Data Port 0.
|
||||
|
||||
|
||||
What: /sys/bus/soundwire/devices/sdw:.../dpN_src/max_word
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/min_word
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/words
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/type
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/max_grouping
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/simple_ch_prep_sm
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/ch_prep_timeout
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/imp_def_interrupts
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/min_ch
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/max_ch
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/channels
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/ch_combinations
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/max_async_buffer
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/block_pack_mode
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_src/port_encoding
|
||||
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/max_word
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/min_word
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/words
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/type
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/max_grouping
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/simple_ch_prep_sm
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/ch_prep_timeout
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/imp_def_interrupts
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/min_ch
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/max_ch
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/channels
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/ch_combinations
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/max_async_buffer
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/block_pack_mode
|
||||
/sys/bus/soundwire/devices/sdw:.../dpN_sink/port_encoding
|
||||
|
||||
Date: May 2020
|
||||
|
||||
Contact: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Bard Liao <yung-chuan.liao@linux.intel.com>
|
||||
Vinod Koul <vkoul@kernel.org>
|
||||
|
||||
Description: SoundWire Slave Data Source/Sink Port-N DisCo properties.
|
||||
These properties are defined by MIPI DisCo Specification
|
||||
for SoundWire. They define various properties of the
|
||||
Source/Sink Data port N and are used by the bus to configure
|
||||
the Data Port N.
|
||||
@@ -178,11 +178,18 @@ KernelVersion: 4.13
|
||||
Contact: thunderbolt-software@lists.01.org
|
||||
Description: When new NVM image is written to the non-active NVM
|
||||
area (through non_activeX NVMem device), the
|
||||
authentication procedure is started by writing 1 to
|
||||
this file. If everything goes well, the device is
|
||||
authentication procedure is started by writing to
|
||||
this file.
|
||||
If everything goes well, the device is
|
||||
restarted with the new NVM firmware. If the image
|
||||
verification fails an error code is returned instead.
|
||||
|
||||
This file will accept writing values "1" or "2"
|
||||
- Writing "1" will flush the image to the storage
|
||||
area and authenticate the image in one action.
|
||||
- Writing "2" will run some basic validation on the image
|
||||
and flush it to the storage area.
|
||||
|
||||
When read holds status of the last authentication
|
||||
operation if an error occurred during the process. This
|
||||
is directly the status value from the DMA configuration
|
||||
@@ -236,3 +243,49 @@ KernelVersion: 4.15
|
||||
Contact: thunderbolt-software@lists.01.org
|
||||
Description: This contains XDomain service specific settings as
|
||||
bitmask. Format: %x
|
||||
|
||||
What: /sys/bus/thunderbolt/devices/<device>:<port>.<index>/device
|
||||
Date: Oct 2020
|
||||
KernelVersion: v5.9
|
||||
Contact: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
Description: Retimer device identifier read from the hardware.
|
||||
|
||||
What: /sys/bus/thunderbolt/devices/<device>:<port>.<index>/nvm_authenticate
|
||||
Date: Oct 2020
|
||||
KernelVersion: v5.9
|
||||
Contact: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
Description: When new NVM image is written to the non-active NVM
|
||||
area (through non_activeX NVMem device), the
|
||||
authentication procedure is started by writing 1 to
|
||||
this file. If everything goes well, the device is
|
||||
restarted with the new NVM firmware. If the image
|
||||
verification fails an error code is returned instead.
|
||||
|
||||
When read holds status of the last authentication
|
||||
operation if an error occurred during the process.
|
||||
Format: %x.
|
||||
|
||||
What: /sys/bus/thunderbolt/devices/<device>:<port>.<index>/nvm_version
|
||||
Date: Oct 2020
|
||||
KernelVersion: v5.9
|
||||
Contact: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
Description: Holds retimer NVM version number. Format: %x.%x, major.minor.
|
||||
|
||||
What: /sys/bus/thunderbolt/devices/<device>:<port>.<index>/vendor
|
||||
Date: Oct 2020
|
||||
KernelVersion: v5.9
|
||||
Contact: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
Description: Retimer vendor identifier read from the hardware.
|
||||
|
||||
What: /sys/bus/thunderbolt/devices/.../nvm_authenticate_on_disconnect
|
||||
Date: Oct 2020
|
||||
KernelVersion: v5.9
|
||||
Contact: Mario Limonciello <mario.limonciello@dell.com>
|
||||
Description: For supported devices, automatically authenticate the new Thunderbolt
|
||||
image when the device is disconnected from the host system.
|
||||
|
||||
This file will accept writing values "1" or "2"
|
||||
- Writing "1" will flush the image to the storage
|
||||
area and prepare the device for authentication on disconnect.
|
||||
- Writing "2" will run some basic validation on the image
|
||||
and flush it to the storage area.
|
||||
|
||||
@@ -108,3 +108,15 @@ Description:
|
||||
frequency requested by governors and min_freq.
|
||||
The max_freq overrides min_freq because max_freq may be
|
||||
used to throttle devices to avoid overheating.
|
||||
|
||||
What: /sys/class/devfreq/.../timer
|
||||
Date: July 2020
|
||||
Contact: Chanwoo Choi <cw00.choi@samsung.com>
|
||||
Description:
|
||||
This ABI shows and stores the kind of work timer by users.
|
||||
This work timer is used by devfreq workqueue in order to
|
||||
monitor the device status such as utilization. The user
|
||||
can change the work timer on runtime according to their demand
|
||||
as following:
|
||||
echo deferrable > /sys/class/devfreq/.../timer
|
||||
echo delayed > /sys/class/devfreq/.../timer
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
What: /sys/class/devlink/.../
|
||||
Date: May 2020
|
||||
Contact: Saravana Kannan <saravanak@google.com>
|
||||
Description:
|
||||
Provide a place in sysfs for the device link objects in the
|
||||
kernel at any given time. The name of a device link directory,
|
||||
denoted as ... above, is of the form <supplier>--<consumer>
|
||||
where <supplier> is the supplier device name and <consumer> is
|
||||
the consumer device name.
|
||||
|
||||
What: /sys/class/devlink/.../auto_remove_on
|
||||
Date: May 2020
|
||||
Contact: Saravana Kannan <saravanak@google.com>
|
||||
Description:
|
||||
This file indicates if the device link will ever be
|
||||
automatically removed by the driver core when the consumer and
|
||||
supplier devices themselves are still present.
|
||||
|
||||
This will be one of the following strings:
|
||||
|
||||
'consumer unbind'
|
||||
'supplier unbind'
|
||||
'never'
|
||||
|
||||
'consumer unbind' means the device link will be removed when
|
||||
the consumer's driver is unbound from the consumer device.
|
||||
|
||||
'supplier unbind' means the device link will be removed when
|
||||
the supplier's driver is unbound from the supplier device.
|
||||
|
||||
'never' means the device link will not be automatically removed
|
||||
when as long as the supplier and consumer devices themselves
|
||||
are still present.
|
||||
|
||||
What: /sys/class/devlink/.../consumer
|
||||
Date: May 2020
|
||||
Contact: Saravana Kannan <saravanak@google.com>
|
||||
Description:
|
||||
This file is a symlink to the consumer device's sysfs directory.
|
||||
|
||||
What: /sys/class/devlink/.../runtime_pm
|
||||
Date: May 2020
|
||||
Contact: Saravana Kannan <saravanak@google.com>
|
||||
Description:
|
||||
This file indicates if the device link has any impact on the
|
||||
runtime power management behavior of the consumer and supplier
|
||||
devices. For example: Making sure the supplier doesn't enter
|
||||
runtime suspend while the consumer is active.
|
||||
|
||||
This will be one of the following strings:
|
||||
|
||||
'0' - Does not affect runtime power management
|
||||
'1' - Affects runtime power management
|
||||
|
||||
What: /sys/class/devlink/.../status
|
||||
Date: May 2020
|
||||
Contact: Saravana Kannan <saravanak@google.com>
|
||||
Description:
|
||||
This file indicates the status of the device link. The status
|
||||
of a device link is affected by whether the supplier and
|
||||
consumer devices have been bound to their corresponding
|
||||
drivers. The status of a device link also affects the binding
|
||||
and unbinding of the supplier and consumer devices with their
|
||||
drivers and also affects whether the software state of the
|
||||
supplier device is synced with the hardware state of the
|
||||
supplier device after boot up.
|
||||
See also: sysfs-devices-state_synced.
|
||||
|
||||
This will be one of the following strings:
|
||||
|
||||
'not tracked'
|
||||
'dormant'
|
||||
'available'
|
||||
'consumer probing'
|
||||
'active'
|
||||
'supplier unbinding'
|
||||
'unknown'
|
||||
|
||||
'not tracked' means this device link does not track the status
|
||||
and has no impact on the binding, unbinding and syncing the
|
||||
hardware and software device state.
|
||||
|
||||
'dormant' means the supplier and the consumer devices have not
|
||||
bound to their driver.
|
||||
|
||||
'available' means the supplier has bound to its driver and is
|
||||
available to supply resources to the consumer device.
|
||||
|
||||
'consumer probing' means the consumer device is currently
|
||||
trying to bind to its driver.
|
||||
|
||||
'active' means the supplier and consumer devices have both
|
||||
bound successfully to their drivers.
|
||||
|
||||
'supplier unbinding' means the supplier devices is currently in
|
||||
the process of unbinding from its driver.
|
||||
|
||||
'unknown' means the state of the device link is not any of the
|
||||
above. If this is ever the value, there's a bug in the kernel.
|
||||
|
||||
What: /sys/class/devlink/.../supplier
|
||||
Date: May 2020
|
||||
Contact: Saravana Kannan <saravanak@google.com>
|
||||
Description:
|
||||
This file is a symlink to the supplier device's sysfs directory.
|
||||
|
||||
What: /sys/class/devlink/.../sync_state_only
|
||||
Date: May 2020
|
||||
Contact: Saravana Kannan <saravanak@google.com>
|
||||
Description:
|
||||
This file indicates if the device link is limited to only
|
||||
affecting the syncing of the hardware and software state of the
|
||||
supplier device.
|
||||
|
||||
This will be one of the following strings:
|
||||
|
||||
'0'
|
||||
'1' - Affects runtime power management
|
||||
|
||||
'0' means the device link can affect other device behaviors
|
||||
like binding/unbinding, suspend/resume, runtime power
|
||||
management, etc.
|
||||
|
||||
'1' means the device link will only affect the syncing of
|
||||
hardware and software state of the supplier device after boot
|
||||
up and doesn't not affect other behaviors of the devices.
|
||||
@@ -0,0 +1,14 @@
|
||||
What: /sys/class/leds/<led>/device/brightness
|
||||
Date: July 2020
|
||||
KernelVersion: 5.9
|
||||
Contact: Marek Behún <marek.behun@nic.cz>
|
||||
Description: (RW) On the front panel of the Turris Omnia router there is also
|
||||
a button which can be used to control the intensity of all the
|
||||
LEDs at once, so that if they are too bright, user can dim them.
|
||||
|
||||
The microcontroller cycles between 8 levels of this global
|
||||
brightness (from 100% to 0%), but this setting can have any
|
||||
integer value between 0 and 100. It is therefore convenient to be
|
||||
able to change this setting from software.
|
||||
|
||||
Format: %i
|
||||
@@ -0,0 +1,35 @@
|
||||
What: /sys/class/leds/<led>/brightness
|
||||
Date: March 2020
|
||||
KernelVersion: 5.9
|
||||
Contact: Dan Murphy <dmurphy@ti.com>
|
||||
Description: read/write
|
||||
Writing to this file will update all LEDs within the group to a
|
||||
calculated percentage of what each color LED intensity is set
|
||||
to. The percentage is calculated for each grouped LED via the
|
||||
equation below:
|
||||
|
||||
led_brightness = brightness * multi_intensity/max_brightness
|
||||
|
||||
For additional details please refer to
|
||||
Documentation/leds/leds-class-multicolor.rst.
|
||||
|
||||
The value of the LED is from 0 to
|
||||
/sys/class/leds/<led>/max_brightness.
|
||||
|
||||
What: /sys/class/leds/<led>/multi_index
|
||||
Date: March 2020
|
||||
KernelVersion: 5.9
|
||||
Contact: Dan Murphy <dmurphy@ti.com>
|
||||
Description: read
|
||||
The multi_index array, when read, will output the LED colors
|
||||
as an array of strings as they are indexed in the
|
||||
multi_intensity file.
|
||||
|
||||
What: /sys/class/leds/<led>/multi_intensity
|
||||
Date: March 2020
|
||||
KernelVersion: 5.9
|
||||
Contact: Dan Murphy <dmurphy@ti.com>
|
||||
Description: read/write
|
||||
This file contains array of integers. Order of components is
|
||||
described by the multi_index array. The maximum intensity should
|
||||
not exceed /sys/class/leds/<led>/max_brightness.
|
||||
@@ -90,3 +90,16 @@ Description: Display trc status register content
|
||||
The ME FW writes Glitch Detection HW (TRC)
|
||||
status information into trc status register
|
||||
for BIOS and OS to monitor fw health.
|
||||
|
||||
What: /sys/class/mei/meiN/kind
|
||||
Date: Jul 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: Tomas Winkler <tomas.winkler@intel.com>
|
||||
Description: Display kind of the device
|
||||
|
||||
Generic devices are marked as "mei"
|
||||
while special purpose have their own
|
||||
names.
|
||||
Available options:
|
||||
- mei: generic mei device.
|
||||
- itouch: itouch (ipts) mei device.
|
||||
|
||||
@@ -124,6 +124,19 @@ Description:
|
||||
authentication is performed (e.g: 802.1x). 'link_mode' attribute
|
||||
will also reflect the dormant state.
|
||||
|
||||
What: /sys/class/net/<iface>/testing
|
||||
Date: April 2002
|
||||
KernelVersion: 5.8
|
||||
Contact: netdev@vger.kernel.org
|
||||
Description:
|
||||
Indicates whether the interface is under test. Possible
|
||||
values are:
|
||||
0: interface is not being tested
|
||||
1: interface is being tested
|
||||
|
||||
When an interface is under test, it cannot be expected
|
||||
to pass packets as normal.
|
||||
|
||||
What: /sys/clas/net/<iface>/duplex
|
||||
Date: October 2009
|
||||
KernelVersion: 2.6.33
|
||||
|
||||
@@ -33,3 +33,14 @@ Date: January 2018
|
||||
Contact: linuxppc-dev@lists.ozlabs.org
|
||||
Description: read/write
|
||||
Give access the global mmio area for the AFU
|
||||
|
||||
What: /sys/class/ocxl/<afu name>/reload_on_reset
|
||||
Date: February 2020
|
||||
Contact: linuxppc-dev@lists.ozlabs.org
|
||||
Description: read/write
|
||||
Control whether the FPGA is reloaded on a link reset. Enabled
|
||||
through a vendor-specific logic block on the FPGA.
|
||||
0 Do not reload FPGA image from flash
|
||||
1 Reload FPGA image from flash
|
||||
unavailable
|
||||
The device does not support this capability
|
||||
|
||||
@@ -74,6 +74,21 @@ Description:
|
||||
Access: Read, Write
|
||||
Valid values: 0 - 100 (percent)
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/capacity_error_margin
|
||||
Date: April 2019
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Battery capacity measurement becomes unreliable without
|
||||
recalibration. This values provides the maximum error
|
||||
margin expected to exist by the fuel gauge in percent.
|
||||
Values close to 0% will be returned after (re-)calibration
|
||||
has happened. Over time the error margin will increase.
|
||||
100% means, that the capacity related values are basically
|
||||
completely useless.
|
||||
|
||||
Access: Read
|
||||
Valid values: 0 - 100 (percent)
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/capacity_level
|
||||
Date: June 2009
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
@@ -190,7 +205,8 @@ Description:
|
||||
Valid values: "Unknown", "Good", "Overheat", "Dead",
|
||||
"Over voltage", "Unspecified failure", "Cold",
|
||||
"Watchdog timer expire", "Safety timer expire",
|
||||
"Over current"
|
||||
"Over current", "Calibration required", "Warm",
|
||||
"Cool", "Hot"
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/precharge_current
|
||||
Date: June 2017
|
||||
@@ -665,3 +681,31 @@ Description:
|
||||
Valid values:
|
||||
- 1: enabled
|
||||
- 0: disabled
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/manufacture_year
|
||||
Date: January 2020
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the year (following Gregorian calendar) when the device has been
|
||||
manufactured.
|
||||
|
||||
Access: Read
|
||||
Valid values: Reported as integer
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/manufacture_month
|
||||
Date: January 2020
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the month when the device has been manufactured.
|
||||
|
||||
Access: Read
|
||||
Valid values: 1-12
|
||||
|
||||
What: /sys/class/power_supply/<supply_name>/manufacture_day
|
||||
Date: January 2020
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Reports the day of month when the device has been manufactured.
|
||||
|
||||
Access: Read
|
||||
Valid values: 1-31
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
What: /sys/class/power_supply/mp2629_battery/batt_impedance_compen
|
||||
Date: April 2020
|
||||
KernelVersion: 5.7
|
||||
Description:
|
||||
Represents a battery impedance compensation to accelerate charging.
|
||||
|
||||
Access: Read, Write
|
||||
Valid values: Represented in milli-ohms. Valid range is [0, 140].
|
||||
@@ -14,6 +14,10 @@ Description:
|
||||
Charging begins when level drops below
|
||||
charge_control_start_threshold, and ceases when
|
||||
level is above charge_control_end_threshold.
|
||||
Long Life: Customized charge rate for last longer battery life.
|
||||
On Wilco device this mode is pre-configured in the factory
|
||||
through EC's private PID. Swiching to a different mode will
|
||||
be denied by Wilco EC when Long Life mode is enabled.
|
||||
|
||||
What: /sys/class/power_supply/wilco-charger/charge_control_start_threshold
|
||||
Date: April 2019
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
What: /sys/class/rnbd-client
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Provide information about RNBD-client.
|
||||
All sysfs files that are not read-only provide the usage information on read:
|
||||
|
||||
Example:
|
||||
# cat /sys/class/rnbd-client/ctl/map_device
|
||||
|
||||
> Usage: echo "sessname=<name of the rtrs session> path=<[srcaddr,]dstaddr>
|
||||
> [path=<[srcaddr,]dstaddr>] device_path=<full path on remote side>
|
||||
> [access_mode=<ro|rw|migration>] > map_device
|
||||
>
|
||||
> addr ::= [ ip:<ipv4> | ip:<ipv6> | gid:<gid> ]
|
||||
|
||||
What: /sys/class/rnbd-client/ctl/map_device
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Expected format is the following:
|
||||
|
||||
sessname=<name of the rtrs session>
|
||||
path=<[srcaddr,]dstaddr> [path=<[srcaddr,]dstaddr> ...]
|
||||
device_path=<full path on remote side>
|
||||
[access_mode=<ro|rw|migration>]
|
||||
|
||||
Where:
|
||||
|
||||
sessname: accepts a string not bigger than 256 chars, which identifies
|
||||
a given session on the client and on the server.
|
||||
I.e. "clt_hostname-srv_hostname" could be a natural choice.
|
||||
|
||||
path: describes a connection between the client and the server by
|
||||
specifying destination and, when required, the source address.
|
||||
The addresses are to be provided in the following format:
|
||||
|
||||
ip:<IPv6>
|
||||
ip:<IPv4>
|
||||
gid:<GID>
|
||||
|
||||
for example:
|
||||
|
||||
path=ip:10.0.0.66
|
||||
The single addr is treated as the destination.
|
||||
The connection will be established to this server from any client IP address.
|
||||
|
||||
path=ip:10.0.0.66,ip:10.0.1.66
|
||||
First addr is the source address and the second is the destination.
|
||||
|
||||
If multiple "path=" options are specified multiple connection
|
||||
will be established and data will be sent according to
|
||||
the selected multipath policy (see RTRS mp_policy sysfs entry description).
|
||||
|
||||
device_path: Path to the block device on the server side. Path is specified
|
||||
relative to the directory on server side configured in the
|
||||
'dev_search_path' module parameter of the rnbd_server.
|
||||
The rnbd_server prepends the <device_path> received from client
|
||||
with <dev_search_path> and tries to open the
|
||||
<dev_search_path>/<device_path> block device. On success,
|
||||
a /dev/rnbd<N> device file, a /sys/block/rnbd_client/rnbd<N>/
|
||||
directory and an entry in /sys/class/rnbd-client/ctl/devices
|
||||
will be created.
|
||||
|
||||
If 'dev_search_path' contains '%SESSNAME%', then each session can
|
||||
have different devices namespace, e.g. server was configured with
|
||||
the following parameter "dev_search_path=/run/rnbd-devs/%SESSNAME%",
|
||||
client has this string "sessname=blya device_path=sda", then server
|
||||
will try to open: /run/rnbd-devs/blya/sda.
|
||||
|
||||
access_mode: the access_mode parameter specifies if the device is to be
|
||||
mapped as "ro" read-only or "rw" read-write. The server allows
|
||||
a device to be exported in rw mode only once. The "migration"
|
||||
access mode has to be specified if a second mapping in read-write
|
||||
mode is desired.
|
||||
|
||||
By default "rw" is used.
|
||||
|
||||
Exit Codes:
|
||||
|
||||
If the device is already mapped it will fail with EEXIST. If the input
|
||||
has an invalid format it will return EINVAL. If the device path cannot
|
||||
be found on the server, it will fail with ENOENT.
|
||||
|
||||
Finding device file after mapping
|
||||
---------------------------------
|
||||
|
||||
After mapping, the device file can be found by:
|
||||
o The symlink /sys/class/rnbd-client/ctl/devices/<device_id>
|
||||
points to /sys/block/<dev-name>. The last part of the symlink destination
|
||||
is the same as the device name. By extracting the last part of the
|
||||
path the path to the device /dev/<dev-name> can be build.
|
||||
|
||||
o /dev/block/$(cat /sys/class/rnbd-client/ctl/devices/<device_id>/dev)
|
||||
|
||||
How to find the <device_id> of the device is described on the next
|
||||
section.
|
||||
|
||||
What: /sys/class/rnbd-client/ctl/devices/
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: For each device mapped on the client a new symbolic link is created as
|
||||
/sys/class/rnbd-client/ctl/devices/<device_id>, which points
|
||||
to the block device created by rnbd (/sys/block/rnbd<N>/).
|
||||
The <device_id> of each device is created as follows:
|
||||
|
||||
- If the 'device_path' provided during mapping contains slashes ("/"),
|
||||
they are replaced by exclamation mark ("!") and used as as the
|
||||
<device_id>. Otherwise, the <device_id> will be the same as the
|
||||
"device_path" provided.
|
||||
@@ -0,0 +1,50 @@
|
||||
What: /sys/class/rnbd-server
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: provide information about RNBD-server.
|
||||
|
||||
What: /sys/class/rnbd-server/ctl/
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: When a client maps a device, a directory entry with the name of the
|
||||
block device is created under /sys/class/rnbd-server/ctl/devices/.
|
||||
|
||||
What: /sys/class/rnbd-server/ctl/devices/<device_name>/block_dev
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Is a symlink to the sysfs entry of the exported device.
|
||||
|
||||
Example:
|
||||
block_dev -> ../../../../class/block/ram0
|
||||
|
||||
What: /sys/class/rnbd-server/ctl/devices/<device_name>/sessions/
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: For each client a particular device is exported to, following directory will be
|
||||
created:
|
||||
|
||||
/sys/class/rnbd-server/ctl/devices/<device_name>/sessions/<session-name>/
|
||||
|
||||
When the device is unmapped by that client, the directory will be removed.
|
||||
|
||||
What: /sys/class/rnbd-server/ctl/devices/<device_name>/sessions/<session-name>/read_only
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Contains '1' if device is mapped read-only, otherwise '0'.
|
||||
|
||||
What: /sys/class/rnbd-server/ctl/devices/<device_name>/sessions/<session-name>/mapping_path
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Contains the relative device path provided by the user during mapping.
|
||||
|
||||
What: /sys/class/rnbd-server/ctl/devices/<device_name>/sessions/<session-name>/access_mode
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Contains the device access mode: ro, rw or migration.
|
||||
@@ -0,0 +1,131 @@
|
||||
What: /sys/class/rtrs-client
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: When a user of RTRS API creates a new session, a directory entry with
|
||||
the name of that session is created under /sys/class/rtrs-client/<session-name>/
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/add_path
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RW, adds a new path (connection) to an existing session. Expected format is the
|
||||
following:
|
||||
|
||||
<[source addr,]destination addr>
|
||||
*addr ::= [ ip:<ipv4|ipv6> | gid:<gid> ]
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/max_reconnect_attempts
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Maximum number reconnect attempts the client should make before giving up
|
||||
after connection breaks unexpectedly.
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/mp_policy
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Multipath policy specifies which path should be selected on each IO:
|
||||
|
||||
round-robin (0):
|
||||
select path in per CPU round-robin manner.
|
||||
|
||||
min-inflight (1):
|
||||
select path with minimum inflights.
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Each path belonging to a given session is listed here by its source and
|
||||
destination address. When a new path is added to a session by writing to
|
||||
the "add_path" entry, a directory <src@dst> is created.
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/<src@dst>/state
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RO, Contains "connected" if the session is connected to the peer and fully
|
||||
functional. Otherwise the file contains "disconnected"
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/<src@dst>/reconnect
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Write "1" to the file in order to reconnect the path.
|
||||
Operation is blocking and returns 0 if reconnect was successful.
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/<src@dst>/disconnect
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Write "1" to the file in order to disconnect the path.
|
||||
Operation blocks until RTRS path is disconnected.
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/<src@dst>/remove_path
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Write "1" to the file in order to disconnected and remove the path
|
||||
from the session. Operation blocks until the path is disconnected
|
||||
and removed from the session.
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/<src@dst>/hca_name
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RO, Contains the the name of HCA the connection established on.
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/<src@dst>/hca_port
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RO, Contains the port number of active port traffic is going through.
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/<src@dst>/src_addr
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RO, Contains the source address of the path
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/<src@dst>/dst_addr
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RO, Contains the destination address of the path
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/<src@dst>/stats/reset_all
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RW, Read will return usage help, write 0 will clear all the statistics.
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/<src@dst>/stats/cpu_migration
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RTRS expects that each HCA IRQ is pinned to a separate CPU. If it's
|
||||
not the case, the processing of an I/O response could be processed on a
|
||||
different CPU than where it was originally submitted. This file shows
|
||||
how many interrupts where generated on a non expected CPU.
|
||||
"from:" is the CPU on which the IRQ was expected, but not generated.
|
||||
"to:" is the CPU on which the IRQ was generated, but not expected.
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/<src@dst>/stats/reconnects
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Contains 2 unsigned int values, the first one records number of successful
|
||||
reconnects in the path lifetime, the second one records number of failed
|
||||
reconnects in the path lifetime.
|
||||
|
||||
What: /sys/class/rtrs-client/<session-name>/paths/<src@dst>/stats/rdma
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Contains statistics regarding rdma operations and inflight operations.
|
||||
The output consists of 6 values:
|
||||
|
||||
<read-count> <read-total-size> <write-count> <write-total-size> \
|
||||
<inflights> <failovered>
|
||||
@@ -0,0 +1,53 @@
|
||||
What: /sys/class/rtrs-server
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: When a user of RTRS API creates a new session on a client side, a
|
||||
directory entry with the name of that session is created in here.
|
||||
|
||||
What: /sys/class/rtrs-server/<session-name>/paths/
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: When new path is created by writing to "add_path" entry on client side,
|
||||
a directory entry named as <source address>@<destination address> is created
|
||||
on server.
|
||||
|
||||
What: /sys/class/rtrs-server/<session-name>/paths/<src@dst>/disconnect
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: When "1" is written to the file, the RTRS session is being disconnected.
|
||||
Operations is non-blocking and returns control immediately to the caller.
|
||||
|
||||
What: /sys/class/rtrs-server/<session-name>/paths/<src@dst>/hca_name
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RO, Contains the the name of HCA the connection established on.
|
||||
|
||||
What: /sys/class/rtrs-server/<session-name>/paths/<src@dst>/hca_port
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RO, Contains the port number of active port traffic is going through.
|
||||
|
||||
What: /sys/class/rtrs-server/<session-name>/paths/<src@dst>/src_addr
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RO, Contains the source address of the path
|
||||
|
||||
What: /sys/class/rtrs-server/<session-name>/paths/<src@dst>/dst_addr
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: RO, Contains the destination address of the path
|
||||
|
||||
What: /sys/class/rtrs-server/<session-name>/paths/<src@dst>/stats/rdma
|
||||
Date: Feb 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: Jack Wang <jinpu.wang@cloud.ionos.com> Danil Kipnis <danil.kipnis@cloud.ionos.com>
|
||||
Description: Contains statistics regarding rdma operations and inflight operations.
|
||||
The output consists of 5 values:
|
||||
<read-count> <read-total-size> <write-count> <write-total-size> <inflights>
|
||||
@@ -0,0 +1,8 @@
|
||||
What: /sys/devices/.../consumer:<consumer>
|
||||
Date: May 2020
|
||||
Contact: Saravana Kannan <saravanak@google.com>
|
||||
Description:
|
||||
The /sys/devices/.../consumer:<consumer> are symlinks to device
|
||||
links where this device is the supplier. <consumer> denotes the
|
||||
name of the consumer in that device link. There can be zero or
|
||||
more of these symlinks for a given device.
|
||||
@@ -0,0 +1,33 @@
|
||||
What: /sys/devices/uncore_iio_x/dieX
|
||||
Date: February 2020
|
||||
Contact: Roman Sudarikov <roman.sudarikov@linux.intel.com>
|
||||
Description:
|
||||
Each IIO stack (PCIe root port) has its own IIO PMON block, so
|
||||
each dieX file (where X is die number) holds "Segment:Root Bus"
|
||||
for PCIe root port, which can be monitored by that IIO PMON
|
||||
block.
|
||||
For example, on 4-die Xeon platform with up to 6 IIO stacks per
|
||||
die and, therefore, 6 IIO PMON blocks per die, the mapping of
|
||||
IIO PMON block 0 exposes as the following:
|
||||
|
||||
$ ls /sys/devices/uncore_iio_0/die*
|
||||
-r--r--r-- /sys/devices/uncore_iio_0/die0
|
||||
-r--r--r-- /sys/devices/uncore_iio_0/die1
|
||||
-r--r--r-- /sys/devices/uncore_iio_0/die2
|
||||
-r--r--r-- /sys/devices/uncore_iio_0/die3
|
||||
|
||||
$ tail /sys/devices/uncore_iio_0/die*
|
||||
==> /sys/devices/uncore_iio_0/die0 <==
|
||||
0000:00
|
||||
==> /sys/devices/uncore_iio_0/die1 <==
|
||||
0000:40
|
||||
==> /sys/devices/uncore_iio_0/die2 <==
|
||||
0000:80
|
||||
==> /sys/devices/uncore_iio_0/die3 <==
|
||||
0000:c0
|
||||
|
||||
Which means:
|
||||
IIO PMU 0 on die 0 belongs to PCI RP on bus 0x00, domain 0x0000
|
||||
IIO PMU 0 on die 1 belongs to PCI RP on bus 0x40, domain 0x0000
|
||||
IIO PMU 0 on die 2 belongs to PCI RP on bus 0x80, domain 0x0000
|
||||
IIO PMU 0 on die 3 belongs to PCI RP on bus 0xc0, domain 0x0000
|
||||
@@ -126,3 +126,39 @@ Description:
|
||||
1 no action
|
||||
0 firmware record the notify code defined
|
||||
in b[15:0].
|
||||
|
||||
What: /sys/devices/platform/stratix10-rsu.0/dcmf0
|
||||
Date: June 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: Richard Gong <richard.gong@linux.intel.com>
|
||||
Description:
|
||||
(RO) Decision firmware copy 0 version information.
|
||||
|
||||
What: /sys/devices/platform/stratix10-rsu.0/dcmf1
|
||||
Date: June 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: Richard Gong <richard.gong@linux.intel.com>
|
||||
Description:
|
||||
(RO) Decision firmware copy 1 version information.
|
||||
|
||||
What: /sys/devices/platform/stratix10-rsu.0/dcmf2
|
||||
Date: June 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: Richard Gong <richard.gong@linux.intel.com>
|
||||
Description:
|
||||
(RO) Decision firmware copy 2 version information.
|
||||
|
||||
What: /sys/devices/platform/stratix10-rsu.0/dcmf3
|
||||
Date: June 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: Richard Gong <richard.gong@linux.intel.com>
|
||||
Description:
|
||||
(RO) Decision firmware copy 3 version information.
|
||||
|
||||
What: /sys/devices/platform/stratix10-rsu.0/max_retry
|
||||
Date: June 2020
|
||||
KernelVersion: 5.8
|
||||
Contact: Richard Gong <richard.gong@linux.intel.com>
|
||||
Description:
|
||||
(RO) max retry parameter is stored in the firmware
|
||||
decision IO section, as a byte located at offset 0x18c.
|
||||
|
||||
@@ -26,6 +26,30 @@ Description:
|
||||
Read-only attribute common to all SoCs. Contains SoC family name
|
||||
(e.g. DB8500).
|
||||
|
||||
On many of ARM based silicon with SMCCC v1.2+ compliant firmware
|
||||
this will contain the JEDEC JEP106 manufacturer’s identification
|
||||
code. The format is "jep106:XXYY" where XX is identity code and
|
||||
YY is continuation code.
|
||||
|
||||
This manufacturer’s identification code is defined by one
|
||||
or more eight (8) bit fields, each consisting of seven (7)
|
||||
data bits plus one (1) odd parity bit. It is a single field,
|
||||
limiting the possible number of vendors to 126. To expand
|
||||
the maximum number of identification codes, a continuation
|
||||
scheme has been defined.
|
||||
|
||||
The specified mechanism is that an identity code of 0x7F
|
||||
represents the "continuation code" and implies the presence
|
||||
of an additional identity code field, and this mechanism
|
||||
may be extended to multiple continuation codes followed
|
||||
by the manufacturer's identity code.
|
||||
|
||||
For example, ARM has identity code 0x7F 0x7F 0x7F 0x7F 0x3B,
|
||||
which is code 0x3B on the fifth 'page'. This is shortened
|
||||
as JEP106 identity code of 0x3B and a continuation code of
|
||||
0x4 to represent the four continuation codes preceding the
|
||||
identity code.
|
||||
|
||||
What: /sys/devices/socX/serial_number
|
||||
Date: January 2019
|
||||
contact: Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
@@ -40,6 +64,12 @@ Description:
|
||||
Read-only attribute supported by most SoCs. In the case of
|
||||
ST-Ericsson's chips this contains the SoC serial number.
|
||||
|
||||
On many of ARM based silicon with SMCCC v1.2+ compliant firmware
|
||||
this will contain the SOC ID appended to the family attribute
|
||||
to ensure there is no conflict in this namespace across various
|
||||
vendors. The format is "jep106:XXYY:ZZZZ" where XX is identity
|
||||
code, YY is continuation code and ZZZZ is the SOC ID.
|
||||
|
||||
What: /sys/devices/socX/revision
|
||||
Date: January 2012
|
||||
contact: Lee Jones <lee.jones@linaro.org>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
What: /sys/devices/.../state_synced
|
||||
Date: May 2020
|
||||
Contact: Saravana Kannan <saravanak@google.com>
|
||||
Description:
|
||||
The /sys/devices/.../state_synced attribute is only present for
|
||||
devices whose bus types or driver provides the .sync_state()
|
||||
callback. The number read from it (0 or 1) reflects the value
|
||||
of the device's 'state_synced' field. A value of 0 means the
|
||||
.sync_state() callback hasn't been called yet. A value of 1
|
||||
means the .sync_state() callback has been called.
|
||||
|
||||
Generally, if a device has sync_state() support and has some of
|
||||
the resources it provides enabled at the time the kernel starts
|
||||
(Eg: enabled by hardware reset or bootloader or anything that
|
||||
run before the kernel starts), then it'll keep those resources
|
||||
enabled and in a state that's compatible with the state they
|
||||
were in at the start of the kernel. The device will stop doing
|
||||
this only when the sync_state() callback has been called --
|
||||
which happens only when all its consumer devices are registered
|
||||
and have probed successfully. Resources that were left disabled
|
||||
at the time the kernel starts are not affected or limited in
|
||||
any way by sync_state() callbacks.
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
What: /sys/devices/.../supplier:<supplier>
|
||||
Date: May 2020
|
||||
Contact: Saravana Kannan <saravanak@google.com>
|
||||
Description:
|
||||
The /sys/devices/.../supplier:<supplier> are symlinks to device
|
||||
links where this device is the consumer. <supplier> denotes the
|
||||
name of the supplier in that device link. There can be zero or
|
||||
more of these symlinks for a given device.
|
||||
@@ -106,10 +106,10 @@ Description: CPU topology files that describe a logical CPU's relationship
|
||||
See Documentation/admin-guide/cputopology.rst for more information.
|
||||
|
||||
|
||||
What: /sys/devices/system/cpu/cpuidle/current_driver
|
||||
/sys/devices/system/cpu/cpuidle/current_governer_ro
|
||||
/sys/devices/system/cpu/cpuidle/available_governors
|
||||
What: /sys/devices/system/cpu/cpuidle/available_governors
|
||||
/sys/devices/system/cpu/cpuidle/current_driver
|
||||
/sys/devices/system/cpu/cpuidle/current_governor
|
||||
/sys/devices/system/cpu/cpuidle/current_governer_ro
|
||||
Date: September 2007
|
||||
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
||||
Description: Discover cpuidle policy and mechanism
|
||||
@@ -119,24 +119,18 @@ Description: Discover cpuidle policy and mechanism
|
||||
consumption during idle.
|
||||
|
||||
Idle policy (governor) is differentiated from idle mechanism
|
||||
(driver)
|
||||
|
||||
current_driver: (RO) displays current idle mechanism
|
||||
|
||||
current_governor_ro: (RO) displays current idle policy
|
||||
|
||||
With the cpuidle_sysfs_switch boot option enabled (meant for
|
||||
developer testing), the following three attributes are visible
|
||||
instead:
|
||||
|
||||
current_driver: same as described above
|
||||
(driver).
|
||||
|
||||
available_governors: (RO) displays a space separated list of
|
||||
available governors
|
||||
available governors.
|
||||
|
||||
current_driver: (RO) displays current idle mechanism.
|
||||
|
||||
current_governor: (RW) displays current idle policy. Users can
|
||||
switch the governor at runtime by writing to this file.
|
||||
|
||||
current_governor_ro: (RO) displays current idle policy.
|
||||
|
||||
See Documentation/admin-guide/pm/cpuidle.rst and
|
||||
Documentation/driver-api/pm/cpuidle.rst for more information.
|
||||
|
||||
@@ -492,6 +486,7 @@ What: /sys/devices/system/cpu/vulnerabilities
|
||||
/sys/devices/system/cpu/vulnerabilities/spec_store_bypass
|
||||
/sys/devices/system/cpu/vulnerabilities/l1tf
|
||||
/sys/devices/system/cpu/vulnerabilities/mds
|
||||
/sys/devices/system/cpu/vulnerabilities/srbds
|
||||
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
|
||||
/sys/devices/system/cpu/vulnerabilities/itlb_multihit
|
||||
Date: January 2018
|
||||
@@ -580,3 +575,42 @@ Description: Secure Virtual Machine
|
||||
If 1, it means the system is using the Protected Execution
|
||||
Facility in POWER9 and newer processors. i.e., it is a Secure
|
||||
Virtual Machine.
|
||||
|
||||
What: /sys/devices/system/cpu/cpuX/purr
|
||||
Date: Apr 2005
|
||||
Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
|
||||
Description: PURR ticks for this CPU since the system boot.
|
||||
|
||||
The Processor Utilization Resources Register (PURR) is
|
||||
a 64-bit counter which provides an estimate of the
|
||||
resources used by the CPU thread. The contents of this
|
||||
register increases monotonically. This sysfs interface
|
||||
exposes the number of PURR ticks for cpuX.
|
||||
|
||||
What: /sys/devices/system/cpu/cpuX/spurr
|
||||
Date: Dec 2006
|
||||
Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
|
||||
Description: SPURR ticks for this CPU since the system boot.
|
||||
|
||||
The Scaled Processor Utilization Resources Register
|
||||
(SPURR) is a 64-bit counter that provides a frequency
|
||||
invariant estimate of the resources used by the CPU
|
||||
thread. The contents of this register increases
|
||||
monotonically. This sysfs interface exposes the number
|
||||
of SPURR ticks for cpuX.
|
||||
|
||||
What: /sys/devices/system/cpu/cpuX/idle_purr
|
||||
Date: Apr 2020
|
||||
Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
|
||||
Description: PURR ticks for cpuX when it was idle.
|
||||
|
||||
This sysfs interface exposes the number of PURR ticks
|
||||
for cpuX when it was idle.
|
||||
|
||||
What: /sys/devices/system/cpu/cpuX/idle_spurr
|
||||
Date: Apr 2020
|
||||
Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
|
||||
Description: SPURR ticks for cpuX when it was idle.
|
||||
|
||||
This sysfs interface exposes the number of SPURR ticks
|
||||
for cpuX when it was idle.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
What: /sys/devices/.../waiting_for_supplier
|
||||
Date: May 2020
|
||||
Contact: Saravana Kannan <saravanak@google.com>
|
||||
Description:
|
||||
The /sys/devices/.../waiting_for_supplier attribute is only
|
||||
present when fw_devlink kernel command line option is enabled
|
||||
and is set to something stricter than "permissive". It is
|
||||
removed once a device probes successfully (because the
|
||||
information is no longer relevant). The number read from it (0
|
||||
or 1) reflects whether the device is waiting for one or more
|
||||
suppliers to be added and then linked to using device links
|
||||
before the device can probe.
|
||||
|
||||
A value of 0 means the device is not waiting for any suppliers
|
||||
to be added before it can probe. A value of 1 means the device
|
||||
is waiting for one or more suppliers to be added before it can
|
||||
probe.
|
||||
@@ -10,6 +10,23 @@ KernelVersion: 5.1
|
||||
Contact: oded.gabbay@gmail.com
|
||||
Description: Version of the application running on the device's CPU
|
||||
|
||||
What: /sys/class/habanalabs/hl<n>/clk_max_freq_mhz
|
||||
Date: Jun 2019
|
||||
KernelVersion: not yet upstreamed
|
||||
Contact: oded.gabbay@gmail.com
|
||||
Description: Allows the user to set the maximum clock frequency, in MHz.
|
||||
The device clock might be set to lower value than the maximum.
|
||||
The user should read the clk_cur_freq_mhz to see the actual
|
||||
frequency value of the device clock. This property is valid
|
||||
only for the Gaudi ASIC family
|
||||
|
||||
What: /sys/class/habanalabs/hl<n>/clk_cur_freq_mhz
|
||||
Date: Jun 2019
|
||||
KernelVersion: not yet upstreamed
|
||||
Contact: oded.gabbay@gmail.com
|
||||
Description: Displays the current frequency, in MHz, of the device clock.
|
||||
This property is valid only for the Gaudi ASIC family
|
||||
|
||||
What: /sys/class/habanalabs/hl<n>/cpld_ver
|
||||
Date: Jan 2019
|
||||
KernelVersion: 5.1
|
||||
|
||||
@@ -883,3 +883,139 @@ Contact: Subhash Jadavani <subhashj@codeaurora.org>
|
||||
Description: This entry shows the target state of an UFS UIC link
|
||||
for the chosen system power management level.
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/wb_presv_us_en
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows if preserve user-space was configured
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/wb_shared_alloc_units
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows the shared allocated units of WB buffer
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/wb_type
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows the configured WB type.
|
||||
0x1 for shared buffer mode. 0x0 for dedicated buffer mode.
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_buff_cap_adj
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows the total user-space decrease in shared
|
||||
buffer mode.
|
||||
The value of this parameter is 3 for TLC NAND when SLC mode
|
||||
is used as WriteBooster Buffer. 2 for MLC NAND.
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_max_alloc_units
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows the Maximum total WriteBooster Buffer size
|
||||
which is supported by the entire device.
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_max_wb_luns
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows the maximum number of luns that can support
|
||||
WriteBooster.
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_sup_red_type
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: The supportability of user space reduction mode
|
||||
and preserve user space mode.
|
||||
00h: WriteBooster Buffer can be configured only in
|
||||
user space reduction type.
|
||||
01h: WriteBooster Buffer can be configured only in
|
||||
preserve user space type.
|
||||
02h: Device can be configured in either user space
|
||||
reduction type or preserve user space type.
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/wb_sup_wb_type
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: The supportability of WriteBooster Buffer type.
|
||||
00h: LU based WriteBooster Buffer configuration
|
||||
01h: Single shared WriteBooster Buffer
|
||||
configuration
|
||||
02h: Supporting both LU based WriteBooster
|
||||
Buffer and Single shared WriteBooster Buffer
|
||||
configuration
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/flags/wb_enable
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows the status of WriteBooster.
|
||||
0: WriteBooster is not enabled.
|
||||
1: WriteBooster is enabled
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/flags/wb_flush_en
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows if flush is enabled.
|
||||
0: Flush operation is not performed.
|
||||
1: Flush operation is performed.
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/flags/wb_flush_during_h8
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: Flush WriteBooster Buffer during hibernate state.
|
||||
0: Device is not allowed to flush the
|
||||
WriteBooster Buffer during link hibernate
|
||||
state.
|
||||
1: Device is allowed to flush the
|
||||
WriteBooster Buffer during link hibernate
|
||||
state
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/attributes/wb_avail_buf
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows the amount of unused WriteBooster buffer
|
||||
available.
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/attributes/wb_cur_buf
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows the amount of unused current buffer.
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/attributes/wb_flush_status
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows the flush operation status.
|
||||
00h: idle
|
||||
01h: Flush operation in progress
|
||||
02h: Flush operation stopped prematurely.
|
||||
03h: Flush operation completed successfully
|
||||
04h: Flush operation general failure
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/attributes/wb_life_time_est
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows an indication of the WriteBooster Buffer
|
||||
lifetime based on the amount of performed program/erase cycles
|
||||
01h: 0% - 10% WriteBooster Buffer life time used
|
||||
...
|
||||
0Ah: 90% - 100% WriteBooster Buffer life time used
|
||||
The file is read only.
|
||||
|
||||
What: /sys/class/scsi_device/*/device/unit_descriptor/wb_buf_alloc_units
|
||||
Date: June 2020
|
||||
Contact: Asutosh Das <asutoshd@codeaurora.org>
|
||||
Description: This entry shows the configured size of WriteBooster buffer.
|
||||
0400h corresponds to 4GB.
|
||||
The file is read only.
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
What: /sys/bus/w1/devices/.../alarms
|
||||
Date: May 2020
|
||||
Contact: Akira Shimahara <akira215corp@gmail.com>
|
||||
Description:
|
||||
(RW) read or write TH and TL (Temperature High an Low) alarms.
|
||||
Values shall be space separated and in the device range
|
||||
(typical -55 degC to 125 degC), if not values will be trimmed
|
||||
to device min/max capabilities. Values are integer as they are
|
||||
stored in a 8bit register in the device. Lowest value is
|
||||
automatically put to TL. Once set, alarms could be search at
|
||||
master level, refer to Documentation/w1/w1-generic.rst for
|
||||
detailed information
|
||||
Users: any user space application which wants to communicate with
|
||||
w1_term device
|
||||
|
||||
|
||||
What: /sys/bus/w1/devices/.../eeprom
|
||||
Date: May 2020
|
||||
Contact: Akira Shimahara <akira215corp@gmail.com>
|
||||
Description:
|
||||
(WO) writing that file will either trigger a save of the
|
||||
device data to its embedded EEPROM, either restore data
|
||||
embedded in device EEPROM. Be aware that devices support
|
||||
limited EEPROM writing cycles (typical 50k)
|
||||
* 'save': save device RAM to EEPROM
|
||||
* 'restore': restore EEPROM data in device RAM
|
||||
Users: any user space application which wants to communicate with
|
||||
w1_term device
|
||||
|
||||
|
||||
What: /sys/bus/w1/devices/.../ext_power
|
||||
Date: May 2020
|
||||
Contact: Akira Shimahara <akira215corp@gmail.com>
|
||||
Description:
|
||||
(RO) return the power status by asking the device
|
||||
* '0': device parasite powered
|
||||
* '1': device externally powered
|
||||
* '-xx': xx is kernel error when reading power status
|
||||
Users: any user space application which wants to communicate with
|
||||
w1_term device
|
||||
|
||||
|
||||
What: /sys/bus/w1/devices/.../resolution
|
||||
Date: May 2020
|
||||
Contact: Akira Shimahara <akira215corp@gmail.com>
|
||||
Description:
|
||||
(RW) get or set the device resolution (on supported devices,
|
||||
if not, this entry is not present). Note that the resolution
|
||||
will be changed only in device RAM, so it will be cleared when
|
||||
power is lost. Trigger a 'save' to EEPROM command to keep
|
||||
values after power-on. Read or write are :
|
||||
* '9..12': device resolution in bit
|
||||
or resolution to set in bit
|
||||
* '-xx': xx is kernel error when reading the resolution
|
||||
* Anything else: do nothing
|
||||
Users: any user space application which wants to communicate with
|
||||
w1_term device
|
||||
|
||||
|
||||
What: /sys/bus/w1/devices/.../temperature
|
||||
Date: May 2020
|
||||
Contact: Akira Shimahara <akira215corp@gmail.com>
|
||||
Description:
|
||||
(RO) return the temperature in 1/1000 degC.
|
||||
* If a bulk read has been triggered, it will directly
|
||||
return the temperature computed when the bulk read
|
||||
occurred, if available. If not yet available, nothing
|
||||
is returned (a debug kernel message is sent), you
|
||||
should retry later on.
|
||||
* If no bulk read has been triggered, it will trigger
|
||||
a conversion and send the result. Note that the
|
||||
conversion duration depend on the resolution (if
|
||||
device support this feature). It takes 94ms in 9bits
|
||||
resolution, 750ms for 12bits.
|
||||
Users: any user space application which wants to communicate with
|
||||
w1_term device
|
||||
|
||||
|
||||
What: /sys/bus/w1/devices/.../w1_slave
|
||||
Date: May 2020
|
||||
Contact: Akira Shimahara <akira215corp@gmail.com>
|
||||
Description:
|
||||
(RW) return the temperature in 1/1000 degC.
|
||||
*read*: return 2 lines with the hexa output data sent on the
|
||||
bus, return the CRC check and temperature in 1/1000 degC
|
||||
*write* :
|
||||
* '0' : save the 2 or 3 bytes to the device EEPROM
|
||||
(i.e. TH, TL and config register)
|
||||
* '9..12' : set the device resolution in RAM
|
||||
(if supported)
|
||||
* Anything else: do nothing
|
||||
refer to Documentation/w1/slaves/w1_therm.rst for detailed
|
||||
information.
|
||||
Users: any user space application which wants to communicate with
|
||||
w1_term device
|
||||
|
||||
|
||||
What: /sys/bus/w1/devices/w1_bus_masterXX/therm_bulk_read
|
||||
Date: May 2020
|
||||
Contact: Akira Shimahara <akira215corp@gmail.com>
|
||||
Description:
|
||||
(RW) trigger a bulk read conversion. read the status
|
||||
*read*:
|
||||
* '-1': conversion in progress on at least 1 sensor
|
||||
* '1' : conversion complete but at least one sensor
|
||||
value has not been read yet
|
||||
* '0' : no bulk operation. Reading temperature will
|
||||
trigger a conversion on each device
|
||||
*write*: 'trigger': trigger a bulk read on all supporting
|
||||
devices on the bus
|
||||
Note that if a bulk read is sent but one sensor is not read
|
||||
immediately, the next access to temperature on this device
|
||||
will return the temperature measured at the time of issue
|
||||
of the bulk read command (not the current temperature).
|
||||
Users: any user space application which wants to communicate with
|
||||
w1_term device
|
||||
@@ -229,7 +229,9 @@ Date: August 2017
|
||||
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||
Description: Do background GC agressively when set. When gc_urgent = 1,
|
||||
background thread starts to do GC by given gc_urgent_sleep_time
|
||||
interval. It is set to 0 by default.
|
||||
interval. When gc_urgent = 2, F2FS will lower the bar of
|
||||
checking idle in order to process outstanding discard commands
|
||||
and GC a little bit aggressively. It is set to 0 by default.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/gc_urgent_sleep_time
|
||||
Date: August 2017
|
||||
@@ -323,3 +325,27 @@ What: /sys/fs/f2fs/<disk>/mounted_time_sec
|
||||
Date: February 2020
|
||||
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||
Description: Show the mounted time in secs of this partition.
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/data_io_flag
|
||||
Date: April 2020
|
||||
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||
Description: Give a way to attach REQ_META|FUA to data writes
|
||||
given temperature-based bits. Now the bits indicate:
|
||||
* REQ_META | REQ_FUA |
|
||||
* 5 | 4 | 3 | 2 | 1 | 0 |
|
||||
* Cold | Warm | Hot | Cold | Warm | Hot |
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/node_io_flag
|
||||
Date: June 2020
|
||||
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||
Description: Give a way to attach REQ_META|FUA to node writes
|
||||
given temperature-based bits. Now the bits indicate:
|
||||
* REQ_META | REQ_FUA |
|
||||
* 5 | 4 | 3 | 2 | 1 | 0 |
|
||||
* Cold | Warm | Hot | Cold | Warm | Hot |
|
||||
|
||||
What: /sys/fs/f2fs/<disk>/iostat_period_ms
|
||||
Date: April 2020
|
||||
Contact: "Daeho Jeong" <daehojeong@google.com>
|
||||
Description: Give a way to change iostat_period time. 3secs by default.
|
||||
The new iostat trace gives stats gap given the period.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
What: /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_req
|
||||
Date: Feb 2014
|
||||
Contact: Li Jun <b47624@freescale.com>
|
||||
Contact: Li Jun <jun.li@nxp.com>
|
||||
Description:
|
||||
Can be set and read.
|
||||
Set a_bus_req(A-device bus request) input to be 1 if
|
||||
@@ -17,7 +17,7 @@ Description:
|
||||
|
||||
What: /sys/bus/platform/devices/ci_hdrc.0/inputs/a_bus_drop
|
||||
Date: Feb 2014
|
||||
Contact: Li Jun <b47624@freescale.com>
|
||||
Contact: Li Jun <jun.li@nxp.com>
|
||||
Description:
|
||||
Can be set and read
|
||||
The a_bus_drop(A-device bus drop) input is 1 when the
|
||||
@@ -32,7 +32,7 @@ Description:
|
||||
|
||||
What: /sys/bus/platform/devices/ci_hdrc.0/inputs/b_bus_req
|
||||
Date: Feb 2014
|
||||
Contact: Li Jun <b47624@freescale.com>
|
||||
Contact: Li Jun <jun.li@nxp.com>
|
||||
Description:
|
||||
Can be set and read.
|
||||
The b_bus_req(B-device bus request) input is 1 during the time
|
||||
@@ -47,7 +47,7 @@ Description:
|
||||
|
||||
What: /sys/bus/platform/devices/ci_hdrc.0/inputs/a_clr_err
|
||||
Date: Feb 2014
|
||||
Contact: Li Jun <b47624@freescale.com>
|
||||
Contact: Li Jun <jun.li@nxp.com>
|
||||
Description:
|
||||
Only can be set.
|
||||
The a_clr_err(A-device Vbus error clear) input is used to clear
|
||||
|
||||
@@ -27,10 +27,12 @@ KernelVersion: v4.10
|
||||
Contact: linux-acpi@vger.kernel.org
|
||||
Description:
|
||||
(RO) Display the platform power source
|
||||
0x00 = DC
|
||||
0x01 = AC
|
||||
0x02 = USB
|
||||
0x03 = Wireless Charger
|
||||
bits[3:0] Current power source
|
||||
0x00 = DC
|
||||
0x01 = AC
|
||||
0x02 = USB
|
||||
0x03 = Wireless Charger
|
||||
bits[7:4] Power source sequence number
|
||||
|
||||
What: /sys/bus/platform/devices/INT3407:00/dptf_power/battery_steady_power
|
||||
Date: Jul, 2016
|
||||
@@ -38,3 +40,55 @@ KernelVersion: v4.10
|
||||
Contact: linux-acpi@vger.kernel.org
|
||||
Description:
|
||||
(RO) The maximum sustained power for battery in milliwatts.
|
||||
|
||||
What: /sys/bus/platform/devices/INT3407:00/dptf_power/rest_of_platform_power_mw
|
||||
Date: June, 2020
|
||||
KernelVersion: v5.8
|
||||
Contact: linux-acpi@vger.kernel.org
|
||||
Description:
|
||||
(RO) Shows the rest (outside of SoC) of worst-case platform power.
|
||||
|
||||
What: /sys/bus/platform/devices/INT3407:00/dptf_power/prochot_confirm
|
||||
Date: June, 2020
|
||||
KernelVersion: v5.8
|
||||
Contact: linux-acpi@vger.kernel.org
|
||||
Description:
|
||||
(WO) Confirm embedded controller about a prochot notification.
|
||||
|
||||
What: /sys/bus/platform/devices/INT3532:00/dptf_battery/max_platform_power_mw
|
||||
Date: June, 2020
|
||||
KernelVersion: v5.8
|
||||
Contact: linux-acpi@vger.kernel.org
|
||||
Description:
|
||||
(RO) The maximum platform power that can be supported by the battery in milli watts.
|
||||
|
||||
What: /sys/bus/platform/devices/INT3532:00/dptf_battery/max_steady_state_power_mw
|
||||
Date: June, 2020
|
||||
KernelVersion: v5.8
|
||||
Contact: linux-acpi@vger.kernel.org
|
||||
Description:
|
||||
(RO) The maximum sustained power for battery in milli watts.
|
||||
|
||||
What: /sys/bus/platform/devices/INT3532:00/dptf_battery/high_freq_impedance_mohm
|
||||
Date: June, 2020
|
||||
KernelVersion: v5.8
|
||||
Contact: linux-acpi@vger.kernel.org
|
||||
Description:
|
||||
(RO) The high frequency impedance value that can be obtained from battery
|
||||
fuel gauge in milli Ohms.
|
||||
|
||||
What: /sys/bus/platform/devices/INT3532:00/dptf_battery/no_load_voltage_mv
|
||||
Date: June, 2020
|
||||
KernelVersion: v5.8
|
||||
Contact: linux-acpi@vger.kernel.org
|
||||
Description:
|
||||
(RO) The no-load voltage that can be obtained from battery fuel gauge in
|
||||
milli volts.
|
||||
|
||||
What: /sys/bus/platform/devices/INT3532:00/dptf_battery/current_discharge_capbility_ma
|
||||
Date: June, 2020
|
||||
KernelVersion: v5.8
|
||||
Contact: linux-acpi@vger.kernel.org
|
||||
Description:
|
||||
(RO) The battery discharge current capability obtained from battery fuel gauge in
|
||||
milli Amps.
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
What: /sys/bus/wmi/devices/44FADEB1-B204-40F2-8581-394BBDC1B651/firmware_update_request
|
||||
Date: April 2020
|
||||
KernelVersion: 5.7
|
||||
Contact: "Jithu Joseph" <jithu.joseph@intel.com>
|
||||
Description:
|
||||
Allow user space entities to trigger update of Slim
|
||||
Bootloader (SBL). This attribute normally has a value
|
||||
of 0 and userspace can signal SBL to update firmware,
|
||||
on next reboot, by writing a value of 1.
|
||||
There are two available states:
|
||||
* 0 -> Skip firmware update while rebooting
|
||||
* 1 -> Attempt firmware update on next reboot
|
||||
@@ -9,5 +9,5 @@ scale down to smaller sizes and are better for letterheads or whatever
|
||||
you want to use it for: for the full range of logos take a look at
|
||||
Larry's web-page:
|
||||
|
||||
http://www.isc.tamu.edu/~lewing/linux/
|
||||
https://www.isc.tamu.edu/~lewing/linux/
|
||||
|
||||
|
||||
@@ -1,745 +0,0 @@
|
||||
============================================
|
||||
Dynamic DMA mapping using the generic device
|
||||
============================================
|
||||
|
||||
:Author: James E.J. Bottomley <James.Bottomley@HansenPartnership.com>
|
||||
|
||||
This document describes the DMA API. For a more gentle introduction
|
||||
of the API (and actual examples), see Documentation/DMA-API-HOWTO.txt.
|
||||
|
||||
This API is split into two pieces. Part I describes the basic API.
|
||||
Part II describes extensions for supporting non-consistent memory
|
||||
machines. Unless you know that your driver absolutely has to support
|
||||
non-consistent platforms (this is usually only legacy platforms) you
|
||||
should only use the API described in part I.
|
||||
|
||||
Part I - dma_API
|
||||
----------------
|
||||
|
||||
To get the dma_API, you must #include <linux/dma-mapping.h>. This
|
||||
provides dma_addr_t and the interfaces described below.
|
||||
|
||||
A dma_addr_t can hold any valid DMA address for the platform. It can be
|
||||
given to a device to use as a DMA source or target. A CPU cannot reference
|
||||
a dma_addr_t directly because there may be translation between its physical
|
||||
address space and the DMA address space.
|
||||
|
||||
Part Ia - Using large DMA-coherent buffers
|
||||
------------------------------------------
|
||||
|
||||
::
|
||||
|
||||
void *
|
||||
dma_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag)
|
||||
|
||||
Consistent memory is memory for which a write by either the device or
|
||||
the processor can immediately be read by the processor or device
|
||||
without having to worry about caching effects. (You may however need
|
||||
to make sure to flush the processor's write buffers before telling
|
||||
devices to read that memory.)
|
||||
|
||||
This routine allocates a region of <size> bytes of consistent memory.
|
||||
|
||||
It returns a pointer to the allocated region (in the processor's virtual
|
||||
address space) or NULL if the allocation failed.
|
||||
|
||||
It also returns a <dma_handle> which may be cast to an unsigned integer the
|
||||
same width as the bus and given to the device as the DMA address base of
|
||||
the region.
|
||||
|
||||
Note: consistent memory can be expensive on some platforms, and the
|
||||
minimum allocation length may be as big as a page, so you should
|
||||
consolidate your requests for consistent memory as much as possible.
|
||||
The simplest way to do that is to use the dma_pool calls (see below).
|
||||
|
||||
The flag parameter (dma_alloc_coherent() only) allows the caller to
|
||||
specify the ``GFP_`` flags (see kmalloc()) for the allocation (the
|
||||
implementation may choose to ignore flags that affect the location of
|
||||
the returned memory, like GFP_DMA).
|
||||
|
||||
::
|
||||
|
||||
void
|
||||
dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
|
||||
dma_addr_t dma_handle)
|
||||
|
||||
Free a region of consistent memory you previously allocated. dev,
|
||||
size and dma_handle must all be the same as those passed into
|
||||
dma_alloc_coherent(). cpu_addr must be the virtual address returned by
|
||||
the dma_alloc_coherent().
|
||||
|
||||
Note that unlike their sibling allocation calls, these routines
|
||||
may only be called with IRQs enabled.
|
||||
|
||||
|
||||
Part Ib - Using small DMA-coherent buffers
|
||||
------------------------------------------
|
||||
|
||||
To get this part of the dma_API, you must #include <linux/dmapool.h>
|
||||
|
||||
Many drivers need lots of small DMA-coherent memory regions for DMA
|
||||
descriptors or I/O buffers. Rather than allocating in units of a page
|
||||
or more using dma_alloc_coherent(), you can use DMA pools. These work
|
||||
much like a struct kmem_cache, except that they use the DMA-coherent allocator,
|
||||
not __get_free_pages(). Also, they understand common hardware constraints
|
||||
for alignment, like queue heads needing to be aligned on N-byte boundaries.
|
||||
|
||||
|
||||
::
|
||||
|
||||
struct dma_pool *
|
||||
dma_pool_create(const char *name, struct device *dev,
|
||||
size_t size, size_t align, size_t alloc);
|
||||
|
||||
dma_pool_create() initializes a pool of DMA-coherent buffers
|
||||
for use with a given device. It must be called in a context which
|
||||
can sleep.
|
||||
|
||||
The "name" is for diagnostics (like a struct kmem_cache name); dev and size
|
||||
are like what you'd pass to dma_alloc_coherent(). The device's hardware
|
||||
alignment requirement for this type of data is "align" (which is expressed
|
||||
in bytes, and must be a power of two). If your device has no boundary
|
||||
crossing restrictions, pass 0 for alloc; passing 4096 says memory allocated
|
||||
from this pool must not cross 4KByte boundaries.
|
||||
|
||||
::
|
||||
|
||||
void *
|
||||
dma_pool_zalloc(struct dma_pool *pool, gfp_t mem_flags,
|
||||
dma_addr_t *handle)
|
||||
|
||||
Wraps dma_pool_alloc() and also zeroes the returned memory if the
|
||||
allocation attempt succeeded.
|
||||
|
||||
|
||||
::
|
||||
|
||||
void *
|
||||
dma_pool_alloc(struct dma_pool *pool, gfp_t gfp_flags,
|
||||
dma_addr_t *dma_handle);
|
||||
|
||||
This allocates memory from the pool; the returned memory will meet the
|
||||
size and alignment requirements specified at creation time. Pass
|
||||
GFP_ATOMIC to prevent blocking, or if it's permitted (not
|
||||
in_interrupt, not holding SMP locks), pass GFP_KERNEL to allow
|
||||
blocking. Like dma_alloc_coherent(), this returns two values: an
|
||||
address usable by the CPU, and the DMA address usable by the pool's
|
||||
device.
|
||||
|
||||
::
|
||||
|
||||
void
|
||||
dma_pool_free(struct dma_pool *pool, void *vaddr,
|
||||
dma_addr_t addr);
|
||||
|
||||
This puts memory back into the pool. The pool is what was passed to
|
||||
dma_pool_alloc(); the CPU (vaddr) and DMA addresses are what
|
||||
were returned when that routine allocated the memory being freed.
|
||||
|
||||
::
|
||||
|
||||
void
|
||||
dma_pool_destroy(struct dma_pool *pool);
|
||||
|
||||
dma_pool_destroy() frees the resources of the pool. It must be
|
||||
called in a context which can sleep. Make sure you've freed all allocated
|
||||
memory back to the pool before you destroy it.
|
||||
|
||||
|
||||
Part Ic - DMA addressing limitations
|
||||
------------------------------------
|
||||
|
||||
::
|
||||
|
||||
int
|
||||
dma_set_mask_and_coherent(struct device *dev, u64 mask)
|
||||
|
||||
Checks to see if the mask is possible and updates the device
|
||||
streaming and coherent DMA mask parameters if it is.
|
||||
|
||||
Returns: 0 if successful and a negative error if not.
|
||||
|
||||
::
|
||||
|
||||
int
|
||||
dma_set_mask(struct device *dev, u64 mask)
|
||||
|
||||
Checks to see if the mask is possible and updates the device
|
||||
parameters if it is.
|
||||
|
||||
Returns: 0 if successful and a negative error if not.
|
||||
|
||||
::
|
||||
|
||||
int
|
||||
dma_set_coherent_mask(struct device *dev, u64 mask)
|
||||
|
||||
Checks to see if the mask is possible and updates the device
|
||||
parameters if it is.
|
||||
|
||||
Returns: 0 if successful and a negative error if not.
|
||||
|
||||
::
|
||||
|
||||
u64
|
||||
dma_get_required_mask(struct device *dev)
|
||||
|
||||
This API returns the mask that the platform requires to
|
||||
operate efficiently. Usually this means the returned mask
|
||||
is the minimum required to cover all of memory. Examining the
|
||||
required mask gives drivers with variable descriptor sizes the
|
||||
opportunity to use smaller descriptors as necessary.
|
||||
|
||||
Requesting the required mask does not alter the current mask. If you
|
||||
wish to take advantage of it, you should issue a dma_set_mask()
|
||||
call to set the mask to the value returned.
|
||||
|
||||
::
|
||||
|
||||
size_t
|
||||
dma_max_mapping_size(struct device *dev);
|
||||
|
||||
Returns the maximum size of a mapping for the device. The size parameter
|
||||
of the mapping functions like dma_map_single(), dma_map_page() and
|
||||
others should not be larger than the returned value.
|
||||
|
||||
::
|
||||
|
||||
unsigned long
|
||||
dma_get_merge_boundary(struct device *dev);
|
||||
|
||||
Returns the DMA merge boundary. If the device cannot merge any the DMA address
|
||||
segments, the function returns 0.
|
||||
|
||||
Part Id - Streaming DMA mappings
|
||||
--------------------------------
|
||||
|
||||
::
|
||||
|
||||
dma_addr_t
|
||||
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
|
||||
Maps a piece of processor virtual memory so it can be accessed by the
|
||||
device and returns the DMA address of the memory.
|
||||
|
||||
The direction for both APIs may be converted freely by casting.
|
||||
However the dma_API uses a strongly typed enumerator for its
|
||||
direction:
|
||||
|
||||
======================= =============================================
|
||||
DMA_NONE no direction (used for debugging)
|
||||
DMA_TO_DEVICE data is going from the memory to the device
|
||||
DMA_FROM_DEVICE data is coming from the device to the memory
|
||||
DMA_BIDIRECTIONAL direction isn't known
|
||||
======================= =============================================
|
||||
|
||||
.. note::
|
||||
|
||||
Not all memory regions in a machine can be mapped by this API.
|
||||
Further, contiguous kernel virtual space may not be contiguous as
|
||||
physical memory. Since this API does not provide any scatter/gather
|
||||
capability, it will fail if the user tries to map a non-physically
|
||||
contiguous piece of memory. For this reason, memory to be mapped by
|
||||
this API should be obtained from sources which guarantee it to be
|
||||
physically contiguous (like kmalloc).
|
||||
|
||||
Further, the DMA address of the memory must be within the
|
||||
dma_mask of the device (the dma_mask is a bit mask of the
|
||||
addressable region for the device, i.e., if the DMA address of
|
||||
the memory ANDed with the dma_mask is still equal to the DMA
|
||||
address, then the device can perform DMA to the memory). To
|
||||
ensure that the memory allocated by kmalloc is within the dma_mask,
|
||||
the driver may specify various platform-dependent flags to restrict
|
||||
the DMA address range of the allocation (e.g., on x86, GFP_DMA
|
||||
guarantees to be within the first 16MB of available DMA addresses,
|
||||
as required by ISA devices).
|
||||
|
||||
Note also that the above constraints on physical contiguity and
|
||||
dma_mask may not apply if the platform has an IOMMU (a device which
|
||||
maps an I/O DMA address to a physical memory address). However, to be
|
||||
portable, device driver writers may *not* assume that such an IOMMU
|
||||
exists.
|
||||
|
||||
.. warning::
|
||||
|
||||
Memory coherency operates at a granularity called the cache
|
||||
line width. In order for memory mapped by this API to operate
|
||||
correctly, the mapped region must begin exactly on a cache line
|
||||
boundary and end exactly on one (to prevent two separately mapped
|
||||
regions from sharing a single cache line). Since the cache line size
|
||||
may not be known at compile time, the API will not enforce this
|
||||
requirement. Therefore, it is recommended that driver writers who
|
||||
don't take special care to determine the cache line size at run time
|
||||
only map virtual regions that begin and end on page boundaries (which
|
||||
are guaranteed also to be cache line boundaries).
|
||||
|
||||
DMA_TO_DEVICE synchronisation must be done after the last modification
|
||||
of the memory region by the software and before it is handed off to
|
||||
the device. Once this primitive is used, memory covered by this
|
||||
primitive should be treated as read-only by the device. If the device
|
||||
may write to it at any point, it should be DMA_BIDIRECTIONAL (see
|
||||
below).
|
||||
|
||||
DMA_FROM_DEVICE synchronisation must be done before the driver
|
||||
accesses data that may be changed by the device. This memory should
|
||||
be treated as read-only by the driver. If the driver needs to write
|
||||
to it at any point, it should be DMA_BIDIRECTIONAL (see below).
|
||||
|
||||
DMA_BIDIRECTIONAL requires special handling: it means that the driver
|
||||
isn't sure if the memory was modified before being handed off to the
|
||||
device and also isn't sure if the device will also modify it. Thus,
|
||||
you must always sync bidirectional memory twice: once before the
|
||||
memory is handed off to the device (to make sure all memory changes
|
||||
are flushed from the processor) and once before the data may be
|
||||
accessed after being used by the device (to make sure any processor
|
||||
cache lines are updated with data that the device may have changed).
|
||||
|
||||
::
|
||||
|
||||
void
|
||||
dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
|
||||
Unmaps the region previously mapped. All the parameters passed in
|
||||
must be identical to those passed in (and returned) by the mapping
|
||||
API.
|
||||
|
||||
::
|
||||
|
||||
dma_addr_t
|
||||
dma_map_page(struct device *dev, struct page *page,
|
||||
unsigned long offset, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
|
||||
void
|
||||
dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
|
||||
API for mapping and unmapping for pages. All the notes and warnings
|
||||
for the other mapping APIs apply here. Also, although the <offset>
|
||||
and <size> parameters are provided to do partial page mapping, it is
|
||||
recommended that you never use these unless you really know what the
|
||||
cache width is.
|
||||
|
||||
::
|
||||
|
||||
dma_addr_t
|
||||
dma_map_resource(struct device *dev, phys_addr_t phys_addr, size_t size,
|
||||
enum dma_data_direction dir, unsigned long attrs)
|
||||
|
||||
void
|
||||
dma_unmap_resource(struct device *dev, dma_addr_t addr, size_t size,
|
||||
enum dma_data_direction dir, unsigned long attrs)
|
||||
|
||||
API for mapping and unmapping for MMIO resources. All the notes and
|
||||
warnings for the other mapping APIs apply here. The API should only be
|
||||
used to map device MMIO resources, mapping of RAM is not permitted.
|
||||
|
||||
::
|
||||
|
||||
int
|
||||
dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
|
||||
|
||||
In some circumstances dma_map_single(), dma_map_page() and dma_map_resource()
|
||||
will fail to create a mapping. A driver can check for these errors by testing
|
||||
the returned DMA address with dma_mapping_error(). A non-zero return value
|
||||
means the mapping could not be created and the driver should take appropriate
|
||||
action (e.g. reduce current DMA mapping usage or delay and try again later).
|
||||
|
||||
::
|
||||
|
||||
int
|
||||
dma_map_sg(struct device *dev, struct scatterlist *sg,
|
||||
int nents, enum dma_data_direction direction)
|
||||
|
||||
Returns: the number of DMA address segments mapped (this may be shorter
|
||||
than <nents> passed in if some elements of the scatter/gather list are
|
||||
physically or virtually adjacent and an IOMMU maps them with a single
|
||||
entry).
|
||||
|
||||
Please note that the sg cannot be mapped again if it has been mapped once.
|
||||
The mapping process is allowed to destroy information in the sg.
|
||||
|
||||
As with the other mapping interfaces, dma_map_sg() can fail. When it
|
||||
does, 0 is returned and a driver must take appropriate action. It is
|
||||
critical that the driver do something, in the case of a block driver
|
||||
aborting the request or even oopsing is better than doing nothing and
|
||||
corrupting the filesystem.
|
||||
|
||||
With scatterlists, you use the resulting mapping like this::
|
||||
|
||||
int i, count = dma_map_sg(dev, sglist, nents, direction);
|
||||
struct scatterlist *sg;
|
||||
|
||||
for_each_sg(sglist, sg, count, i) {
|
||||
hw_address[i] = sg_dma_address(sg);
|
||||
hw_len[i] = sg_dma_len(sg);
|
||||
}
|
||||
|
||||
where nents is the number of entries in the sglist.
|
||||
|
||||
The implementation is free to merge several consecutive sglist entries
|
||||
into one (e.g. with an IOMMU, or if several pages just happen to be
|
||||
physically contiguous) and returns the actual number of sg entries it
|
||||
mapped them to. On failure 0, is returned.
|
||||
|
||||
Then you should loop count times (note: this can be less than nents times)
|
||||
and use sg_dma_address() and sg_dma_len() macros where you previously
|
||||
accessed sg->address and sg->length as shown above.
|
||||
|
||||
::
|
||||
|
||||
void
|
||||
dma_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||
int nents, enum dma_data_direction direction)
|
||||
|
||||
Unmap the previously mapped scatter/gather list. All the parameters
|
||||
must be the same as those and passed in to the scatter/gather mapping
|
||||
API.
|
||||
|
||||
Note: <nents> must be the number you passed in, *not* the number of
|
||||
DMA address entries returned.
|
||||
|
||||
::
|
||||
|
||||
void
|
||||
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
|
||||
size_t size,
|
||||
enum dma_data_direction direction)
|
||||
|
||||
void
|
||||
dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
|
||||
size_t size,
|
||||
enum dma_data_direction direction)
|
||||
|
||||
void
|
||||
dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
|
||||
int nents,
|
||||
enum dma_data_direction direction)
|
||||
|
||||
void
|
||||
dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
|
||||
int nents,
|
||||
enum dma_data_direction direction)
|
||||
|
||||
Synchronise a single contiguous or scatter/gather mapping for the CPU
|
||||
and device. With the sync_sg API, all the parameters must be the same
|
||||
as those passed into the single mapping API. With the sync_single API,
|
||||
you can use dma_handle and size parameters that aren't identical to
|
||||
those passed into the single mapping API to do a partial sync.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
You must do this:
|
||||
|
||||
- Before reading values that have been written by DMA from the device
|
||||
(use the DMA_FROM_DEVICE direction)
|
||||
- After writing values that will be written to the device using DMA
|
||||
(use the DMA_TO_DEVICE) direction
|
||||
- before *and* after handing memory to the device if the memory is
|
||||
DMA_BIDIRECTIONAL
|
||||
|
||||
See also dma_map_single().
|
||||
|
||||
::
|
||||
|
||||
dma_addr_t
|
||||
dma_map_single_attrs(struct device *dev, void *cpu_addr, size_t size,
|
||||
enum dma_data_direction dir,
|
||||
unsigned long attrs)
|
||||
|
||||
void
|
||||
dma_unmap_single_attrs(struct device *dev, dma_addr_t dma_addr,
|
||||
size_t size, enum dma_data_direction dir,
|
||||
unsigned long attrs)
|
||||
|
||||
int
|
||||
dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
|
||||
int nents, enum dma_data_direction dir,
|
||||
unsigned long attrs)
|
||||
|
||||
void
|
||||
dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl,
|
||||
int nents, enum dma_data_direction dir,
|
||||
unsigned long attrs)
|
||||
|
||||
The four functions above are just like the counterpart functions
|
||||
without the _attrs suffixes, except that they pass an optional
|
||||
dma_attrs.
|
||||
|
||||
The interpretation of DMA attributes is architecture-specific, and
|
||||
each attribute should be documented in Documentation/DMA-attributes.txt.
|
||||
|
||||
If dma_attrs are 0, the semantics of each of these functions
|
||||
is identical to those of the corresponding function
|
||||
without the _attrs suffix. As a result dma_map_single_attrs()
|
||||
can generally replace dma_map_single(), etc.
|
||||
|
||||
As an example of the use of the ``*_attrs`` functions, here's how
|
||||
you could pass an attribute DMA_ATTR_FOO when mapping memory
|
||||
for DMA::
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
/* DMA_ATTR_FOO should be defined in linux/dma-mapping.h and
|
||||
* documented in Documentation/DMA-attributes.txt */
|
||||
...
|
||||
|
||||
unsigned long attr;
|
||||
attr |= DMA_ATTR_FOO;
|
||||
....
|
||||
n = dma_map_sg_attrs(dev, sg, nents, DMA_TO_DEVICE, attr);
|
||||
....
|
||||
|
||||
Architectures that care about DMA_ATTR_FOO would check for its
|
||||
presence in their implementations of the mapping and unmapping
|
||||
routines, e.g.:::
|
||||
|
||||
void whizco_dma_map_sg_attrs(struct device *dev, dma_addr_t dma_addr,
|
||||
size_t size, enum dma_data_direction dir,
|
||||
unsigned long attrs)
|
||||
{
|
||||
....
|
||||
if (attrs & DMA_ATTR_FOO)
|
||||
/* twizzle the frobnozzle */
|
||||
....
|
||||
}
|
||||
|
||||
|
||||
Part II - Advanced dma usage
|
||||
----------------------------
|
||||
|
||||
Warning: These pieces of the DMA API should not be used in the
|
||||
majority of cases, since they cater for unlikely corner cases that
|
||||
don't belong in usual drivers.
|
||||
|
||||
If you don't understand how cache line coherency works between a
|
||||
processor and an I/O device, you should not be using this part of the
|
||||
API at all.
|
||||
|
||||
::
|
||||
|
||||
void *
|
||||
dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,
|
||||
gfp_t flag, unsigned long attrs)
|
||||
|
||||
Identical to dma_alloc_coherent() except that when the
|
||||
DMA_ATTR_NON_CONSISTENT flags is passed in the attrs argument, the
|
||||
platform will choose to return either consistent or non-consistent memory
|
||||
as it sees fit. By using this API, you are guaranteeing to the platform
|
||||
that you have all the correct and necessary sync points for this memory
|
||||
in the driver should it choose to return non-consistent memory.
|
||||
|
||||
Note: where the platform can return consistent memory, it will
|
||||
guarantee that the sync points become nops.
|
||||
|
||||
Warning: Handling non-consistent memory is a real pain. You should
|
||||
only use this API if you positively know your driver will be
|
||||
required to work on one of the rare (usually non-PCI) architectures
|
||||
that simply cannot make consistent memory.
|
||||
|
||||
::
|
||||
|
||||
void
|
||||
dma_free_attrs(struct device *dev, size_t size, void *cpu_addr,
|
||||
dma_addr_t dma_handle, unsigned long attrs)
|
||||
|
||||
Free memory allocated by the dma_alloc_attrs(). All common
|
||||
parameters must be identical to those otherwise passed to dma_free_coherent,
|
||||
and the attrs argument must be identical to the attrs passed to
|
||||
dma_alloc_attrs().
|
||||
|
||||
::
|
||||
|
||||
int
|
||||
dma_get_cache_alignment(void)
|
||||
|
||||
Returns the processor cache alignment. This is the absolute minimum
|
||||
alignment *and* width that you must observe when either mapping
|
||||
memory or doing partial flushes.
|
||||
|
||||
.. note::
|
||||
|
||||
This API may return a number *larger* than the actual cache
|
||||
line, but it will guarantee that one or more cache lines fit exactly
|
||||
into the width returned by this call. It will also always be a power
|
||||
of two for easy alignment.
|
||||
|
||||
::
|
||||
|
||||
void
|
||||
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
|
||||
Do a partial sync of memory that was allocated by dma_alloc_attrs() with
|
||||
the DMA_ATTR_NON_CONSISTENT flag starting at virtual address vaddr and
|
||||
continuing on for size. Again, you *must* observe the cache line
|
||||
boundaries when doing this.
|
||||
|
||||
::
|
||||
|
||||
int
|
||||
dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
|
||||
dma_addr_t device_addr, size_t size);
|
||||
|
||||
Declare region of memory to be handed out by dma_alloc_coherent() when
|
||||
it's asked for coherent memory for this device.
|
||||
|
||||
phys_addr is the CPU physical address to which the memory is currently
|
||||
assigned (this will be ioremapped so the CPU can access the region).
|
||||
|
||||
device_addr is the DMA address the device needs to be programmed
|
||||
with to actually address this memory (this will be handed out as the
|
||||
dma_addr_t in dma_alloc_coherent()).
|
||||
|
||||
size is the size of the area (must be multiples of PAGE_SIZE).
|
||||
|
||||
As a simplification for the platforms, only *one* such region of
|
||||
memory may be declared per device.
|
||||
|
||||
For reasons of efficiency, most platforms choose to track the declared
|
||||
region only at the granularity of a page. For smaller allocations,
|
||||
you should use the dma_pool() API.
|
||||
|
||||
Part III - Debug drivers use of the DMA-API
|
||||
-------------------------------------------
|
||||
|
||||
The DMA-API as described above has some constraints. DMA addresses must be
|
||||
released with the corresponding function with the same size for example. With
|
||||
the advent of hardware IOMMUs it becomes more and more important that drivers
|
||||
do not violate those constraints. In the worst case such a violation can
|
||||
result in data corruption up to destroyed filesystems.
|
||||
|
||||
To debug drivers and find bugs in the usage of the DMA-API checking code can
|
||||
be compiled into the kernel which will tell the developer about those
|
||||
violations. If your architecture supports it you can select the "Enable
|
||||
debugging of DMA-API usage" option in your kernel configuration. Enabling this
|
||||
option has a performance impact. Do not enable it in production kernels.
|
||||
|
||||
If you boot the resulting kernel will contain code which does some bookkeeping
|
||||
about what DMA memory was allocated for which device. If this code detects an
|
||||
error it prints a warning message with some details into your kernel log. An
|
||||
example warning message may look like this::
|
||||
|
||||
WARNING: at /data2/repos/linux-2.6-iommu/lib/dma-debug.c:448
|
||||
check_unmap+0x203/0x490()
|
||||
Hardware name:
|
||||
forcedeth 0000:00:08.0: DMA-API: device driver frees DMA memory with wrong
|
||||
function [device address=0x00000000640444be] [size=66 bytes] [mapped as
|
||||
single] [unmapped as page]
|
||||
Modules linked in: nfsd exportfs bridge stp llc r8169
|
||||
Pid: 0, comm: swapper Tainted: G W 2.6.28-dmatest-09289-g8bb99c0 #1
|
||||
Call Trace:
|
||||
<IRQ> [<ffffffff80240b22>] warn_slowpath+0xf2/0x130
|
||||
[<ffffffff80647b70>] _spin_unlock+0x10/0x30
|
||||
[<ffffffff80537e75>] usb_hcd_link_urb_to_ep+0x75/0xc0
|
||||
[<ffffffff80647c22>] _spin_unlock_irqrestore+0x12/0x40
|
||||
[<ffffffff8055347f>] ohci_urb_enqueue+0x19f/0x7c0
|
||||
[<ffffffff80252f96>] queue_work+0x56/0x60
|
||||
[<ffffffff80237e10>] enqueue_task_fair+0x20/0x50
|
||||
[<ffffffff80539279>] usb_hcd_submit_urb+0x379/0xbc0
|
||||
[<ffffffff803b78c3>] cpumask_next_and+0x23/0x40
|
||||
[<ffffffff80235177>] find_busiest_group+0x207/0x8a0
|
||||
[<ffffffff8064784f>] _spin_lock_irqsave+0x1f/0x50
|
||||
[<ffffffff803c7ea3>] check_unmap+0x203/0x490
|
||||
[<ffffffff803c8259>] debug_dma_unmap_page+0x49/0x50
|
||||
[<ffffffff80485f26>] nv_tx_done_optimized+0xc6/0x2c0
|
||||
[<ffffffff80486c13>] nv_nic_irq_optimized+0x73/0x2b0
|
||||
[<ffffffff8026df84>] handle_IRQ_event+0x34/0x70
|
||||
[<ffffffff8026ffe9>] handle_edge_irq+0xc9/0x150
|
||||
[<ffffffff8020e3ab>] do_IRQ+0xcb/0x1c0
|
||||
[<ffffffff8020c093>] ret_from_intr+0x0/0xa
|
||||
<EOI> <4>---[ end trace f6435a98e2a38c0e ]---
|
||||
|
||||
The driver developer can find the driver and the device including a stacktrace
|
||||
of the DMA-API call which caused this warning.
|
||||
|
||||
Per default only the first error will result in a warning message. All other
|
||||
errors will only silently counted. This limitation exist to prevent the code
|
||||
from flooding your kernel log. To support debugging a device driver this can
|
||||
be disabled via debugfs. See the debugfs interface documentation below for
|
||||
details.
|
||||
|
||||
The debugfs directory for the DMA-API debugging code is called dma-api/. In
|
||||
this directory the following files can currently be found:
|
||||
|
||||
=============================== ===============================================
|
||||
dma-api/all_errors This file contains a numeric value. If this
|
||||
value is not equal to zero the debugging code
|
||||
will print a warning for every error it finds
|
||||
into the kernel log. Be careful with this
|
||||
option, as it can easily flood your logs.
|
||||
|
||||
dma-api/disabled This read-only file contains the character 'Y'
|
||||
if the debugging code is disabled. This can
|
||||
happen when it runs out of memory or if it was
|
||||
disabled at boot time
|
||||
|
||||
dma-api/dump This read-only file contains current DMA
|
||||
mappings.
|
||||
|
||||
dma-api/error_count This file is read-only and shows the total
|
||||
numbers of errors found.
|
||||
|
||||
dma-api/num_errors The number in this file shows how many
|
||||
warnings will be printed to the kernel log
|
||||
before it stops. This number is initialized to
|
||||
one at system boot and be set by writing into
|
||||
this file
|
||||
|
||||
dma-api/min_free_entries This read-only file can be read to get the
|
||||
minimum number of free dma_debug_entries the
|
||||
allocator has ever seen. If this value goes
|
||||
down to zero the code will attempt to increase
|
||||
nr_total_entries to compensate.
|
||||
|
||||
dma-api/num_free_entries The current number of free dma_debug_entries
|
||||
in the allocator.
|
||||
|
||||
dma-api/nr_total_entries The total number of dma_debug_entries in the
|
||||
allocator, both free and used.
|
||||
|
||||
dma-api/driver_filter You can write a name of a driver into this file
|
||||
to limit the debug output to requests from that
|
||||
particular driver. Write an empty string to
|
||||
that file to disable the filter and see
|
||||
all errors again.
|
||||
=============================== ===============================================
|
||||
|
||||
If you have this code compiled into your kernel it will be enabled by default.
|
||||
If you want to boot without the bookkeeping anyway you can provide
|
||||
'dma_debug=off' as a boot parameter. This will disable DMA-API debugging.
|
||||
Notice that you can not enable it again at runtime. You have to reboot to do
|
||||
so.
|
||||
|
||||
If you want to see debug messages only for a special device driver you can
|
||||
specify the dma_debug_driver=<drivername> parameter. This will enable the
|
||||
driver filter at boot time. The debug code will only print errors for that
|
||||
driver afterwards. This filter can be disabled or changed later using debugfs.
|
||||
|
||||
When the code disables itself at runtime this is most likely because it ran
|
||||
out of dma_debug_entries and was unable to allocate more on-demand. 65536
|
||||
entries are preallocated at boot - if this is too low for you boot with
|
||||
'dma_debug_entries=<your_desired_number>' to overwrite the default. Note
|
||||
that the code allocates entries in batches, so the exact number of
|
||||
preallocated entries may be greater than the actual number requested. The
|
||||
code will print to the kernel log each time it has dynamically allocated
|
||||
as many entries as were initially preallocated. This is to indicate that a
|
||||
larger preallocation size may be appropriate, or if it happens continually
|
||||
that a driver may be leaking mappings.
|
||||
|
||||
::
|
||||
|
||||
void
|
||||
debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
|
||||
|
||||
dma-debug interface debug_dma_mapping_error() to debug drivers that fail
|
||||
to check DMA mapping errors on addresses returned by dma_map_single() and
|
||||
dma_map_page() interfaces. This interface clears a flag set by
|
||||
debug_dma_map_page() to indicate that dma_mapping_error() has been called by
|
||||
the driver. When driver does unmap, debug_dma_unmap() checks the flag and if
|
||||
this flag is still set, prints warning message that includes call trace that
|
||||
leads up to the unmap. This interface can be called from dma_mapping_error()
|
||||
routines to enable DMA mapping error check debugging.
|
||||
@@ -1,152 +0,0 @@
|
||||
============================
|
||||
DMA with ISA and LPC devices
|
||||
============================
|
||||
|
||||
:Author: Pierre Ossman <drzeus@drzeus.cx>
|
||||
|
||||
This document describes how to do DMA transfers using the old ISA DMA
|
||||
controller. Even though ISA is more or less dead today the LPC bus
|
||||
uses the same DMA system so it will be around for quite some time.
|
||||
|
||||
Headers and dependencies
|
||||
------------------------
|
||||
|
||||
To do ISA style DMA you need to include two headers::
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <asm/dma.h>
|
||||
|
||||
The first is the generic DMA API used to convert virtual addresses to
|
||||
bus addresses (see Documentation/DMA-API.txt for details).
|
||||
|
||||
The second contains the routines specific to ISA DMA transfers. Since
|
||||
this is not present on all platforms make sure you construct your
|
||||
Kconfig to be dependent on ISA_DMA_API (not ISA) so that nobody tries
|
||||
to build your driver on unsupported platforms.
|
||||
|
||||
Buffer allocation
|
||||
-----------------
|
||||
|
||||
The ISA DMA controller has some very strict requirements on which
|
||||
memory it can access so extra care must be taken when allocating
|
||||
buffers.
|
||||
|
||||
(You usually need a special buffer for DMA transfers instead of
|
||||
transferring directly to and from your normal data structures.)
|
||||
|
||||
The DMA-able address space is the lowest 16 MB of _physical_ memory.
|
||||
Also the transfer block may not cross page boundaries (which are 64
|
||||
or 128 KiB depending on which channel you use).
|
||||
|
||||
In order to allocate a piece of memory that satisfies all these
|
||||
requirements you pass the flag GFP_DMA to kmalloc.
|
||||
|
||||
Unfortunately the memory available for ISA DMA is scarce so unless you
|
||||
allocate the memory during boot-up it's a good idea to also pass
|
||||
__GFP_RETRY_MAYFAIL and __GFP_NOWARN to make the allocator try a bit harder.
|
||||
|
||||
(This scarcity also means that you should allocate the buffer as
|
||||
early as possible and not release it until the driver is unloaded.)
|
||||
|
||||
Address translation
|
||||
-------------------
|
||||
|
||||
To translate the virtual address to a bus address, use the normal DMA
|
||||
API. Do _not_ use isa_virt_to_bus() even though it does the same
|
||||
thing. The reason for this is that the function isa_virt_to_bus()
|
||||
will require a Kconfig dependency to ISA, not just ISA_DMA_API which
|
||||
is really all you need. Remember that even though the DMA controller
|
||||
has its origins in ISA it is used elsewhere.
|
||||
|
||||
Note: x86_64 had a broken DMA API when it came to ISA but has since
|
||||
been fixed. If your arch has problems then fix the DMA API instead of
|
||||
reverting to the ISA functions.
|
||||
|
||||
Channels
|
||||
--------
|
||||
|
||||
A normal ISA DMA controller has 8 channels. The lower four are for
|
||||
8-bit transfers and the upper four are for 16-bit transfers.
|
||||
|
||||
(Actually the DMA controller is really two separate controllers where
|
||||
channel 4 is used to give DMA access for the second controller (0-3).
|
||||
This means that of the four 16-bits channels only three are usable.)
|
||||
|
||||
You allocate these in a similar fashion as all basic resources:
|
||||
|
||||
extern int request_dma(unsigned int dmanr, const char * device_id);
|
||||
extern void free_dma(unsigned int dmanr);
|
||||
|
||||
The ability to use 16-bit or 8-bit transfers is _not_ up to you as a
|
||||
driver author but depends on what the hardware supports. Check your
|
||||
specs or test different channels.
|
||||
|
||||
Transfer data
|
||||
-------------
|
||||
|
||||
Now for the good stuff, the actual DMA transfer. :)
|
||||
|
||||
Before you use any ISA DMA routines you need to claim the DMA lock
|
||||
using claim_dma_lock(). The reason is that some DMA operations are
|
||||
not atomic so only one driver may fiddle with the registers at a
|
||||
time.
|
||||
|
||||
The first time you use the DMA controller you should call
|
||||
clear_dma_ff(). This clears an internal register in the DMA
|
||||
controller that is used for the non-atomic operations. As long as you
|
||||
(and everyone else) uses the locking functions then you only need to
|
||||
reset this once.
|
||||
|
||||
Next, you tell the controller in which direction you intend to do the
|
||||
transfer using set_dma_mode(). Currently you have the options
|
||||
DMA_MODE_READ and DMA_MODE_WRITE.
|
||||
|
||||
Set the address from where the transfer should start (this needs to
|
||||
be 16-bit aligned for 16-bit transfers) and how many bytes to
|
||||
transfer. Note that it's _bytes_. The DMA routines will do all the
|
||||
required translation to values that the DMA controller understands.
|
||||
|
||||
The final step is enabling the DMA channel and releasing the DMA
|
||||
lock.
|
||||
|
||||
Once the DMA transfer is finished (or timed out) you should disable
|
||||
the channel again. You should also check get_dma_residue() to make
|
||||
sure that all data has been transferred.
|
||||
|
||||
Example::
|
||||
|
||||
int flags, residue;
|
||||
|
||||
flags = claim_dma_lock();
|
||||
|
||||
clear_dma_ff();
|
||||
|
||||
set_dma_mode(channel, DMA_MODE_WRITE);
|
||||
set_dma_addr(channel, phys_addr);
|
||||
set_dma_count(channel, num_bytes);
|
||||
|
||||
dma_enable(channel);
|
||||
|
||||
release_dma_lock(flags);
|
||||
|
||||
while (!device_done());
|
||||
|
||||
flags = claim_dma_lock();
|
||||
|
||||
dma_disable(channel);
|
||||
|
||||
residue = dma_get_residue(channel);
|
||||
if (residue != 0)
|
||||
printk(KERN_ERR "driver: Incomplete DMA transfer!"
|
||||
" %d bytes left!\n", residue);
|
||||
|
||||
release_dma_lock(flags);
|
||||
|
||||
Suspend/resume
|
||||
--------------
|
||||
|
||||
It is the driver's responsibility to make sure that the machine isn't
|
||||
suspended while a DMA transfer is in progress. Also, all DMA settings
|
||||
are lost when the system suspends so if your driver relies on the DMA
|
||||
controller being in a certain state then you have to restore these
|
||||
registers upon resume.
|
||||
@@ -1,746 +0,0 @@
|
||||
=====================
|
||||
The Linux IPMI Driver
|
||||
=====================
|
||||
|
||||
:Author: Corey Minyard <minyard@mvista.com> / <minyard@acm.org>
|
||||
|
||||
The Intelligent Platform Management Interface, or IPMI, is a
|
||||
standard for controlling intelligent devices that monitor a system.
|
||||
It provides for dynamic discovery of sensors in the system and the
|
||||
ability to monitor the sensors and be informed when the sensor's
|
||||
values change or go outside certain boundaries. It also has a
|
||||
standardized database for field-replaceable units (FRUs) and a watchdog
|
||||
timer.
|
||||
|
||||
To use this, you need an interface to an IPMI controller in your
|
||||
system (called a Baseboard Management Controller, or BMC) and
|
||||
management software that can use the IPMI system.
|
||||
|
||||
This document describes how to use the IPMI driver for Linux. If you
|
||||
are not familiar with IPMI itself, see the web site at
|
||||
http://www.intel.com/design/servers/ipmi/index.htm. IPMI is a big
|
||||
subject and I can't cover it all here!
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
The Linux IPMI driver is modular, which means you have to pick several
|
||||
things to have it work right depending on your hardware. Most of
|
||||
these are available in the 'Character Devices' menu then the IPMI
|
||||
menu.
|
||||
|
||||
No matter what, you must pick 'IPMI top-level message handler' to use
|
||||
IPMI. What you do beyond that depends on your needs and hardware.
|
||||
|
||||
The message handler does not provide any user-level interfaces.
|
||||
Kernel code (like the watchdog) can still use it. If you need access
|
||||
from userland, you need to select 'Device interface for IPMI' if you
|
||||
want access through a device driver.
|
||||
|
||||
The driver interface depends on your hardware. If your system
|
||||
properly provides the SMBIOS info for IPMI, the driver will detect it
|
||||
and just work. If you have a board with a standard interface (These
|
||||
will generally be either "KCS", "SMIC", or "BT", consult your hardware
|
||||
manual), choose the 'IPMI SI handler' option. A driver also exists
|
||||
for direct I2C access to the IPMI management controller. Some boards
|
||||
support this, but it is unknown if it will work on every board. For
|
||||
this, choose 'IPMI SMBus handler', but be ready to try to do some
|
||||
figuring to see if it will work on your system if the SMBIOS/APCI
|
||||
information is wrong or not present. It is fairly safe to have both
|
||||
these enabled and let the drivers auto-detect what is present.
|
||||
|
||||
You should generally enable ACPI on your system, as systems with IPMI
|
||||
can have ACPI tables describing them.
|
||||
|
||||
If you have a standard interface and the board manufacturer has done
|
||||
their job correctly, the IPMI controller should be automatically
|
||||
detected (via ACPI or SMBIOS tables) and should just work. Sadly,
|
||||
many boards do not have this information. The driver attempts
|
||||
standard defaults, but they may not work. If you fall into this
|
||||
situation, you need to read the section below named 'The SI Driver' or
|
||||
"The SMBus Driver" on how to hand-configure your system.
|
||||
|
||||
IPMI defines a standard watchdog timer. You can enable this with the
|
||||
'IPMI Watchdog Timer' config option. If you compile the driver into
|
||||
the kernel, then via a kernel command-line option you can have the
|
||||
watchdog timer start as soon as it initializes. It also have a lot
|
||||
of other options, see the 'Watchdog' section below for more details.
|
||||
Note that you can also have the watchdog continue to run if it is
|
||||
closed (by default it is disabled on close). Go into the 'Watchdog
|
||||
Cards' menu, enable 'Watchdog Timer Support', and enable the option
|
||||
'Disable watchdog shutdown on close'.
|
||||
|
||||
IPMI systems can often be powered off using IPMI commands. Select
|
||||
'IPMI Poweroff' to do this. The driver will auto-detect if the system
|
||||
can be powered off by IPMI. It is safe to enable this even if your
|
||||
system doesn't support this option. This works on ATCA systems, the
|
||||
Radisys CPI1 card, and any IPMI system that supports standard chassis
|
||||
management commands.
|
||||
|
||||
If you want the driver to put an event into the event log on a panic,
|
||||
enable the 'Generate a panic event to all BMCs on a panic' option. If
|
||||
you want the whole panic string put into the event log using OEM
|
||||
events, enable the 'Generate OEM events containing the panic string'
|
||||
option. You can also enable these dynamically by setting the module
|
||||
parameter named "panic_op" in the ipmi_msghandler module to "event"
|
||||
or "string". Setting that parameter to "none" disables this function.
|
||||
|
||||
Basic Design
|
||||
------------
|
||||
|
||||
The Linux IPMI driver is designed to be very modular and flexible, you
|
||||
only need to take the pieces you need and you can use it in many
|
||||
different ways. Because of that, it's broken into many chunks of
|
||||
code. These chunks (by module name) are:
|
||||
|
||||
ipmi_msghandler - This is the central piece of software for the IPMI
|
||||
system. It handles all messages, message timing, and responses. The
|
||||
IPMI users tie into this, and the IPMI physical interfaces (called
|
||||
System Management Interfaces, or SMIs) also tie in here. This
|
||||
provides the kernelland interface for IPMI, but does not provide an
|
||||
interface for use by application processes.
|
||||
|
||||
ipmi_devintf - This provides a userland IOCTL interface for the IPMI
|
||||
driver, each open file for this device ties in to the message handler
|
||||
as an IPMI user.
|
||||
|
||||
ipmi_si - A driver for various system interfaces. This supports KCS,
|
||||
SMIC, and BT interfaces. Unless you have an SMBus interface or your
|
||||
own custom interface, you probably need to use this.
|
||||
|
||||
ipmi_ssif - A driver for accessing BMCs on the SMBus. It uses the
|
||||
I2C kernel driver's SMBus interfaces to send and receive IPMI messages
|
||||
over the SMBus.
|
||||
|
||||
ipmi_powernv - A driver for access BMCs on POWERNV systems.
|
||||
|
||||
ipmi_watchdog - IPMI requires systems to have a very capable watchdog
|
||||
timer. This driver implements the standard Linux watchdog timer
|
||||
interface on top of the IPMI message handler.
|
||||
|
||||
ipmi_poweroff - Some systems support the ability to be turned off via
|
||||
IPMI commands.
|
||||
|
||||
bt-bmc - This is not part of the main driver, but instead a driver for
|
||||
accessing a BMC-side interface of a BT interface. It is used on BMCs
|
||||
running Linux to provide an interface to the host.
|
||||
|
||||
These are all individually selectable via configuration options.
|
||||
|
||||
Much documentation for the interface is in the include files. The
|
||||
IPMI include files are:
|
||||
|
||||
linux/ipmi.h - Contains the user interface and IOCTL interface for IPMI.
|
||||
|
||||
linux/ipmi_smi.h - Contains the interface for system management interfaces
|
||||
(things that interface to IPMI controllers) to use.
|
||||
|
||||
linux/ipmi_msgdefs.h - General definitions for base IPMI messaging.
|
||||
|
||||
|
||||
Addressing
|
||||
----------
|
||||
|
||||
The IPMI addressing works much like IP addresses, you have an overlay
|
||||
to handle the different address types. The overlay is::
|
||||
|
||||
struct ipmi_addr
|
||||
{
|
||||
int addr_type;
|
||||
short channel;
|
||||
char data[IPMI_MAX_ADDR_SIZE];
|
||||
};
|
||||
|
||||
The addr_type determines what the address really is. The driver
|
||||
currently understands two different types of addresses.
|
||||
|
||||
"System Interface" addresses are defined as::
|
||||
|
||||
struct ipmi_system_interface_addr
|
||||
{
|
||||
int addr_type;
|
||||
short channel;
|
||||
};
|
||||
|
||||
and the type is IPMI_SYSTEM_INTERFACE_ADDR_TYPE. This is used for talking
|
||||
straight to the BMC on the current card. The channel must be
|
||||
IPMI_BMC_CHANNEL.
|
||||
|
||||
Messages that are destined to go out on the IPMB bus use the
|
||||
IPMI_IPMB_ADDR_TYPE address type. The format is::
|
||||
|
||||
struct ipmi_ipmb_addr
|
||||
{
|
||||
int addr_type;
|
||||
short channel;
|
||||
unsigned char slave_addr;
|
||||
unsigned char lun;
|
||||
};
|
||||
|
||||
The "channel" here is generally zero, but some devices support more
|
||||
than one channel, it corresponds to the channel as defined in the IPMI
|
||||
spec.
|
||||
|
||||
|
||||
Messages
|
||||
--------
|
||||
|
||||
Messages are defined as::
|
||||
|
||||
struct ipmi_msg
|
||||
{
|
||||
unsigned char netfn;
|
||||
unsigned char lun;
|
||||
unsigned char cmd;
|
||||
unsigned char *data;
|
||||
int data_len;
|
||||
};
|
||||
|
||||
The driver takes care of adding/stripping the header information. The
|
||||
data portion is just the data to be send (do NOT put addressing info
|
||||
here) or the response. Note that the completion code of a response is
|
||||
the first item in "data", it is not stripped out because that is how
|
||||
all the messages are defined in the spec (and thus makes counting the
|
||||
offsets a little easier :-).
|
||||
|
||||
When using the IOCTL interface from userland, you must provide a block
|
||||
of data for "data", fill it, and set data_len to the length of the
|
||||
block of data, even when receiving messages. Otherwise the driver
|
||||
will have no place to put the message.
|
||||
|
||||
Messages coming up from the message handler in kernelland will come in
|
||||
as::
|
||||
|
||||
struct ipmi_recv_msg
|
||||
{
|
||||
struct list_head link;
|
||||
|
||||
/* The type of message as defined in the "Receive Types"
|
||||
defines above. */
|
||||
int recv_type;
|
||||
|
||||
ipmi_user_t *user;
|
||||
struct ipmi_addr addr;
|
||||
long msgid;
|
||||
struct ipmi_msg msg;
|
||||
|
||||
/* Call this when done with the message. It will presumably free
|
||||
the message and do any other necessary cleanup. */
|
||||
void (*done)(struct ipmi_recv_msg *msg);
|
||||
|
||||
/* Place-holder for the data, don't make any assumptions about
|
||||
the size or existence of this, since it may change. */
|
||||
unsigned char msg_data[IPMI_MAX_MSG_LENGTH];
|
||||
};
|
||||
|
||||
You should look at the receive type and handle the message
|
||||
appropriately.
|
||||
|
||||
|
||||
The Upper Layer Interface (Message Handler)
|
||||
-------------------------------------------
|
||||
|
||||
The upper layer of the interface provides the users with a consistent
|
||||
view of the IPMI interfaces. It allows multiple SMI interfaces to be
|
||||
addressed (because some boards actually have multiple BMCs on them)
|
||||
and the user should not have to care what type of SMI is below them.
|
||||
|
||||
|
||||
Watching For Interfaces
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When your code comes up, the IPMI driver may or may not have detected
|
||||
if IPMI devices exist. So you might have to defer your setup until
|
||||
the device is detected, or you might be able to do it immediately.
|
||||
To handle this, and to allow for discovery, you register an SMI
|
||||
watcher with ipmi_smi_watcher_register() to iterate over interfaces
|
||||
and tell you when they come and go.
|
||||
|
||||
|
||||
Creating the User
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
To use the message handler, you must first create a user using
|
||||
ipmi_create_user. The interface number specifies which SMI you want
|
||||
to connect to, and you must supply callback functions to be called
|
||||
when data comes in. The callback function can run at interrupt level,
|
||||
so be careful using the callbacks. This also allows to you pass in a
|
||||
piece of data, the handler_data, that will be passed back to you on
|
||||
all calls.
|
||||
|
||||
Once you are done, call ipmi_destroy_user() to get rid of the user.
|
||||
|
||||
From userland, opening the device automatically creates a user, and
|
||||
closing the device automatically destroys the user.
|
||||
|
||||
|
||||
Messaging
|
||||
^^^^^^^^^
|
||||
|
||||
To send a message from kernel-land, the ipmi_request_settime() call does
|
||||
pretty much all message handling. Most of the parameter are
|
||||
self-explanatory. However, it takes a "msgid" parameter. This is NOT
|
||||
the sequence number of messages. It is simply a long value that is
|
||||
passed back when the response for the message is returned. You may
|
||||
use it for anything you like.
|
||||
|
||||
Responses come back in the function pointed to by the ipmi_recv_hndl
|
||||
field of the "handler" that you passed in to ipmi_create_user().
|
||||
Remember again, these may be running at interrupt level. Remember to
|
||||
look at the receive type, too.
|
||||
|
||||
From userland, you fill out an ipmi_req_t structure and use the
|
||||
IPMICTL_SEND_COMMAND ioctl. For incoming stuff, you can use select()
|
||||
or poll() to wait for messages to come in. However, you cannot use
|
||||
read() to get them, you must call the IPMICTL_RECEIVE_MSG with the
|
||||
ipmi_recv_t structure to actually get the message. Remember that you
|
||||
must supply a pointer to a block of data in the msg.data field, and
|
||||
you must fill in the msg.data_len field with the size of the data.
|
||||
This gives the receiver a place to actually put the message.
|
||||
|
||||
If the message cannot fit into the data you provide, you will get an
|
||||
EMSGSIZE error and the driver will leave the data in the receive
|
||||
queue. If you want to get it and have it truncate the message, us
|
||||
the IPMICTL_RECEIVE_MSG_TRUNC ioctl.
|
||||
|
||||
When you send a command (which is defined by the lowest-order bit of
|
||||
the netfn per the IPMI spec) on the IPMB bus, the driver will
|
||||
automatically assign the sequence number to the command and save the
|
||||
command. If the response is not receive in the IPMI-specified 5
|
||||
seconds, it will generate a response automatically saying the command
|
||||
timed out. If an unsolicited response comes in (if it was after 5
|
||||
seconds, for instance), that response will be ignored.
|
||||
|
||||
In kernelland, after you receive a message and are done with it, you
|
||||
MUST call ipmi_free_recv_msg() on it, or you will leak messages. Note
|
||||
that you should NEVER mess with the "done" field of a message, that is
|
||||
required to properly clean up the message.
|
||||
|
||||
Note that when sending, there is an ipmi_request_supply_msgs() call
|
||||
that lets you supply the smi and receive message. This is useful for
|
||||
pieces of code that need to work even if the system is out of buffers
|
||||
(the watchdog timer uses this, for instance). You supply your own
|
||||
buffer and own free routines. This is not recommended for normal use,
|
||||
though, since it is tricky to manage your own buffers.
|
||||
|
||||
|
||||
Events and Incoming Commands
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The driver takes care of polling for IPMI events and receiving
|
||||
commands (commands are messages that are not responses, they are
|
||||
commands that other things on the IPMB bus have sent you). To receive
|
||||
these, you must register for them, they will not automatically be sent
|
||||
to you.
|
||||
|
||||
To receive events, you must call ipmi_set_gets_events() and set the
|
||||
"val" to non-zero. Any events that have been received by the driver
|
||||
since startup will immediately be delivered to the first user that
|
||||
registers for events. After that, if multiple users are registered
|
||||
for events, they will all receive all events that come in.
|
||||
|
||||
For receiving commands, you have to individually register commands you
|
||||
want to receive. Call ipmi_register_for_cmd() and supply the netfn
|
||||
and command name for each command you want to receive. You also
|
||||
specify a bitmask of the channels you want to receive the command from
|
||||
(or use IPMI_CHAN_ALL for all channels if you don't care). Only one
|
||||
user may be registered for each netfn/cmd/channel, but different users
|
||||
may register for different commands, or the same command if the
|
||||
channel bitmasks do not overlap.
|
||||
|
||||
From userland, equivalent IOCTLs are provided to do these functions.
|
||||
|
||||
|
||||
The Lower Layer (SMI) Interface
|
||||
-------------------------------
|
||||
|
||||
As mentioned before, multiple SMI interfaces may be registered to the
|
||||
message handler, each of these is assigned an interface number when
|
||||
they register with the message handler. They are generally assigned
|
||||
in the order they register, although if an SMI unregisters and then
|
||||
another one registers, all bets are off.
|
||||
|
||||
The ipmi_smi.h defines the interface for management interfaces, see
|
||||
that for more details.
|
||||
|
||||
|
||||
The SI Driver
|
||||
-------------
|
||||
|
||||
The SI driver allows KCS, BT, and SMIC interfaces to be configured
|
||||
in the system. It discovers interfaces through a host of different
|
||||
methods, depending on the system.
|
||||
|
||||
You can specify up to four interfaces on the module load line and
|
||||
control some module parameters::
|
||||
|
||||
modprobe ipmi_si.o type=<type1>,<type2>....
|
||||
ports=<port1>,<port2>... addrs=<addr1>,<addr2>...
|
||||
irqs=<irq1>,<irq2>...
|
||||
regspacings=<sp1>,<sp2>,... regsizes=<size1>,<size2>,...
|
||||
regshifts=<shift1>,<shift2>,...
|
||||
slave_addrs=<addr1>,<addr2>,...
|
||||
force_kipmid=<enable1>,<enable2>,...
|
||||
kipmid_max_busy_us=<ustime1>,<ustime2>,...
|
||||
unload_when_empty=[0|1]
|
||||
trydmi=[0|1] tryacpi=[0|1]
|
||||
tryplatform=[0|1] trypci=[0|1]
|
||||
|
||||
Each of these except try... items is a list, the first item for the
|
||||
first interface, second item for the second interface, etc.
|
||||
|
||||
The si_type may be either "kcs", "smic", or "bt". If you leave it blank, it
|
||||
defaults to "kcs".
|
||||
|
||||
If you specify addrs as non-zero for an interface, the driver will
|
||||
use the memory address given as the address of the device. This
|
||||
overrides si_ports.
|
||||
|
||||
If you specify ports as non-zero for an interface, the driver will
|
||||
use the I/O port given as the device address.
|
||||
|
||||
If you specify irqs as non-zero for an interface, the driver will
|
||||
attempt to use the given interrupt for the device.
|
||||
|
||||
The other try... items disable discovery by their corresponding
|
||||
names. These are all enabled by default, set them to zero to disable
|
||||
them. The tryplatform disables openfirmware.
|
||||
|
||||
The next three parameters have to do with register layout. The
|
||||
registers used by the interfaces may not appear at successive
|
||||
locations and they may not be in 8-bit registers. These parameters
|
||||
allow the layout of the data in the registers to be more precisely
|
||||
specified.
|
||||
|
||||
The regspacings parameter give the number of bytes between successive
|
||||
register start addresses. For instance, if the regspacing is set to 4
|
||||
and the start address is 0xca2, then the address for the second
|
||||
register would be 0xca6. This defaults to 1.
|
||||
|
||||
The regsizes parameter gives the size of a register, in bytes. The
|
||||
data used by IPMI is 8-bits wide, but it may be inside a larger
|
||||
register. This parameter allows the read and write type to specified.
|
||||
It may be 1, 2, 4, or 8. The default is 1.
|
||||
|
||||
Since the register size may be larger than 32 bits, the IPMI data may not
|
||||
be in the lower 8 bits. The regshifts parameter give the amount to shift
|
||||
the data to get to the actual IPMI data.
|
||||
|
||||
The slave_addrs specifies the IPMI address of the local BMC. This is
|
||||
usually 0x20 and the driver defaults to that, but in case it's not, it
|
||||
can be specified when the driver starts up.
|
||||
|
||||
The force_ipmid parameter forcefully enables (if set to 1) or disables
|
||||
(if set to 0) the kernel IPMI daemon. Normally this is auto-detected
|
||||
by the driver, but systems with broken interrupts might need an enable,
|
||||
or users that don't want the daemon (don't need the performance, don't
|
||||
want the CPU hit) can disable it.
|
||||
|
||||
If unload_when_empty is set to 1, the driver will be unloaded if it
|
||||
doesn't find any interfaces or all the interfaces fail to work. The
|
||||
default is one. Setting to 0 is useful with the hotmod, but is
|
||||
obviously only useful for modules.
|
||||
|
||||
When compiled into the kernel, the parameters can be specified on the
|
||||
kernel command line as::
|
||||
|
||||
ipmi_si.type=<type1>,<type2>...
|
||||
ipmi_si.ports=<port1>,<port2>... ipmi_si.addrs=<addr1>,<addr2>...
|
||||
ipmi_si.irqs=<irq1>,<irq2>...
|
||||
ipmi_si.regspacings=<sp1>,<sp2>,...
|
||||
ipmi_si.regsizes=<size1>,<size2>,...
|
||||
ipmi_si.regshifts=<shift1>,<shift2>,...
|
||||
ipmi_si.slave_addrs=<addr1>,<addr2>,...
|
||||
ipmi_si.force_kipmid=<enable1>,<enable2>,...
|
||||
ipmi_si.kipmid_max_busy_us=<ustime1>,<ustime2>,...
|
||||
|
||||
It works the same as the module parameters of the same names.
|
||||
|
||||
If your IPMI interface does not support interrupts and is a KCS or
|
||||
SMIC interface, the IPMI driver will start a kernel thread for the
|
||||
interface to help speed things up. This is a low-priority kernel
|
||||
thread that constantly polls the IPMI driver while an IPMI operation
|
||||
is in progress. The force_kipmid module parameter will all the user to
|
||||
force this thread on or off. If you force it off and don't have
|
||||
interrupts, the driver will run VERY slowly. Don't blame me,
|
||||
these interfaces suck.
|
||||
|
||||
Unfortunately, this thread can use a lot of CPU depending on the
|
||||
interface's performance. This can waste a lot of CPU and cause
|
||||
various issues with detecting idle CPU and using extra power. To
|
||||
avoid this, the kipmid_max_busy_us sets the maximum amount of time, in
|
||||
microseconds, that kipmid will spin before sleeping for a tick. This
|
||||
value sets a balance between performance and CPU waste and needs to be
|
||||
tuned to your needs. Maybe, someday, auto-tuning will be added, but
|
||||
that's not a simple thing and even the auto-tuning would need to be
|
||||
tuned to the user's desired performance.
|
||||
|
||||
The driver supports a hot add and remove of interfaces. This way,
|
||||
interfaces can be added or removed after the kernel is up and running.
|
||||
This is done using /sys/modules/ipmi_si/parameters/hotmod, which is a
|
||||
write-only parameter. You write a string to this interface. The string
|
||||
has the format::
|
||||
|
||||
<op1>[:op2[:op3...]]
|
||||
|
||||
The "op"s are::
|
||||
|
||||
add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]]
|
||||
|
||||
You can specify more than one interface on the line. The "opt"s are::
|
||||
|
||||
rsp=<regspacing>
|
||||
rsi=<regsize>
|
||||
rsh=<regshift>
|
||||
irq=<irq>
|
||||
ipmb=<ipmb slave addr>
|
||||
|
||||
and these have the same meanings as discussed above. Note that you
|
||||
can also use this on the kernel command line for a more compact format
|
||||
for specifying an interface. Note that when removing an interface,
|
||||
only the first three parameters (si type, address type, and address)
|
||||
are used for the comparison. Any options are ignored for removing.
|
||||
|
||||
The SMBus Driver (SSIF)
|
||||
-----------------------
|
||||
|
||||
The SMBus driver allows up to 4 SMBus devices to be configured in the
|
||||
system. By default, the driver will only register with something it
|
||||
finds in DMI or ACPI tables. You can change this
|
||||
at module load time (for a module) with::
|
||||
|
||||
modprobe ipmi_ssif.o
|
||||
addr=<i2caddr1>[,<i2caddr2>[,...]]
|
||||
adapter=<adapter1>[,<adapter2>[...]]
|
||||
dbg=<flags1>,<flags2>...
|
||||
slave_addrs=<addr1>,<addr2>,...
|
||||
tryacpi=[0|1] trydmi=[0|1]
|
||||
[dbg_probe=1]
|
||||
|
||||
The addresses are normal I2C addresses. The adapter is the string
|
||||
name of the adapter, as shown in /sys/class/i2c-adapter/i2c-<n>/name.
|
||||
It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring
|
||||
spaces, so if the name is "This is an I2C chip" you can say
|
||||
adapter_name=ThisisanI2cchip. This is because it's hard to pass in
|
||||
spaces in kernel parameters.
|
||||
|
||||
The debug flags are bit flags for each BMC found, they are:
|
||||
IPMI messages: 1, driver state: 2, timing: 4, I2C probe: 8
|
||||
|
||||
The tryxxx parameters can be used to disable detecting interfaces
|
||||
from various sources.
|
||||
|
||||
Setting dbg_probe to 1 will enable debugging of the probing and
|
||||
detection process for BMCs on the SMBusses.
|
||||
|
||||
The slave_addrs specifies the IPMI address of the local BMC. This is
|
||||
usually 0x20 and the driver defaults to that, but in case it's not, it
|
||||
can be specified when the driver starts up.
|
||||
|
||||
Discovering the IPMI compliant BMC on the SMBus can cause devices on
|
||||
the I2C bus to fail. The SMBus driver writes a "Get Device ID" IPMI
|
||||
message as a block write to the I2C bus and waits for a response.
|
||||
This action can be detrimental to some I2C devices. It is highly
|
||||
recommended that the known I2C address be given to the SMBus driver in
|
||||
the smb_addr parameter unless you have DMI or ACPI data to tell the
|
||||
driver what to use.
|
||||
|
||||
When compiled into the kernel, the addresses can be specified on the
|
||||
kernel command line as::
|
||||
|
||||
ipmb_ssif.addr=<i2caddr1>[,<i2caddr2>[...]]
|
||||
ipmi_ssif.adapter=<adapter1>[,<adapter2>[...]]
|
||||
ipmi_ssif.dbg=<flags1>[,<flags2>[...]]
|
||||
ipmi_ssif.dbg_probe=1
|
||||
ipmi_ssif.slave_addrs=<addr1>[,<addr2>[...]]
|
||||
ipmi_ssif.tryacpi=[0|1] ipmi_ssif.trydmi=[0|1]
|
||||
|
||||
These are the same options as on the module command line.
|
||||
|
||||
The I2C driver does not support non-blocking access or polling, so
|
||||
this driver cannod to IPMI panic events, extend the watchdog at panic
|
||||
time, or other panic-related IPMI functions without special kernel
|
||||
patches and driver modifications. You can get those at the openipmi
|
||||
web page.
|
||||
|
||||
The driver supports a hot add and remove of interfaces through the I2C
|
||||
sysfs interface.
|
||||
|
||||
Other Pieces
|
||||
------------
|
||||
|
||||
Get the detailed info related with the IPMI device
|
||||
--------------------------------------------------
|
||||
|
||||
Some users need more detailed information about a device, like where
|
||||
the address came from or the raw base device for the IPMI interface.
|
||||
You can use the IPMI smi_watcher to catch the IPMI interfaces as they
|
||||
come or go, and to grab the information, you can use the function
|
||||
ipmi_get_smi_info(), which returns the following structure::
|
||||
|
||||
struct ipmi_smi_info {
|
||||
enum ipmi_addr_src addr_src;
|
||||
struct device *dev;
|
||||
union {
|
||||
struct {
|
||||
void *acpi_handle;
|
||||
} acpi_info;
|
||||
} addr_info;
|
||||
};
|
||||
|
||||
Currently special info for only for SI_ACPI address sources is
|
||||
returned. Others may be added as necessary.
|
||||
|
||||
Note that the dev pointer is included in the above structure, and
|
||||
assuming ipmi_smi_get_info returns success, you must call put_device
|
||||
on the dev pointer.
|
||||
|
||||
|
||||
Watchdog
|
||||
--------
|
||||
|
||||
A watchdog timer is provided that implements the Linux-standard
|
||||
watchdog timer interface. It has three module parameters that can be
|
||||
used to control it::
|
||||
|
||||
modprobe ipmi_watchdog timeout=<t> pretimeout=<t> action=<action type>
|
||||
preaction=<preaction type> preop=<preop type> start_now=x
|
||||
nowayout=x ifnum_to_use=n panic_wdt_timeout=<t>
|
||||
|
||||
ifnum_to_use specifies which interface the watchdog timer should use.
|
||||
The default is -1, which means to pick the first one registered.
|
||||
|
||||
The timeout is the number of seconds to the action, and the pretimeout
|
||||
is the amount of seconds before the reset that the pre-timeout panic will
|
||||
occur (if pretimeout is zero, then pretimeout will not be enabled). Note
|
||||
that the pretimeout is the time before the final timeout. So if the
|
||||
timeout is 50 seconds and the pretimeout is 10 seconds, then the pretimeout
|
||||
will occur in 40 second (10 seconds before the timeout). The panic_wdt_timeout
|
||||
is the value of timeout which is set on kernel panic, in order to let actions
|
||||
such as kdump to occur during panic.
|
||||
|
||||
The action may be "reset", "power_cycle", or "power_off", and
|
||||
specifies what to do when the timer times out, and defaults to
|
||||
"reset".
|
||||
|
||||
The preaction may be "pre_smi" for an indication through the SMI
|
||||
interface, "pre_int" for an indication through the SMI with an
|
||||
interrupts, and "pre_nmi" for a NMI on a preaction. This is how
|
||||
the driver is informed of the pretimeout.
|
||||
|
||||
The preop may be set to "preop_none" for no operation on a pretimeout,
|
||||
"preop_panic" to set the preoperation to panic, or "preop_give_data"
|
||||
to provide data to read from the watchdog device when the pretimeout
|
||||
occurs. A "pre_nmi" setting CANNOT be used with "preop_give_data"
|
||||
because you can't do data operations from an NMI.
|
||||
|
||||
When preop is set to "preop_give_data", one byte comes ready to read
|
||||
on the device when the pretimeout occurs. Select and fasync work on
|
||||
the device, as well.
|
||||
|
||||
If start_now is set to 1, the watchdog timer will start running as
|
||||
soon as the driver is loaded.
|
||||
|
||||
If nowayout is set to 1, the watchdog timer will not stop when the
|
||||
watchdog device is closed. The default value of nowayout is true
|
||||
if the CONFIG_WATCHDOG_NOWAYOUT option is enabled, or false if not.
|
||||
|
||||
When compiled into the kernel, the kernel command line is available
|
||||
for configuring the watchdog::
|
||||
|
||||
ipmi_watchdog.timeout=<t> ipmi_watchdog.pretimeout=<t>
|
||||
ipmi_watchdog.action=<action type>
|
||||
ipmi_watchdog.preaction=<preaction type>
|
||||
ipmi_watchdog.preop=<preop type>
|
||||
ipmi_watchdog.start_now=x
|
||||
ipmi_watchdog.nowayout=x
|
||||
ipmi_watchdog.panic_wdt_timeout=<t>
|
||||
|
||||
The options are the same as the module parameter options.
|
||||
|
||||
The watchdog will panic and start a 120 second reset timeout if it
|
||||
gets a pre-action. During a panic or a reboot, the watchdog will
|
||||
start a 120 timer if it is running to make sure the reboot occurs.
|
||||
|
||||
Note that if you use the NMI preaction for the watchdog, you MUST NOT
|
||||
use the nmi watchdog. There is no reasonable way to tell if an NMI
|
||||
comes from the IPMI controller, so it must assume that if it gets an
|
||||
otherwise unhandled NMI, it must be from IPMI and it will panic
|
||||
immediately.
|
||||
|
||||
Once you open the watchdog timer, you must write a 'V' character to the
|
||||
device to close it, or the timer will not stop. This is a new semantic
|
||||
for the driver, but makes it consistent with the rest of the watchdog
|
||||
drivers in Linux.
|
||||
|
||||
|
||||
Panic Timeouts
|
||||
--------------
|
||||
|
||||
The OpenIPMI driver supports the ability to put semi-custom and custom
|
||||
events in the system event log if a panic occurs. if you enable the
|
||||
'Generate a panic event to all BMCs on a panic' option, you will get
|
||||
one event on a panic in a standard IPMI event format. If you enable
|
||||
the 'Generate OEM events containing the panic string' option, you will
|
||||
also get a bunch of OEM events holding the panic string.
|
||||
|
||||
|
||||
The field settings of the events are:
|
||||
|
||||
* Generator ID: 0x21 (kernel)
|
||||
* EvM Rev: 0x03 (this event is formatting in IPMI 1.0 format)
|
||||
* Sensor Type: 0x20 (OS critical stop sensor)
|
||||
* Sensor #: The first byte of the panic string (0 if no panic string)
|
||||
* Event Dir | Event Type: 0x6f (Assertion, sensor-specific event info)
|
||||
* Event Data 1: 0xa1 (Runtime stop in OEM bytes 2 and 3)
|
||||
* Event data 2: second byte of panic string
|
||||
* Event data 3: third byte of panic string
|
||||
|
||||
See the IPMI spec for the details of the event layout. This event is
|
||||
always sent to the local management controller. It will handle routing
|
||||
the message to the right place
|
||||
|
||||
Other OEM events have the following format:
|
||||
|
||||
* Record ID (bytes 0-1): Set by the SEL.
|
||||
* Record type (byte 2): 0xf0 (OEM non-timestamped)
|
||||
* byte 3: The slave address of the card saving the panic
|
||||
* byte 4: A sequence number (starting at zero)
|
||||
The rest of the bytes (11 bytes) are the panic string. If the panic string
|
||||
is longer than 11 bytes, multiple messages will be sent with increasing
|
||||
sequence numbers.
|
||||
|
||||
Because you cannot send OEM events using the standard interface, this
|
||||
function will attempt to find an SEL and add the events there. It
|
||||
will first query the capabilities of the local management controller.
|
||||
If it has an SEL, then they will be stored in the SEL of the local
|
||||
management controller. If not, and the local management controller is
|
||||
an event generator, the event receiver from the local management
|
||||
controller will be queried and the events sent to the SEL on that
|
||||
device. Otherwise, the events go nowhere since there is nowhere to
|
||||
send them.
|
||||
|
||||
|
||||
Poweroff
|
||||
--------
|
||||
|
||||
If the poweroff capability is selected, the IPMI driver will install
|
||||
a shutdown function into the standard poweroff function pointer. This
|
||||
is in the ipmi_poweroff module. When the system requests a powerdown,
|
||||
it will send the proper IPMI commands to do this. This is supported on
|
||||
several platforms.
|
||||
|
||||
There is a module parameter named "poweroff_powercycle" that may
|
||||
either be zero (do a power down) or non-zero (do a power cycle, power
|
||||
the system off, then power it on in a few seconds). Setting
|
||||
ipmi_poweroff.poweroff_control=x will do the same thing on the kernel
|
||||
command line. The parameter is also available via the proc filesystem
|
||||
in /proc/sys/dev/ipmi/poweroff_powercycle. Note that if the system
|
||||
does not support power cycling, it will always do the power off.
|
||||
|
||||
The "ifnum_to_use" parameter specifies which interface the poweroff
|
||||
code should use. The default is -1, which means to pick the first one
|
||||
registered.
|
||||
|
||||
Note that if you have ACPI enabled, the system will prefer using ACPI to
|
||||
power off.
|
||||
@@ -1,269 +0,0 @@
|
||||
===============================================
|
||||
The irq_domain interrupt number mapping library
|
||||
===============================================
|
||||
|
||||
The current design of the Linux kernel uses a single large number
|
||||
space where each separate IRQ source is assigned a different number.
|
||||
This is simple when there is only one interrupt controller, but in
|
||||
systems with multiple interrupt controllers the kernel must ensure
|
||||
that each one gets assigned non-overlapping allocations of Linux
|
||||
IRQ numbers.
|
||||
|
||||
The number of interrupt controllers registered as unique irqchips
|
||||
show a rising tendency: for example subdrivers of different kinds
|
||||
such as GPIO controllers avoid reimplementing identical callback
|
||||
mechanisms as the IRQ core system by modelling their interrupt
|
||||
handlers as irqchips, i.e. in effect cascading interrupt controllers.
|
||||
|
||||
Here the interrupt number loose all kind of correspondence to
|
||||
hardware interrupt numbers: whereas in the past, IRQ numbers could
|
||||
be chosen so they matched the hardware IRQ line into the root
|
||||
interrupt controller (i.e. the component actually fireing the
|
||||
interrupt line to the CPU) nowadays this number is just a number.
|
||||
|
||||
For this reason we need a mechanism to separate controller-local
|
||||
interrupt numbers, called hardware irq's, from Linux IRQ numbers.
|
||||
|
||||
The irq_alloc_desc*() and irq_free_desc*() APIs provide allocation of
|
||||
irq numbers, but they don't provide any support for reverse mapping of
|
||||
the controller-local IRQ (hwirq) number into the Linux IRQ number
|
||||
space.
|
||||
|
||||
The irq_domain library adds mapping between hwirq and IRQ numbers on
|
||||
top of the irq_alloc_desc*() API. An irq_domain to manage mapping is
|
||||
preferred over interrupt controller drivers open coding their own
|
||||
reverse mapping scheme.
|
||||
|
||||
irq_domain also implements translation from an abstract irq_fwspec
|
||||
structure to hwirq numbers (Device Tree and ACPI GSI so far), and can
|
||||
be easily extended to support other IRQ topology data sources.
|
||||
|
||||
irq_domain usage
|
||||
================
|
||||
|
||||
An interrupt controller driver creates and registers an irq_domain by
|
||||
calling one of the irq_domain_add_*() functions (each mapping method
|
||||
has a different allocator function, more on that later). The function
|
||||
will return a pointer to the irq_domain on success. The caller must
|
||||
provide the allocator function with an irq_domain_ops structure.
|
||||
|
||||
In most cases, the irq_domain will begin empty without any mappings
|
||||
between hwirq and IRQ numbers. Mappings are added to the irq_domain
|
||||
by calling irq_create_mapping() which accepts the irq_domain and a
|
||||
hwirq number as arguments. If a mapping for the hwirq doesn't already
|
||||
exist then it will allocate a new Linux irq_desc, associate it with
|
||||
the hwirq, and call the .map() callback so the driver can perform any
|
||||
required hardware setup.
|
||||
|
||||
When an interrupt is received, irq_find_mapping() function should
|
||||
be used to find the Linux IRQ number from the hwirq number.
|
||||
|
||||
The irq_create_mapping() function must be called *atleast once*
|
||||
before any call to irq_find_mapping(), lest the descriptor will not
|
||||
be allocated.
|
||||
|
||||
If the driver has the Linux IRQ number or the irq_data pointer, and
|
||||
needs to know the associated hwirq number (such as in the irq_chip
|
||||
callbacks) then it can be directly obtained from irq_data->hwirq.
|
||||
|
||||
Types of irq_domain mappings
|
||||
============================
|
||||
|
||||
There are several mechanisms available for reverse mapping from hwirq
|
||||
to Linux irq, and each mechanism uses a different allocation function.
|
||||
Which reverse map type should be used depends on the use case. Each
|
||||
of the reverse map types are described below:
|
||||
|
||||
Linear
|
||||
------
|
||||
|
||||
::
|
||||
|
||||
irq_domain_add_linear()
|
||||
irq_domain_create_linear()
|
||||
|
||||
The linear reverse map maintains a fixed size table indexed by the
|
||||
hwirq number. When a hwirq is mapped, an irq_desc is allocated for
|
||||
the hwirq, and the IRQ number is stored in the table.
|
||||
|
||||
The Linear map is a good choice when the maximum number of hwirqs is
|
||||
fixed and a relatively small number (~ < 256). The advantages of this
|
||||
map are fixed time lookup for IRQ numbers, and irq_descs are only
|
||||
allocated for in-use IRQs. The disadvantage is that the table must be
|
||||
as large as the largest possible hwirq number.
|
||||
|
||||
irq_domain_add_linear() and irq_domain_create_linear() are functionally
|
||||
equivalent, except for the first argument is different - the former
|
||||
accepts an Open Firmware specific 'struct device_node', while the latter
|
||||
accepts a more general abstraction 'struct fwnode_handle'.
|
||||
|
||||
The majority of drivers should use the linear map.
|
||||
|
||||
Tree
|
||||
----
|
||||
|
||||
::
|
||||
|
||||
irq_domain_add_tree()
|
||||
irq_domain_create_tree()
|
||||
|
||||
The irq_domain maintains a radix tree map from hwirq numbers to Linux
|
||||
IRQs. When an hwirq is mapped, an irq_desc is allocated and the
|
||||
hwirq is used as the lookup key for the radix tree.
|
||||
|
||||
The tree map is a good choice if the hwirq number can be very large
|
||||
since it doesn't need to allocate a table as large as the largest
|
||||
hwirq number. The disadvantage is that hwirq to IRQ number lookup is
|
||||
dependent on how many entries are in the table.
|
||||
|
||||
irq_domain_add_tree() and irq_domain_create_tree() are functionally
|
||||
equivalent, except for the first argument is different - the former
|
||||
accepts an Open Firmware specific 'struct device_node', while the latter
|
||||
accepts a more general abstraction 'struct fwnode_handle'.
|
||||
|
||||
Very few drivers should need this mapping.
|
||||
|
||||
No Map
|
||||
------
|
||||
|
||||
::
|
||||
|
||||
irq_domain_add_nomap()
|
||||
|
||||
The No Map mapping is to be used when the hwirq number is
|
||||
programmable in the hardware. In this case it is best to program the
|
||||
Linux IRQ number into the hardware itself so that no mapping is
|
||||
required. Calling irq_create_direct_mapping() will allocate a Linux
|
||||
IRQ number and call the .map() callback so that driver can program the
|
||||
Linux IRQ number into the hardware.
|
||||
|
||||
Most drivers cannot use this mapping.
|
||||
|
||||
Legacy
|
||||
------
|
||||
|
||||
::
|
||||
|
||||
irq_domain_add_simple()
|
||||
irq_domain_add_legacy()
|
||||
irq_domain_add_legacy_isa()
|
||||
|
||||
The Legacy mapping is a special case for drivers that already have a
|
||||
range of irq_descs allocated for the hwirqs. It is used when the
|
||||
driver cannot be immediately converted to use the linear mapping. For
|
||||
example, many embedded system board support files use a set of #defines
|
||||
for IRQ numbers that are passed to struct device registrations. In that
|
||||
case the Linux IRQ numbers cannot be dynamically assigned and the legacy
|
||||
mapping should be used.
|
||||
|
||||
The legacy map assumes a contiguous range of IRQ numbers has already
|
||||
been allocated for the controller and that the IRQ number can be
|
||||
calculated by adding a fixed offset to the hwirq number, and
|
||||
visa-versa. The disadvantage is that it requires the interrupt
|
||||
controller to manage IRQ allocations and it requires an irq_desc to be
|
||||
allocated for every hwirq, even if it is unused.
|
||||
|
||||
The legacy map should only be used if fixed IRQ mappings must be
|
||||
supported. For example, ISA controllers would use the legacy map for
|
||||
mapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ
|
||||
numbers.
|
||||
|
||||
Most users of legacy mappings should use irq_domain_add_simple() which
|
||||
will use a legacy domain only if an IRQ range is supplied by the
|
||||
system and will otherwise use a linear domain mapping. The semantics
|
||||
of this call are such that if an IRQ range is specified then
|
||||
descriptors will be allocated on-the-fly for it, and if no range is
|
||||
specified it will fall through to irq_domain_add_linear() which means
|
||||
*no* irq descriptors will be allocated.
|
||||
|
||||
A typical use case for simple domains is where an irqchip provider
|
||||
is supporting both dynamic and static IRQ assignments.
|
||||
|
||||
In order to avoid ending up in a situation where a linear domain is
|
||||
used and no descriptor gets allocated it is very important to make sure
|
||||
that the driver using the simple domain call irq_create_mapping()
|
||||
before any irq_find_mapping() since the latter will actually work
|
||||
for the static IRQ assignment case.
|
||||
|
||||
Hierarchy IRQ domain
|
||||
--------------------
|
||||
|
||||
On some architectures, there may be multiple interrupt controllers
|
||||
involved in delivering an interrupt from the device to the target CPU.
|
||||
Let's look at a typical interrupt delivering path on x86 platforms::
|
||||
|
||||
Device --> IOAPIC -> Interrupt remapping Controller -> Local APIC -> CPU
|
||||
|
||||
There are three interrupt controllers involved:
|
||||
|
||||
1) IOAPIC controller
|
||||
2) Interrupt remapping controller
|
||||
3) Local APIC controller
|
||||
|
||||
To support such a hardware topology and make software architecture match
|
||||
hardware architecture, an irq_domain data structure is built for each
|
||||
interrupt controller and those irq_domains are organized into hierarchy.
|
||||
When building irq_domain hierarchy, the irq_domain near to the device is
|
||||
child and the irq_domain near to CPU is parent. So a hierarchy structure
|
||||
as below will be built for the example above::
|
||||
|
||||
CPU Vector irq_domain (root irq_domain to manage CPU vectors)
|
||||
^
|
||||
|
|
||||
Interrupt Remapping irq_domain (manage irq_remapping entries)
|
||||
^
|
||||
|
|
||||
IOAPIC irq_domain (manage IOAPIC delivery entries/pins)
|
||||
|
||||
There are four major interfaces to use hierarchy irq_domain:
|
||||
|
||||
1) irq_domain_alloc_irqs(): allocate IRQ descriptors and interrupt
|
||||
controller related resources to deliver these interrupts.
|
||||
2) irq_domain_free_irqs(): free IRQ descriptors and interrupt controller
|
||||
related resources associated with these interrupts.
|
||||
3) irq_domain_activate_irq(): activate interrupt controller hardware to
|
||||
deliver the interrupt.
|
||||
4) irq_domain_deactivate_irq(): deactivate interrupt controller hardware
|
||||
to stop delivering the interrupt.
|
||||
|
||||
Following changes are needed to support hierarchy irq_domain:
|
||||
|
||||
1) a new field 'parent' is added to struct irq_domain; it's used to
|
||||
maintain irq_domain hierarchy information.
|
||||
2) a new field 'parent_data' is added to struct irq_data; it's used to
|
||||
build hierarchy irq_data to match hierarchy irq_domains. The irq_data
|
||||
is used to store irq_domain pointer and hardware irq number.
|
||||
3) new callbacks are added to struct irq_domain_ops to support hierarchy
|
||||
irq_domain operations.
|
||||
|
||||
With support of hierarchy irq_domain and hierarchy irq_data ready, an
|
||||
irq_domain structure is built for each interrupt controller, and an
|
||||
irq_data structure is allocated for each irq_domain associated with an
|
||||
IRQ. Now we could go one step further to support stacked(hierarchy)
|
||||
irq_chip. That is, an irq_chip is associated with each irq_data along
|
||||
the hierarchy. A child irq_chip may implement a required action by
|
||||
itself or by cooperating with its parent irq_chip.
|
||||
|
||||
With stacked irq_chip, interrupt controller driver only needs to deal
|
||||
with the hardware managed by itself and may ask for services from its
|
||||
parent irq_chip when needed. So we could achieve a much cleaner
|
||||
software architecture.
|
||||
|
||||
For an interrupt controller driver to support hierarchy irq_domain, it
|
||||
needs to:
|
||||
|
||||
1) Implement irq_domain_ops.alloc and irq_domain_ops.free
|
||||
2) Optionally implement irq_domain_ops.activate and
|
||||
irq_domain_ops.deactivate.
|
||||
3) Optionally implement an irq_chip to manage the interrupt controller
|
||||
hardware.
|
||||
4) No need to implement irq_domain_ops.map and irq_domain_ops.unmap,
|
||||
they are unused with hierarchy irq_domain.
|
||||
|
||||
Hierarchy irq_domain is in no way x86 specific, and is heavily used to
|
||||
support other architectures, such as ARM, ARM64 etc.
|
||||
|
||||
=== Debugging ===
|
||||
|
||||
Most of the internals of the IRQ subsystem are exposed in debugfs by
|
||||
turning CONFIG_GENERIC_IRQ_DEBUGFS on.
|
||||
+10
-6
@@ -55,15 +55,15 @@ I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
loop_cmd = $(echo-cmd) $(cmd_$(1)) || exit;
|
||||
|
||||
# $2 sphinx builder e.g. "html"
|
||||
# $3 name of the build subfolder / e.g. "media", used as:
|
||||
# $3 name of the build subfolder / e.g. "userspace-api/media", used as:
|
||||
# * dest folder relative to $(BUILDDIR) and
|
||||
# * cache folder relative to $(BUILDDIR)/.doctrees
|
||||
# $4 dest subfolder e.g. "man" for man pages at media/man
|
||||
# $4 dest subfolder e.g. "man" for man pages at userspace-api/media/man
|
||||
# $5 reST source folder relative to $(srctree)/$(src),
|
||||
# e.g. "media" for the linux-tv book-set at ./Documentation/media
|
||||
# e.g. "userspace-api/media" for the linux-tv book-set at ./Documentation/userspace-api/media
|
||||
|
||||
quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4)
|
||||
cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media $2 && \
|
||||
cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/userspace-api/media $2 && \
|
||||
PYTHONDONTWRITEBYTECODE=1 \
|
||||
BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \
|
||||
$(PYTHON) $(srctree)/scripts/jobserver-exec \
|
||||
@@ -98,7 +98,11 @@ else # HAVE_PDFLATEX
|
||||
|
||||
pdfdocs: latexdocs
|
||||
@$(srctree)/scripts/sphinx-pre-install --version-check
|
||||
$(foreach var,$(SPHINXDIRS), $(MAKE) PDFLATEX="$(PDFLATEX)" LATEXOPTS="$(LATEXOPTS)" -C $(BUILDDIR)/$(var)/latex || exit;)
|
||||
$(foreach var,$(SPHINXDIRS), \
|
||||
$(MAKE) PDFLATEX="$(PDFLATEX)" LATEXOPTS="$(LATEXOPTS)" -C $(BUILDDIR)/$(var)/latex || exit; \
|
||||
mkdir -p $(BUILDDIR)/$(var)/pdf; \
|
||||
mv $(subst .tex,.pdf,$(wildcard $(BUILDDIR)/$(var)/latex/*.tex)) $(BUILDDIR)/$(var)/pdf/; \
|
||||
)
|
||||
|
||||
endif # HAVE_PDFLATEX
|
||||
|
||||
@@ -120,7 +124,7 @@ refcheckdocs:
|
||||
|
||||
cleandocs:
|
||||
$(Q)rm -rf $(BUILDDIR)
|
||||
$(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media clean
|
||||
$(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/userspace-api/media clean
|
||||
|
||||
dochelp:
|
||||
@echo ' Linux kernel internal documentation in different formats from ReST:'
|
||||
|
||||
@@ -32,12 +32,13 @@ interrupt goes unhandled over time, they are tracked by the Linux kernel as
|
||||
Spurious Interrupts. The IRQ will be disabled by the Linux kernel after it
|
||||
reaches a specific count with the error "nobody cared". This disabled IRQ
|
||||
now prevents valid usage by an existing interrupt which may happen to share
|
||||
the IRQ line.
|
||||
the IRQ line::
|
||||
|
||||
irq 19: nobody cared (try booting with the "irqpoll" option)
|
||||
CPU: 0 PID: 2988 Comm: irq/34-nipalk Tainted: 4.14.87-rt49-02410-g4a640ec-dirty #1
|
||||
Hardware name: National Instruments NI PXIe-8880/NI PXIe-8880, BIOS 2.1.5f1 01/09/2020
|
||||
Call Trace:
|
||||
|
||||
<IRQ>
|
||||
? dump_stack+0x46/0x5e
|
||||
? __report_bad_irq+0x2e/0xb0
|
||||
@@ -85,15 +86,18 @@ Mitigations
|
||||
The mitigations take the form of PCI quirks. The preference has been to
|
||||
first identify and make use of a means to disable the routing to the PCH.
|
||||
In such a case a quirk to disable boot interrupt generation can be
|
||||
added.[1]
|
||||
added. [1]_
|
||||
|
||||
Intel® 6300ESB I/O Controller Hub
|
||||
Intel® 6300ESB I/O Controller Hub
|
||||
Alternate Base Address Register:
|
||||
BIE: Boot Interrupt Enable
|
||||
0 = Boot interrupt is enabled.
|
||||
1 = Boot interrupt is disabled.
|
||||
|
||||
Intel® Sandy Bridge through Sky Lake based Xeon servers:
|
||||
== ===========================
|
||||
0 Boot interrupt is enabled.
|
||||
1 Boot interrupt is disabled.
|
||||
== ===========================
|
||||
|
||||
Intel® Sandy Bridge through Sky Lake based Xeon servers:
|
||||
Coherent Interface Protocol Interrupt Control
|
||||
dis_intx_route2pch/dis_intx_route2ich/dis_intx_route2dmi2:
|
||||
When this bit is set. Local INTx messages received from the
|
||||
@@ -109,12 +113,12 @@ line by default. Therefore, on chipsets where this INTx routing cannot be
|
||||
disabled, the Linux kernel will reroute the valid interrupt to its legacy
|
||||
interrupt. This redirection of the handler will prevent the occurrence of
|
||||
the spurious interrupt detection which would ordinarily disable the IRQ
|
||||
line due to excessive unhandled counts.[2]
|
||||
line due to excessive unhandled counts. [2]_
|
||||
|
||||
The config option X86_REROUTE_FOR_BROKEN_BOOT_IRQS exists to enable (or
|
||||
disable) the redirection of the interrupt handler to the PCH interrupt
|
||||
line. The option can be overridden by either pci=ioapicreroute or
|
||||
pci=noioapicreroute.[3]
|
||||
pci=noioapicreroute. [3]_
|
||||
|
||||
|
||||
More Documentation
|
||||
@@ -127,19 +131,19 @@ into the evolution of its handling with chipsets.
|
||||
Example of disabling of the boot interrupt
|
||||
------------------------------------------
|
||||
|
||||
Intel® 6300ESB I/O Controller Hub (Document # 300641-004US)
|
||||
- Intel® 6300ESB I/O Controller Hub (Document # 300641-004US)
|
||||
5.7.3 Boot Interrupt
|
||||
https://www.intel.com/content/dam/doc/datasheet/6300esb-io-controller-hub-datasheet.pdf
|
||||
|
||||
Intel® Xeon® Processor E5-1600/2400/2600/4600 v3 Product Families
|
||||
Datasheet - Volume 2: Registers (Document # 330784-003)
|
||||
- Intel® Xeon® Processor E5-1600/2400/2600/4600 v3 Product Families
|
||||
Datasheet - Volume 2: Registers (Document # 330784-003)
|
||||
6.6.41 cipintrc Coherent Interface Protocol Interrupt Control
|
||||
https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/xeon-e5-v3-datasheet-vol-2.pdf
|
||||
|
||||
Example of handler rerouting
|
||||
----------------------------
|
||||
|
||||
Intel® 6700PXH 64-bit PCI Hub (Document # 302628)
|
||||
- Intel® 6700PXH 64-bit PCI Hub (Document # 302628)
|
||||
2.15.2 PCI Express Legacy INTx Support and Boot Interrupt
|
||||
https://www.intel.com/content/dam/doc/datasheet/6700pxh-64-bit-pci-hub-datasheet.pdf
|
||||
|
||||
@@ -150,6 +154,6 @@ Cheers,
|
||||
Sean V Kelley
|
||||
sean.v.kelley@linux.intel.com
|
||||
|
||||
[1] https://lore.kernel.org/r/12131949181903-git-send-email-sassmann@suse.de/
|
||||
[2] https://lore.kernel.org/r/12131949182094-git-send-email-sassmann@suse.de/
|
||||
[3] https://lore.kernel.org/r/487C8EA7.6020205@suse.de/
|
||||
.. [1] https://lore.kernel.org/r/12131949181903-git-send-email-sassmann@suse.de/
|
||||
.. [2] https://lore.kernel.org/r/12131949182094-git-send-email-sassmann@suse.de/
|
||||
.. [3] https://lore.kernel.org/r/487C8EA7.6020205@suse.de/
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
==========================
|
||||
PCI Test Endpoint Function
|
||||
==========================
|
||||
|
||||
name: Should be "pci_epf_test" to bind to the pci_epf_test driver.
|
||||
|
||||
Configurable Fields:
|
||||
|
||||
================ ===========================================================
|
||||
vendorid should be 0x104c
|
||||
deviceid should be 0xb500 for DRA74x and 0xb501 for DRA72x
|
||||
revid don't care
|
||||
progif_code don't care
|
||||
subclass_code don't care
|
||||
baseclass_code should be 0xff
|
||||
cache_line_size don't care
|
||||
subsys_vendor_id don't care
|
||||
subsys_id don't care
|
||||
interrupt_pin Should be 1 - INTA, 2 - INTB, 3 - INTC, 4 -INTD
|
||||
msi_interrupts Should be 1 to 32 depending on the number of MSI interrupts
|
||||
to test
|
||||
msix_interrupts Should be 1 to 2048 depending on the number of MSI-X
|
||||
interrupts to test
|
||||
================ ===========================================================
|
||||
@@ -1,19 +0,0 @@
|
||||
PCI TEST ENDPOINT FUNCTION
|
||||
|
||||
name: Should be "pci_epf_test" to bind to the pci_epf_test driver.
|
||||
|
||||
Configurable Fields:
|
||||
vendorid : should be 0x104c
|
||||
deviceid : should be 0xb500 for DRA74x and 0xb501 for DRA72x
|
||||
revid : don't care
|
||||
progif_code : don't care
|
||||
subclass_code : don't care
|
||||
baseclass_code : should be 0xff
|
||||
cache_line_size : don't care
|
||||
subsys_vendor_id : don't care
|
||||
subsys_id : don't care
|
||||
interrupt_pin : Should be 1 - INTA, 2 - INTB, 3 - INTC, 4 -INTD
|
||||
msi_interrupts : Should be 1 to 32 depending on the number of MSI interrupts
|
||||
to test
|
||||
msix_interrupts : Should be 1 to 2048 depending on the number of MSI-X
|
||||
interrupts to test
|
||||
@@ -11,3 +11,5 @@ PCI Endpoint Framework
|
||||
pci-endpoint-cfs
|
||||
pci-test-function
|
||||
pci-test-howto
|
||||
|
||||
function/binding/pci-test
|
||||
|
||||
@@ -24,7 +24,7 @@ Directory Structure
|
||||
|
||||
The pci_ep configfs has two directories at its root: controllers and
|
||||
functions. Every EPC device present in the system will have an entry in
|
||||
the *controllers* directory and and every EPF driver present in the system
|
||||
the *controllers* directory and every EPF driver present in the system
|
||||
will have an entry in the *functions* directory.
|
||||
::
|
||||
|
||||
|
||||
@@ -78,8 +78,8 @@ by the PCI controller driver.
|
||||
Cleanup the pci_epc_mem structure allocated during pci_epc_mem_init().
|
||||
|
||||
|
||||
APIs for the PCI Endpoint Function Driver
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
EPC APIs for the PCI Endpoint Function Driver
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This section lists the APIs that the PCI Endpoint core provides to be used
|
||||
by the PCI endpoint function driver.
|
||||
@@ -117,8 +117,8 @@ by the PCI endpoint function driver.
|
||||
The PCI endpoint function driver should use pci_epc_mem_free_addr() to
|
||||
free the memory space allocated using pci_epc_mem_alloc_addr().
|
||||
|
||||
Other APIs
|
||||
~~~~~~~~~~
|
||||
Other EPC APIs
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
There are other APIs provided by the EPC library. These are used for binding
|
||||
the EPF device with EPC device. pci-ep-cfs.c can be used as reference for
|
||||
@@ -160,8 +160,8 @@ PCI Endpoint Function(EPF) Library
|
||||
The EPF library provides APIs to be used by the function driver and the EPC
|
||||
library to provide endpoint mode functionality.
|
||||
|
||||
APIs for the PCI Endpoint Function Driver
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
EPF APIs for the PCI Endpoint Function Driver
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This section lists the APIs that the PCI Endpoint core provides to be used
|
||||
by the PCI endpoint function driver.
|
||||
@@ -204,8 +204,8 @@ by the PCI endpoint controller library.
|
||||
The PCI endpoint controller library invokes pci_epf_linkup() when the
|
||||
EPC device has established the connection to the host.
|
||||
|
||||
Other APIs
|
||||
~~~~~~~~~~
|
||||
Other EPF APIs
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
There are other APIs provided by the EPF library. These are used to notify
|
||||
the function driver when the EPF device is bound to the EPC device.
|
||||
@@ -214,7 +214,7 @@ pci-ep-cfs.c can be used as reference for using these APIs.
|
||||
* pci_epf_create()
|
||||
|
||||
Create a new PCI EPF device by passing the name of the PCI EPF device.
|
||||
This name will be used to bind the the EPF device to a EPF driver.
|
||||
This name will be used to bind the EPF device to a EPF driver.
|
||||
|
||||
* pci_epf_destroy()
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ This structure has the form::
|
||||
|
||||
struct pci_error_handlers
|
||||
{
|
||||
int (*error_detected)(struct pci_dev *dev, enum pci_channel_state);
|
||||
int (*error_detected)(struct pci_dev *dev, pci_channel_state_t);
|
||||
int (*mmio_enabled)(struct pci_dev *dev);
|
||||
int (*slot_reset)(struct pci_dev *dev);
|
||||
void (*resume)(struct pci_dev *dev);
|
||||
@@ -87,11 +87,11 @@ This structure has the form::
|
||||
|
||||
The possible channel states are::
|
||||
|
||||
enum pci_channel_state {
|
||||
typedef enum {
|
||||
pci_channel_io_normal, /* I/O channel is in normal state */
|
||||
pci_channel_io_frozen, /* I/O to channel is blocked */
|
||||
pci_channel_io_perm_failure, /* PCI card is dead */
|
||||
};
|
||||
} pci_channel_state_t;
|
||||
|
||||
Possible return values are::
|
||||
|
||||
@@ -248,7 +248,7 @@ STEP 4: Slot Reset
|
||||
------------------
|
||||
|
||||
In response to a return value of PCI_ERS_RESULT_NEED_RESET, the
|
||||
the platform will perform a slot reset on the requesting PCI device(s).
|
||||
platform will perform a slot reset on the requesting PCI device(s).
|
||||
The actual steps taken by a platform to perform a slot reset
|
||||
will be platform-dependent. Upon completion of slot reset, the
|
||||
platform will call the device slot_reset() callback.
|
||||
@@ -348,7 +348,7 @@ STEP 6: Permanent Failure
|
||||
-------------------------
|
||||
A "permanent failure" has occurred, and the platform cannot recover
|
||||
the device. The platform will call error_detected() with a
|
||||
pci_channel_state value of pci_channel_io_perm_failure.
|
||||
pci_channel_state_t value of pci_channel_io_perm_failure.
|
||||
|
||||
The device driver should, at this point, assume the worst. It should
|
||||
cancel all pending I/O, refuse all new I/O, returning -EIO to
|
||||
|
||||
@@ -17,7 +17,7 @@ PCI device drivers.
|
||||
A more complete resource is the third edition of "Linux Device Drivers"
|
||||
by Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman.
|
||||
LDD3 is available for free (under Creative Commons License) from:
|
||||
http://lwn.net/Kernel/LDD3/.
|
||||
https://lwn.net/Kernel/LDD3/.
|
||||
|
||||
However, keep in mind that all documents are subject to "bit rot".
|
||||
Refer to the source code if things are not working as described here.
|
||||
@@ -209,12 +209,12 @@ the PCI device by calling pci_enable_device(). This will:
|
||||
OS BUG: we don't check resource allocations before enabling those
|
||||
resources. The sequence would make more sense if we called
|
||||
pci_request_resources() before calling pci_enable_device().
|
||||
Currently, the device drivers can't detect the bug when when two
|
||||
Currently, the device drivers can't detect the bug when two
|
||||
devices have been allocated the same range. This is not a common
|
||||
problem and unlikely to get fixed soon.
|
||||
|
||||
This has been discussed before but not changed as of 2.6.19:
|
||||
http://lkml.org/lkml/2006/3/2/194
|
||||
https://lore.kernel.org/r/20060302180025.GC28895@flint.arm.linux.org.uk/
|
||||
|
||||
|
||||
pci_set_master() will enable DMA by setting the bus master bit
|
||||
@@ -265,7 +265,7 @@ Set the DMA mask size
|
||||
---------------------
|
||||
.. note::
|
||||
If anything below doesn't make sense, please refer to
|
||||
Documentation/DMA-API.txt. This section is just a reminder that
|
||||
:doc:`/core-api/dma-api`. This section is just a reminder that
|
||||
drivers need to indicate DMA capabilities of the device and is not
|
||||
an authoritative source for DMA interfaces.
|
||||
|
||||
@@ -291,7 +291,7 @@ Many 64-bit "PCI" devices (before PCI-X) and some PCI-X devices are
|
||||
Setup shared control data
|
||||
-------------------------
|
||||
Once the DMA masks are set, the driver can allocate "consistent" (a.k.a. shared)
|
||||
memory. See Documentation/DMA-API.txt for a full description of
|
||||
memory. See :doc:`/core-api/dma-api` for a full description of
|
||||
the DMA APIs. This section is just a reminder that it needs to be done
|
||||
before enabling DMA on the device.
|
||||
|
||||
@@ -421,7 +421,7 @@ owners if there is one.
|
||||
|
||||
Then clean up "consistent" buffers which contain the control data.
|
||||
|
||||
See Documentation/DMA-API.txt for details on unmapping interfaces.
|
||||
See :doc:`/core-api/dma-api` for details on unmapping interfaces.
|
||||
|
||||
|
||||
Unregister from other subsystems
|
||||
@@ -514,9 +514,8 @@ your driver if they're helpful, or just use plain hex constants.
|
||||
The device IDs are arbitrary hex numbers (vendor controlled) and normally used
|
||||
only in a single location, the pci_device_id table.
|
||||
|
||||
Please DO submit new vendor/device IDs to http://pci-ids.ucw.cz/.
|
||||
There are mirrors of the pci.ids file at http://pciids.sourceforge.net/
|
||||
and https://github.com/pciutils/pciids.
|
||||
Please DO submit new vendor/device IDs to https://pci-ids.ucw.cz/.
|
||||
There's a mirror of the pci.ids file at https://github.com/pciutils/pciids.
|
||||
|
||||
|
||||
Obsolete functions
|
||||
|
||||
@@ -463,7 +463,7 @@ again without disrupting RCU readers.
|
||||
This guarantee was only partially premeditated. DYNIX/ptx used an
|
||||
explicit memory barrier for publication, but had nothing resembling
|
||||
``rcu_dereference()`` for subscription, nor did it have anything
|
||||
resembling the ``smp_read_barrier_depends()`` that was later subsumed
|
||||
resembling the dependency-ordering barrier that was later subsumed
|
||||
into ``rcu_dereference()`` and later still into ``READ_ONCE()``. The
|
||||
need for these operations made itself known quite suddenly at a
|
||||
late-1990s meeting with the DEC Alpha architects, back in the days when
|
||||
@@ -1943,56 +1943,27 @@ invoked from a CPU-hotplug notifier.
|
||||
Scheduler and RCU
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
RCU depends on the scheduler, and the scheduler uses RCU to protect some
|
||||
of its data structures. The preemptible-RCU ``rcu_read_unlock()``
|
||||
implementation must therefore be written carefully to avoid deadlocks
|
||||
involving the scheduler's runqueue and priority-inheritance locks. In
|
||||
particular, ``rcu_read_unlock()`` must tolerate an interrupt where the
|
||||
interrupt handler invokes both ``rcu_read_lock()`` and
|
||||
``rcu_read_unlock()``. This possibility requires ``rcu_read_unlock()``
|
||||
to use negative nesting levels to avoid destructive recursion via
|
||||
interrupt handler's use of RCU.
|
||||
|
||||
This scheduler-RCU requirement came as a `complete
|
||||
surprise <https://lwn.net/Articles/453002/>`__.
|
||||
|
||||
As noted above, RCU makes use of kthreads, and it is necessary to avoid
|
||||
excessive CPU-time accumulation by these kthreads. This requirement was
|
||||
no surprise, but RCU's violation of it when running context-switch-heavy
|
||||
workloads when built with ``CONFIG_NO_HZ_FULL=y`` `did come as a
|
||||
surprise
|
||||
RCU makes use of kthreads, and it is necessary to avoid excessive CPU-time
|
||||
accumulation by these kthreads. This requirement was no surprise, but
|
||||
RCU's violation of it when running context-switch-heavy workloads when
|
||||
built with ``CONFIG_NO_HZ_FULL=y`` `did come as a surprise
|
||||
[PDF] <http://www.rdrop.com/users/paulmck/scalability/paper/BareMetal.2015.01.15b.pdf>`__.
|
||||
RCU has made good progress towards meeting this requirement, even for
|
||||
context-switch-heavy ``CONFIG_NO_HZ_FULL=y`` workloads, but there is
|
||||
room for further improvement.
|
||||
|
||||
It is forbidden to hold any of scheduler's runqueue or
|
||||
priority-inheritance spinlocks across an ``rcu_read_unlock()`` unless
|
||||
interrupts have been disabled across the entire RCU read-side critical
|
||||
section, that is, up to and including the matching ``rcu_read_lock()``.
|
||||
Violating this restriction can result in deadlocks involving these
|
||||
scheduler spinlocks. There was hope that this restriction might be
|
||||
lifted when interrupt-disabled calls to ``rcu_read_unlock()`` started
|
||||
deferring the reporting of the resulting RCU-preempt quiescent state
|
||||
until the end of the corresponding interrupts-disabled region.
|
||||
Unfortunately, timely reporting of the corresponding quiescent state to
|
||||
expedited grace periods requires a call to ``raise_softirq()``, which
|
||||
can acquire these scheduler spinlocks. In addition, real-time systems
|
||||
using RCU priority boosting need this restriction to remain in effect
|
||||
because deferred quiescent-state reporting would also defer deboosting,
|
||||
which in turn would degrade real-time latencies.
|
||||
There is no longer any prohibition against holding any of
|
||||
scheduler's runqueue or priority-inheritance spinlocks across an
|
||||
``rcu_read_unlock()``, even if interrupts and preemption were enabled
|
||||
somewhere within the corresponding RCU read-side critical section.
|
||||
Therefore, it is now perfectly legal to execute ``rcu_read_lock()``
|
||||
with preemption enabled, acquire one of the scheduler locks, and hold
|
||||
that lock across the matching ``rcu_read_unlock()``.
|
||||
|
||||
In theory, if a given RCU read-side critical section could be guaranteed
|
||||
to be less than one second in duration, holding a scheduler spinlock
|
||||
across that critical section's ``rcu_read_unlock()`` would require only
|
||||
that preemption be disabled across the entire RCU read-side critical
|
||||
section, not interrupts. Unfortunately, given the possibility of vCPU
|
||||
preemption, long-running interrupts, and so on, it is not possible in
|
||||
practice to guarantee that a given RCU read-side critical section will
|
||||
complete in less than one second. Therefore, as noted above, if
|
||||
scheduler spinlocks are held across a given call to
|
||||
``rcu_read_unlock()``, interrupts must be disabled across the entire RCU
|
||||
read-side critical section.
|
||||
Similarly, the RCU flavor consolidation has removed the need for negative
|
||||
nesting. The fact that interrupt-disabled regions of code act as RCU
|
||||
read-side critical sections implicitly avoids earlier issues that used
|
||||
to result in destructive recursion via interrupt handler's use of RCU.
|
||||
|
||||
Tracing and RCU
|
||||
~~~~~~~~~~~~~~~
|
||||
@@ -2612,7 +2583,12 @@ not work to have these markers in the trampoline itself, because there
|
||||
would need to be instructions following ``rcu_read_unlock()``. Although
|
||||
``synchronize_rcu()`` would guarantee that execution reached the
|
||||
``rcu_read_unlock()``, it would not be able to guarantee that execution
|
||||
had completely left the trampoline.
|
||||
had completely left the trampoline. Worse yet, in some situations
|
||||
the trampoline's protection must extend a few instructions *prior* to
|
||||
execution reaching the trampoline. For example, these few instructions
|
||||
might calculate the address of the trampoline, so that entering the
|
||||
trampoline would be pre-ordained a surprisingly long time before execution
|
||||
actually reached the trampoline itself.
|
||||
|
||||
The solution, in the form of `Tasks
|
||||
RCU <https://lwn.net/Articles/607117/>`__, is to have implicit read-side
|
||||
|
||||
@@ -0,0 +1,465 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
================================
|
||||
Review Checklist for RCU Patches
|
||||
================================
|
||||
|
||||
|
||||
This document contains a checklist for producing and reviewing patches
|
||||
that make use of RCU. Violating any of the rules listed below will
|
||||
result in the same sorts of problems that leaving out a locking primitive
|
||||
would cause. This list is based on experiences reviewing such patches
|
||||
over a rather long period of time, but improvements are always welcome!
|
||||
|
||||
0. Is RCU being applied to a read-mostly situation? If the data
|
||||
structure is updated more than about 10% of the time, then you
|
||||
should strongly consider some other approach, unless detailed
|
||||
performance measurements show that RCU is nonetheless the right
|
||||
tool for the job. Yes, RCU does reduce read-side overhead by
|
||||
increasing write-side overhead, which is exactly why normal uses
|
||||
of RCU will do much more reading than updating.
|
||||
|
||||
Another exception is where performance is not an issue, and RCU
|
||||
provides a simpler implementation. An example of this situation
|
||||
is the dynamic NMI code in the Linux 2.6 kernel, at least on
|
||||
architectures where NMIs are rare.
|
||||
|
||||
Yet another exception is where the low real-time latency of RCU's
|
||||
read-side primitives is critically important.
|
||||
|
||||
One final exception is where RCU readers are used to prevent
|
||||
the ABA problem (https://en.wikipedia.org/wiki/ABA_problem)
|
||||
for lockless updates. This does result in the mildly
|
||||
counter-intuitive situation where rcu_read_lock() and
|
||||
rcu_read_unlock() are used to protect updates, however, this
|
||||
approach provides the same potential simplifications that garbage
|
||||
collectors do.
|
||||
|
||||
1. Does the update code have proper mutual exclusion?
|
||||
|
||||
RCU does allow -readers- to run (almost) naked, but -writers- must
|
||||
still use some sort of mutual exclusion, such as:
|
||||
|
||||
a. locking,
|
||||
b. atomic operations, or
|
||||
c. restricting updates to a single task.
|
||||
|
||||
If you choose #b, be prepared to describe how you have handled
|
||||
memory barriers on weakly ordered machines (pretty much all of
|
||||
them -- even x86 allows later loads to be reordered to precede
|
||||
earlier stores), and be prepared to explain why this added
|
||||
complexity is worthwhile. If you choose #c, be prepared to
|
||||
explain how this single task does not become a major bottleneck on
|
||||
big multiprocessor machines (for example, if the task is updating
|
||||
information relating to itself that other tasks can read, there
|
||||
by definition can be no bottleneck). Note that the definition
|
||||
of "large" has changed significantly: Eight CPUs was "large"
|
||||
in the year 2000, but a hundred CPUs was unremarkable in 2017.
|
||||
|
||||
2. Do the RCU read-side critical sections make proper use of
|
||||
rcu_read_lock() and friends? These primitives are needed
|
||||
to prevent grace periods from ending prematurely, which
|
||||
could result in data being unceremoniously freed out from
|
||||
under your read-side code, which can greatly increase the
|
||||
actuarial risk of your kernel.
|
||||
|
||||
As a rough rule of thumb, any dereference of an RCU-protected
|
||||
pointer must be covered by rcu_read_lock(), rcu_read_lock_bh(),
|
||||
rcu_read_lock_sched(), or by the appropriate update-side lock.
|
||||
Disabling of preemption can serve as rcu_read_lock_sched(), but
|
||||
is less readable and prevents lockdep from detecting locking issues.
|
||||
|
||||
Letting RCU-protected pointers "leak" out of an RCU read-side
|
||||
critical section is every bid as bad as letting them leak out
|
||||
from under a lock. Unless, of course, you have arranged some
|
||||
other means of protection, such as a lock or a reference count
|
||||
-before- letting them out of the RCU read-side critical section.
|
||||
|
||||
3. Does the update code tolerate concurrent accesses?
|
||||
|
||||
The whole point of RCU is to permit readers to run without
|
||||
any locks or atomic operations. This means that readers will
|
||||
be running while updates are in progress. There are a number
|
||||
of ways to handle this concurrency, depending on the situation:
|
||||
|
||||
a. Use the RCU variants of the list and hlist update
|
||||
primitives to add, remove, and replace elements on
|
||||
an RCU-protected list. Alternatively, use the other
|
||||
RCU-protected data structures that have been added to
|
||||
the Linux kernel.
|
||||
|
||||
This is almost always the best approach.
|
||||
|
||||
b. Proceed as in (a) above, but also maintain per-element
|
||||
locks (that are acquired by both readers and writers)
|
||||
that guard per-element state. Of course, fields that
|
||||
the readers refrain from accessing can be guarded by
|
||||
some other lock acquired only by updaters, if desired.
|
||||
|
||||
This works quite well, also.
|
||||
|
||||
c. Make updates appear atomic to readers. For example,
|
||||
pointer updates to properly aligned fields will
|
||||
appear atomic, as will individual atomic primitives.
|
||||
Sequences of operations performed under a lock will -not-
|
||||
appear to be atomic to RCU readers, nor will sequences
|
||||
of multiple atomic primitives.
|
||||
|
||||
This can work, but is starting to get a bit tricky.
|
||||
|
||||
d. Carefully order the updates and the reads so that
|
||||
readers see valid data at all phases of the update.
|
||||
This is often more difficult than it sounds, especially
|
||||
given modern CPUs' tendency to reorder memory references.
|
||||
One must usually liberally sprinkle memory barriers
|
||||
(smp_wmb(), smp_rmb(), smp_mb()) through the code,
|
||||
making it difficult to understand and to test.
|
||||
|
||||
It is usually better to group the changing data into
|
||||
a separate structure, so that the change may be made
|
||||
to appear atomic by updating a pointer to reference
|
||||
a new structure containing updated values.
|
||||
|
||||
4. Weakly ordered CPUs pose special challenges. Almost all CPUs
|
||||
are weakly ordered -- even x86 CPUs allow later loads to be
|
||||
reordered to precede earlier stores. RCU code must take all of
|
||||
the following measures to prevent memory-corruption problems:
|
||||
|
||||
a. Readers must maintain proper ordering of their memory
|
||||
accesses. The rcu_dereference() primitive ensures that
|
||||
the CPU picks up the pointer before it picks up the data
|
||||
that the pointer points to. This really is necessary
|
||||
on Alpha CPUs. If you don't believe me, see:
|
||||
|
||||
http://www.openvms.compaq.com/wizard/wiz_2637.html
|
||||
|
||||
The rcu_dereference() primitive is also an excellent
|
||||
documentation aid, letting the person reading the
|
||||
code know exactly which pointers are protected by RCU.
|
||||
Please note that compilers can also reorder code, and
|
||||
they are becoming increasingly aggressive about doing
|
||||
just that. The rcu_dereference() primitive therefore also
|
||||
prevents destructive compiler optimizations. However,
|
||||
with a bit of devious creativity, it is possible to
|
||||
mishandle the return value from rcu_dereference().
|
||||
Please see rcu_dereference.txt in this directory for
|
||||
more information.
|
||||
|
||||
The rcu_dereference() primitive is used by the
|
||||
various "_rcu()" list-traversal primitives, such
|
||||
as the list_for_each_entry_rcu(). Note that it is
|
||||
perfectly legal (if redundant) for update-side code to
|
||||
use rcu_dereference() and the "_rcu()" list-traversal
|
||||
primitives. This is particularly useful in code that
|
||||
is common to readers and updaters. However, lockdep
|
||||
will complain if you access rcu_dereference() outside
|
||||
of an RCU read-side critical section. See lockdep.txt
|
||||
to learn what to do about this.
|
||||
|
||||
Of course, neither rcu_dereference() nor the "_rcu()"
|
||||
list-traversal primitives can substitute for a good
|
||||
concurrency design coordinating among multiple updaters.
|
||||
|
||||
b. If the list macros are being used, the list_add_tail_rcu()
|
||||
and list_add_rcu() primitives must be used in order
|
||||
to prevent weakly ordered machines from misordering
|
||||
structure initialization and pointer planting.
|
||||
Similarly, if the hlist macros are being used, the
|
||||
hlist_add_head_rcu() primitive is required.
|
||||
|
||||
c. If the list macros are being used, the list_del_rcu()
|
||||
primitive must be used to keep list_del()'s pointer
|
||||
poisoning from inflicting toxic effects on concurrent
|
||||
readers. Similarly, if the hlist macros are being used,
|
||||
the hlist_del_rcu() primitive is required.
|
||||
|
||||
The list_replace_rcu() and hlist_replace_rcu() primitives
|
||||
may be used to replace an old structure with a new one
|
||||
in their respective types of RCU-protected lists.
|
||||
|
||||
d. Rules similar to (4b) and (4c) apply to the "hlist_nulls"
|
||||
type of RCU-protected linked lists.
|
||||
|
||||
e. Updates must ensure that initialization of a given
|
||||
structure happens before pointers to that structure are
|
||||
publicized. Use the rcu_assign_pointer() primitive
|
||||
when publicizing a pointer to a structure that can
|
||||
be traversed by an RCU read-side critical section.
|
||||
|
||||
5. If call_rcu() or call_srcu() is used, the callback function will
|
||||
be called from softirq context. In particular, it cannot block.
|
||||
|
||||
6. Since synchronize_rcu() can block, it cannot be called
|
||||
from any sort of irq context. The same rule applies
|
||||
for synchronize_srcu(), synchronize_rcu_expedited(), and
|
||||
synchronize_srcu_expedited().
|
||||
|
||||
The expedited forms of these primitives have the same semantics
|
||||
as the non-expedited forms, but expediting is both expensive and
|
||||
(with the exception of synchronize_srcu_expedited()) unfriendly
|
||||
to real-time workloads. Use of the expedited primitives should
|
||||
be restricted to rare configuration-change operations that would
|
||||
not normally be undertaken while a real-time workload is running.
|
||||
However, real-time workloads can use rcupdate.rcu_normal kernel
|
||||
boot parameter to completely disable expedited grace periods,
|
||||
though this might have performance implications.
|
||||
|
||||
In particular, if you find yourself invoking one of the expedited
|
||||
primitives repeatedly in a loop, please do everyone a favor:
|
||||
Restructure your code so that it batches the updates, allowing
|
||||
a single non-expedited primitive to cover the entire batch.
|
||||
This will very likely be faster than the loop containing the
|
||||
expedited primitive, and will be much much easier on the rest
|
||||
of the system, especially to real-time workloads running on
|
||||
the rest of the system.
|
||||
|
||||
7. As of v4.20, a given kernel implements only one RCU flavor,
|
||||
which is RCU-sched for PREEMPT=n and RCU-preempt for PREEMPT=y.
|
||||
If the updater uses call_rcu() or synchronize_rcu(),
|
||||
then the corresponding readers my use rcu_read_lock() and
|
||||
rcu_read_unlock(), rcu_read_lock_bh() and rcu_read_unlock_bh(),
|
||||
or any pair of primitives that disables and re-enables preemption,
|
||||
for example, rcu_read_lock_sched() and rcu_read_unlock_sched().
|
||||
If the updater uses synchronize_srcu() or call_srcu(),
|
||||
then the corresponding readers must use srcu_read_lock() and
|
||||
srcu_read_unlock(), and with the same srcu_struct. The rules for
|
||||
the expedited primitives are the same as for their non-expedited
|
||||
counterparts. Mixing things up will result in confusion and
|
||||
broken kernels, and has even resulted in an exploitable security
|
||||
issue.
|
||||
|
||||
One exception to this rule: rcu_read_lock() and rcu_read_unlock()
|
||||
may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh()
|
||||
in cases where local bottom halves are already known to be
|
||||
disabled, for example, in irq or softirq context. Commenting
|
||||
such cases is a must, of course! And the jury is still out on
|
||||
whether the increased speed is worth it.
|
||||
|
||||
8. Although synchronize_rcu() is slower than is call_rcu(), it
|
||||
usually results in simpler code. So, unless update performance is
|
||||
critically important, the updaters cannot block, or the latency of
|
||||
synchronize_rcu() is visible from userspace, synchronize_rcu()
|
||||
should be used in preference to call_rcu(). Furthermore,
|
||||
kfree_rcu() usually results in even simpler code than does
|
||||
synchronize_rcu() without synchronize_rcu()'s multi-millisecond
|
||||
latency. So please take advantage of kfree_rcu()'s "fire and
|
||||
forget" memory-freeing capabilities where it applies.
|
||||
|
||||
An especially important property of the synchronize_rcu()
|
||||
primitive is that it automatically self-limits: if grace periods
|
||||
are delayed for whatever reason, then the synchronize_rcu()
|
||||
primitive will correspondingly delay updates. In contrast,
|
||||
code using call_rcu() should explicitly limit update rate in
|
||||
cases where grace periods are delayed, as failing to do so can
|
||||
result in excessive realtime latencies or even OOM conditions.
|
||||
|
||||
Ways of gaining this self-limiting property when using call_rcu()
|
||||
include:
|
||||
|
||||
a. Keeping a count of the number of data-structure elements
|
||||
used by the RCU-protected data structure, including
|
||||
those waiting for a grace period to elapse. Enforce a
|
||||
limit on this number, stalling updates as needed to allow
|
||||
previously deferred frees to complete. Alternatively,
|
||||
limit only the number awaiting deferred free rather than
|
||||
the total number of elements.
|
||||
|
||||
One way to stall the updates is to acquire the update-side
|
||||
mutex. (Don't try this with a spinlock -- other CPUs
|
||||
spinning on the lock could prevent the grace period
|
||||
from ever ending.) Another way to stall the updates
|
||||
is for the updates to use a wrapper function around
|
||||
the memory allocator, so that this wrapper function
|
||||
simulates OOM when there is too much memory awaiting an
|
||||
RCU grace period. There are of course many other
|
||||
variations on this theme.
|
||||
|
||||
b. Limiting update rate. For example, if updates occur only
|
||||
once per hour, then no explicit rate limiting is
|
||||
required, unless your system is already badly broken.
|
||||
Older versions of the dcache subsystem take this approach,
|
||||
guarding updates with a global lock, limiting their rate.
|
||||
|
||||
c. Trusted update -- if updates can only be done manually by
|
||||
superuser or some other trusted user, then it might not
|
||||
be necessary to automatically limit them. The theory
|
||||
here is that superuser already has lots of ways to crash
|
||||
the machine.
|
||||
|
||||
d. Periodically invoke synchronize_rcu(), permitting a limited
|
||||
number of updates per grace period.
|
||||
|
||||
The same cautions apply to call_srcu() and kfree_rcu().
|
||||
|
||||
Note that although these primitives do take action to avoid memory
|
||||
exhaustion when any given CPU has too many callbacks, a determined
|
||||
user could still exhaust memory. This is especially the case
|
||||
if a system with a large number of CPUs has been configured to
|
||||
offload all of its RCU callbacks onto a single CPU, or if the
|
||||
system has relatively little free memory.
|
||||
|
||||
9. All RCU list-traversal primitives, which include
|
||||
rcu_dereference(), list_for_each_entry_rcu(), and
|
||||
list_for_each_safe_rcu(), must be either within an RCU read-side
|
||||
critical section or must be protected by appropriate update-side
|
||||
locks. RCU read-side critical sections are delimited by
|
||||
rcu_read_lock() and rcu_read_unlock(), or by similar primitives
|
||||
such as rcu_read_lock_bh() and rcu_read_unlock_bh(), in which
|
||||
case the matching rcu_dereference() primitive must be used in
|
||||
order to keep lockdep happy, in this case, rcu_dereference_bh().
|
||||
|
||||
The reason that it is permissible to use RCU list-traversal
|
||||
primitives when the update-side lock is held is that doing so
|
||||
can be quite helpful in reducing code bloat when common code is
|
||||
shared between readers and updaters. Additional primitives
|
||||
are provided for this case, as discussed in lockdep.txt.
|
||||
|
||||
10. Conversely, if you are in an RCU read-side critical section,
|
||||
and you don't hold the appropriate update-side lock, you -must-
|
||||
use the "_rcu()" variants of the list macros. Failing to do so
|
||||
will break Alpha, cause aggressive compilers to generate bad code,
|
||||
and confuse people trying to read your code.
|
||||
|
||||
11. Any lock acquired by an RCU callback must be acquired elsewhere
|
||||
with softirq disabled, e.g., via spin_lock_irqsave(),
|
||||
spin_lock_bh(), etc. Failing to disable softirq on a given
|
||||
acquisition of that lock will result in deadlock as soon as
|
||||
the RCU softirq handler happens to run your RCU callback while
|
||||
interrupting that acquisition's critical section.
|
||||
|
||||
12. RCU callbacks can be and are executed in parallel. In many cases,
|
||||
the callback code simply wrappers around kfree(), so that this
|
||||
is not an issue (or, more accurately, to the extent that it is
|
||||
an issue, the memory-allocator locking handles it). However,
|
||||
if the callbacks do manipulate a shared data structure, they
|
||||
must use whatever locking or other synchronization is required
|
||||
to safely access and/or modify that data structure.
|
||||
|
||||
Do not assume that RCU callbacks will be executed on the same
|
||||
CPU that executed the corresponding call_rcu() or call_srcu().
|
||||
For example, if a given CPU goes offline while having an RCU
|
||||
callback pending, then that RCU callback will execute on some
|
||||
surviving CPU. (If this was not the case, a self-spawning RCU
|
||||
callback would prevent the victim CPU from ever going offline.)
|
||||
Furthermore, CPUs designated by rcu_nocbs= might well -always-
|
||||
have their RCU callbacks executed on some other CPUs, in fact,
|
||||
for some real-time workloads, this is the whole point of using
|
||||
the rcu_nocbs= kernel boot parameter.
|
||||
|
||||
13. Unlike other forms of RCU, it -is- permissible to block in an
|
||||
SRCU read-side critical section (demarked by srcu_read_lock()
|
||||
and srcu_read_unlock()), hence the "SRCU": "sleepable RCU".
|
||||
Please note that if you don't need to sleep in read-side critical
|
||||
sections, you should be using RCU rather than SRCU, because RCU
|
||||
is almost always faster and easier to use than is SRCU.
|
||||
|
||||
Also unlike other forms of RCU, explicit initialization and
|
||||
cleanup is required either at build time via DEFINE_SRCU()
|
||||
or DEFINE_STATIC_SRCU() or at runtime via init_srcu_struct()
|
||||
and cleanup_srcu_struct(). These last two are passed a
|
||||
"struct srcu_struct" that defines the scope of a given
|
||||
SRCU domain. Once initialized, the srcu_struct is passed
|
||||
to srcu_read_lock(), srcu_read_unlock() synchronize_srcu(),
|
||||
synchronize_srcu_expedited(), and call_srcu(). A given
|
||||
synchronize_srcu() waits only for SRCU read-side critical
|
||||
sections governed by srcu_read_lock() and srcu_read_unlock()
|
||||
calls that have been passed the same srcu_struct. This property
|
||||
is what makes sleeping read-side critical sections tolerable --
|
||||
a given subsystem delays only its own updates, not those of other
|
||||
subsystems using SRCU. Therefore, SRCU is less prone to OOM the
|
||||
system than RCU would be if RCU's read-side critical sections
|
||||
were permitted to sleep.
|
||||
|
||||
The ability to sleep in read-side critical sections does not
|
||||
come for free. First, corresponding srcu_read_lock() and
|
||||
srcu_read_unlock() calls must be passed the same srcu_struct.
|
||||
Second, grace-period-detection overhead is amortized only
|
||||
over those updates sharing a given srcu_struct, rather than
|
||||
being globally amortized as they are for other forms of RCU.
|
||||
Therefore, SRCU should be used in preference to rw_semaphore
|
||||
only in extremely read-intensive situations, or in situations
|
||||
requiring SRCU's read-side deadlock immunity or low read-side
|
||||
realtime latency. You should also consider percpu_rw_semaphore
|
||||
when you need lightweight readers.
|
||||
|
||||
SRCU's expedited primitive (synchronize_srcu_expedited())
|
||||
never sends IPIs to other CPUs, so it is easier on
|
||||
real-time workloads than is synchronize_rcu_expedited().
|
||||
|
||||
Note that rcu_assign_pointer() relates to SRCU just as it does to
|
||||
other forms of RCU, but instead of rcu_dereference() you should
|
||||
use srcu_dereference() in order to avoid lockdep splats.
|
||||
|
||||
14. The whole point of call_rcu(), synchronize_rcu(), and friends
|
||||
is to wait until all pre-existing readers have finished before
|
||||
carrying out some otherwise-destructive operation. It is
|
||||
therefore critically important to -first- remove any path
|
||||
that readers can follow that could be affected by the
|
||||
destructive operation, and -only- -then- invoke call_rcu(),
|
||||
synchronize_rcu(), or friends.
|
||||
|
||||
Because these primitives only wait for pre-existing readers, it
|
||||
is the caller's responsibility to guarantee that any subsequent
|
||||
readers will execute safely.
|
||||
|
||||
15. The various RCU read-side primitives do -not- necessarily contain
|
||||
memory barriers. You should therefore plan for the CPU
|
||||
and the compiler to freely reorder code into and out of RCU
|
||||
read-side critical sections. It is the responsibility of the
|
||||
RCU update-side primitives to deal with this.
|
||||
|
||||
For SRCU readers, you can use smp_mb__after_srcu_read_unlock()
|
||||
immediately after an srcu_read_unlock() to get a full barrier.
|
||||
|
||||
16. Use CONFIG_PROVE_LOCKING, CONFIG_DEBUG_OBJECTS_RCU_HEAD, and the
|
||||
__rcu sparse checks to validate your RCU code. These can help
|
||||
find problems as follows:
|
||||
|
||||
CONFIG_PROVE_LOCKING:
|
||||
check that accesses to RCU-protected data
|
||||
structures are carried out under the proper RCU
|
||||
read-side critical section, while holding the right
|
||||
combination of locks, or whatever other conditions
|
||||
are appropriate.
|
||||
|
||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD:
|
||||
check that you don't pass the
|
||||
same object to call_rcu() (or friends) before an RCU
|
||||
grace period has elapsed since the last time that you
|
||||
passed that same object to call_rcu() (or friends).
|
||||
|
||||
__rcu sparse checks:
|
||||
tag the pointer to the RCU-protected data
|
||||
structure with __rcu, and sparse will warn you if you
|
||||
access that pointer without the services of one of the
|
||||
variants of rcu_dereference().
|
||||
|
||||
These debugging aids can help you find problems that are
|
||||
otherwise extremely difficult to spot.
|
||||
|
||||
17. If you register a callback using call_rcu() or call_srcu(), and
|
||||
pass in a function defined within a loadable module, then it in
|
||||
necessary to wait for all pending callbacks to be invoked after
|
||||
the last invocation and before unloading that module. Note that
|
||||
it is absolutely -not- sufficient to wait for a grace period!
|
||||
The current (say) synchronize_rcu() implementation is -not-
|
||||
guaranteed to wait for callbacks registered on other CPUs.
|
||||
Or even on the current CPU if that CPU recently went offline
|
||||
and came back online.
|
||||
|
||||
You instead need to use one of the barrier functions:
|
||||
|
||||
- call_rcu() -> rcu_barrier()
|
||||
- call_srcu() -> srcu_barrier()
|
||||
|
||||
However, these barrier functions are absolutely -not- guaranteed
|
||||
to wait for a grace period. In fact, if there are no call_rcu()
|
||||
callbacks waiting anywhere in the system, rcu_barrier() is within
|
||||
its rights to return immediately.
|
||||
|
||||
So if you need to wait for both an RCU grace period and for
|
||||
all pre-existing call_rcu() callbacks, you will need to execute
|
||||
both rcu_barrier() and synchronize_rcu(), if necessary, using
|
||||
something like workqueues to to execute them concurrently.
|
||||
|
||||
See rcubarrier.txt for more information.
|
||||
@@ -1,458 +0,0 @@
|
||||
Review Checklist for RCU Patches
|
||||
|
||||
|
||||
This document contains a checklist for producing and reviewing patches
|
||||
that make use of RCU. Violating any of the rules listed below will
|
||||
result in the same sorts of problems that leaving out a locking primitive
|
||||
would cause. This list is based on experiences reviewing such patches
|
||||
over a rather long period of time, but improvements are always welcome!
|
||||
|
||||
0. Is RCU being applied to a read-mostly situation? If the data
|
||||
structure is updated more than about 10% of the time, then you
|
||||
should strongly consider some other approach, unless detailed
|
||||
performance measurements show that RCU is nonetheless the right
|
||||
tool for the job. Yes, RCU does reduce read-side overhead by
|
||||
increasing write-side overhead, which is exactly why normal uses
|
||||
of RCU will do much more reading than updating.
|
||||
|
||||
Another exception is where performance is not an issue, and RCU
|
||||
provides a simpler implementation. An example of this situation
|
||||
is the dynamic NMI code in the Linux 2.6 kernel, at least on
|
||||
architectures where NMIs are rare.
|
||||
|
||||
Yet another exception is where the low real-time latency of RCU's
|
||||
read-side primitives is critically important.
|
||||
|
||||
One final exception is where RCU readers are used to prevent
|
||||
the ABA problem (https://en.wikipedia.org/wiki/ABA_problem)
|
||||
for lockless updates. This does result in the mildly
|
||||
counter-intuitive situation where rcu_read_lock() and
|
||||
rcu_read_unlock() are used to protect updates, however, this
|
||||
approach provides the same potential simplifications that garbage
|
||||
collectors do.
|
||||
|
||||
1. Does the update code have proper mutual exclusion?
|
||||
|
||||
RCU does allow -readers- to run (almost) naked, but -writers- must
|
||||
still use some sort of mutual exclusion, such as:
|
||||
|
||||
a. locking,
|
||||
b. atomic operations, or
|
||||
c. restricting updates to a single task.
|
||||
|
||||
If you choose #b, be prepared to describe how you have handled
|
||||
memory barriers on weakly ordered machines (pretty much all of
|
||||
them -- even x86 allows later loads to be reordered to precede
|
||||
earlier stores), and be prepared to explain why this added
|
||||
complexity is worthwhile. If you choose #c, be prepared to
|
||||
explain how this single task does not become a major bottleneck on
|
||||
big multiprocessor machines (for example, if the task is updating
|
||||
information relating to itself that other tasks can read, there
|
||||
by definition can be no bottleneck). Note that the definition
|
||||
of "large" has changed significantly: Eight CPUs was "large"
|
||||
in the year 2000, but a hundred CPUs was unremarkable in 2017.
|
||||
|
||||
2. Do the RCU read-side critical sections make proper use of
|
||||
rcu_read_lock() and friends? These primitives are needed
|
||||
to prevent grace periods from ending prematurely, which
|
||||
could result in data being unceremoniously freed out from
|
||||
under your read-side code, which can greatly increase the
|
||||
actuarial risk of your kernel.
|
||||
|
||||
As a rough rule of thumb, any dereference of an RCU-protected
|
||||
pointer must be covered by rcu_read_lock(), rcu_read_lock_bh(),
|
||||
rcu_read_lock_sched(), or by the appropriate update-side lock.
|
||||
Disabling of preemption can serve as rcu_read_lock_sched(), but
|
||||
is less readable and prevents lockdep from detecting locking issues.
|
||||
|
||||
Letting RCU-protected pointers "leak" out of an RCU read-side
|
||||
critical section is every bid as bad as letting them leak out
|
||||
from under a lock. Unless, of course, you have arranged some
|
||||
other means of protection, such as a lock or a reference count
|
||||
-before- letting them out of the RCU read-side critical section.
|
||||
|
||||
3. Does the update code tolerate concurrent accesses?
|
||||
|
||||
The whole point of RCU is to permit readers to run without
|
||||
any locks or atomic operations. This means that readers will
|
||||
be running while updates are in progress. There are a number
|
||||
of ways to handle this concurrency, depending on the situation:
|
||||
|
||||
a. Use the RCU variants of the list and hlist update
|
||||
primitives to add, remove, and replace elements on
|
||||
an RCU-protected list. Alternatively, use the other
|
||||
RCU-protected data structures that have been added to
|
||||
the Linux kernel.
|
||||
|
||||
This is almost always the best approach.
|
||||
|
||||
b. Proceed as in (a) above, but also maintain per-element
|
||||
locks (that are acquired by both readers and writers)
|
||||
that guard per-element state. Of course, fields that
|
||||
the readers refrain from accessing can be guarded by
|
||||
some other lock acquired only by updaters, if desired.
|
||||
|
||||
This works quite well, also.
|
||||
|
||||
c. Make updates appear atomic to readers. For example,
|
||||
pointer updates to properly aligned fields will
|
||||
appear atomic, as will individual atomic primitives.
|
||||
Sequences of operations performed under a lock will -not-
|
||||
appear to be atomic to RCU readers, nor will sequences
|
||||
of multiple atomic primitives.
|
||||
|
||||
This can work, but is starting to get a bit tricky.
|
||||
|
||||
d. Carefully order the updates and the reads so that
|
||||
readers see valid data at all phases of the update.
|
||||
This is often more difficult than it sounds, especially
|
||||
given modern CPUs' tendency to reorder memory references.
|
||||
One must usually liberally sprinkle memory barriers
|
||||
(smp_wmb(), smp_rmb(), smp_mb()) through the code,
|
||||
making it difficult to understand and to test.
|
||||
|
||||
It is usually better to group the changing data into
|
||||
a separate structure, so that the change may be made
|
||||
to appear atomic by updating a pointer to reference
|
||||
a new structure containing updated values.
|
||||
|
||||
4. Weakly ordered CPUs pose special challenges. Almost all CPUs
|
||||
are weakly ordered -- even x86 CPUs allow later loads to be
|
||||
reordered to precede earlier stores. RCU code must take all of
|
||||
the following measures to prevent memory-corruption problems:
|
||||
|
||||
a. Readers must maintain proper ordering of their memory
|
||||
accesses. The rcu_dereference() primitive ensures that
|
||||
the CPU picks up the pointer before it picks up the data
|
||||
that the pointer points to. This really is necessary
|
||||
on Alpha CPUs. If you don't believe me, see:
|
||||
|
||||
http://www.openvms.compaq.com/wizard/wiz_2637.html
|
||||
|
||||
The rcu_dereference() primitive is also an excellent
|
||||
documentation aid, letting the person reading the
|
||||
code know exactly which pointers are protected by RCU.
|
||||
Please note that compilers can also reorder code, and
|
||||
they are becoming increasingly aggressive about doing
|
||||
just that. The rcu_dereference() primitive therefore also
|
||||
prevents destructive compiler optimizations. However,
|
||||
with a bit of devious creativity, it is possible to
|
||||
mishandle the return value from rcu_dereference().
|
||||
Please see rcu_dereference.txt in this directory for
|
||||
more information.
|
||||
|
||||
The rcu_dereference() primitive is used by the
|
||||
various "_rcu()" list-traversal primitives, such
|
||||
as the list_for_each_entry_rcu(). Note that it is
|
||||
perfectly legal (if redundant) for update-side code to
|
||||
use rcu_dereference() and the "_rcu()" list-traversal
|
||||
primitives. This is particularly useful in code that
|
||||
is common to readers and updaters. However, lockdep
|
||||
will complain if you access rcu_dereference() outside
|
||||
of an RCU read-side critical section. See lockdep.txt
|
||||
to learn what to do about this.
|
||||
|
||||
Of course, neither rcu_dereference() nor the "_rcu()"
|
||||
list-traversal primitives can substitute for a good
|
||||
concurrency design coordinating among multiple updaters.
|
||||
|
||||
b. If the list macros are being used, the list_add_tail_rcu()
|
||||
and list_add_rcu() primitives must be used in order
|
||||
to prevent weakly ordered machines from misordering
|
||||
structure initialization and pointer planting.
|
||||
Similarly, if the hlist macros are being used, the
|
||||
hlist_add_head_rcu() primitive is required.
|
||||
|
||||
c. If the list macros are being used, the list_del_rcu()
|
||||
primitive must be used to keep list_del()'s pointer
|
||||
poisoning from inflicting toxic effects on concurrent
|
||||
readers. Similarly, if the hlist macros are being used,
|
||||
the hlist_del_rcu() primitive is required.
|
||||
|
||||
The list_replace_rcu() and hlist_replace_rcu() primitives
|
||||
may be used to replace an old structure with a new one
|
||||
in their respective types of RCU-protected lists.
|
||||
|
||||
d. Rules similar to (4b) and (4c) apply to the "hlist_nulls"
|
||||
type of RCU-protected linked lists.
|
||||
|
||||
e. Updates must ensure that initialization of a given
|
||||
structure happens before pointers to that structure are
|
||||
publicized. Use the rcu_assign_pointer() primitive
|
||||
when publicizing a pointer to a structure that can
|
||||
be traversed by an RCU read-side critical section.
|
||||
|
||||
5. If call_rcu() or call_srcu() is used, the callback function will
|
||||
be called from softirq context. In particular, it cannot block.
|
||||
|
||||
6. Since synchronize_rcu() can block, it cannot be called
|
||||
from any sort of irq context. The same rule applies
|
||||
for synchronize_srcu(), synchronize_rcu_expedited(), and
|
||||
synchronize_srcu_expedited().
|
||||
|
||||
The expedited forms of these primitives have the same semantics
|
||||
as the non-expedited forms, but expediting is both expensive and
|
||||
(with the exception of synchronize_srcu_expedited()) unfriendly
|
||||
to real-time workloads. Use of the expedited primitives should
|
||||
be restricted to rare configuration-change operations that would
|
||||
not normally be undertaken while a real-time workload is running.
|
||||
However, real-time workloads can use rcupdate.rcu_normal kernel
|
||||
boot parameter to completely disable expedited grace periods,
|
||||
though this might have performance implications.
|
||||
|
||||
In particular, if you find yourself invoking one of the expedited
|
||||
primitives repeatedly in a loop, please do everyone a favor:
|
||||
Restructure your code so that it batches the updates, allowing
|
||||
a single non-expedited primitive to cover the entire batch.
|
||||
This will very likely be faster than the loop containing the
|
||||
expedited primitive, and will be much much easier on the rest
|
||||
of the system, especially to real-time workloads running on
|
||||
the rest of the system.
|
||||
|
||||
7. As of v4.20, a given kernel implements only one RCU flavor,
|
||||
which is RCU-sched for PREEMPT=n and RCU-preempt for PREEMPT=y.
|
||||
If the updater uses call_rcu() or synchronize_rcu(),
|
||||
then the corresponding readers my use rcu_read_lock() and
|
||||
rcu_read_unlock(), rcu_read_lock_bh() and rcu_read_unlock_bh(),
|
||||
or any pair of primitives that disables and re-enables preemption,
|
||||
for example, rcu_read_lock_sched() and rcu_read_unlock_sched().
|
||||
If the updater uses synchronize_srcu() or call_srcu(),
|
||||
then the corresponding readers must use srcu_read_lock() and
|
||||
srcu_read_unlock(), and with the same srcu_struct. The rules for
|
||||
the expedited primitives are the same as for their non-expedited
|
||||
counterparts. Mixing things up will result in confusion and
|
||||
broken kernels, and has even resulted in an exploitable security
|
||||
issue.
|
||||
|
||||
One exception to this rule: rcu_read_lock() and rcu_read_unlock()
|
||||
may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh()
|
||||
in cases where local bottom halves are already known to be
|
||||
disabled, for example, in irq or softirq context. Commenting
|
||||
such cases is a must, of course! And the jury is still out on
|
||||
whether the increased speed is worth it.
|
||||
|
||||
8. Although synchronize_rcu() is slower than is call_rcu(), it
|
||||
usually results in simpler code. So, unless update performance is
|
||||
critically important, the updaters cannot block, or the latency of
|
||||
synchronize_rcu() is visible from userspace, synchronize_rcu()
|
||||
should be used in preference to call_rcu(). Furthermore,
|
||||
kfree_rcu() usually results in even simpler code than does
|
||||
synchronize_rcu() without synchronize_rcu()'s multi-millisecond
|
||||
latency. So please take advantage of kfree_rcu()'s "fire and
|
||||
forget" memory-freeing capabilities where it applies.
|
||||
|
||||
An especially important property of the synchronize_rcu()
|
||||
primitive is that it automatically self-limits: if grace periods
|
||||
are delayed for whatever reason, then the synchronize_rcu()
|
||||
primitive will correspondingly delay updates. In contrast,
|
||||
code using call_rcu() should explicitly limit update rate in
|
||||
cases where grace periods are delayed, as failing to do so can
|
||||
result in excessive realtime latencies or even OOM conditions.
|
||||
|
||||
Ways of gaining this self-limiting property when using call_rcu()
|
||||
include:
|
||||
|
||||
a. Keeping a count of the number of data-structure elements
|
||||
used by the RCU-protected data structure, including
|
||||
those waiting for a grace period to elapse. Enforce a
|
||||
limit on this number, stalling updates as needed to allow
|
||||
previously deferred frees to complete. Alternatively,
|
||||
limit only the number awaiting deferred free rather than
|
||||
the total number of elements.
|
||||
|
||||
One way to stall the updates is to acquire the update-side
|
||||
mutex. (Don't try this with a spinlock -- other CPUs
|
||||
spinning on the lock could prevent the grace period
|
||||
from ever ending.) Another way to stall the updates
|
||||
is for the updates to use a wrapper function around
|
||||
the memory allocator, so that this wrapper function
|
||||
simulates OOM when there is too much memory awaiting an
|
||||
RCU grace period. There are of course many other
|
||||
variations on this theme.
|
||||
|
||||
b. Limiting update rate. For example, if updates occur only
|
||||
once per hour, then no explicit rate limiting is
|
||||
required, unless your system is already badly broken.
|
||||
Older versions of the dcache subsystem take this approach,
|
||||
guarding updates with a global lock, limiting their rate.
|
||||
|
||||
c. Trusted update -- if updates can only be done manually by
|
||||
superuser or some other trusted user, then it might not
|
||||
be necessary to automatically limit them. The theory
|
||||
here is that superuser already has lots of ways to crash
|
||||
the machine.
|
||||
|
||||
d. Periodically invoke synchronize_rcu(), permitting a limited
|
||||
number of updates per grace period.
|
||||
|
||||
The same cautions apply to call_srcu() and kfree_rcu().
|
||||
|
||||
Note that although these primitives do take action to avoid memory
|
||||
exhaustion when any given CPU has too many callbacks, a determined
|
||||
user could still exhaust memory. This is especially the case
|
||||
if a system with a large number of CPUs has been configured to
|
||||
offload all of its RCU callbacks onto a single CPU, or if the
|
||||
system has relatively little free memory.
|
||||
|
||||
9. All RCU list-traversal primitives, which include
|
||||
rcu_dereference(), list_for_each_entry_rcu(), and
|
||||
list_for_each_safe_rcu(), must be either within an RCU read-side
|
||||
critical section or must be protected by appropriate update-side
|
||||
locks. RCU read-side critical sections are delimited by
|
||||
rcu_read_lock() and rcu_read_unlock(), or by similar primitives
|
||||
such as rcu_read_lock_bh() and rcu_read_unlock_bh(), in which
|
||||
case the matching rcu_dereference() primitive must be used in
|
||||
order to keep lockdep happy, in this case, rcu_dereference_bh().
|
||||
|
||||
The reason that it is permissible to use RCU list-traversal
|
||||
primitives when the update-side lock is held is that doing so
|
||||
can be quite helpful in reducing code bloat when common code is
|
||||
shared between readers and updaters. Additional primitives
|
||||
are provided for this case, as discussed in lockdep.txt.
|
||||
|
||||
10. Conversely, if you are in an RCU read-side critical section,
|
||||
and you don't hold the appropriate update-side lock, you -must-
|
||||
use the "_rcu()" variants of the list macros. Failing to do so
|
||||
will break Alpha, cause aggressive compilers to generate bad code,
|
||||
and confuse people trying to read your code.
|
||||
|
||||
11. Any lock acquired by an RCU callback must be acquired elsewhere
|
||||
with softirq disabled, e.g., via spin_lock_irqsave(),
|
||||
spin_lock_bh(), etc. Failing to disable softirq on a given
|
||||
acquisition of that lock will result in deadlock as soon as
|
||||
the RCU softirq handler happens to run your RCU callback while
|
||||
interrupting that acquisition's critical section.
|
||||
|
||||
12. RCU callbacks can be and are executed in parallel. In many cases,
|
||||
the callback code simply wrappers around kfree(), so that this
|
||||
is not an issue (or, more accurately, to the extent that it is
|
||||
an issue, the memory-allocator locking handles it). However,
|
||||
if the callbacks do manipulate a shared data structure, they
|
||||
must use whatever locking or other synchronization is required
|
||||
to safely access and/or modify that data structure.
|
||||
|
||||
Do not assume that RCU callbacks will be executed on the same
|
||||
CPU that executed the corresponding call_rcu() or call_srcu().
|
||||
For example, if a given CPU goes offline while having an RCU
|
||||
callback pending, then that RCU callback will execute on some
|
||||
surviving CPU. (If this was not the case, a self-spawning RCU
|
||||
callback would prevent the victim CPU from ever going offline.)
|
||||
Furthermore, CPUs designated by rcu_nocbs= might well -always-
|
||||
have their RCU callbacks executed on some other CPUs, in fact,
|
||||
for some real-time workloads, this is the whole point of using
|
||||
the rcu_nocbs= kernel boot parameter.
|
||||
|
||||
13. Unlike other forms of RCU, it -is- permissible to block in an
|
||||
SRCU read-side critical section (demarked by srcu_read_lock()
|
||||
and srcu_read_unlock()), hence the "SRCU": "sleepable RCU".
|
||||
Please note that if you don't need to sleep in read-side critical
|
||||
sections, you should be using RCU rather than SRCU, because RCU
|
||||
is almost always faster and easier to use than is SRCU.
|
||||
|
||||
Also unlike other forms of RCU, explicit initialization and
|
||||
cleanup is required either at build time via DEFINE_SRCU()
|
||||
or DEFINE_STATIC_SRCU() or at runtime via init_srcu_struct()
|
||||
and cleanup_srcu_struct(). These last two are passed a
|
||||
"struct srcu_struct" that defines the scope of a given
|
||||
SRCU domain. Once initialized, the srcu_struct is passed
|
||||
to srcu_read_lock(), srcu_read_unlock() synchronize_srcu(),
|
||||
synchronize_srcu_expedited(), and call_srcu(). A given
|
||||
synchronize_srcu() waits only for SRCU read-side critical
|
||||
sections governed by srcu_read_lock() and srcu_read_unlock()
|
||||
calls that have been passed the same srcu_struct. This property
|
||||
is what makes sleeping read-side critical sections tolerable --
|
||||
a given subsystem delays only its own updates, not those of other
|
||||
subsystems using SRCU. Therefore, SRCU is less prone to OOM the
|
||||
system than RCU would be if RCU's read-side critical sections
|
||||
were permitted to sleep.
|
||||
|
||||
The ability to sleep in read-side critical sections does not
|
||||
come for free. First, corresponding srcu_read_lock() and
|
||||
srcu_read_unlock() calls must be passed the same srcu_struct.
|
||||
Second, grace-period-detection overhead is amortized only
|
||||
over those updates sharing a given srcu_struct, rather than
|
||||
being globally amortized as they are for other forms of RCU.
|
||||
Therefore, SRCU should be used in preference to rw_semaphore
|
||||
only in extremely read-intensive situations, or in situations
|
||||
requiring SRCU's read-side deadlock immunity or low read-side
|
||||
realtime latency. You should also consider percpu_rw_semaphore
|
||||
when you need lightweight readers.
|
||||
|
||||
SRCU's expedited primitive (synchronize_srcu_expedited())
|
||||
never sends IPIs to other CPUs, so it is easier on
|
||||
real-time workloads than is synchronize_rcu_expedited().
|
||||
|
||||
Note that rcu_assign_pointer() relates to SRCU just as it does to
|
||||
other forms of RCU, but instead of rcu_dereference() you should
|
||||
use srcu_dereference() in order to avoid lockdep splats.
|
||||
|
||||
14. The whole point of call_rcu(), synchronize_rcu(), and friends
|
||||
is to wait until all pre-existing readers have finished before
|
||||
carrying out some otherwise-destructive operation. It is
|
||||
therefore critically important to -first- remove any path
|
||||
that readers can follow that could be affected by the
|
||||
destructive operation, and -only- -then- invoke call_rcu(),
|
||||
synchronize_rcu(), or friends.
|
||||
|
||||
Because these primitives only wait for pre-existing readers, it
|
||||
is the caller's responsibility to guarantee that any subsequent
|
||||
readers will execute safely.
|
||||
|
||||
15. The various RCU read-side primitives do -not- necessarily contain
|
||||
memory barriers. You should therefore plan for the CPU
|
||||
and the compiler to freely reorder code into and out of RCU
|
||||
read-side critical sections. It is the responsibility of the
|
||||
RCU update-side primitives to deal with this.
|
||||
|
||||
For SRCU readers, you can use smp_mb__after_srcu_read_unlock()
|
||||
immediately after an srcu_read_unlock() to get a full barrier.
|
||||
|
||||
16. Use CONFIG_PROVE_LOCKING, CONFIG_DEBUG_OBJECTS_RCU_HEAD, and the
|
||||
__rcu sparse checks to validate your RCU code. These can help
|
||||
find problems as follows:
|
||||
|
||||
CONFIG_PROVE_LOCKING: check that accesses to RCU-protected data
|
||||
structures are carried out under the proper RCU
|
||||
read-side critical section, while holding the right
|
||||
combination of locks, or whatever other conditions
|
||||
are appropriate.
|
||||
|
||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD: check that you don't pass the
|
||||
same object to call_rcu() (or friends) before an RCU
|
||||
grace period has elapsed since the last time that you
|
||||
passed that same object to call_rcu() (or friends).
|
||||
|
||||
__rcu sparse checks: tag the pointer to the RCU-protected data
|
||||
structure with __rcu, and sparse will warn you if you
|
||||
access that pointer without the services of one of the
|
||||
variants of rcu_dereference().
|
||||
|
||||
These debugging aids can help you find problems that are
|
||||
otherwise extremely difficult to spot.
|
||||
|
||||
17. If you register a callback using call_rcu() or call_srcu(), and
|
||||
pass in a function defined within a loadable module, then it in
|
||||
necessary to wait for all pending callbacks to be invoked after
|
||||
the last invocation and before unloading that module. Note that
|
||||
it is absolutely -not- sufficient to wait for a grace period!
|
||||
The current (say) synchronize_rcu() implementation is -not-
|
||||
guaranteed to wait for callbacks registered on other CPUs.
|
||||
Or even on the current CPU if that CPU recently went offline
|
||||
and came back online.
|
||||
|
||||
You instead need to use one of the barrier functions:
|
||||
|
||||
o call_rcu() -> rcu_barrier()
|
||||
o call_srcu() -> srcu_barrier()
|
||||
|
||||
However, these barrier functions are absolutely -not- guaranteed
|
||||
to wait for a grace period. In fact, if there are no call_rcu()
|
||||
callbacks waiting anywhere in the system, rcu_barrier() is within
|
||||
its rights to return immediately.
|
||||
|
||||
So if you need to wait for both an RCU grace period and for
|
||||
all pre-existing call_rcu() callbacks, you will need to execute
|
||||
both rcu_barrier() and synchronize_rcu(), if necessary, using
|
||||
something like workqueues to to execute them concurrently.
|
||||
|
||||
See rcubarrier.txt for more information.
|
||||
@@ -1,3 +1,5 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. _rcu_concepts:
|
||||
|
||||
============
|
||||
@@ -8,10 +10,17 @@ RCU concepts
|
||||
:maxdepth: 3
|
||||
|
||||
arrayRCU
|
||||
checklist
|
||||
lockdep
|
||||
lockdep-splat
|
||||
rcubarrier
|
||||
rcu_dereference
|
||||
whatisRCU
|
||||
rcu
|
||||
rculist_nulls
|
||||
rcuref
|
||||
torture
|
||||
stallwarn
|
||||
listRCU
|
||||
NMI-RCU
|
||||
UP
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=================
|
||||
Lockdep-RCU Splat
|
||||
=================
|
||||
|
||||
Lockdep-RCU was added to the Linux kernel in early 2010
|
||||
(http://lwn.net/Articles/371986/). This facility checks for some common
|
||||
misuses of the RCU API, most notably using one of the rcu_dereference()
|
||||
family to access an RCU-protected pointer without the proper protection.
|
||||
When such misuse is detected, an lockdep-RCU splat is emitted.
|
||||
|
||||
The usual cause of a lockdep-RCU slat is someone accessing an
|
||||
RCU-protected data structure without either (1) being in the right kind of
|
||||
RCU read-side critical section or (2) holding the right update-side lock.
|
||||
This problem can therefore be serious: it might result in random memory
|
||||
overwriting or worse. There can of course be false positives, this
|
||||
being the real world and all that.
|
||||
|
||||
So let's look at an example RCU lockdep splat from 3.0-rc5, one that
|
||||
has long since been fixed::
|
||||
|
||||
=============================
|
||||
WARNING: suspicious RCU usage
|
||||
-----------------------------
|
||||
block/cfq-iosched.c:2776 suspicious rcu_dereference_protected() usage!
|
||||
|
||||
other info that might help us debug this::
|
||||
|
||||
rcu_scheduler_active = 1, debug_locks = 0
|
||||
3 locks held by scsi_scan_6/1552:
|
||||
#0: (&shost->scan_mutex){+.+.}, at: [<ffffffff8145efca>]
|
||||
scsi_scan_host_selected+0x5a/0x150
|
||||
#1: (&eq->sysfs_lock){+.+.}, at: [<ffffffff812a5032>]
|
||||
elevator_exit+0x22/0x60
|
||||
#2: (&(&q->__queue_lock)->rlock){-.-.}, at: [<ffffffff812b6233>]
|
||||
cfq_exit_queue+0x43/0x190
|
||||
|
||||
stack backtrace:
|
||||
Pid: 1552, comm: scsi_scan_6 Not tainted 3.0.0-rc5 #17
|
||||
Call Trace:
|
||||
[<ffffffff810abb9b>] lockdep_rcu_dereference+0xbb/0xc0
|
||||
[<ffffffff812b6139>] __cfq_exit_single_io_context+0xe9/0x120
|
||||
[<ffffffff812b626c>] cfq_exit_queue+0x7c/0x190
|
||||
[<ffffffff812a5046>] elevator_exit+0x36/0x60
|
||||
[<ffffffff812a802a>] blk_cleanup_queue+0x4a/0x60
|
||||
[<ffffffff8145cc09>] scsi_free_queue+0x9/0x10
|
||||
[<ffffffff81460944>] __scsi_remove_device+0x84/0xd0
|
||||
[<ffffffff8145dca3>] scsi_probe_and_add_lun+0x353/0xb10
|
||||
[<ffffffff817da069>] ? error_exit+0x29/0xb0
|
||||
[<ffffffff817d98ed>] ? _raw_spin_unlock_irqrestore+0x3d/0x80
|
||||
[<ffffffff8145e722>] __scsi_scan_target+0x112/0x680
|
||||
[<ffffffff812c690d>] ? trace_hardirqs_off_thunk+0x3a/0x3c
|
||||
[<ffffffff817da069>] ? error_exit+0x29/0xb0
|
||||
[<ffffffff812bcc60>] ? kobject_del+0x40/0x40
|
||||
[<ffffffff8145ed16>] scsi_scan_channel+0x86/0xb0
|
||||
[<ffffffff8145f0b0>] scsi_scan_host_selected+0x140/0x150
|
||||
[<ffffffff8145f149>] do_scsi_scan_host+0x89/0x90
|
||||
[<ffffffff8145f170>] do_scan_async+0x20/0x160
|
||||
[<ffffffff8145f150>] ? do_scsi_scan_host+0x90/0x90
|
||||
[<ffffffff810975b6>] kthread+0xa6/0xb0
|
||||
[<ffffffff817db154>] kernel_thread_helper+0x4/0x10
|
||||
[<ffffffff81066430>] ? finish_task_switch+0x80/0x110
|
||||
[<ffffffff817d9c04>] ? retint_restore_args+0xe/0xe
|
||||
[<ffffffff81097510>] ? __kthread_init_worker+0x70/0x70
|
||||
[<ffffffff817db150>] ? gs_change+0xb/0xb
|
||||
|
||||
Line 2776 of block/cfq-iosched.c in v3.0-rc5 is as follows::
|
||||
|
||||
if (rcu_dereference(ioc->ioc_data) == cic) {
|
||||
|
||||
This form says that it must be in a plain vanilla RCU read-side critical
|
||||
section, but the "other info" list above shows that this is not the
|
||||
case. Instead, we hold three locks, one of which might be RCU related.
|
||||
And maybe that lock really does protect this reference. If so, the fix
|
||||
is to inform RCU, perhaps by changing __cfq_exit_single_io_context() to
|
||||
take the struct request_queue "q" from cfq_exit_queue() as an argument,
|
||||
which would permit us to invoke rcu_dereference_protected as follows::
|
||||
|
||||
if (rcu_dereference_protected(ioc->ioc_data,
|
||||
lockdep_is_held(&q->queue_lock)) == cic) {
|
||||
|
||||
With this change, there would be no lockdep-RCU splat emitted if this
|
||||
code was invoked either from within an RCU read-side critical section
|
||||
or with the ->queue_lock held. In particular, this would have suppressed
|
||||
the above lockdep-RCU splat because ->queue_lock is held (see #2 in the
|
||||
list above).
|
||||
|
||||
On the other hand, perhaps we really do need an RCU read-side critical
|
||||
section. In this case, the critical section must span the use of the
|
||||
return value from rcu_dereference(), or at least until there is some
|
||||
reference count incremented or some such. One way to handle this is to
|
||||
add rcu_read_lock() and rcu_read_unlock() as follows::
|
||||
|
||||
rcu_read_lock();
|
||||
if (rcu_dereference(ioc->ioc_data) == cic) {
|
||||
spin_lock(&ioc->lock);
|
||||
rcu_assign_pointer(ioc->ioc_data, NULL);
|
||||
spin_unlock(&ioc->lock);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
With this change, the rcu_dereference() is always within an RCU
|
||||
read-side critical section, which again would have suppressed the
|
||||
above lockdep-RCU splat.
|
||||
|
||||
But in this particular case, we don't actually dereference the pointer
|
||||
returned from rcu_dereference(). Instead, that pointer is just compared
|
||||
to the cic pointer, which means that the rcu_dereference() can be replaced
|
||||
by rcu_access_pointer() as follows::
|
||||
|
||||
if (rcu_access_pointer(ioc->ioc_data) == cic) {
|
||||
|
||||
Because it is legal to invoke rcu_access_pointer() without protection,
|
||||
this change would also suppress the above lockdep-RCU splat.
|
||||
@@ -1,110 +0,0 @@
|
||||
Lockdep-RCU was added to the Linux kernel in early 2010
|
||||
(http://lwn.net/Articles/371986/). This facility checks for some common
|
||||
misuses of the RCU API, most notably using one of the rcu_dereference()
|
||||
family to access an RCU-protected pointer without the proper protection.
|
||||
When such misuse is detected, an lockdep-RCU splat is emitted.
|
||||
|
||||
The usual cause of a lockdep-RCU slat is someone accessing an
|
||||
RCU-protected data structure without either (1) being in the right kind of
|
||||
RCU read-side critical section or (2) holding the right update-side lock.
|
||||
This problem can therefore be serious: it might result in random memory
|
||||
overwriting or worse. There can of course be false positives, this
|
||||
being the real world and all that.
|
||||
|
||||
So let's look at an example RCU lockdep splat from 3.0-rc5, one that
|
||||
has long since been fixed:
|
||||
|
||||
=============================
|
||||
WARNING: suspicious RCU usage
|
||||
-----------------------------
|
||||
block/cfq-iosched.c:2776 suspicious rcu_dereference_protected() usage!
|
||||
|
||||
other info that might help us debug this:
|
||||
|
||||
|
||||
rcu_scheduler_active = 1, debug_locks = 0
|
||||
3 locks held by scsi_scan_6/1552:
|
||||
#0: (&shost->scan_mutex){+.+.}, at: [<ffffffff8145efca>]
|
||||
scsi_scan_host_selected+0x5a/0x150
|
||||
#1: (&eq->sysfs_lock){+.+.}, at: [<ffffffff812a5032>]
|
||||
elevator_exit+0x22/0x60
|
||||
#2: (&(&q->__queue_lock)->rlock){-.-.}, at: [<ffffffff812b6233>]
|
||||
cfq_exit_queue+0x43/0x190
|
||||
|
||||
stack backtrace:
|
||||
Pid: 1552, comm: scsi_scan_6 Not tainted 3.0.0-rc5 #17
|
||||
Call Trace:
|
||||
[<ffffffff810abb9b>] lockdep_rcu_dereference+0xbb/0xc0
|
||||
[<ffffffff812b6139>] __cfq_exit_single_io_context+0xe9/0x120
|
||||
[<ffffffff812b626c>] cfq_exit_queue+0x7c/0x190
|
||||
[<ffffffff812a5046>] elevator_exit+0x36/0x60
|
||||
[<ffffffff812a802a>] blk_cleanup_queue+0x4a/0x60
|
||||
[<ffffffff8145cc09>] scsi_free_queue+0x9/0x10
|
||||
[<ffffffff81460944>] __scsi_remove_device+0x84/0xd0
|
||||
[<ffffffff8145dca3>] scsi_probe_and_add_lun+0x353/0xb10
|
||||
[<ffffffff817da069>] ? error_exit+0x29/0xb0
|
||||
[<ffffffff817d98ed>] ? _raw_spin_unlock_irqrestore+0x3d/0x80
|
||||
[<ffffffff8145e722>] __scsi_scan_target+0x112/0x680
|
||||
[<ffffffff812c690d>] ? trace_hardirqs_off_thunk+0x3a/0x3c
|
||||
[<ffffffff817da069>] ? error_exit+0x29/0xb0
|
||||
[<ffffffff812bcc60>] ? kobject_del+0x40/0x40
|
||||
[<ffffffff8145ed16>] scsi_scan_channel+0x86/0xb0
|
||||
[<ffffffff8145f0b0>] scsi_scan_host_selected+0x140/0x150
|
||||
[<ffffffff8145f149>] do_scsi_scan_host+0x89/0x90
|
||||
[<ffffffff8145f170>] do_scan_async+0x20/0x160
|
||||
[<ffffffff8145f150>] ? do_scsi_scan_host+0x90/0x90
|
||||
[<ffffffff810975b6>] kthread+0xa6/0xb0
|
||||
[<ffffffff817db154>] kernel_thread_helper+0x4/0x10
|
||||
[<ffffffff81066430>] ? finish_task_switch+0x80/0x110
|
||||
[<ffffffff817d9c04>] ? retint_restore_args+0xe/0xe
|
||||
[<ffffffff81097510>] ? __kthread_init_worker+0x70/0x70
|
||||
[<ffffffff817db150>] ? gs_change+0xb/0xb
|
||||
|
||||
Line 2776 of block/cfq-iosched.c in v3.0-rc5 is as follows:
|
||||
|
||||
if (rcu_dereference(ioc->ioc_data) == cic) {
|
||||
|
||||
This form says that it must be in a plain vanilla RCU read-side critical
|
||||
section, but the "other info" list above shows that this is not the
|
||||
case. Instead, we hold three locks, one of which might be RCU related.
|
||||
And maybe that lock really does protect this reference. If so, the fix
|
||||
is to inform RCU, perhaps by changing __cfq_exit_single_io_context() to
|
||||
take the struct request_queue "q" from cfq_exit_queue() as an argument,
|
||||
which would permit us to invoke rcu_dereference_protected as follows:
|
||||
|
||||
if (rcu_dereference_protected(ioc->ioc_data,
|
||||
lockdep_is_held(&q->queue_lock)) == cic) {
|
||||
|
||||
With this change, there would be no lockdep-RCU splat emitted if this
|
||||
code was invoked either from within an RCU read-side critical section
|
||||
or with the ->queue_lock held. In particular, this would have suppressed
|
||||
the above lockdep-RCU splat because ->queue_lock is held (see #2 in the
|
||||
list above).
|
||||
|
||||
On the other hand, perhaps we really do need an RCU read-side critical
|
||||
section. In this case, the critical section must span the use of the
|
||||
return value from rcu_dereference(), or at least until there is some
|
||||
reference count incremented or some such. One way to handle this is to
|
||||
add rcu_read_lock() and rcu_read_unlock() as follows:
|
||||
|
||||
rcu_read_lock();
|
||||
if (rcu_dereference(ioc->ioc_data) == cic) {
|
||||
spin_lock(&ioc->lock);
|
||||
rcu_assign_pointer(ioc->ioc_data, NULL);
|
||||
spin_unlock(&ioc->lock);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
With this change, the rcu_dereference() is always within an RCU
|
||||
read-side critical section, which again would have suppressed the
|
||||
above lockdep-RCU splat.
|
||||
|
||||
But in this particular case, we don't actually dereference the pointer
|
||||
returned from rcu_dereference(). Instead, that pointer is just compared
|
||||
to the cic pointer, which means that the rcu_dereference() can be replaced
|
||||
by rcu_access_pointer() as follows:
|
||||
|
||||
if (rcu_access_pointer(ioc->ioc_data) == cic) {
|
||||
|
||||
Because it is legal to invoke rcu_access_pointer() without protection,
|
||||
this change would also suppress the above lockdep-RCU splat.
|
||||
@@ -0,0 +1,116 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
========================
|
||||
RCU and lockdep checking
|
||||
========================
|
||||
|
||||
All flavors of RCU have lockdep checking available, so that lockdep is
|
||||
aware of when each task enters and leaves any flavor of RCU read-side
|
||||
critical section. Each flavor of RCU is tracked separately (but note
|
||||
that this is not the case in 2.6.32 and earlier). This allows lockdep's
|
||||
tracking to include RCU state, which can sometimes help when debugging
|
||||
deadlocks and the like.
|
||||
|
||||
In addition, RCU provides the following primitives that check lockdep's
|
||||
state::
|
||||
|
||||
rcu_read_lock_held() for normal RCU.
|
||||
rcu_read_lock_bh_held() for RCU-bh.
|
||||
rcu_read_lock_sched_held() for RCU-sched.
|
||||
srcu_read_lock_held() for SRCU.
|
||||
|
||||
These functions are conservative, and will therefore return 1 if they
|
||||
aren't certain (for example, if CONFIG_DEBUG_LOCK_ALLOC is not set).
|
||||
This prevents things like WARN_ON(!rcu_read_lock_held()) from giving false
|
||||
positives when lockdep is disabled.
|
||||
|
||||
In addition, a separate kernel config parameter CONFIG_PROVE_RCU enables
|
||||
checking of rcu_dereference() primitives:
|
||||
|
||||
rcu_dereference(p):
|
||||
Check for RCU read-side critical section.
|
||||
rcu_dereference_bh(p):
|
||||
Check for RCU-bh read-side critical section.
|
||||
rcu_dereference_sched(p):
|
||||
Check for RCU-sched read-side critical section.
|
||||
srcu_dereference(p, sp):
|
||||
Check for SRCU read-side critical section.
|
||||
rcu_dereference_check(p, c):
|
||||
Use explicit check expression "c" along with
|
||||
rcu_read_lock_held(). This is useful in code that is
|
||||
invoked by both RCU readers and updaters.
|
||||
rcu_dereference_bh_check(p, c):
|
||||
Use explicit check expression "c" along with
|
||||
rcu_read_lock_bh_held(). This is useful in code that
|
||||
is invoked by both RCU-bh readers and updaters.
|
||||
rcu_dereference_sched_check(p, c):
|
||||
Use explicit check expression "c" along with
|
||||
rcu_read_lock_sched_held(). This is useful in code that
|
||||
is invoked by both RCU-sched readers and updaters.
|
||||
srcu_dereference_check(p, c):
|
||||
Use explicit check expression "c" along with
|
||||
srcu_read_lock_held(). This is useful in code that
|
||||
is invoked by both SRCU readers and updaters.
|
||||
rcu_dereference_raw(p):
|
||||
Don't check. (Use sparingly, if at all.)
|
||||
rcu_dereference_protected(p, c):
|
||||
Use explicit check expression "c", and omit all barriers
|
||||
and compiler constraints. This is useful when the data
|
||||
structure cannot change, for example, in code that is
|
||||
invoked only by updaters.
|
||||
rcu_access_pointer(p):
|
||||
Return the value of the pointer and omit all barriers,
|
||||
but retain the compiler constraints that prevent duplicating
|
||||
or coalescsing. This is useful when when testing the
|
||||
value of the pointer itself, for example, against NULL.
|
||||
|
||||
The rcu_dereference_check() check expression can be any boolean
|
||||
expression, but would normally include a lockdep expression. However,
|
||||
any boolean expression can be used. For a moderately ornate example,
|
||||
consider the following::
|
||||
|
||||
file = rcu_dereference_check(fdt->fd[fd],
|
||||
lockdep_is_held(&files->file_lock) ||
|
||||
atomic_read(&files->count) == 1);
|
||||
|
||||
This expression picks up the pointer "fdt->fd[fd]" in an RCU-safe manner,
|
||||
and, if CONFIG_PROVE_RCU is configured, verifies that this expression
|
||||
is used in:
|
||||
|
||||
1. An RCU read-side critical section (implicit), or
|
||||
2. with files->file_lock held, or
|
||||
3. on an unshared files_struct.
|
||||
|
||||
In case (1), the pointer is picked up in an RCU-safe manner for vanilla
|
||||
RCU read-side critical sections, in case (2) the ->file_lock prevents
|
||||
any change from taking place, and finally, in case (3) the current task
|
||||
is the only task accessing the file_struct, again preventing any change
|
||||
from taking place. If the above statement was invoked only from updater
|
||||
code, it could instead be written as follows::
|
||||
|
||||
file = rcu_dereference_protected(fdt->fd[fd],
|
||||
lockdep_is_held(&files->file_lock) ||
|
||||
atomic_read(&files->count) == 1);
|
||||
|
||||
This would verify cases #2 and #3 above, and furthermore lockdep would
|
||||
complain if this was used in an RCU read-side critical section unless one
|
||||
of these two cases held. Because rcu_dereference_protected() omits all
|
||||
barriers and compiler constraints, it generates better code than do the
|
||||
other flavors of rcu_dereference(). On the other hand, it is illegal
|
||||
to use rcu_dereference_protected() if either the RCU-protected pointer
|
||||
or the RCU-protected data that it points to can change concurrently.
|
||||
|
||||
Like rcu_dereference(), when lockdep is enabled, RCU list and hlist
|
||||
traversal primitives check for being called from within an RCU read-side
|
||||
critical section. However, a lockdep expression can be passed to them
|
||||
as a additional optional argument. With this lockdep expression, these
|
||||
traversal primitives will complain only if the lockdep expression is
|
||||
false and they are called from outside any RCU read-side critical section.
|
||||
|
||||
For example, the workqueue for_each_pwq() macro is intended to be used
|
||||
either within an RCU read-side critical section or with wq->mutex held.
|
||||
It is thus implemented as follows::
|
||||
|
||||
#define for_each_pwq(pwq, wq)
|
||||
list_for_each_entry_rcu((pwq), &(wq)->pwqs, pwqs_node,
|
||||
lock_is_held(&(wq->mutex).dep_map))
|
||||
@@ -1,112 +0,0 @@
|
||||
RCU and lockdep checking
|
||||
|
||||
All flavors of RCU have lockdep checking available, so that lockdep is
|
||||
aware of when each task enters and leaves any flavor of RCU read-side
|
||||
critical section. Each flavor of RCU is tracked separately (but note
|
||||
that this is not the case in 2.6.32 and earlier). This allows lockdep's
|
||||
tracking to include RCU state, which can sometimes help when debugging
|
||||
deadlocks and the like.
|
||||
|
||||
In addition, RCU provides the following primitives that check lockdep's
|
||||
state:
|
||||
|
||||
rcu_read_lock_held() for normal RCU.
|
||||
rcu_read_lock_bh_held() for RCU-bh.
|
||||
rcu_read_lock_sched_held() for RCU-sched.
|
||||
srcu_read_lock_held() for SRCU.
|
||||
|
||||
These functions are conservative, and will therefore return 1 if they
|
||||
aren't certain (for example, if CONFIG_DEBUG_LOCK_ALLOC is not set).
|
||||
This prevents things like WARN_ON(!rcu_read_lock_held()) from giving false
|
||||
positives when lockdep is disabled.
|
||||
|
||||
In addition, a separate kernel config parameter CONFIG_PROVE_RCU enables
|
||||
checking of rcu_dereference() primitives:
|
||||
|
||||
rcu_dereference(p):
|
||||
Check for RCU read-side critical section.
|
||||
rcu_dereference_bh(p):
|
||||
Check for RCU-bh read-side critical section.
|
||||
rcu_dereference_sched(p):
|
||||
Check for RCU-sched read-side critical section.
|
||||
srcu_dereference(p, sp):
|
||||
Check for SRCU read-side critical section.
|
||||
rcu_dereference_check(p, c):
|
||||
Use explicit check expression "c" along with
|
||||
rcu_read_lock_held(). This is useful in code that is
|
||||
invoked by both RCU readers and updaters.
|
||||
rcu_dereference_bh_check(p, c):
|
||||
Use explicit check expression "c" along with
|
||||
rcu_read_lock_bh_held(). This is useful in code that
|
||||
is invoked by both RCU-bh readers and updaters.
|
||||
rcu_dereference_sched_check(p, c):
|
||||
Use explicit check expression "c" along with
|
||||
rcu_read_lock_sched_held(). This is useful in code that
|
||||
is invoked by both RCU-sched readers and updaters.
|
||||
srcu_dereference_check(p, c):
|
||||
Use explicit check expression "c" along with
|
||||
srcu_read_lock_held()(). This is useful in code that
|
||||
is invoked by both SRCU readers and updaters.
|
||||
rcu_dereference_raw(p):
|
||||
Don't check. (Use sparingly, if at all.)
|
||||
rcu_dereference_protected(p, c):
|
||||
Use explicit check expression "c", and omit all barriers
|
||||
and compiler constraints. This is useful when the data
|
||||
structure cannot change, for example, in code that is
|
||||
invoked only by updaters.
|
||||
rcu_access_pointer(p):
|
||||
Return the value of the pointer and omit all barriers,
|
||||
but retain the compiler constraints that prevent duplicating
|
||||
or coalescsing. This is useful when when testing the
|
||||
value of the pointer itself, for example, against NULL.
|
||||
|
||||
The rcu_dereference_check() check expression can be any boolean
|
||||
expression, but would normally include a lockdep expression. However,
|
||||
any boolean expression can be used. For a moderately ornate example,
|
||||
consider the following:
|
||||
|
||||
file = rcu_dereference_check(fdt->fd[fd],
|
||||
lockdep_is_held(&files->file_lock) ||
|
||||
atomic_read(&files->count) == 1);
|
||||
|
||||
This expression picks up the pointer "fdt->fd[fd]" in an RCU-safe manner,
|
||||
and, if CONFIG_PROVE_RCU is configured, verifies that this expression
|
||||
is used in:
|
||||
|
||||
1. An RCU read-side critical section (implicit), or
|
||||
2. with files->file_lock held, or
|
||||
3. on an unshared files_struct.
|
||||
|
||||
In case (1), the pointer is picked up in an RCU-safe manner for vanilla
|
||||
RCU read-side critical sections, in case (2) the ->file_lock prevents
|
||||
any change from taking place, and finally, in case (3) the current task
|
||||
is the only task accessing the file_struct, again preventing any change
|
||||
from taking place. If the above statement was invoked only from updater
|
||||
code, it could instead be written as follows:
|
||||
|
||||
file = rcu_dereference_protected(fdt->fd[fd],
|
||||
lockdep_is_held(&files->file_lock) ||
|
||||
atomic_read(&files->count) == 1);
|
||||
|
||||
This would verify cases #2 and #3 above, and furthermore lockdep would
|
||||
complain if this was used in an RCU read-side critical section unless one
|
||||
of these two cases held. Because rcu_dereference_protected() omits all
|
||||
barriers and compiler constraints, it generates better code than do the
|
||||
other flavors of rcu_dereference(). On the other hand, it is illegal
|
||||
to use rcu_dereference_protected() if either the RCU-protected pointer
|
||||
or the RCU-protected data that it points to can change concurrently.
|
||||
|
||||
Like rcu_dereference(), when lockdep is enabled, RCU list and hlist
|
||||
traversal primitives check for being called from within an RCU read-side
|
||||
critical section. However, a lockdep expression can be passed to them
|
||||
as a additional optional argument. With this lockdep expression, these
|
||||
traversal primitives will complain only if the lockdep expression is
|
||||
false and they are called from outside any RCU read-side critical section.
|
||||
|
||||
For example, the workqueue for_each_pwq() macro is intended to be used
|
||||
either within an RCU read-side critical section or with wq->mutex held.
|
||||
It is thus implemented as follows:
|
||||
|
||||
#define for_each_pwq(pwq, wq)
|
||||
list_for_each_entry_rcu((pwq), &(wq)->pwqs, pwqs_node,
|
||||
lock_is_held(&(wq->mutex).dep_map))
|
||||
@@ -0,0 +1,200 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=================================================
|
||||
Using RCU hlist_nulls to protect list and objects
|
||||
=================================================
|
||||
|
||||
This section describes how to use hlist_nulls to
|
||||
protect read-mostly linked lists and
|
||||
objects using SLAB_TYPESAFE_BY_RCU allocations.
|
||||
|
||||
Please read the basics in Documentation/RCU/listRCU.rst
|
||||
|
||||
Using 'nulls'
|
||||
=============
|
||||
|
||||
Using special makers (called 'nulls') is a convenient way
|
||||
to solve following problem :
|
||||
|
||||
A typical RCU linked list managing objects which are
|
||||
allocated with SLAB_TYPESAFE_BY_RCU kmem_cache can
|
||||
use following algos :
|
||||
|
||||
1) Lookup algo
|
||||
--------------
|
||||
|
||||
::
|
||||
|
||||
rcu_read_lock()
|
||||
begin:
|
||||
obj = lockless_lookup(key);
|
||||
if (obj) {
|
||||
if (!try_get_ref(obj)) // might fail for free objects
|
||||
goto begin;
|
||||
/*
|
||||
* Because a writer could delete object, and a writer could
|
||||
* reuse these object before the RCU grace period, we
|
||||
* must check key after getting the reference on object
|
||||
*/
|
||||
if (obj->key != key) { // not the object we expected
|
||||
put_ref(obj);
|
||||
goto begin;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
Beware that lockless_lookup(key) cannot use traditional hlist_for_each_entry_rcu()
|
||||
but a version with an additional memory barrier (smp_rmb())
|
||||
|
||||
::
|
||||
|
||||
lockless_lookup(key)
|
||||
{
|
||||
struct hlist_node *node, *next;
|
||||
for (pos = rcu_dereference((head)->first);
|
||||
pos && ({ next = pos->next; smp_rmb(); prefetch(next); 1; }) &&
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; });
|
||||
pos = rcu_dereference(next))
|
||||
if (obj->key == key)
|
||||
return obj;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
And note the traditional hlist_for_each_entry_rcu() misses this smp_rmb()::
|
||||
|
||||
struct hlist_node *node;
|
||||
for (pos = rcu_dereference((head)->first);
|
||||
pos && ({ prefetch(pos->next); 1; }) &&
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; });
|
||||
pos = rcu_dereference(pos->next))
|
||||
if (obj->key == key)
|
||||
return obj;
|
||||
return NULL;
|
||||
|
||||
Quoting Corey Minyard::
|
||||
|
||||
"If the object is moved from one list to another list in-between the
|
||||
time the hash is calculated and the next field is accessed, and the
|
||||
object has moved to the end of a new list, the traversal will not
|
||||
complete properly on the list it should have, since the object will
|
||||
be on the end of the new list and there's not a way to tell it's on a
|
||||
new list and restart the list traversal. I think that this can be
|
||||
solved by pre-fetching the "next" field (with proper barriers) before
|
||||
checking the key."
|
||||
|
||||
2) Insert algo
|
||||
--------------
|
||||
|
||||
We need to make sure a reader cannot read the new 'obj->obj_next' value
|
||||
and previous value of 'obj->key'. Or else, an item could be deleted
|
||||
from a chain, and inserted into another chain. If new chain was empty
|
||||
before the move, 'next' pointer is NULL, and lockless reader can
|
||||
not detect it missed following items in original chain.
|
||||
|
||||
::
|
||||
|
||||
/*
|
||||
* Please note that new inserts are done at the head of list,
|
||||
* not in the middle or end.
|
||||
*/
|
||||
obj = kmem_cache_alloc(...);
|
||||
lock_chain(); // typically a spin_lock()
|
||||
obj->key = key;
|
||||
/*
|
||||
* we need to make sure obj->key is updated before obj->next
|
||||
* or obj->refcnt
|
||||
*/
|
||||
smp_wmb();
|
||||
atomic_set(&obj->refcnt, 1);
|
||||
hlist_add_head_rcu(&obj->obj_node, list);
|
||||
unlock_chain(); // typically a spin_unlock()
|
||||
|
||||
|
||||
3) Remove algo
|
||||
--------------
|
||||
Nothing special here, we can use a standard RCU hlist deletion.
|
||||
But thanks to SLAB_TYPESAFE_BY_RCU, beware a deleted object can be reused
|
||||
very very fast (before the end of RCU grace period)
|
||||
|
||||
::
|
||||
|
||||
if (put_last_reference_on(obj) {
|
||||
lock_chain(); // typically a spin_lock()
|
||||
hlist_del_init_rcu(&obj->obj_node);
|
||||
unlock_chain(); // typically a spin_unlock()
|
||||
kmem_cache_free(cachep, obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Avoiding extra smp_rmb()
|
||||
========================
|
||||
|
||||
With hlist_nulls we can avoid extra smp_rmb() in lockless_lookup()
|
||||
and extra smp_wmb() in insert function.
|
||||
|
||||
For example, if we choose to store the slot number as the 'nulls'
|
||||
end-of-list marker for each slot of the hash table, we can detect
|
||||
a race (some writer did a delete and/or a move of an object
|
||||
to another chain) checking the final 'nulls' value if
|
||||
the lookup met the end of chain. If final 'nulls' value
|
||||
is not the slot number, then we must restart the lookup at
|
||||
the beginning. If the object was moved to the same chain,
|
||||
then the reader doesn't care : It might eventually
|
||||
scan the list again without harm.
|
||||
|
||||
|
||||
1) lookup algo
|
||||
--------------
|
||||
|
||||
::
|
||||
|
||||
head = &table[slot];
|
||||
rcu_read_lock();
|
||||
begin:
|
||||
hlist_nulls_for_each_entry_rcu(obj, node, head, member) {
|
||||
if (obj->key == key) {
|
||||
if (!try_get_ref(obj)) // might fail for free objects
|
||||
goto begin;
|
||||
if (obj->key != key) { // not the object we expected
|
||||
put_ref(obj);
|
||||
goto begin;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* if the nulls value we got at the end of this lookup is
|
||||
* not the expected one, we must restart lookup.
|
||||
* We probably met an item that was moved to another chain.
|
||||
*/
|
||||
if (get_nulls_value(node) != slot)
|
||||
goto begin;
|
||||
obj = NULL;
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
|
||||
2) Insert function
|
||||
------------------
|
||||
|
||||
::
|
||||
|
||||
/*
|
||||
* Please note that new inserts are done at the head of list,
|
||||
* not in the middle or end.
|
||||
*/
|
||||
obj = kmem_cache_alloc(cachep);
|
||||
lock_chain(); // typically a spin_lock()
|
||||
obj->key = key;
|
||||
/*
|
||||
* changes to obj->key must be visible before refcnt one
|
||||
*/
|
||||
smp_wmb();
|
||||
atomic_set(&obj->refcnt, 1);
|
||||
/*
|
||||
* insert obj in RCU way (readers might be traversing chain)
|
||||
*/
|
||||
hlist_nulls_add_head_rcu(&obj->obj_node, list);
|
||||
unlock_chain(); // typically a spin_unlock()
|
||||
@@ -1,172 +0,0 @@
|
||||
Using hlist_nulls to protect read-mostly linked lists and
|
||||
objects using SLAB_TYPESAFE_BY_RCU allocations.
|
||||
|
||||
Please read the basics in Documentation/RCU/listRCU.rst
|
||||
|
||||
Using special makers (called 'nulls') is a convenient way
|
||||
to solve following problem :
|
||||
|
||||
A typical RCU linked list managing objects which are
|
||||
allocated with SLAB_TYPESAFE_BY_RCU kmem_cache can
|
||||
use following algos :
|
||||
|
||||
1) Lookup algo
|
||||
--------------
|
||||
rcu_read_lock()
|
||||
begin:
|
||||
obj = lockless_lookup(key);
|
||||
if (obj) {
|
||||
if (!try_get_ref(obj)) // might fail for free objects
|
||||
goto begin;
|
||||
/*
|
||||
* Because a writer could delete object, and a writer could
|
||||
* reuse these object before the RCU grace period, we
|
||||
* must check key after getting the reference on object
|
||||
*/
|
||||
if (obj->key != key) { // not the object we expected
|
||||
put_ref(obj);
|
||||
goto begin;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
Beware that lockless_lookup(key) cannot use traditional hlist_for_each_entry_rcu()
|
||||
but a version with an additional memory barrier (smp_rmb())
|
||||
|
||||
lockless_lookup(key)
|
||||
{
|
||||
struct hlist_node *node, *next;
|
||||
for (pos = rcu_dereference((head)->first);
|
||||
pos && ({ next = pos->next; smp_rmb(); prefetch(next); 1; }) &&
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; });
|
||||
pos = rcu_dereference(next))
|
||||
if (obj->key == key)
|
||||
return obj;
|
||||
return NULL;
|
||||
|
||||
And note the traditional hlist_for_each_entry_rcu() misses this smp_rmb() :
|
||||
|
||||
struct hlist_node *node;
|
||||
for (pos = rcu_dereference((head)->first);
|
||||
pos && ({ prefetch(pos->next); 1; }) &&
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; });
|
||||
pos = rcu_dereference(pos->next))
|
||||
if (obj->key == key)
|
||||
return obj;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Quoting Corey Minyard :
|
||||
|
||||
"If the object is moved from one list to another list in-between the
|
||||
time the hash is calculated and the next field is accessed, and the
|
||||
object has moved to the end of a new list, the traversal will not
|
||||
complete properly on the list it should have, since the object will
|
||||
be on the end of the new list and there's not a way to tell it's on a
|
||||
new list and restart the list traversal. I think that this can be
|
||||
solved by pre-fetching the "next" field (with proper barriers) before
|
||||
checking the key."
|
||||
|
||||
2) Insert algo :
|
||||
----------------
|
||||
|
||||
We need to make sure a reader cannot read the new 'obj->obj_next' value
|
||||
and previous value of 'obj->key'. Or else, an item could be deleted
|
||||
from a chain, and inserted into another chain. If new chain was empty
|
||||
before the move, 'next' pointer is NULL, and lockless reader can
|
||||
not detect it missed following items in original chain.
|
||||
|
||||
/*
|
||||
* Please note that new inserts are done at the head of list,
|
||||
* not in the middle or end.
|
||||
*/
|
||||
obj = kmem_cache_alloc(...);
|
||||
lock_chain(); // typically a spin_lock()
|
||||
obj->key = key;
|
||||
/*
|
||||
* we need to make sure obj->key is updated before obj->next
|
||||
* or obj->refcnt
|
||||
*/
|
||||
smp_wmb();
|
||||
atomic_set(&obj->refcnt, 1);
|
||||
hlist_add_head_rcu(&obj->obj_node, list);
|
||||
unlock_chain(); // typically a spin_unlock()
|
||||
|
||||
|
||||
3) Remove algo
|
||||
--------------
|
||||
Nothing special here, we can use a standard RCU hlist deletion.
|
||||
But thanks to SLAB_TYPESAFE_BY_RCU, beware a deleted object can be reused
|
||||
very very fast (before the end of RCU grace period)
|
||||
|
||||
if (put_last_reference_on(obj) {
|
||||
lock_chain(); // typically a spin_lock()
|
||||
hlist_del_init_rcu(&obj->obj_node);
|
||||
unlock_chain(); // typically a spin_unlock()
|
||||
kmem_cache_free(cachep, obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
With hlist_nulls we can avoid extra smp_rmb() in lockless_lookup()
|
||||
and extra smp_wmb() in insert function.
|
||||
|
||||
For example, if we choose to store the slot number as the 'nulls'
|
||||
end-of-list marker for each slot of the hash table, we can detect
|
||||
a race (some writer did a delete and/or a move of an object
|
||||
to another chain) checking the final 'nulls' value if
|
||||
the lookup met the end of chain. If final 'nulls' value
|
||||
is not the slot number, then we must restart the lookup at
|
||||
the beginning. If the object was moved to the same chain,
|
||||
then the reader doesn't care : It might eventually
|
||||
scan the list again without harm.
|
||||
|
||||
|
||||
1) lookup algo
|
||||
|
||||
head = &table[slot];
|
||||
rcu_read_lock();
|
||||
begin:
|
||||
hlist_nulls_for_each_entry_rcu(obj, node, head, member) {
|
||||
if (obj->key == key) {
|
||||
if (!try_get_ref(obj)) // might fail for free objects
|
||||
goto begin;
|
||||
if (obj->key != key) { // not the object we expected
|
||||
put_ref(obj);
|
||||
goto begin;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* if the nulls value we got at the end of this lookup is
|
||||
* not the expected one, we must restart lookup.
|
||||
* We probably met an item that was moved to another chain.
|
||||
*/
|
||||
if (get_nulls_value(node) != slot)
|
||||
goto begin;
|
||||
obj = NULL;
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
|
||||
2) Insert function :
|
||||
--------------------
|
||||
|
||||
/*
|
||||
* Please note that new inserts are done at the head of list,
|
||||
* not in the middle or end.
|
||||
*/
|
||||
obj = kmem_cache_alloc(cachep);
|
||||
lock_chain(); // typically a spin_lock()
|
||||
obj->key = key;
|
||||
/*
|
||||
* changes to obj->key must be visible before refcnt one
|
||||
*/
|
||||
smp_wmb();
|
||||
atomic_set(&obj->refcnt, 1);
|
||||
/*
|
||||
* insert obj in RCU way (readers might be traversing chain)
|
||||
*/
|
||||
hlist_nulls_add_head_rcu(&obj->obj_node, list);
|
||||
unlock_chain(); // typically a spin_unlock()
|
||||
@@ -0,0 +1,158 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
====================================================================
|
||||
Reference-count design for elements of lists/arrays protected by RCU
|
||||
====================================================================
|
||||
|
||||
|
||||
Please note that the percpu-ref feature is likely your first
|
||||
stop if you need to combine reference counts and RCU. Please see
|
||||
include/linux/percpu-refcount.h for more information. However, in
|
||||
those unusual cases where percpu-ref would consume too much memory,
|
||||
please read on.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Reference counting on elements of lists which are protected by traditional
|
||||
reader/writer spinlocks or semaphores are straightforward:
|
||||
|
||||
CODE LISTING A::
|
||||
|
||||
1. 2.
|
||||
add() search_and_reference()
|
||||
{ {
|
||||
alloc_object read_lock(&list_lock);
|
||||
... search_for_element
|
||||
atomic_set(&el->rc, 1); atomic_inc(&el->rc);
|
||||
write_lock(&list_lock); ...
|
||||
add_element read_unlock(&list_lock);
|
||||
... ...
|
||||
write_unlock(&list_lock); }
|
||||
}
|
||||
|
||||
3. 4.
|
||||
release_referenced() delete()
|
||||
{ {
|
||||
... write_lock(&list_lock);
|
||||
if(atomic_dec_and_test(&el->rc)) ...
|
||||
kfree(el);
|
||||
... remove_element
|
||||
} write_unlock(&list_lock);
|
||||
...
|
||||
if (atomic_dec_and_test(&el->rc))
|
||||
kfree(el);
|
||||
...
|
||||
}
|
||||
|
||||
If this list/array is made lock free using RCU as in changing the
|
||||
write_lock() in add() and delete() to spin_lock() and changing read_lock()
|
||||
in search_and_reference() to rcu_read_lock(), the atomic_inc() in
|
||||
search_and_reference() could potentially hold reference to an element which
|
||||
has already been deleted from the list/array. Use atomic_inc_not_zero()
|
||||
in this scenario as follows:
|
||||
|
||||
CODE LISTING B::
|
||||
|
||||
1. 2.
|
||||
add() search_and_reference()
|
||||
{ {
|
||||
alloc_object rcu_read_lock();
|
||||
... search_for_element
|
||||
atomic_set(&el->rc, 1); if (!atomic_inc_not_zero(&el->rc)) {
|
||||
spin_lock(&list_lock); rcu_read_unlock();
|
||||
return FAIL;
|
||||
add_element }
|
||||
... ...
|
||||
spin_unlock(&list_lock); rcu_read_unlock();
|
||||
} }
|
||||
3. 4.
|
||||
release_referenced() delete()
|
||||
{ {
|
||||
... spin_lock(&list_lock);
|
||||
if (atomic_dec_and_test(&el->rc)) ...
|
||||
call_rcu(&el->head, el_free); remove_element
|
||||
... spin_unlock(&list_lock);
|
||||
} ...
|
||||
if (atomic_dec_and_test(&el->rc))
|
||||
call_rcu(&el->head, el_free);
|
||||
...
|
||||
}
|
||||
|
||||
Sometimes, a reference to the element needs to be obtained in the
|
||||
update (write) stream. In such cases, atomic_inc_not_zero() might be
|
||||
overkill, since we hold the update-side spinlock. One might instead
|
||||
use atomic_inc() in such cases.
|
||||
|
||||
It is not always convenient to deal with "FAIL" in the
|
||||
search_and_reference() code path. In such cases, the
|
||||
atomic_dec_and_test() may be moved from delete() to el_free()
|
||||
as follows:
|
||||
|
||||
CODE LISTING C::
|
||||
|
||||
1. 2.
|
||||
add() search_and_reference()
|
||||
{ {
|
||||
alloc_object rcu_read_lock();
|
||||
... search_for_element
|
||||
atomic_set(&el->rc, 1); atomic_inc(&el->rc);
|
||||
spin_lock(&list_lock); ...
|
||||
|
||||
add_element rcu_read_unlock();
|
||||
... }
|
||||
spin_unlock(&list_lock); 4.
|
||||
} delete()
|
||||
3. {
|
||||
release_referenced() spin_lock(&list_lock);
|
||||
{ ...
|
||||
... remove_element
|
||||
if (atomic_dec_and_test(&el->rc)) spin_unlock(&list_lock);
|
||||
kfree(el); ...
|
||||
... call_rcu(&el->head, el_free);
|
||||
} ...
|
||||
5. }
|
||||
void el_free(struct rcu_head *rhp)
|
||||
{
|
||||
release_referenced();
|
||||
}
|
||||
|
||||
The key point is that the initial reference added by add() is not removed
|
||||
until after a grace period has elapsed following removal. This means that
|
||||
search_and_reference() cannot find this element, which means that the value
|
||||
of el->rc cannot increase. Thus, once it reaches zero, there are no
|
||||
readers that can or ever will be able to reference the element. The
|
||||
element can therefore safely be freed. This in turn guarantees that if
|
||||
any reader finds the element, that reader may safely acquire a reference
|
||||
without checking the value of the reference counter.
|
||||
|
||||
A clear advantage of the RCU-based pattern in listing C over the one
|
||||
in listing B is that any call to search_and_reference() that locates
|
||||
a given object will succeed in obtaining a reference to that object,
|
||||
even given a concurrent invocation of delete() for that same object.
|
||||
Similarly, a clear advantage of both listings B and C over listing A is
|
||||
that a call to delete() is not delayed even if there are an arbitrarily
|
||||
large number of calls to search_and_reference() searching for the same
|
||||
object that delete() was invoked on. Instead, all that is delayed is
|
||||
the eventual invocation of kfree(), which is usually not a problem on
|
||||
modern computer systems, even the small ones.
|
||||
|
||||
In cases where delete() can sleep, synchronize_rcu() can be called from
|
||||
delete(), so that el_free() can be subsumed into delete as follows::
|
||||
|
||||
4.
|
||||
delete()
|
||||
{
|
||||
spin_lock(&list_lock);
|
||||
...
|
||||
remove_element
|
||||
spin_unlock(&list_lock);
|
||||
...
|
||||
synchronize_rcu();
|
||||
if (atomic_dec_and_test(&el->rc))
|
||||
kfree(el);
|
||||
...
|
||||
}
|
||||
|
||||
As additional examples in the kernel, the pattern in listing C is used by
|
||||
reference counting of struct pid, while the pattern in listing B is used by
|
||||
struct posix_acl.
|
||||
@@ -1,151 +0,0 @@
|
||||
Reference-count design for elements of lists/arrays protected by RCU.
|
||||
|
||||
|
||||
Please note that the percpu-ref feature is likely your first
|
||||
stop if you need to combine reference counts and RCU. Please see
|
||||
include/linux/percpu-refcount.h for more information. However, in
|
||||
those unusual cases where percpu-ref would consume too much memory,
|
||||
please read on.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Reference counting on elements of lists which are protected by traditional
|
||||
reader/writer spinlocks or semaphores are straightforward:
|
||||
|
||||
CODE LISTING A:
|
||||
1. 2.
|
||||
add() search_and_reference()
|
||||
{ {
|
||||
alloc_object read_lock(&list_lock);
|
||||
... search_for_element
|
||||
atomic_set(&el->rc, 1); atomic_inc(&el->rc);
|
||||
write_lock(&list_lock); ...
|
||||
add_element read_unlock(&list_lock);
|
||||
... ...
|
||||
write_unlock(&list_lock); }
|
||||
}
|
||||
|
||||
3. 4.
|
||||
release_referenced() delete()
|
||||
{ {
|
||||
... write_lock(&list_lock);
|
||||
if(atomic_dec_and_test(&el->rc)) ...
|
||||
kfree(el);
|
||||
... remove_element
|
||||
} write_unlock(&list_lock);
|
||||
...
|
||||
if (atomic_dec_and_test(&el->rc))
|
||||
kfree(el);
|
||||
...
|
||||
}
|
||||
|
||||
If this list/array is made lock free using RCU as in changing the
|
||||
write_lock() in add() and delete() to spin_lock() and changing read_lock()
|
||||
in search_and_reference() to rcu_read_lock(), the atomic_inc() in
|
||||
search_and_reference() could potentially hold reference to an element which
|
||||
has already been deleted from the list/array. Use atomic_inc_not_zero()
|
||||
in this scenario as follows:
|
||||
|
||||
CODE LISTING B:
|
||||
1. 2.
|
||||
add() search_and_reference()
|
||||
{ {
|
||||
alloc_object rcu_read_lock();
|
||||
... search_for_element
|
||||
atomic_set(&el->rc, 1); if (!atomic_inc_not_zero(&el->rc)) {
|
||||
spin_lock(&list_lock); rcu_read_unlock();
|
||||
return FAIL;
|
||||
add_element }
|
||||
... ...
|
||||
spin_unlock(&list_lock); rcu_read_unlock();
|
||||
} }
|
||||
3. 4.
|
||||
release_referenced() delete()
|
||||
{ {
|
||||
... spin_lock(&list_lock);
|
||||
if (atomic_dec_and_test(&el->rc)) ...
|
||||
call_rcu(&el->head, el_free); remove_element
|
||||
... spin_unlock(&list_lock);
|
||||
} ...
|
||||
if (atomic_dec_and_test(&el->rc))
|
||||
call_rcu(&el->head, el_free);
|
||||
...
|
||||
}
|
||||
|
||||
Sometimes, a reference to the element needs to be obtained in the
|
||||
update (write) stream. In such cases, atomic_inc_not_zero() might be
|
||||
overkill, since we hold the update-side spinlock. One might instead
|
||||
use atomic_inc() in such cases.
|
||||
|
||||
It is not always convenient to deal with "FAIL" in the
|
||||
search_and_reference() code path. In such cases, the
|
||||
atomic_dec_and_test() may be moved from delete() to el_free()
|
||||
as follows:
|
||||
|
||||
CODE LISTING C:
|
||||
1. 2.
|
||||
add() search_and_reference()
|
||||
{ {
|
||||
alloc_object rcu_read_lock();
|
||||
... search_for_element
|
||||
atomic_set(&el->rc, 1); atomic_inc(&el->rc);
|
||||
spin_lock(&list_lock); ...
|
||||
|
||||
add_element rcu_read_unlock();
|
||||
... }
|
||||
spin_unlock(&list_lock); 4.
|
||||
} delete()
|
||||
3. {
|
||||
release_referenced() spin_lock(&list_lock);
|
||||
{ ...
|
||||
... remove_element
|
||||
if (atomic_dec_and_test(&el->rc)) spin_unlock(&list_lock);
|
||||
kfree(el); ...
|
||||
... call_rcu(&el->head, el_free);
|
||||
} ...
|
||||
5. }
|
||||
void el_free(struct rcu_head *rhp)
|
||||
{
|
||||
release_referenced();
|
||||
}
|
||||
|
||||
The key point is that the initial reference added by add() is not removed
|
||||
until after a grace period has elapsed following removal. This means that
|
||||
search_and_reference() cannot find this element, which means that the value
|
||||
of el->rc cannot increase. Thus, once it reaches zero, there are no
|
||||
readers that can or ever will be able to reference the element. The
|
||||
element can therefore safely be freed. This in turn guarantees that if
|
||||
any reader finds the element, that reader may safely acquire a reference
|
||||
without checking the value of the reference counter.
|
||||
|
||||
A clear advantage of the RCU-based pattern in listing C over the one
|
||||
in listing B is that any call to search_and_reference() that locates
|
||||
a given object will succeed in obtaining a reference to that object,
|
||||
even given a concurrent invocation of delete() for that same object.
|
||||
Similarly, a clear advantage of both listings B and C over listing A is
|
||||
that a call to delete() is not delayed even if there are an arbitrarily
|
||||
large number of calls to search_and_reference() searching for the same
|
||||
object that delete() was invoked on. Instead, all that is delayed is
|
||||
the eventual invocation of kfree(), which is usually not a problem on
|
||||
modern computer systems, even the small ones.
|
||||
|
||||
In cases where delete() can sleep, synchronize_rcu() can be called from
|
||||
delete(), so that el_free() can be subsumed into delete as follows:
|
||||
|
||||
4.
|
||||
delete()
|
||||
{
|
||||
spin_lock(&list_lock);
|
||||
...
|
||||
remove_element
|
||||
spin_unlock(&list_lock);
|
||||
...
|
||||
synchronize_rcu();
|
||||
if (atomic_dec_and_test(&el->rc))
|
||||
kfree(el);
|
||||
...
|
||||
}
|
||||
|
||||
As additional examples in the kernel, the pattern in listing C is used by
|
||||
reference counting of struct pid, while the pattern in listing B is used by
|
||||
struct posix_acl.
|
||||
@@ -0,0 +1,336 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
==============================
|
||||
Using RCU's CPU Stall Detector
|
||||
==============================
|
||||
|
||||
This document first discusses what sorts of issues RCU's CPU stall
|
||||
detector can locate, and then discusses kernel parameters and Kconfig
|
||||
options that can be used to fine-tune the detector's operation. Finally,
|
||||
this document explains the stall detector's "splat" format.
|
||||
|
||||
|
||||
What Causes RCU CPU Stall Warnings?
|
||||
===================================
|
||||
|
||||
So your kernel printed an RCU CPU stall warning. The next question is
|
||||
"What caused it?" The following problems can result in RCU CPU stall
|
||||
warnings:
|
||||
|
||||
- A CPU looping in an RCU read-side critical section.
|
||||
|
||||
- A CPU looping with interrupts disabled.
|
||||
|
||||
- A CPU looping with preemption disabled.
|
||||
|
||||
- A CPU looping with bottom halves disabled.
|
||||
|
||||
- For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
|
||||
without invoking schedule(). If the looping in the kernel is
|
||||
really expected and desirable behavior, you might need to add
|
||||
some calls to cond_resched().
|
||||
|
||||
- Booting Linux using a console connection that is too slow to
|
||||
keep up with the boot-time console-message rate. For example,
|
||||
a 115Kbaud serial console can be -way- too slow to keep up
|
||||
with boot-time message rates, and will frequently result in
|
||||
RCU CPU stall warning messages. Especially if you have added
|
||||
debug printk()s.
|
||||
|
||||
- Anything that prevents RCU's grace-period kthreads from running.
|
||||
This can result in the "All QSes seen" console-log message.
|
||||
This message will include information on when the kthread last
|
||||
ran and how often it should be expected to run. It can also
|
||||
result in the ``rcu_.*kthread starved for`` console-log message,
|
||||
which will include additional debugging information.
|
||||
|
||||
- A CPU-bound real-time task in a CONFIG_PREEMPT kernel, which might
|
||||
happen to preempt a low-priority task in the middle of an RCU
|
||||
read-side critical section. This is especially damaging if
|
||||
that low-priority task is not permitted to run on any other CPU,
|
||||
in which case the next RCU grace period can never complete, which
|
||||
will eventually cause the system to run out of memory and hang.
|
||||
While the system is in the process of running itself out of
|
||||
memory, you might see stall-warning messages.
|
||||
|
||||
- A CPU-bound real-time task in a CONFIG_PREEMPT_RT kernel that
|
||||
is running at a higher priority than the RCU softirq threads.
|
||||
This will prevent RCU callbacks from ever being invoked,
|
||||
and in a CONFIG_PREEMPT_RCU kernel will further prevent
|
||||
RCU grace periods from ever completing. Either way, the
|
||||
system will eventually run out of memory and hang. In the
|
||||
CONFIG_PREEMPT_RCU case, you might see stall-warning
|
||||
messages.
|
||||
|
||||
You can use the rcutree.kthread_prio kernel boot parameter to
|
||||
increase the scheduling priority of RCU's kthreads, which can
|
||||
help avoid this problem. However, please note that doing this
|
||||
can increase your system's context-switch rate and thus degrade
|
||||
performance.
|
||||
|
||||
- A periodic interrupt whose handler takes longer than the time
|
||||
interval between successive pairs of interrupts. This can
|
||||
prevent RCU's kthreads and softirq handlers from running.
|
||||
Note that certain high-overhead debugging options, for example
|
||||
the function_graph tracer, can result in interrupt handler taking
|
||||
considerably longer than normal, which can in turn result in
|
||||
RCU CPU stall warnings.
|
||||
|
||||
- Testing a workload on a fast system, tuning the stall-warning
|
||||
timeout down to just barely avoid RCU CPU stall warnings, and then
|
||||
running the same workload with the same stall-warning timeout on a
|
||||
slow system. Note that thermal throttling and on-demand governors
|
||||
can cause a single system to be sometimes fast and sometimes slow!
|
||||
|
||||
- A hardware or software issue shuts off the scheduler-clock
|
||||
interrupt on a CPU that is not in dyntick-idle mode. This
|
||||
problem really has happened, and seems to be most likely to
|
||||
result in RCU CPU stall warnings for CONFIG_NO_HZ_COMMON=n kernels.
|
||||
|
||||
- A hardware or software issue that prevents time-based wakeups
|
||||
from occurring. These issues can range from misconfigured or
|
||||
buggy timer hardware through bugs in the interrupt or exception
|
||||
path (whether hardware, firmware, or software) through bugs
|
||||
in Linux's timer subsystem through bugs in the scheduler, and,
|
||||
yes, even including bugs in RCU itself.
|
||||
|
||||
- A bug in the RCU implementation.
|
||||
|
||||
- A hardware failure. This is quite unlikely, but has occurred
|
||||
at least once in real life. A CPU failed in a running system,
|
||||
becoming unresponsive, but not causing an immediate crash.
|
||||
This resulted in a series of RCU CPU stall warnings, eventually
|
||||
leading the realization that the CPU had failed.
|
||||
|
||||
The RCU, RCU-sched, and RCU-tasks implementations have CPU stall warning.
|
||||
Note that SRCU does -not- have CPU stall warnings. Please note that
|
||||
RCU only detects CPU stalls when there is a grace period in progress.
|
||||
No grace period, no CPU stall warnings.
|
||||
|
||||
To diagnose the cause of the stall, inspect the stack traces.
|
||||
The offending function will usually be near the top of the stack.
|
||||
If you have a series of stall warnings from a single extended stall,
|
||||
comparing the stack traces can often help determine where the stall
|
||||
is occurring, which will usually be in the function nearest the top of
|
||||
that portion of the stack which remains the same from trace to trace.
|
||||
If you can reliably trigger the stall, ftrace can be quite helpful.
|
||||
|
||||
RCU bugs can often be debugged with the help of CONFIG_RCU_TRACE
|
||||
and with RCU's event tracing. For information on RCU's event tracing,
|
||||
see include/trace/events/rcu.h.
|
||||
|
||||
|
||||
Fine-Tuning the RCU CPU Stall Detector
|
||||
======================================
|
||||
|
||||
The rcuupdate.rcu_cpu_stall_suppress module parameter disables RCU's
|
||||
CPU stall detector, which detects conditions that unduly delay RCU grace
|
||||
periods. This module parameter enables CPU stall detection by default,
|
||||
but may be overridden via boot-time parameter or at runtime via sysfs.
|
||||
The stall detector's idea of what constitutes "unduly delayed" is
|
||||
controlled by a set of kernel configuration variables and cpp macros:
|
||||
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT
|
||||
----------------------------
|
||||
|
||||
This kernel configuration parameter defines the period of time
|
||||
that RCU will wait from the beginning of a grace period until it
|
||||
issues an RCU CPU stall warning. This time period is normally
|
||||
21 seconds.
|
||||
|
||||
This configuration parameter may be changed at runtime via the
|
||||
/sys/module/rcupdate/parameters/rcu_cpu_stall_timeout, however
|
||||
this parameter is checked only at the beginning of a cycle.
|
||||
So if you are 10 seconds into a 40-second stall, setting this
|
||||
sysfs parameter to (say) five will shorten the timeout for the
|
||||
-next- stall, or the following warning for the current stall
|
||||
(assuming the stall lasts long enough). It will not affect the
|
||||
timing of the next warning for the current stall.
|
||||
|
||||
Stall-warning messages may be enabled and disabled completely via
|
||||
/sys/module/rcupdate/parameters/rcu_cpu_stall_suppress.
|
||||
|
||||
RCU_STALL_DELAY_DELTA
|
||||
---------------------
|
||||
|
||||
Although the lockdep facility is extremely useful, it does add
|
||||
some overhead. Therefore, under CONFIG_PROVE_RCU, the
|
||||
RCU_STALL_DELAY_DELTA macro allows five extra seconds before
|
||||
giving an RCU CPU stall warning message. (This is a cpp
|
||||
macro, not a kernel configuration parameter.)
|
||||
|
||||
RCU_STALL_RAT_DELAY
|
||||
-------------------
|
||||
|
||||
The CPU stall detector tries to make the offending CPU print its
|
||||
own warnings, as this often gives better-quality stack traces.
|
||||
However, if the offending CPU does not detect its own stall in
|
||||
the number of jiffies specified by RCU_STALL_RAT_DELAY, then
|
||||
some other CPU will complain. This delay is normally set to
|
||||
two jiffies. (This is a cpp macro, not a kernel configuration
|
||||
parameter.)
|
||||
|
||||
rcupdate.rcu_task_stall_timeout
|
||||
-------------------------------
|
||||
|
||||
This boot/sysfs parameter controls the RCU-tasks stall warning
|
||||
interval. A value of zero or less suppresses RCU-tasks stall
|
||||
warnings. A positive value sets the stall-warning interval
|
||||
in seconds. An RCU-tasks stall warning starts with the line:
|
||||
|
||||
INFO: rcu_tasks detected stalls on tasks:
|
||||
|
||||
And continues with the output of sched_show_task() for each
|
||||
task stalling the current RCU-tasks grace period.
|
||||
|
||||
|
||||
Interpreting RCU's CPU Stall-Detector "Splats"
|
||||
==============================================
|
||||
|
||||
For non-RCU-tasks flavors of RCU, when a CPU detects that it is stalling,
|
||||
it will print a message similar to the following::
|
||||
|
||||
INFO: rcu_sched detected stalls on CPUs/tasks:
|
||||
2-...: (3 GPs behind) idle=06c/0/0 softirq=1453/1455 fqs=0
|
||||
16-...: (0 ticks this GP) idle=81c/0/0 softirq=764/764 fqs=0
|
||||
(detected by 32, t=2603 jiffies, g=7075, q=625)
|
||||
|
||||
This message indicates that CPU 32 detected that CPUs 2 and 16 were both
|
||||
causing stalls, and that the stall was affecting RCU-sched. This message
|
||||
will normally be followed by stack dumps for each CPU. Please note that
|
||||
PREEMPT_RCU builds can be stalled by tasks as well as by CPUs, and that
|
||||
the tasks will be indicated by PID, for example, "P3421". It is even
|
||||
possible for an rcu_state stall to be caused by both CPUs -and- tasks,
|
||||
in which case the offending CPUs and tasks will all be called out in the list.
|
||||
|
||||
CPU 2's "(3 GPs behind)" indicates that this CPU has not interacted with
|
||||
the RCU core for the past three grace periods. In contrast, CPU 16's "(0
|
||||
ticks this GP)" indicates that this CPU has not taken any scheduling-clock
|
||||
interrupts during the current stalled grace period.
|
||||
|
||||
The "idle=" portion of the message prints the dyntick-idle state.
|
||||
The hex number before the first "/" is the low-order 12 bits of the
|
||||
dynticks counter, which will have an even-numbered value if the CPU
|
||||
is in dyntick-idle mode and an odd-numbered value otherwise. The hex
|
||||
number between the two "/"s is the value of the nesting, which will be
|
||||
a small non-negative number if in the idle loop (as shown above) and a
|
||||
very large positive number otherwise.
|
||||
|
||||
The "softirq=" portion of the message tracks the number of RCU softirq
|
||||
handlers that the stalled CPU has executed. The number before the "/"
|
||||
is the number that had executed since boot at the time that this CPU
|
||||
last noted the beginning of a grace period, which might be the current
|
||||
(stalled) grace period, or it might be some earlier grace period (for
|
||||
example, if the CPU might have been in dyntick-idle mode for an extended
|
||||
time period. The number after the "/" is the number that have executed
|
||||
since boot until the current time. If this latter number stays constant
|
||||
across repeated stall-warning messages, it is possible that RCU's softirq
|
||||
handlers are no longer able to execute on this CPU. This can happen if
|
||||
the stalled CPU is spinning with interrupts are disabled, or, in -rt
|
||||
kernels, if a high-priority process is starving RCU's softirq handler.
|
||||
|
||||
The "fqs=" shows the number of force-quiescent-state idle/offline
|
||||
detection passes that the grace-period kthread has made across this
|
||||
CPU since the last time that this CPU noted the beginning of a grace
|
||||
period.
|
||||
|
||||
The "detected by" line indicates which CPU detected the stall (in this
|
||||
case, CPU 32), how many jiffies have elapsed since the start of the grace
|
||||
period (in this case 2603), the grace-period sequence number (7075), and
|
||||
an estimate of the total number of RCU callbacks queued across all CPUs
|
||||
(625 in this case).
|
||||
|
||||
In kernels with CONFIG_RCU_FAST_NO_HZ, more information is printed
|
||||
for each CPU::
|
||||
|
||||
0: (64628 ticks this GP) idle=dd5/3fffffffffffffff/0 softirq=82/543 last_accelerate: a345/d342 dyntick_enabled: 1
|
||||
|
||||
The "last_accelerate:" prints the low-order 16 bits (in hex) of the
|
||||
jiffies counter when this CPU last invoked rcu_try_advance_all_cbs()
|
||||
from rcu_needs_cpu() or last invoked rcu_accelerate_cbs() from
|
||||
rcu_prepare_for_idle(). "dyntick_enabled: 1" indicates that dyntick-idle
|
||||
processing is enabled.
|
||||
|
||||
If the grace period ends just as the stall warning starts printing,
|
||||
there will be a spurious stall-warning message, which will include
|
||||
the following::
|
||||
|
||||
INFO: Stall ended before state dump start
|
||||
|
||||
This is rare, but does happen from time to time in real life. It is also
|
||||
possible for a zero-jiffy stall to be flagged in this case, depending
|
||||
on how the stall warning and the grace-period initialization happen to
|
||||
interact. Please note that it is not possible to entirely eliminate this
|
||||
sort of false positive without resorting to things like stop_machine(),
|
||||
which is overkill for this sort of problem.
|
||||
|
||||
If all CPUs and tasks have passed through quiescent states, but the
|
||||
grace period has nevertheless failed to end, the stall-warning splat
|
||||
will include something like the following::
|
||||
|
||||
All QSes seen, last rcu_preempt kthread activity 23807 (4297905177-4297881370), jiffies_till_next_fqs=3, root ->qsmask 0x0
|
||||
|
||||
The "23807" indicates that it has been more than 23 thousand jiffies
|
||||
since the grace-period kthread ran. The "jiffies_till_next_fqs"
|
||||
indicates how frequently that kthread should run, giving the number
|
||||
of jiffies between force-quiescent-state scans, in this case three,
|
||||
which is way less than 23807. Finally, the root rcu_node structure's
|
||||
->qsmask field is printed, which will normally be zero.
|
||||
|
||||
If the relevant grace-period kthread has been unable to run prior to
|
||||
the stall warning, as was the case in the "All QSes seen" line above,
|
||||
the following additional line is printed::
|
||||
|
||||
kthread starved for 23807 jiffies! g7075 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1 ->cpu=5
|
||||
|
||||
Starving the grace-period kthreads of CPU time can of course result
|
||||
in RCU CPU stall warnings even when all CPUs and tasks have passed
|
||||
through the required quiescent states. The "g" number shows the current
|
||||
grace-period sequence number, the "f" precedes the ->gp_flags command
|
||||
to the grace-period kthread, the "RCU_GP_WAIT_FQS" indicates that the
|
||||
kthread is waiting for a short timeout, the "state" precedes value of the
|
||||
task_struct ->state field, and the "cpu" indicates that the grace-period
|
||||
kthread last ran on CPU 5.
|
||||
|
||||
|
||||
Multiple Warnings From One Stall
|
||||
================================
|
||||
|
||||
If a stall lasts long enough, multiple stall-warning messages will be
|
||||
printed for it. The second and subsequent messages are printed at
|
||||
longer intervals, so that the time between (say) the first and second
|
||||
message will be about three times the interval between the beginning
|
||||
of the stall and the first message.
|
||||
|
||||
|
||||
Stall Warnings for Expedited Grace Periods
|
||||
==========================================
|
||||
|
||||
If an expedited grace period detects a stall, it will place a message
|
||||
like the following in dmesg::
|
||||
|
||||
INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 7-... } 21119 jiffies s: 73 root: 0x2/.
|
||||
|
||||
This indicates that CPU 7 has failed to respond to a reschedule IPI.
|
||||
The three periods (".") following the CPU number indicate that the CPU
|
||||
is online (otherwise the first period would instead have been "O"),
|
||||
that the CPU was online at the beginning of the expedited grace period
|
||||
(otherwise the second period would have instead been "o"), and that
|
||||
the CPU has been online at least once since boot (otherwise, the third
|
||||
period would instead have been "N"). The number before the "jiffies"
|
||||
indicates that the expedited grace period has been going on for 21,119
|
||||
jiffies. The number following the "s:" indicates that the expedited
|
||||
grace-period sequence counter is 73. The fact that this last value is
|
||||
odd indicates that an expedited grace period is in flight. The number
|
||||
following "root:" is a bitmask that indicates which children of the root
|
||||
rcu_node structure correspond to CPUs and/or tasks that are blocking the
|
||||
current expedited grace period. If the tree had more than one level,
|
||||
additional hex numbers would be printed for the states of the other
|
||||
rcu_node structures in the tree.
|
||||
|
||||
As with normal grace periods, PREEMPT_RCU builds can be stalled by
|
||||
tasks as well as by CPUs, and that the tasks will be indicated by PID,
|
||||
for example, "P3421".
|
||||
|
||||
It is entirely possible to see stall warnings from normal and from
|
||||
expedited grace periods at about the same time during the same run.
|
||||
@@ -1,316 +0,0 @@
|
||||
Using RCU's CPU Stall Detector
|
||||
|
||||
This document first discusses what sorts of issues RCU's CPU stall
|
||||
detector can locate, and then discusses kernel parameters and Kconfig
|
||||
options that can be used to fine-tune the detector's operation. Finally,
|
||||
this document explains the stall detector's "splat" format.
|
||||
|
||||
|
||||
What Causes RCU CPU Stall Warnings?
|
||||
|
||||
So your kernel printed an RCU CPU stall warning. The next question is
|
||||
"What caused it?" The following problems can result in RCU CPU stall
|
||||
warnings:
|
||||
|
||||
o A CPU looping in an RCU read-side critical section.
|
||||
|
||||
o A CPU looping with interrupts disabled.
|
||||
|
||||
o A CPU looping with preemption disabled.
|
||||
|
||||
o A CPU looping with bottom halves disabled.
|
||||
|
||||
o For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
|
||||
without invoking schedule(). If the looping in the kernel is
|
||||
really expected and desirable behavior, you might need to add
|
||||
some calls to cond_resched().
|
||||
|
||||
o Booting Linux using a console connection that is too slow to
|
||||
keep up with the boot-time console-message rate. For example,
|
||||
a 115Kbaud serial console can be -way- too slow to keep up
|
||||
with boot-time message rates, and will frequently result in
|
||||
RCU CPU stall warning messages. Especially if you have added
|
||||
debug printk()s.
|
||||
|
||||
o Anything that prevents RCU's grace-period kthreads from running.
|
||||
This can result in the "All QSes seen" console-log message.
|
||||
This message will include information on when the kthread last
|
||||
ran and how often it should be expected to run. It can also
|
||||
result in the "rcu_.*kthread starved for" console-log message,
|
||||
which will include additional debugging information.
|
||||
|
||||
o A CPU-bound real-time task in a CONFIG_PREEMPT kernel, which might
|
||||
happen to preempt a low-priority task in the middle of an RCU
|
||||
read-side critical section. This is especially damaging if
|
||||
that low-priority task is not permitted to run on any other CPU,
|
||||
in which case the next RCU grace period can never complete, which
|
||||
will eventually cause the system to run out of memory and hang.
|
||||
While the system is in the process of running itself out of
|
||||
memory, you might see stall-warning messages.
|
||||
|
||||
o A CPU-bound real-time task in a CONFIG_PREEMPT_RT kernel that
|
||||
is running at a higher priority than the RCU softirq threads.
|
||||
This will prevent RCU callbacks from ever being invoked,
|
||||
and in a CONFIG_PREEMPT_RCU kernel will further prevent
|
||||
RCU grace periods from ever completing. Either way, the
|
||||
system will eventually run out of memory and hang. In the
|
||||
CONFIG_PREEMPT_RCU case, you might see stall-warning
|
||||
messages.
|
||||
|
||||
You can use the rcutree.kthread_prio kernel boot parameter to
|
||||
increase the scheduling priority of RCU's kthreads, which can
|
||||
help avoid this problem. However, please note that doing this
|
||||
can increase your system's context-switch rate and thus degrade
|
||||
performance.
|
||||
|
||||
o A periodic interrupt whose handler takes longer than the time
|
||||
interval between successive pairs of interrupts. This can
|
||||
prevent RCU's kthreads and softirq handlers from running.
|
||||
Note that certain high-overhead debugging options, for example
|
||||
the function_graph tracer, can result in interrupt handler taking
|
||||
considerably longer than normal, which can in turn result in
|
||||
RCU CPU stall warnings.
|
||||
|
||||
o Testing a workload on a fast system, tuning the stall-warning
|
||||
timeout down to just barely avoid RCU CPU stall warnings, and then
|
||||
running the same workload with the same stall-warning timeout on a
|
||||
slow system. Note that thermal throttling and on-demand governors
|
||||
can cause a single system to be sometimes fast and sometimes slow!
|
||||
|
||||
o A hardware or software issue shuts off the scheduler-clock
|
||||
interrupt on a CPU that is not in dyntick-idle mode. This
|
||||
problem really has happened, and seems to be most likely to
|
||||
result in RCU CPU stall warnings for CONFIG_NO_HZ_COMMON=n kernels.
|
||||
|
||||
o A bug in the RCU implementation.
|
||||
|
||||
o A hardware failure. This is quite unlikely, but has occurred
|
||||
at least once in real life. A CPU failed in a running system,
|
||||
becoming unresponsive, but not causing an immediate crash.
|
||||
This resulted in a series of RCU CPU stall warnings, eventually
|
||||
leading the realization that the CPU had failed.
|
||||
|
||||
The RCU, RCU-sched, and RCU-tasks implementations have CPU stall warning.
|
||||
Note that SRCU does -not- have CPU stall warnings. Please note that
|
||||
RCU only detects CPU stalls when there is a grace period in progress.
|
||||
No grace period, no CPU stall warnings.
|
||||
|
||||
To diagnose the cause of the stall, inspect the stack traces.
|
||||
The offending function will usually be near the top of the stack.
|
||||
If you have a series of stall warnings from a single extended stall,
|
||||
comparing the stack traces can often help determine where the stall
|
||||
is occurring, which will usually be in the function nearest the top of
|
||||
that portion of the stack which remains the same from trace to trace.
|
||||
If you can reliably trigger the stall, ftrace can be quite helpful.
|
||||
|
||||
RCU bugs can often be debugged with the help of CONFIG_RCU_TRACE
|
||||
and with RCU's event tracing. For information on RCU's event tracing,
|
||||
see include/trace/events/rcu.h.
|
||||
|
||||
|
||||
Fine-Tuning the RCU CPU Stall Detector
|
||||
|
||||
The rcuupdate.rcu_cpu_stall_suppress module parameter disables RCU's
|
||||
CPU stall detector, which detects conditions that unduly delay RCU grace
|
||||
periods. This module parameter enables CPU stall detection by default,
|
||||
but may be overridden via boot-time parameter or at runtime via sysfs.
|
||||
The stall detector's idea of what constitutes "unduly delayed" is
|
||||
controlled by a set of kernel configuration variables and cpp macros:
|
||||
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT
|
||||
|
||||
This kernel configuration parameter defines the period of time
|
||||
that RCU will wait from the beginning of a grace period until it
|
||||
issues an RCU CPU stall warning. This time period is normally
|
||||
21 seconds.
|
||||
|
||||
This configuration parameter may be changed at runtime via the
|
||||
/sys/module/rcupdate/parameters/rcu_cpu_stall_timeout, however
|
||||
this parameter is checked only at the beginning of a cycle.
|
||||
So if you are 10 seconds into a 40-second stall, setting this
|
||||
sysfs parameter to (say) five will shorten the timeout for the
|
||||
-next- stall, or the following warning for the current stall
|
||||
(assuming the stall lasts long enough). It will not affect the
|
||||
timing of the next warning for the current stall.
|
||||
|
||||
Stall-warning messages may be enabled and disabled completely via
|
||||
/sys/module/rcupdate/parameters/rcu_cpu_stall_suppress.
|
||||
|
||||
RCU_STALL_DELAY_DELTA
|
||||
|
||||
Although the lockdep facility is extremely useful, it does add
|
||||
some overhead. Therefore, under CONFIG_PROVE_RCU, the
|
||||
RCU_STALL_DELAY_DELTA macro allows five extra seconds before
|
||||
giving an RCU CPU stall warning message. (This is a cpp
|
||||
macro, not a kernel configuration parameter.)
|
||||
|
||||
RCU_STALL_RAT_DELAY
|
||||
|
||||
The CPU stall detector tries to make the offending CPU print its
|
||||
own warnings, as this often gives better-quality stack traces.
|
||||
However, if the offending CPU does not detect its own stall in
|
||||
the number of jiffies specified by RCU_STALL_RAT_DELAY, then
|
||||
some other CPU will complain. This delay is normally set to
|
||||
two jiffies. (This is a cpp macro, not a kernel configuration
|
||||
parameter.)
|
||||
|
||||
rcupdate.rcu_task_stall_timeout
|
||||
|
||||
This boot/sysfs parameter controls the RCU-tasks stall warning
|
||||
interval. A value of zero or less suppresses RCU-tasks stall
|
||||
warnings. A positive value sets the stall-warning interval
|
||||
in seconds. An RCU-tasks stall warning starts with the line:
|
||||
|
||||
INFO: rcu_tasks detected stalls on tasks:
|
||||
|
||||
And continues with the output of sched_show_task() for each
|
||||
task stalling the current RCU-tasks grace period.
|
||||
|
||||
|
||||
Interpreting RCU's CPU Stall-Detector "Splats"
|
||||
|
||||
For non-RCU-tasks flavors of RCU, when a CPU detects that it is stalling,
|
||||
it will print a message similar to the following:
|
||||
|
||||
INFO: rcu_sched detected stalls on CPUs/tasks:
|
||||
2-...: (3 GPs behind) idle=06c/0/0 softirq=1453/1455 fqs=0
|
||||
16-...: (0 ticks this GP) idle=81c/0/0 softirq=764/764 fqs=0
|
||||
(detected by 32, t=2603 jiffies, g=7075, q=625)
|
||||
|
||||
This message indicates that CPU 32 detected that CPUs 2 and 16 were both
|
||||
causing stalls, and that the stall was affecting RCU-sched. This message
|
||||
will normally be followed by stack dumps for each CPU. Please note that
|
||||
PREEMPT_RCU builds can be stalled by tasks as well as by CPUs, and that
|
||||
the tasks will be indicated by PID, for example, "P3421". It is even
|
||||
possible for an rcu_state stall to be caused by both CPUs -and- tasks,
|
||||
in which case the offending CPUs and tasks will all be called out in the list.
|
||||
|
||||
CPU 2's "(3 GPs behind)" indicates that this CPU has not interacted with
|
||||
the RCU core for the past three grace periods. In contrast, CPU 16's "(0
|
||||
ticks this GP)" indicates that this CPU has not taken any scheduling-clock
|
||||
interrupts during the current stalled grace period.
|
||||
|
||||
The "idle=" portion of the message prints the dyntick-idle state.
|
||||
The hex number before the first "/" is the low-order 12 bits of the
|
||||
dynticks counter, which will have an even-numbered value if the CPU
|
||||
is in dyntick-idle mode and an odd-numbered value otherwise. The hex
|
||||
number between the two "/"s is the value of the nesting, which will be
|
||||
a small non-negative number if in the idle loop (as shown above) and a
|
||||
very large positive number otherwise.
|
||||
|
||||
The "softirq=" portion of the message tracks the number of RCU softirq
|
||||
handlers that the stalled CPU has executed. The number before the "/"
|
||||
is the number that had executed since boot at the time that this CPU
|
||||
last noted the beginning of a grace period, which might be the current
|
||||
(stalled) grace period, or it might be some earlier grace period (for
|
||||
example, if the CPU might have been in dyntick-idle mode for an extended
|
||||
time period. The number after the "/" is the number that have executed
|
||||
since boot until the current time. If this latter number stays constant
|
||||
across repeated stall-warning messages, it is possible that RCU's softirq
|
||||
handlers are no longer able to execute on this CPU. This can happen if
|
||||
the stalled CPU is spinning with interrupts are disabled, or, in -rt
|
||||
kernels, if a high-priority process is starving RCU's softirq handler.
|
||||
|
||||
The "fqs=" shows the number of force-quiescent-state idle/offline
|
||||
detection passes that the grace-period kthread has made across this
|
||||
CPU since the last time that this CPU noted the beginning of a grace
|
||||
period.
|
||||
|
||||
The "detected by" line indicates which CPU detected the stall (in this
|
||||
case, CPU 32), how many jiffies have elapsed since the start of the grace
|
||||
period (in this case 2603), the grace-period sequence number (7075), and
|
||||
an estimate of the total number of RCU callbacks queued across all CPUs
|
||||
(625 in this case).
|
||||
|
||||
In kernels with CONFIG_RCU_FAST_NO_HZ, more information is printed
|
||||
for each CPU:
|
||||
|
||||
0: (64628 ticks this GP) idle=dd5/3fffffffffffffff/0 softirq=82/543 last_accelerate: a345/d342 dyntick_enabled: 1
|
||||
|
||||
The "last_accelerate:" prints the low-order 16 bits (in hex) of the
|
||||
jiffies counter when this CPU last invoked rcu_try_advance_all_cbs()
|
||||
from rcu_needs_cpu() or last invoked rcu_accelerate_cbs() from
|
||||
rcu_prepare_for_idle(). "dyntick_enabled: 1" indicates that dyntick-idle
|
||||
processing is enabled.
|
||||
|
||||
If the grace period ends just as the stall warning starts printing,
|
||||
there will be a spurious stall-warning message, which will include
|
||||
the following:
|
||||
|
||||
INFO: Stall ended before state dump start
|
||||
|
||||
This is rare, but does happen from time to time in real life. It is also
|
||||
possible for a zero-jiffy stall to be flagged in this case, depending
|
||||
on how the stall warning and the grace-period initialization happen to
|
||||
interact. Please note that it is not possible to entirely eliminate this
|
||||
sort of false positive without resorting to things like stop_machine(),
|
||||
which is overkill for this sort of problem.
|
||||
|
||||
If all CPUs and tasks have passed through quiescent states, but the
|
||||
grace period has nevertheless failed to end, the stall-warning splat
|
||||
will include something like the following:
|
||||
|
||||
All QSes seen, last rcu_preempt kthread activity 23807 (4297905177-4297881370), jiffies_till_next_fqs=3, root ->qsmask 0x0
|
||||
|
||||
The "23807" indicates that it has been more than 23 thousand jiffies
|
||||
since the grace-period kthread ran. The "jiffies_till_next_fqs"
|
||||
indicates how frequently that kthread should run, giving the number
|
||||
of jiffies between force-quiescent-state scans, in this case three,
|
||||
which is way less than 23807. Finally, the root rcu_node structure's
|
||||
->qsmask field is printed, which will normally be zero.
|
||||
|
||||
If the relevant grace-period kthread has been unable to run prior to
|
||||
the stall warning, as was the case in the "All QSes seen" line above,
|
||||
the following additional line is printed:
|
||||
|
||||
kthread starved for 23807 jiffies! g7075 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1 ->cpu=5
|
||||
|
||||
Starving the grace-period kthreads of CPU time can of course result
|
||||
in RCU CPU stall warnings even when all CPUs and tasks have passed
|
||||
through the required quiescent states. The "g" number shows the current
|
||||
grace-period sequence number, the "f" precedes the ->gp_flags command
|
||||
to the grace-period kthread, the "RCU_GP_WAIT_FQS" indicates that the
|
||||
kthread is waiting for a short timeout, the "state" precedes value of the
|
||||
task_struct ->state field, and the "cpu" indicates that the grace-period
|
||||
kthread last ran on CPU 5.
|
||||
|
||||
|
||||
Multiple Warnings From One Stall
|
||||
|
||||
If a stall lasts long enough, multiple stall-warning messages will be
|
||||
printed for it. The second and subsequent messages are printed at
|
||||
longer intervals, so that the time between (say) the first and second
|
||||
message will be about three times the interval between the beginning
|
||||
of the stall and the first message.
|
||||
|
||||
|
||||
Stall Warnings for Expedited Grace Periods
|
||||
|
||||
If an expedited grace period detects a stall, it will place a message
|
||||
like the following in dmesg:
|
||||
|
||||
INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 7-... } 21119 jiffies s: 73 root: 0x2/.
|
||||
|
||||
This indicates that CPU 7 has failed to respond to a reschedule IPI.
|
||||
The three periods (".") following the CPU number indicate that the CPU
|
||||
is online (otherwise the first period would instead have been "O"),
|
||||
that the CPU was online at the beginning of the expedited grace period
|
||||
(otherwise the second period would have instead been "o"), and that
|
||||
the CPU has been online at least once since boot (otherwise, the third
|
||||
period would instead have been "N"). The number before the "jiffies"
|
||||
indicates that the expedited grace period has been going on for 21,119
|
||||
jiffies. The number following the "s:" indicates that the expedited
|
||||
grace-period sequence counter is 73. The fact that this last value is
|
||||
odd indicates that an expedited grace period is in flight. The number
|
||||
following "root:" is a bitmask that indicates which children of the root
|
||||
rcu_node structure correspond to CPUs and/or tasks that are blocking the
|
||||
current expedited grace period. If the tree had more than one level,
|
||||
additional hex numbers would be printed for the states of the other
|
||||
rcu_node structures in the tree.
|
||||
|
||||
As with normal grace periods, PREEMPT_RCU builds can be stalled by
|
||||
tasks as well as by CPUs, and that the tasks will be indicated by PID,
|
||||
for example, "P3421".
|
||||
|
||||
It is entirely possible to see stall warnings from normal and from
|
||||
expedited grace periods at about the same time during the same run.
|
||||
@@ -0,0 +1,293 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
==========================
|
||||
RCU Torture Test Operation
|
||||
==========================
|
||||
|
||||
|
||||
CONFIG_RCU_TORTURE_TEST
|
||||
=======================
|
||||
|
||||
The CONFIG_RCU_TORTURE_TEST config option is available for all RCU
|
||||
implementations. It creates an rcutorture kernel module that can
|
||||
be loaded to run a torture test. The test periodically outputs
|
||||
status messages via printk(), which can be examined via the dmesg
|
||||
command (perhaps grepping for "torture"). The test is started
|
||||
when the module is loaded, and stops when the module is unloaded.
|
||||
|
||||
Module parameters are prefixed by "rcutorture." in
|
||||
Documentation/admin-guide/kernel-parameters.txt.
|
||||
|
||||
Output
|
||||
======
|
||||
|
||||
The statistics output is as follows::
|
||||
|
||||
rcu-torture:--- Start of test: nreaders=16 nfakewriters=4 stat_interval=30 verbose=0 test_no_idle_hz=1 shuffle_interval=3 stutter=5 irqreader=1 fqs_duration=0 fqs_holdoff=0 fqs_stutter=3 test_boost=1/0 test_boost_interval=7 test_boost_duration=4
|
||||
rcu-torture: rtc: (null) ver: 155441 tfle: 0 rta: 155441 rtaf: 8884 rtf: 155440 rtmbe: 0 rtbe: 0 rtbke: 0 rtbre: 0 rtbf: 0 rtb: 0 nt: 3055767
|
||||
rcu-torture: Reader Pipe: 727860534 34213 0 0 0 0 0 0 0 0 0
|
||||
rcu-torture: Reader Batch: 727877838 17003 0 0 0 0 0 0 0 0 0
|
||||
rcu-torture: Free-Block Circulation: 155440 155440 155440 155440 155440 155440 155440 155440 155440 155440 0
|
||||
rcu-torture:--- End of test: SUCCESS: nreaders=16 nfakewriters=4 stat_interval=30 verbose=0 test_no_idle_hz=1 shuffle_interval=3 stutter=5 irqreader=1 fqs_duration=0 fqs_holdoff=0 fqs_stutter=3 test_boost=1/0 test_boost_interval=7 test_boost_duration=4
|
||||
|
||||
The command "dmesg | grep torture:" will extract this information on
|
||||
most systems. On more esoteric configurations, it may be necessary to
|
||||
use other commands to access the output of the printk()s used by
|
||||
the RCU torture test. The printk()s use KERN_ALERT, so they should
|
||||
be evident. ;-)
|
||||
|
||||
The first and last lines show the rcutorture module parameters, and the
|
||||
last line shows either "SUCCESS" or "FAILURE", based on rcutorture's
|
||||
automatic determination as to whether RCU operated correctly.
|
||||
|
||||
The entries are as follows:
|
||||
|
||||
* "rtc": The hexadecimal address of the structure currently visible
|
||||
to readers.
|
||||
|
||||
* "ver": The number of times since boot that the RCU writer task
|
||||
has changed the structure visible to readers.
|
||||
|
||||
* "tfle": If non-zero, indicates that the "torture freelist"
|
||||
containing structures to be placed into the "rtc" area is empty.
|
||||
This condition is important, since it can fool you into thinking
|
||||
that RCU is working when it is not. :-/
|
||||
|
||||
* "rta": Number of structures allocated from the torture freelist.
|
||||
|
||||
* "rtaf": Number of allocations from the torture freelist that have
|
||||
failed due to the list being empty. It is not unusual for this
|
||||
to be non-zero, but it is bad for it to be a large fraction of
|
||||
the value indicated by "rta".
|
||||
|
||||
* "rtf": Number of frees into the torture freelist.
|
||||
|
||||
* "rtmbe": A non-zero value indicates that rcutorture believes that
|
||||
rcu_assign_pointer() and rcu_dereference() are not working
|
||||
correctly. This value should be zero.
|
||||
|
||||
* "rtbe": A non-zero value indicates that one of the rcu_barrier()
|
||||
family of functions is not working correctly.
|
||||
|
||||
* "rtbke": rcutorture was unable to create the real-time kthreads
|
||||
used to force RCU priority inversion. This value should be zero.
|
||||
|
||||
* "rtbre": Although rcutorture successfully created the kthreads
|
||||
used to force RCU priority inversion, it was unable to set them
|
||||
to the real-time priority level of 1. This value should be zero.
|
||||
|
||||
* "rtbf": The number of times that RCU priority boosting failed
|
||||
to resolve RCU priority inversion.
|
||||
|
||||
* "rtb": The number of times that rcutorture attempted to force
|
||||
an RCU priority inversion condition. If you are testing RCU
|
||||
priority boosting via the "test_boost" module parameter, this
|
||||
value should be non-zero.
|
||||
|
||||
* "nt": The number of times rcutorture ran RCU read-side code from
|
||||
within a timer handler. This value should be non-zero only
|
||||
if you specified the "irqreader" module parameter.
|
||||
|
||||
* "Reader Pipe": Histogram of "ages" of structures seen by readers.
|
||||
If any entries past the first two are non-zero, RCU is broken.
|
||||
And rcutorture prints the error flag string "!!!" to make sure
|
||||
you notice. The age of a newly allocated structure is zero,
|
||||
it becomes one when removed from reader visibility, and is
|
||||
incremented once per grace period subsequently -- and is freed
|
||||
after passing through (RCU_TORTURE_PIPE_LEN-2) grace periods.
|
||||
|
||||
The output displayed above was taken from a correctly working
|
||||
RCU. If you want to see what it looks like when broken, break
|
||||
it yourself. ;-)
|
||||
|
||||
* "Reader Batch": Another histogram of "ages" of structures seen
|
||||
by readers, but in terms of counter flips (or batches) rather
|
||||
than in terms of grace periods. The legal number of non-zero
|
||||
entries is again two. The reason for this separate view is that
|
||||
it is sometimes easier to get the third entry to show up in the
|
||||
"Reader Batch" list than in the "Reader Pipe" list.
|
||||
|
||||
* "Free-Block Circulation": Shows the number of torture structures
|
||||
that have reached a given point in the pipeline. The first element
|
||||
should closely correspond to the number of structures allocated,
|
||||
the second to the number that have been removed from reader view,
|
||||
and all but the last remaining to the corresponding number of
|
||||
passes through a grace period. The last entry should be zero,
|
||||
as it is only incremented if a torture structure's counter
|
||||
somehow gets incremented farther than it should.
|
||||
|
||||
Different implementations of RCU can provide implementation-specific
|
||||
additional information. For example, Tree SRCU provides the following
|
||||
additional line::
|
||||
|
||||
srcud-torture: Tree SRCU per-CPU(idx=0): 0(35,-21) 1(-4,24) 2(1,1) 3(-26,20) 4(28,-47) 5(-9,4) 6(-10,14) 7(-14,11) T(1,6)
|
||||
|
||||
This line shows the per-CPU counter state, in this case for Tree SRCU
|
||||
using a dynamically allocated srcu_struct (hence "srcud-" rather than
|
||||
"srcu-"). The numbers in parentheses are the values of the "old" and
|
||||
"current" counters for the corresponding CPU. The "idx" value maps the
|
||||
"old" and "current" values to the underlying array, and is useful for
|
||||
debugging. The final "T" entry contains the totals of the counters.
|
||||
|
||||
Usage on Specific Kernel Builds
|
||||
===============================
|
||||
|
||||
It is sometimes desirable to torture RCU on a specific kernel build,
|
||||
for example, when preparing to put that kernel build into production.
|
||||
In that case, the kernel should be built with CONFIG_RCU_TORTURE_TEST=m
|
||||
so that the test can be started using modprobe and terminated using rmmod.
|
||||
|
||||
For example, the following script may be used to torture RCU::
|
||||
|
||||
#!/bin/sh
|
||||
|
||||
modprobe rcutorture
|
||||
sleep 3600
|
||||
rmmod rcutorture
|
||||
dmesg | grep torture:
|
||||
|
||||
The output can be manually inspected for the error flag of "!!!".
|
||||
One could of course create a more elaborate script that automatically
|
||||
checked for such errors. The "rmmod" command forces a "SUCCESS",
|
||||
"FAILURE", or "RCU_HOTPLUG" indication to be printk()ed. The first
|
||||
two are self-explanatory, while the last indicates that while there
|
||||
were no RCU failures, CPU-hotplug problems were detected.
|
||||
|
||||
|
||||
Usage on Mainline Kernels
|
||||
=========================
|
||||
|
||||
When using rcutorture to test changes to RCU itself, it is often
|
||||
necessary to build a number of kernels in order to test that change
|
||||
across a broad range of combinations of the relevant Kconfig options
|
||||
and of the relevant kernel boot parameters. In this situation, use
|
||||
of modprobe and rmmod can be quite time-consuming and error-prone.
|
||||
|
||||
Therefore, the tools/testing/selftests/rcutorture/bin/kvm.sh
|
||||
script is available for mainline testing for x86, arm64, and
|
||||
powerpc. By default, it will run the series of tests specified by
|
||||
tools/testing/selftests/rcutorture/configs/rcu/CFLIST, with each test
|
||||
running for 30 minutes within a guest OS using a minimal userspace
|
||||
supplied by an automatically generated initrd. After the tests are
|
||||
complete, the resulting build products and console output are analyzed
|
||||
for errors and the results of the runs are summarized.
|
||||
|
||||
On larger systems, rcutorture testing can be accelerated by passing the
|
||||
--cpus argument to kvm.sh. For example, on a 64-CPU system, "--cpus 43"
|
||||
would use up to 43 CPUs to run tests concurrently, which as of v5.4 would
|
||||
complete all the scenarios in two batches, reducing the time to complete
|
||||
from about eight hours to about one hour (not counting the time to build
|
||||
the sixteen kernels). The "--dryrun sched" argument will not run tests,
|
||||
but rather tell you how the tests would be scheduled into batches. This
|
||||
can be useful when working out how many CPUs to specify in the --cpus
|
||||
argument.
|
||||
|
||||
Not all changes require that all scenarios be run. For example, a change
|
||||
to Tree SRCU might run only the SRCU-N and SRCU-P scenarios using the
|
||||
--configs argument to kvm.sh as follows: "--configs 'SRCU-N SRCU-P'".
|
||||
Large systems can run multiple copies of of the full set of scenarios,
|
||||
for example, a system with 448 hardware threads can run five instances
|
||||
of the full set concurrently. To make this happen::
|
||||
|
||||
kvm.sh --cpus 448 --configs '5*CFLIST'
|
||||
|
||||
Alternatively, such a system can run 56 concurrent instances of a single
|
||||
eight-CPU scenario::
|
||||
|
||||
kvm.sh --cpus 448 --configs '56*TREE04'
|
||||
|
||||
Or 28 concurrent instances of each of two eight-CPU scenarios::
|
||||
|
||||
kvm.sh --cpus 448 --configs '28*TREE03 28*TREE04'
|
||||
|
||||
Of course, each concurrent instance will use memory, which can be
|
||||
limited using the --memory argument, which defaults to 512M. Small
|
||||
values for memory may require disabling the callback-flooding tests
|
||||
using the --bootargs parameter discussed below.
|
||||
|
||||
Sometimes additional debugging is useful, and in such cases the --kconfig
|
||||
parameter to kvm.sh may be used, for example, ``--kconfig 'CONFIG_KASAN=y'``.
|
||||
|
||||
Kernel boot arguments can also be supplied, for example, to control
|
||||
rcutorture's module parameters. For example, to test a change to RCU's
|
||||
CPU stall-warning code, use "--bootargs 'rcutorture.stall_cpu=30'".
|
||||
This will of course result in the scripting reporting a failure, namely
|
||||
the resuling RCU CPU stall warning. As noted above, reducing memory may
|
||||
require disabling rcutorture's callback-flooding tests::
|
||||
|
||||
kvm.sh --cpus 448 --configs '56*TREE04' --memory 128M \
|
||||
--bootargs 'rcutorture.fwd_progress=0'
|
||||
|
||||
Sometimes all that is needed is a full set of kernel builds. This is
|
||||
what the --buildonly argument does.
|
||||
|
||||
Finally, the --trust-make argument allows each kernel build to reuse what
|
||||
it can from the previous kernel build.
|
||||
|
||||
There are additional more arcane arguments that are documented in the
|
||||
source code of the kvm.sh script.
|
||||
|
||||
If a run contains failures, the number of buildtime and runtime failures
|
||||
is listed at the end of the kvm.sh output, which you really should redirect
|
||||
to a file. The build products and console output of each run is kept in
|
||||
tools/testing/selftests/rcutorture/res in timestamped directories. A
|
||||
given directory can be supplied to kvm-find-errors.sh in order to have
|
||||
it cycle you through summaries of errors and full error logs. For example::
|
||||
|
||||
tools/testing/selftests/rcutorture/bin/kvm-find-errors.sh \
|
||||
tools/testing/selftests/rcutorture/res/2020.01.20-15.54.23
|
||||
|
||||
However, it is often more convenient to access the files directly.
|
||||
Files pertaining to all scenarios in a run reside in the top-level
|
||||
directory (2020.01.20-15.54.23 in the example above), while per-scenario
|
||||
files reside in a subdirectory named after the scenario (for example,
|
||||
"TREE04"). If a given scenario ran more than once (as in "--configs
|
||||
'56*TREE04'" above), the directories corresponding to the second and
|
||||
subsequent runs of that scenario include a sequence number, for example,
|
||||
"TREE04.2", "TREE04.3", and so on.
|
||||
|
||||
The most frequently used file in the top-level directory is testid.txt.
|
||||
If the test ran in a git repository, then this file contains the commit
|
||||
that was tested and any uncommitted changes in diff format.
|
||||
|
||||
The most frequently used files in each per-scenario-run directory are:
|
||||
|
||||
.config:
|
||||
This file contains the Kconfig options.
|
||||
|
||||
Make.out:
|
||||
This contains build output for a specific scenario.
|
||||
|
||||
console.log:
|
||||
This contains the console output for a specific scenario.
|
||||
This file may be examined once the kernel has booted, but
|
||||
it might not exist if the build failed.
|
||||
|
||||
vmlinux:
|
||||
This contains the kernel, which can be useful with tools like
|
||||
objdump and gdb.
|
||||
|
||||
A number of additional files are available, but are less frequently used.
|
||||
Many are intended for debugging of rcutorture itself or of its scripting.
|
||||
|
||||
As of v5.4, a successful run with the default set of scenarios produces
|
||||
the following summary at the end of the run on a 12-CPU system::
|
||||
|
||||
SRCU-N ------- 804233 GPs (148.932/s) [srcu: g10008272 f0x0 ]
|
||||
SRCU-P ------- 202320 GPs (37.4667/s) [srcud: g1809476 f0x0 ]
|
||||
SRCU-t ------- 1122086 GPs (207.794/s) [srcu: g0 f0x0 ]
|
||||
SRCU-u ------- 1111285 GPs (205.794/s) [srcud: g1 f0x0 ]
|
||||
TASKS01 ------- 19666 GPs (3.64185/s) [tasks: g0 f0x0 ]
|
||||
TASKS02 ------- 20541 GPs (3.80389/s) [tasks: g0 f0x0 ]
|
||||
TASKS03 ------- 19416 GPs (3.59556/s) [tasks: g0 f0x0 ]
|
||||
TINY01 ------- 836134 GPs (154.84/s) [rcu: g0 f0x0 ] n_max_cbs: 34198
|
||||
TINY02 ------- 850371 GPs (157.476/s) [rcu: g0 f0x0 ] n_max_cbs: 2631
|
||||
TREE01 ------- 162625 GPs (30.1157/s) [rcu: g1124169 f0x0 ]
|
||||
TREE02 ------- 333003 GPs (61.6672/s) [rcu: g2647753 f0x0 ] n_max_cbs: 35844
|
||||
TREE03 ------- 306623 GPs (56.782/s) [rcu: g2975325 f0x0 ] n_max_cbs: 1496497
|
||||
CPU count limited from 16 to 12
|
||||
TREE04 ------- 246149 GPs (45.5831/s) [rcu: g1695737 f0x0 ] n_max_cbs: 434961
|
||||
TREE05 ------- 314603 GPs (58.2598/s) [rcu: g2257741 f0x2 ] n_max_cbs: 193997
|
||||
TREE07 ------- 167347 GPs (30.9902/s) [rcu: g1079021 f0x0 ] n_max_cbs: 478732
|
||||
CPU count limited from 16 to 12
|
||||
TREE09 ------- 752238 GPs (139.303/s) [rcu: g13075057 f0x0 ] n_max_cbs: 99011
|
||||
@@ -1,282 +0,0 @@
|
||||
RCU Torture Test Operation
|
||||
|
||||
|
||||
CONFIG_RCU_TORTURE_TEST
|
||||
|
||||
The CONFIG_RCU_TORTURE_TEST config option is available for all RCU
|
||||
implementations. It creates an rcutorture kernel module that can
|
||||
be loaded to run a torture test. The test periodically outputs
|
||||
status messages via printk(), which can be examined via the dmesg
|
||||
command (perhaps grepping for "torture"). The test is started
|
||||
when the module is loaded, and stops when the module is unloaded.
|
||||
|
||||
Module parameters are prefixed by "rcutorture." in
|
||||
Documentation/admin-guide/kernel-parameters.txt.
|
||||
|
||||
OUTPUT
|
||||
|
||||
The statistics output is as follows:
|
||||
|
||||
rcu-torture:--- Start of test: nreaders=16 nfakewriters=4 stat_interval=30 verbose=0 test_no_idle_hz=1 shuffle_interval=3 stutter=5 irqreader=1 fqs_duration=0 fqs_holdoff=0 fqs_stutter=3 test_boost=1/0 test_boost_interval=7 test_boost_duration=4
|
||||
rcu-torture: rtc: (null) ver: 155441 tfle: 0 rta: 155441 rtaf: 8884 rtf: 155440 rtmbe: 0 rtbe: 0 rtbke: 0 rtbre: 0 rtbf: 0 rtb: 0 nt: 3055767
|
||||
rcu-torture: Reader Pipe: 727860534 34213 0 0 0 0 0 0 0 0 0
|
||||
rcu-torture: Reader Batch: 727877838 17003 0 0 0 0 0 0 0 0 0
|
||||
rcu-torture: Free-Block Circulation: 155440 155440 155440 155440 155440 155440 155440 155440 155440 155440 0
|
||||
rcu-torture:--- End of test: SUCCESS: nreaders=16 nfakewriters=4 stat_interval=30 verbose=0 test_no_idle_hz=1 shuffle_interval=3 stutter=5 irqreader=1 fqs_duration=0 fqs_holdoff=0 fqs_stutter=3 test_boost=1/0 test_boost_interval=7 test_boost_duration=4
|
||||
|
||||
The command "dmesg | grep torture:" will extract this information on
|
||||
most systems. On more esoteric configurations, it may be necessary to
|
||||
use other commands to access the output of the printk()s used by
|
||||
the RCU torture test. The printk()s use KERN_ALERT, so they should
|
||||
be evident. ;-)
|
||||
|
||||
The first and last lines show the rcutorture module parameters, and the
|
||||
last line shows either "SUCCESS" or "FAILURE", based on rcutorture's
|
||||
automatic determination as to whether RCU operated correctly.
|
||||
|
||||
The entries are as follows:
|
||||
|
||||
o "rtc": The hexadecimal address of the structure currently visible
|
||||
to readers.
|
||||
|
||||
o "ver": The number of times since boot that the RCU writer task
|
||||
has changed the structure visible to readers.
|
||||
|
||||
o "tfle": If non-zero, indicates that the "torture freelist"
|
||||
containing structures to be placed into the "rtc" area is empty.
|
||||
This condition is important, since it can fool you into thinking
|
||||
that RCU is working when it is not. :-/
|
||||
|
||||
o "rta": Number of structures allocated from the torture freelist.
|
||||
|
||||
o "rtaf": Number of allocations from the torture freelist that have
|
||||
failed due to the list being empty. It is not unusual for this
|
||||
to be non-zero, but it is bad for it to be a large fraction of
|
||||
the value indicated by "rta".
|
||||
|
||||
o "rtf": Number of frees into the torture freelist.
|
||||
|
||||
o "rtmbe": A non-zero value indicates that rcutorture believes that
|
||||
rcu_assign_pointer() and rcu_dereference() are not working
|
||||
correctly. This value should be zero.
|
||||
|
||||
o "rtbe": A non-zero value indicates that one of the rcu_barrier()
|
||||
family of functions is not working correctly.
|
||||
|
||||
o "rtbke": rcutorture was unable to create the real-time kthreads
|
||||
used to force RCU priority inversion. This value should be zero.
|
||||
|
||||
o "rtbre": Although rcutorture successfully created the kthreads
|
||||
used to force RCU priority inversion, it was unable to set them
|
||||
to the real-time priority level of 1. This value should be zero.
|
||||
|
||||
o "rtbf": The number of times that RCU priority boosting failed
|
||||
to resolve RCU priority inversion.
|
||||
|
||||
o "rtb": The number of times that rcutorture attempted to force
|
||||
an RCU priority inversion condition. If you are testing RCU
|
||||
priority boosting via the "test_boost" module parameter, this
|
||||
value should be non-zero.
|
||||
|
||||
o "nt": The number of times rcutorture ran RCU read-side code from
|
||||
within a timer handler. This value should be non-zero only
|
||||
if you specified the "irqreader" module parameter.
|
||||
|
||||
o "Reader Pipe": Histogram of "ages" of structures seen by readers.
|
||||
If any entries past the first two are non-zero, RCU is broken.
|
||||
And rcutorture prints the error flag string "!!!" to make sure
|
||||
you notice. The age of a newly allocated structure is zero,
|
||||
it becomes one when removed from reader visibility, and is
|
||||
incremented once per grace period subsequently -- and is freed
|
||||
after passing through (RCU_TORTURE_PIPE_LEN-2) grace periods.
|
||||
|
||||
The output displayed above was taken from a correctly working
|
||||
RCU. If you want to see what it looks like when broken, break
|
||||
it yourself. ;-)
|
||||
|
||||
o "Reader Batch": Another histogram of "ages" of structures seen
|
||||
by readers, but in terms of counter flips (or batches) rather
|
||||
than in terms of grace periods. The legal number of non-zero
|
||||
entries is again two. The reason for this separate view is that
|
||||
it is sometimes easier to get the third entry to show up in the
|
||||
"Reader Batch" list than in the "Reader Pipe" list.
|
||||
|
||||
o "Free-Block Circulation": Shows the number of torture structures
|
||||
that have reached a given point in the pipeline. The first element
|
||||
should closely correspond to the number of structures allocated,
|
||||
the second to the number that have been removed from reader view,
|
||||
and all but the last remaining to the corresponding number of
|
||||
passes through a grace period. The last entry should be zero,
|
||||
as it is only incremented if a torture structure's counter
|
||||
somehow gets incremented farther than it should.
|
||||
|
||||
Different implementations of RCU can provide implementation-specific
|
||||
additional information. For example, Tree SRCU provides the following
|
||||
additional line:
|
||||
|
||||
srcud-torture: Tree SRCU per-CPU(idx=0): 0(35,-21) 1(-4,24) 2(1,1) 3(-26,20) 4(28,-47) 5(-9,4) 6(-10,14) 7(-14,11) T(1,6)
|
||||
|
||||
This line shows the per-CPU counter state, in this case for Tree SRCU
|
||||
using a dynamically allocated srcu_struct (hence "srcud-" rather than
|
||||
"srcu-"). The numbers in parentheses are the values of the "old" and
|
||||
"current" counters for the corresponding CPU. The "idx" value maps the
|
||||
"old" and "current" values to the underlying array, and is useful for
|
||||
debugging. The final "T" entry contains the totals of the counters.
|
||||
|
||||
|
||||
USAGE ON SPECIFIC KERNEL BUILDS
|
||||
|
||||
It is sometimes desirable to torture RCU on a specific kernel build,
|
||||
for example, when preparing to put that kernel build into production.
|
||||
In that case, the kernel should be built with CONFIG_RCU_TORTURE_TEST=m
|
||||
so that the test can be started using modprobe and terminated using rmmod.
|
||||
|
||||
For example, the following script may be used to torture RCU:
|
||||
|
||||
#!/bin/sh
|
||||
|
||||
modprobe rcutorture
|
||||
sleep 3600
|
||||
rmmod rcutorture
|
||||
dmesg | grep torture:
|
||||
|
||||
The output can be manually inspected for the error flag of "!!!".
|
||||
One could of course create a more elaborate script that automatically
|
||||
checked for such errors. The "rmmod" command forces a "SUCCESS",
|
||||
"FAILURE", or "RCU_HOTPLUG" indication to be printk()ed. The first
|
||||
two are self-explanatory, while the last indicates that while there
|
||||
were no RCU failures, CPU-hotplug problems were detected.
|
||||
|
||||
|
||||
USAGE ON MAINLINE KERNELS
|
||||
|
||||
When using rcutorture to test changes to RCU itself, it is often
|
||||
necessary to build a number of kernels in order to test that change
|
||||
across a broad range of combinations of the relevant Kconfig options
|
||||
and of the relevant kernel boot parameters. In this situation, use
|
||||
of modprobe and rmmod can be quite time-consuming and error-prone.
|
||||
|
||||
Therefore, the tools/testing/selftests/rcutorture/bin/kvm.sh
|
||||
script is available for mainline testing for x86, arm64, and
|
||||
powerpc. By default, it will run the series of tests specified by
|
||||
tools/testing/selftests/rcutorture/configs/rcu/CFLIST, with each test
|
||||
running for 30 minutes within a guest OS using a minimal userspace
|
||||
supplied by an automatically generated initrd. After the tests are
|
||||
complete, the resulting build products and console output are analyzed
|
||||
for errors and the results of the runs are summarized.
|
||||
|
||||
On larger systems, rcutorture testing can be accelerated by passing the
|
||||
--cpus argument to kvm.sh. For example, on a 64-CPU system, "--cpus 43"
|
||||
would use up to 43 CPUs to run tests concurrently, which as of v5.4 would
|
||||
complete all the scenarios in two batches, reducing the time to complete
|
||||
from about eight hours to about one hour (not counting the time to build
|
||||
the sixteen kernels). The "--dryrun sched" argument will not run tests,
|
||||
but rather tell you how the tests would be scheduled into batches. This
|
||||
can be useful when working out how many CPUs to specify in the --cpus
|
||||
argument.
|
||||
|
||||
Not all changes require that all scenarios be run. For example, a change
|
||||
to Tree SRCU might run only the SRCU-N and SRCU-P scenarios using the
|
||||
--configs argument to kvm.sh as follows: "--configs 'SRCU-N SRCU-P'".
|
||||
Large systems can run multiple copies of of the full set of scenarios,
|
||||
for example, a system with 448 hardware threads can run five instances
|
||||
of the full set concurrently. To make this happen:
|
||||
|
||||
kvm.sh --cpus 448 --configs '5*CFLIST'
|
||||
|
||||
Alternatively, such a system can run 56 concurrent instances of a single
|
||||
eight-CPU scenario:
|
||||
|
||||
kvm.sh --cpus 448 --configs '56*TREE04'
|
||||
|
||||
Or 28 concurrent instances of each of two eight-CPU scenarios:
|
||||
|
||||
kvm.sh --cpus 448 --configs '28*TREE03 28*TREE04'
|
||||
|
||||
Of course, each concurrent instance will use memory, which can be
|
||||
limited using the --memory argument, which defaults to 512M. Small
|
||||
values for memory may require disabling the callback-flooding tests
|
||||
using the --bootargs parameter discussed below.
|
||||
|
||||
Sometimes additional debugging is useful, and in such cases the --kconfig
|
||||
parameter to kvm.sh may be used, for example, "--kconfig 'CONFIG_KASAN=y'".
|
||||
|
||||
Kernel boot arguments can also be supplied, for example, to control
|
||||
rcutorture's module parameters. For example, to test a change to RCU's
|
||||
CPU stall-warning code, use "--bootargs 'rcutorture.stall_cpu=30'".
|
||||
This will of course result in the scripting reporting a failure, namely
|
||||
the resuling RCU CPU stall warning. As noted above, reducing memory may
|
||||
require disabling rcutorture's callback-flooding tests:
|
||||
|
||||
kvm.sh --cpus 448 --configs '56*TREE04' --memory 128M \
|
||||
--bootargs 'rcutorture.fwd_progress=0'
|
||||
|
||||
Sometimes all that is needed is a full set of kernel builds. This is
|
||||
what the --buildonly argument does.
|
||||
|
||||
Finally, the --trust-make argument allows each kernel build to reuse what
|
||||
it can from the previous kernel build.
|
||||
|
||||
There are additional more arcane arguments that are documented in the
|
||||
source code of the kvm.sh script.
|
||||
|
||||
If a run contains failures, the number of buildtime and runtime failures
|
||||
is listed at the end of the kvm.sh output, which you really should redirect
|
||||
to a file. The build products and console output of each run is kept in
|
||||
tools/testing/selftests/rcutorture/res in timestamped directories. A
|
||||
given directory can be supplied to kvm-find-errors.sh in order to have
|
||||
it cycle you through summaries of errors and full error logs. For example:
|
||||
|
||||
tools/testing/selftests/rcutorture/bin/kvm-find-errors.sh \
|
||||
tools/testing/selftests/rcutorture/res/2020.01.20-15.54.23
|
||||
|
||||
However, it is often more convenient to access the files directly.
|
||||
Files pertaining to all scenarios in a run reside in the top-level
|
||||
directory (2020.01.20-15.54.23 in the example above), while per-scenario
|
||||
files reside in a subdirectory named after the scenario (for example,
|
||||
"TREE04"). If a given scenario ran more than once (as in "--configs
|
||||
'56*TREE04'" above), the directories corresponding to the second and
|
||||
subsequent runs of that scenario include a sequence number, for example,
|
||||
"TREE04.2", "TREE04.3", and so on.
|
||||
|
||||
The most frequently used file in the top-level directory is testid.txt.
|
||||
If the test ran in a git repository, then this file contains the commit
|
||||
that was tested and any uncommitted changes in diff format.
|
||||
|
||||
The most frequently used files in each per-scenario-run directory are:
|
||||
|
||||
.config: This file contains the Kconfig options.
|
||||
|
||||
Make.out: This contains build output for a specific scenario.
|
||||
|
||||
console.log: This contains the console output for a specific scenario.
|
||||
This file may be examined once the kernel has booted, but
|
||||
it might not exist if the build failed.
|
||||
|
||||
vmlinux: This contains the kernel, which can be useful with tools like
|
||||
objdump and gdb.
|
||||
|
||||
A number of additional files are available, but are less frequently used.
|
||||
Many are intended for debugging of rcutorture itself or of its scripting.
|
||||
|
||||
As of v5.4, a successful run with the default set of scenarios produces
|
||||
the following summary at the end of the run on a 12-CPU system:
|
||||
|
||||
SRCU-N ------- 804233 GPs (148.932/s) [srcu: g10008272 f0x0 ]
|
||||
SRCU-P ------- 202320 GPs (37.4667/s) [srcud: g1809476 f0x0 ]
|
||||
SRCU-t ------- 1122086 GPs (207.794/s) [srcu: g0 f0x0 ]
|
||||
SRCU-u ------- 1111285 GPs (205.794/s) [srcud: g1 f0x0 ]
|
||||
TASKS01 ------- 19666 GPs (3.64185/s) [tasks: g0 f0x0 ]
|
||||
TASKS02 ------- 20541 GPs (3.80389/s) [tasks: g0 f0x0 ]
|
||||
TASKS03 ------- 19416 GPs (3.59556/s) [tasks: g0 f0x0 ]
|
||||
TINY01 ------- 836134 GPs (154.84/s) [rcu: g0 f0x0 ] n_max_cbs: 34198
|
||||
TINY02 ------- 850371 GPs (157.476/s) [rcu: g0 f0x0 ] n_max_cbs: 2631
|
||||
TREE01 ------- 162625 GPs (30.1157/s) [rcu: g1124169 f0x0 ]
|
||||
TREE02 ------- 333003 GPs (61.6672/s) [rcu: g2647753 f0x0 ] n_max_cbs: 35844
|
||||
TREE03 ------- 306623 GPs (56.782/s) [rcu: g2975325 f0x0 ] n_max_cbs: 1496497
|
||||
CPU count limited from 16 to 12
|
||||
TREE04 ------- 246149 GPs (45.5831/s) [rcu: g1695737 f0x0 ] n_max_cbs: 434961
|
||||
TREE05 ------- 314603 GPs (58.2598/s) [rcu: g2257741 f0x2 ] n_max_cbs: 193997
|
||||
TREE07 ------- 167347 GPs (30.9902/s) [rcu: g1079021 f0x0 ] n_max_cbs: 478732
|
||||
CPU count limited from 16 to 12
|
||||
TREE09 ------- 752238 GPs (139.303/s) [rcu: g13075057 f0x0 ] n_max_cbs: 99011
|
||||
@@ -19,9 +19,10 @@ attach to other running processes (e.g. Firefox, SSH sessions, GPG agent,
|
||||
etc) to extract additional credentials and continue to expand the scope
|
||||
of their attack without resorting to user-assisted phishing.
|
||||
|
||||
This is not a theoretical problem. SSH session hijacking
|
||||
(http://www.storm.net.nz/projects/7) and arbitrary code injection
|
||||
(http://c-skills.blogspot.com/2007/05/injectso.html) attacks already
|
||||
This is not a theoretical problem. `SSH session hijacking
|
||||
<https://www.blackhat.com/presentations/bh-usa-05/bh-us-05-boileau.pdf>`_
|
||||
and `arbitrary code injection
|
||||
<https://c-skills.blogspot.com/2007/05/injectso.html>`_ attacks already
|
||||
exist and remain possible if ptrace is allowed to operate as before.
|
||||
Since ptrace is not commonly used by non-developers and non-admins, system
|
||||
builders should be allowed the option to disable this debugging system.
|
||||
|
||||
@@ -27,29 +27,29 @@ Where is documentation?
|
||||
=======================
|
||||
|
||||
User <-> Kernel interface documentation is available at
|
||||
http://tomoyo.osdn.jp/2.5/policy-specification/index.html .
|
||||
https://tomoyo.osdn.jp/2.5/policy-specification/index.html .
|
||||
|
||||
Materials we prepared for seminars and symposiums are available at
|
||||
http://osdn.jp/projects/tomoyo/docs/?category_id=532&language_id=1 .
|
||||
https://osdn.jp/projects/tomoyo/docs/?category_id=532&language_id=1 .
|
||||
Below lists are chosen from three aspects.
|
||||
|
||||
What is TOMOYO?
|
||||
TOMOYO Linux Overview
|
||||
http://osdn.jp/projects/tomoyo/docs/lca2009-takeda.pdf
|
||||
https://osdn.jp/projects/tomoyo/docs/lca2009-takeda.pdf
|
||||
TOMOYO Linux: pragmatic and manageable security for Linux
|
||||
http://osdn.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf
|
||||
https://osdn.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf
|
||||
TOMOYO Linux: A Practical Method to Understand and Protect Your Own Linux Box
|
||||
http://osdn.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf
|
||||
https://osdn.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf
|
||||
|
||||
What can TOMOYO do?
|
||||
Deep inside TOMOYO Linux
|
||||
http://osdn.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf
|
||||
https://osdn.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf
|
||||
The role of "pathname based access control" in security.
|
||||
http://osdn.jp/projects/tomoyo/docs/lfj2008-bof.pdf
|
||||
https://osdn.jp/projects/tomoyo/docs/lfj2008-bof.pdf
|
||||
|
||||
History of TOMOYO?
|
||||
Realities of Mainlining
|
||||
http://osdn.jp/projects/tomoyo/docs/lfj2008.pdf
|
||||
https://osdn.jp/projects/tomoyo/docs/lfj2008.pdf
|
||||
|
||||
What is future plan?
|
||||
====================
|
||||
|
||||
@@ -209,15 +209,22 @@ Configuring the kernel
|
||||
store the lsmod of that machine into a file
|
||||
and pass it in as a LSMOD parameter.
|
||||
|
||||
Also, you can preserve modules in certain folders
|
||||
or kconfig files by specifying their paths in
|
||||
parameter LMC_KEEP.
|
||||
|
||||
target$ lsmod > /tmp/mylsmod
|
||||
target$ scp /tmp/mylsmod host:/tmp
|
||||
|
||||
host$ make LSMOD=/tmp/mylsmod localmodconfig
|
||||
host$ make LSMOD=/tmp/mylsmod \
|
||||
LMC_KEEP="drivers/usb:drivers/gpu:fs" \
|
||||
localmodconfig
|
||||
|
||||
The above also works when cross compiling.
|
||||
|
||||
"make localyesconfig" Similar to localmodconfig, except it will convert
|
||||
all module options to built in (=y) options.
|
||||
all module options to built in (=y) options. You can
|
||||
also preserve modules by LMC_KEEP.
|
||||
|
||||
"make kvmconfig" Enable additional options for kvm guest kernel support.
|
||||
|
||||
@@ -251,7 +258,7 @@ Configuring the kernel
|
||||
Compiling the kernel
|
||||
--------------------
|
||||
|
||||
- Make sure you have at least gcc 4.6 available.
|
||||
- Make sure you have at least gcc 4.9 available.
|
||||
For more information, refer to :ref:`Documentation/process/changes.rst <changes>`.
|
||||
|
||||
Please note that you can still run a.out user programs with this kernel.
|
||||
|
||||
@@ -102,7 +102,7 @@ Where to retrieve userspace tools
|
||||
=================================
|
||||
|
||||
iasl and acpixtract are part of Intel's ACPICA project:
|
||||
http://acpica.org/
|
||||
https://acpica.org/
|
||||
|
||||
and should be packaged by distributions (for example in the acpica package
|
||||
on SUSE).
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user