linux Documentation

C repository by @torvalds. Model Context Protocol (MCP) server & tools with 253k stars.

252,720 stars C C 1 file ยท ~437,193 tokens
RAW Doc

Technical Documentation: torvalds/linux

โ„น๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference

Documentation .Renames (`Documentation/.renames.txt`)

80211/cfg80211 driver-api/80211/cfg80211
80211/index driver-api/80211/index
80211/introduction driver-api/80211/introduction
80211/mac80211 driver-api/80211/mac80211
80211/mac80211-advanced driver-api/80211/mac80211-advanced
EDID/howto admin-guide/edid
PCI/picebus-howto PCI/pciebus-howto
RAS/address-translation admin-guide/RAS/address-translation
RAS/error-decoding admin-guide/RAS/error-decoding
RAS/ras admin-guide/RAS/error-decoding
accelerators/ocxl userspace-api/accelerators/ocxl
admin-guide/gpio/sysfs userspace-api/gpio/sysfs
admin-guide/l1tf admin-guide/hw-vuln/l1tf
admin-guide/media/v4l-with-ir admin-guide/media/remote-controller
admin-guide/ras admin-guide/RAS/main
admin-guide/security-bugs process/security-bugs
aoe/aoe admin-guide/aoe/aoe
aoe/examples admin-guide/aoe/examples
aoe/index admin-guide/aoe/index
aoe/todo admin-guide/aoe/todo
arc/arc arch/arc/arc
arc/features arch/arc/features
arc/index arch/arc/index
arch/x86/resctrl filesystems/resctrl
arm/arm arch/arm/arm
arm/booting arch/arm/booting
arm/cluster-pm-race-avoidance arch/arm/cluster-pm-race-avoidance
arm/features arch/arm/features
arm/firmware arch/arm/firmware
arm/google/chromebook-boot-flow arch/arm/google/chromebook-boot-flow
arm/index arch/arm/index
arm/interrupts arch/arm/interrupts
arm/ixp4xx arch/arm/ixp4xx
arm/kernel_mode_neon arch/arm/kernel_mode_neon
arm/kernel_user_helpers arch/arm/kernel_user_helpers
arm/keystone/knav-qmss arch/arm/keystone/knav-qmss
arm/keystone/overview arch/arm/keystone/overview
arm/marvel arch/arm/marvell
arm/marvell arch/arm/marvell
arm/mem_alignment arch/arm/mem_alignment
arm/memory arch/arm/memory
arm/microchip arch/arm/microchip
arm/netwinder arch/arm/netwinder
arm/nwfpe/index arch/arm/nwfpe/index
arm/nwfpe/netwinder-fpe arch/arm/nwfpe/netwinder-fpe
arm/nwfpe/notes arch/arm/nwfpe/notes
arm/nwfpe/nwfpe arch/arm/nwfpe/nwfpe
arm/nwfpe/todo arch/arm/nwfpe/todo
arm/omap/dss arch/arm/omap/dss
arm/omap/index arch/arm/omap/index
arm/omap/omap arch/arm/omap/omap
arm/omap/omap_pm arch/arm/omap/omap_pm
arm/porting arch/arm/porting
arm/pxa/mfp arch/arm/pxa/mfp
arm/sa1100/assabet arch/arm/sa1100/assabet
arm/sa1100/cerf arch/arm/sa1100/cerf
arm/sa1100/index arch/arm/sa1100/index
arm/sa1100/lart arch/arm/sa1100/lart
arm/sa1100/serial_uart arch/arm/sa1100/serial_uart
arm/samsung/bootloader-interface arch/arm/samsung/bootloader-interface
arm/samsung/gpio arch/arm/samsung/gpio
arm/samsung/index arch/arm/samsung/index
arm/samsung/overview arch/arm/samsung/overview
arm/setup arch/arm/setup
arm/spear/overview arch/arm/spear/overview
arm/sti/overview arch/arm/sti/overview
arm/sti/stih407-overview arch/arm/sti/stih407-overview
arm/sti/stih418-overview arch/arm/sti/stih418-overview
arm/stm32/overview arch/arm/stm32/overview
arm/stm32/stm32-dma-mdma-chaining arch/arm/stm32/stm32-dma-mdma-chaining
arm/stm32/stm32f429-overview arch/arm/stm32/stm32f429-overview
arm/stm32/stm32f746-overview arch/arm/stm32/stm32f746-overview
arm/stm32/stm32f769-overview arch/arm/stm32/stm32f769-overview
arm/stm32/stm32h743-overview arch/arm/stm32/stm32h743-overview
arm/stm32/stm32h750-overview arch/arm/stm32/stm32h750-overview
arm/stm32/stm32mp13-overview arch/arm/stm32/stm32mp13-overview
arm/stm32/stm32mp151-overview arch/arm/stm32/stm32mp151-overview
arm/stm32/stm32mp157-overview arch/arm/stm32/stm32mp157-overview
arm/sunxi arch/arm/sunxi
arm/sunxi/clocks arch/arm/sunxi/clocks
arm/swp_emulation arch/arm/swp_emulation
arm/tcm arch/arm/tcm
arm/uefi arch/arm/uefi
arm/vfp/release-notes arch/arm/vfp/release-notes
arm/vlocks arch/arm/vlocks
arm64/acpi_object_usage arch/arm64/acpi_object_usage
arm64/amu arch/arm64/amu
arm64/arm-acpi arch/arm64/arm-acpi
arm64/asymmetric-32bit arch/arm64/asymmetric-32bit
arm64/booting arch/arm64/booting
arm64/cpu-feature-registers arch/arm64/cpu-feature-registers
arm64/elf_hwcaps arch/arm64/elf_hwcaps
arm64/features arch/arm64/features
arm64/hugetlbpage arch/arm64/hugetlbpage
arm64/index arch/arm64/index
arm64/legacy_instructions arch/arm64/legacy_instructions
arm64/memory arch/arm64/memory
arm64/memory-tagging-extension arch/arm64/memory-tagging-extension
arm64/perf arch/arm64/perf
arm64/pointer-authentication arch/arm64/pointer-authentication
arm64/silicon-errata arch/arm64/silicon-errata
arm64/sme arch/arm64/sme
arm64/sve arch/arm64/sve
arm64/tagged-address-abi arch/arm64/tagged-address-abi
arm64/tagged-pointers arch/arm64/tagged-pointers
asm-annotations core-api/asm-annotations
auxdisplay/lcd-panel-cgram admin-guide/lcd-panel-cgram
backlight/lp855x-driver driver-api/backlight/lp855x-driver
blockdev/drbd/data-structure-v9 admin-guide/blockdev/drbd/data-structure-v9
blockdev/drbd/figures admin-guide/blockdev/drbd/figures
blockdev/drbd/index admin-guide/blockdev/drbd/index
blockdev/floppy admin-guide/blockdev/floppy
blockdev/index admin-guide/blockdev/index
blockdev/nbd admin-guide/blockdev/nbd
blockdev/paride admin-guide/blockdev/paride
blockdev/ramdisk admin-guide/blockdev/ramdisk
blockdev/zram admin-guide/blockdev/zram
bpf/README bpf/index
bpf/bpf_lsm bpf/prog_lsm
bpf/instruction-set bpf/standardization/instruction-set
bpf/libbpf/libbpf bpf/libbpf/index
bpf/standardization/linux-notes bpf/linux-notes
bus-devices/ti-gpmc driver-api/memory-devices/ti-gpmc
cgroup-v1/blkio-controller admin-guide/cgroup-v1/blkio-controller
cgroup-v1/cgroups admin-guide/cgroup-v1/cgroups
cgroup-v1/cpuacct admin-guide/cgroup-v1/cpuacct
cgroup-v1/cpusets admin-guide/cgroup-v1/cpusets
cgroup-v1/devices admin-guide/cgroup-v1/devices
cgroup-v1/freezer-subsystem admin-guide/cgroup-v1/freezer-subsystem
cgroup-v1/hugetlb admin-guide/cgroup-v1/hugetlb
cgroup-v1/index admin-guide/cgroup-v1/index
cgroup-v1/memcg_test admin-guide/cgroup-v1/memcg_test
cgroup-v1/memory admin-guide/cgroup-v1/memory
cgroup-v1/net_cls admin-guide/cgroup-v1/net_cls
cgroup-v1/net_prio admin-guide/cgroup-v1/net_prio
cgroup-v1/pids admin-guide/cgroup-v1/pids
cgroup-v1/rdma admin-guide/cgroup-v1/rdma
cma/debugfs admin-guide/mm/cma_debugfs
connector/connector driver-api/connector
console/console driver-api/console
core-api/gcc-plugins kbuild/gcc-plugins
core-api/ioctl driver-api/ioctl
core-api/memory-hotplug-notifier core-api/memory-hotplug
dev-tools/gdb-kernel-debugging process/debugging/gdb-kernel-debugging
dev-tools/kgdb process/debugging/kgdb
dev-tools/tools dev-tools/index
development-process/1.Intro process/1.Intro
development-process/2.Process process/2.Process
development-process/3.Early-stage process/3.Early-stage
development-process/4.Coding process/4.Coding
development-process/5.Posting process/5.Posting
development-process/6.Followthrough process/6.Followthrough
development-process/7.AdvancedTopics process/7.AdvancedTopics
development-process/8.Conclusion process/8.Conclusion
development-process/development-process process/development-process
development-process/index process/index
device-mapper/cache admin-guide/device-mapper/cache
device-mapper/cache-policies admin-guide/device-mapper/cache-policies
device-mapper/delay admin-guide/device-mapper/delay
device-mapper/dm-crypt admin-guide/device-mapper/dm-crypt
device-mapper/dm-flakey admin-guide/device-mapper/dm-flakey
device-mapper/dm-init admin-guide/device-mapper/dm-init
device-mapper/dm-integrity admin-guide/device-mapper/dm-integrity
device-mapper/dm-io admin-guide/device-mapper/dm-io
device-mapper/dm-log admin-guide/device-mapper/dm-log
device-mapper/dm-queue-length admin-guide/device-mapper/dm-queue-length
device-mapper/dm-raid admin-guide/device-mapper/dm-raid
device-mapper/dm-service-time admin-guide/device-mapper/dm-service-time
device-mapper/dm-uevent admin-guide/device-mapper/dm-uevent
device-mapper/dm-zoned admin-guide/device-mapper/dm-zoned
device-mapper/era admin-guide/device-mapper/era
device-mapper/index admin-guide/device-mapper/index
device-mapper/kcopyd admin-guide/device-mapper/kcopyd
device-mapper/linear admin-guide/device-mapper/linear
device-mapper/log-writes admin-guide/device-mapper/log-writes
device-mapper/persistent-data admin-guide/device-mapper/persistent-data
device-mapper/snapshot admin-guide/device-mapper/snapshot
device-mapper/statistics admin-guide/device-mapper/statistics
device-mapper/striped admin-guide/device-mapper/striped
device-mapper/switch admin-guide/device-mapper/switch
device-mapper/thin-provisioning admin-guide/device-mapper/thin-provisioning
device-mapper/unstriped admin-guide/device-mapper/unstriped
device-mapper/verity admin-guide/device-mapper/verity
device-mapper/writecache admin-guide/device-mapper/writecache
device-mapper/zero admin-guide/device-mapper/zero
devicetree/writing-schema devicetree/bindings/writing-schema
driver-api/bt8xxgpio driver-api/gpio/bt8xxgpio
driver-api/cxl/access-coordinates driver-api/cxl/linux/access-coordinates
driver-api/cxl/memory-devices driver-api/cxl/theory-of-operation
driver-api/dcdbas userspace-api/dcdbas
driver-api/dell_rbu admin-guide/dell_rbu
driver-api/edid admin-guide/edid
driver-api/gpio driver-api/gpio/index
driver-api/hte/tegra194-hte driver-api/hte/tegra-hte
driver-api/isapnp userspace-api/isapnp
driver-api/media/drivers/v4l-drivers/zoran driver-api/media/drivers/zoran
driver-api/mtd/intel-spi driver-api/mtd/spi-intel
driver-api/pci driver-api/pci/pci
driver-api/pinctl driver-api/pin-control
driver-api/rapidio admin-guide/rapidio
driver-api/serial/moxa-smartio driver-api/tty/moxa-smartio
driver-api/serial/n_gsm driver-api/tty/n_gsm
driver-api/serial/tty driver-api/tty/tty_ldisc
driver-api/thermal/intel_powerclamp admin-guide/thermal/intel_powerclamp
driver-api/usb driver-api/usb/usb
driver-model/binding driver-api/driver-model/binding
driver-model/bus driver-api/driver-model/bus
driver-model/design-patterns driver-api/driver-model/design-patterns
driver-model/device driver-api/driver-model/device
driver-model/devres driver-api/driver-model/devres
driver-model/driver driver-api/driver-model/driver
driver-model/index driver-api/driver-model/index
driver-model/overview driver-api/driver-model/overview
driver-model/platform driver-api/driver-model/platform
driver-model/porting driver-api/driver-model/porting
early-userspace/buffer-format driver-api/early-userspace/buffer-format
early-userspace/early_userspace_support driver-api/early-userspace/early_userspace_support
early-userspace/index driver-api/early-userspace/index
errseq core-api/errseq
filesystems/binderfs admin-guide/binderfs
filesystems/cifs/cifsd filesystems/smb/ksmbd
filesystems/cifs/cifsroot filesystems/smb/cifsroot
filesystems/cifs/index filesystems/smb/index
filesystems/cifs/ksmbd filesystems/smb/ksmbd
filesystems/ext4/ext4 admin-guide/ext4
filesystems/ext4/ondisk/about filesystems/ext4/about
filesystems/ext4/ondisk/allocators filesystems/ext4/allocators
filesystems/ext4/ondisk/attributes filesystems/ext4/attributes
filesystems/ext4/ondisk/bigalloc filesystems/ext4/bigalloc
filesystems/ext4/ondisk/bitmaps filesystems/ext4/bitmaps
filesystems/ext4/ondisk/blockgroup filesystems/ext4/blockgroup
filesystems/ext4/ondisk/blockmap filesystems/ext4/blockmap
filesystems/ext4/ondisk/blocks filesystems/ext4/blocks
filesystems/ext4/ondisk/checksums filesystems/ext4/checksums
filesystems/ext4/ondisk/directory filesystems/ext4/directory
filesystems/ext4/ondisk/dynamic filesystems/ext4/dynamic
filesystems/ext4/ondisk/eainode filesystems/ext4/eainode
filesystems/ext4/ondisk/globals filesystems/ext4/globals
filesystems/ext4/ondisk/group_descr filesystems/ext4/group_descr
filesystems/ext4/ondisk/ifork filesystems/ext4/ifork
filesystems/ext4/ondisk/inlinedata filesystems/ext4/inlinedata
filesystems/ext4/ondisk/inodes filesystems/ext4/inodes
filesystems/ext4/ondisk/journal filesystems/ext4/journal
filesystems/ext4/ondisk/mmp filesystems/ext4/mmp
filesystems/ext4/ondisk/overview filesystems/ext4/overview
filesystems/ext4/ondisk/special_inodes filesystems/ext4/special_inodes
filesystems/ext4/ondisk/super filesystems/ext4/super
filesystems/sysfs-pci PCI/sysfs-pci
filesystems/sysfs-tagging networking/sysfs-tagging
filesystems/xfs-delayed-logging-design filesystems/xfs/xfs-delayed-logging-design
filesystems/xfs-maintainer-entry-profile filesystems/xfs/xfs-maintainer-entry-profile
filesystems/xfs-online-fsck-design filesystems/xfs/xfs-online-fsck-design
filesystems/xfs-self-describing-metadata filesystems/xfs/xfs-self-describing-metadata
gpio/index admin-guide/gpio/index
gpio/sysfs userspace-api/gpio/sysfs
gpu/amdgpu gpu/amdgpu/index
hte/hte driver-api/hte/hte
hte/index driver-api/hte/index
hte/tegra194-hte driver-api/hte/tegra-hte
input/alps input/devices/alps
input/amijoy input/devices/amijoy
input/appletouch input/devices/appletouch
input/atarikbd input/devices/atarikbd
input/bcm5974 input/devices/bcm5974
input/cma3000_d0x input/devices/cma3000_d0x
input/cs461x input/devices/cs461x
input/edt-ft5x06 input/devices/edt-ft5x06
input/elantech input/devices/elantech
input/iforce-protocol input/devices/iforce-protocol
input/joystick input/joydev/joystick
input/joystick-api input/joydev/joystick-api
input/joystick-parport input/devices/joystick-parport
input/ntrig input/devices/ntrig
input/rotary-encoder input/devices/rotary-encoder
input/sentelic input/devices/sentelic
input/walkera0701 input/devices/walkera0701
input/xpad input/devices/xpad
input/yealink input/devices/yealink
interconnect/interconnect driver-api/interconnect
ioctl/botching-up-ioctls process/botching-up-ioctls
ioctl/cdrom userspace-api/ioctl/cdrom
ioctl/hdio userspace-api/ioctl/hdio
ioctl/index userspace-api/ioctl/index
ioctl/ioctl-decoding userspace-api/ioctl/ioctl-decoding
ioctl/ioctl-number userspace-api/ioctl/ioctl-number
kbuild/namespaces core-api/symbol-namespaces
kdump/index admin-guide/kdump/index
kdump/kdump admin-guide/kdump/kdump
kdump/vmcoreinfo admin-guide/kdump/vmcoreinfo
kernel-documentation doc-guide/kernel-doc
laptops/asus-laptop admin-guide/laptops/asus-laptop
laptops/disk-shock-protection admin-guide/laptops/disk-shock-protection
laptops/index admin-guide/laptops/index
laptops/laptop-mode admin-guide/laptops/laptop-mode
laptops/lg-laptop admin-guide/laptops/lg-laptop
laptops/sony-laptop admin-guide/laptops/sony-laptop
laptops/sonypi admin-guide/laptops/sonypi
laptops/thinkpad-acpi admin-guide/laptops/thinkpad-acpi
laptops/toshiba_haps admin-guide/laptops/toshiba_haps
loongarch/booting arch/loongarch/booting
loongarch/features arch/loongarch/features
loongarch/index arch/loongarch/index
loongarch/introduction arch/loongarch/introduction
loongarch/irq-chip-model arch/loongarch/irq-chip-model
m68k/buddha-driver arch/m68k/buddha-driver
m68k/features arch/m68k/features
m68k/index arch/m68k/index
m68k/kernel-options arch/m68k/kernel-options
md/index driver-api/md/index
md/md-cluster driver-api/md/md-cluster
md/raid5-cache driver-api/md/raid5-cache
md/raid5-ppl driver-api/md/raid5-ppl
media/dvb-drivers/avermedia admin-guide/media/avermedia
media/dvb-drivers/bt8xx admin-guide/media/bt8xx
media/dvb-drivers/ci admin-guide/media/ci
media/dvb-drivers/contributors driver-api/media/drivers/contributors
media/dvb-drivers/dvb-usb driver-api/media/drivers/dvb-usb
media/dvb-drivers/faq admin-guide/media/faq
media/dvb-drivers/frontends driver-api/media/drivers/frontends
media/dvb-drivers/index driver-api/media/drivers/index
media/dvb-drivers/lmedm04 admin-guide/media/lmedm04
media/dvb-drivers/opera-firmware admin-guide/media/opera-firmware
media/dvb-drivers/technisat admin-guide/media/technisat
media/dvb-drivers/ttusb-dec admin-guide/media/ttusb-dec
media/intro userspace-api/media/intro
media/kapi/cec-core driver-api/media/cec-core
media/kapi/dtv-ca driver-api/media/dtv-ca
media/kapi/dtv-common driver-api/media/dtv-common
media/kapi/dtv-core driver-api/media/dtv-core
media/kapi/dtv-demux driver-api/media/dtv-demux
media/kapi/dtv-frontend driver-api/media/dtv-frontend
media/kapi/dtv-net driver-api/media/dtv-net
media/kapi/mc-core driver-api/media/mc-core
media/kapi/rc-core driver-api/media/rc-core
media/kapi/v4l2-async driver-api/media/v4l2-async
media/kapi/v4l2-common driver-api/media/v4l2-common
media/kapi/v4l2-controls driver-api/media/v4l2-controls
media/kapi/v4l2-core driver-api/media/v4l2-core
media/kapi/v4l2-dev driver-api/media/v4l2-dev
media/kapi/v4l2-device driver-api/media/v4l2-device
media/kapi/v4l2-dv-timings driver-api/media/v4l2-dv-timings
media/kapi/v4l2-event driver-api/media/v4l2-event
media/kapi/v4l2-fh driver-api/media/v4l2-fh
media/kapi/v4l2-flash-led-class driver-api/media/v4l2-flash-led-class
media/kapi/v4l2-fwnode driver-api/media/v4l2-fwnode
media/kapi/v4l2-intro driver-api/media/v4l2-intro
media/kapi/v4l2-mc driver-api/media/v4l2-mc
media/kapi/v4l2-mediabus driver-api/media/v4l2-mediabus
media/kapi/v4l2-mem2mem driver-api/media/v4l2-mem2mem
media/kapi/v4l2-rect driver-api/media/v4l2-rect
media/kapi/v4l2-subdev driver-api/media/v4l2-subdev
media/kapi/v4l2-tuner driver-api/media/v4l2-tuner
media/kapi/v4l2-tveeprom driver-api/media/v4l2-tveeprom
media/kapi/v4l2-videobuf2 driver-api/media/v4l2-videobuf2
media/media_kapi driver-api/media/index
media/media_uapi userspace-api/media/index
media/uapi/cec/cec-api userspace-api/media/cec/cec-api
media/uapi/cec/cec-func-close userspace-api/media/cec/cec-func-close
media/uapi/cec/cec-func-ioctl userspace-api/media/cec/cec-func-ioctl
media/uapi/cec/cec-func-open userspace-api/media/cec/cec-func-open
media/uapi/cec/cec-func-poll userspace-api/media/cec/cec-func-poll
media/uapi/cec/cec-funcs userspace-api/media/cec/cec-funcs
media/uapi/cec/cec-header userspace-api/media/cec/cec-header
media/uapi/cec/cec-intro userspace-api/media/cec/cec-intro
media/uapi/cec/cec-ioc-adap-g-caps userspace-api/media/cec/cec-ioc-adap-g-caps
media/uapi/cec/cec-ioc-adap-g-conn-info userspace-api/media/cec/cec-ioc-adap-g-conn-info
media/uapi/cec/cec-ioc-adap-g-log-addrs userspace-api/media/cec/cec-ioc-adap-g-log-addrs
media/uapi/cec/cec-ioc-adap-g-phys-addr userspace-api/media/cec/cec-ioc-adap-g-phys-addr
media/uapi/cec/cec-ioc-dqevent userspace-api/media/cec/cec-ioc-dqevent
media/uapi/cec/cec-ioc-g-mode userspace-api/media/cec/cec-ioc-g-mode
media/uapi/cec/cec-ioc-receive userspace-api/media/cec/cec-ioc-receive
media/uapi/cec/cec-pin-error-inj userspace-api/media/cec/cec-pin-error-inj
media/uapi/dvb/ca userspace-api/media/dvb/ca
media/uapi/dvb/ca-fclose userspace-api/media/dvb/ca-fclose
media/uapi/dvb/ca-fopen userspace-api/media/dvb/ca-fopen
media/uapi/dvb/ca-get-cap userspace-api/media/dvb/ca-get-cap
media/uapi/dvb/ca-get-descr-info userspace-api/media/dvb/ca-get-descr-info
media/uapi/dvb/ca-get-msg userspace-api/media/dvb/ca-get-msg
media/uapi/dvb/ca-get-slot-info userspace-api/media/dvb/ca-get-slot-info
media/uapi/dvb/ca-reset userspace-api/media/dvb/ca-reset
media/uapi/dvb/ca-send-msg userspace-api/media/dvb/ca-send-msg
media/uapi/dvb/ca-set-descr userspace-api/media/dvb/ca-set-descr
media/uapi/dvb/ca_data_types userspace-api/media/dvb/ca_data_types
media/uapi/dvb/ca_function_calls userspace-api/media/dvb/ca_function_calls
media/uapi/dvb/ca_high_level userspace-api/media/dvb/ca_high_level
media/uapi/dvb/demux userspace-api/media/dvb/demux
media/uapi/dvb/dmx-add-pid userspace-api/media/dvb/dmx-add-pid
media/uapi/dvb/dmx-expbuf userspace-api/media/dvb/dmx-expbuf
media/uapi/dvb/dmx-fclose userspace-api/media/dvb/dmx-fclose
media/uapi/dvb/dmx-fopen userspace-api/media/dvb/dmx-fopen
media/uapi/dvb/dmx-fread userspace-api/media/dvb/dmx-fread
media/uapi/dvb/dmx-fwrite userspace-api/media/dvb/dmx-fwrite
media/uapi/dvb/dmx-get-pes-pids userspace-api/media/dvb/dmx-get-pes-pids
media/uapi/dvb/dmx-get-stc userspace-api/media/dvb/dmx-get-stc
media/uapi/dvb/dmx-mmap userspace-api/media/dvb/dmx-mmap
media/uapi/dvb/dmx-munmap userspace-api/media/dvb/dmx-munmap
media/uapi/dvb/dmx-qbuf userspace-api/media/dvb/dmx-qbuf
media/uapi/dvb/dmx-querybuf userspace-api/media/dvb/dmx-querybuf
media/uapi/dvb/dmx-remove-pid userspace-api/media/dvb/dmx-remove-pid
media/uapi/dvb/dmx-reqbufs userspace-api/media/dvb/dmx-reqbufs
media/uapi/dvb/dmx-set-buffer-size userspace-api/media/dvb/dmx-set-buffer-size
media/uapi/dvb/dmx-set-filter userspace-api/media/dvb/dmx-set-filter
media/uapi/dvb/dmx-set-pes-filter userspace-api/media/dvb/dmx-set-pes-filter
media/uapi/dvb/dmx-start userspace-api/media/dvb/dmx-start
media/uapi/dvb/dmx-stop userspace-api/media/dvb/dmx-stop
media/uapi/dvb/dmx_fcalls userspace-api/media/dvb/dmx_fcalls
media/uapi/dvb/dmx_types userspace-api/media/dvb/dmx_types
media/uapi/dvb/dvb-fe-read-status userspace-api/media/dvb/dvb-fe-read-status
media/uapi/dvb/dvb-frontend-event userspace-api/media/dvb/dvb-frontend-event
media/uapi/dvb/dvb-frontend-parameters userspace-api/media/dvb/dvb-frontend-parameters
media/uapi/dvb/dvbapi userspace-api/media/dvb/dvbapi
media/uapi/dvb/dvbproperty userspace-api/media/dvb/dvbproperty
media/uapi/dvb/examples userspace-api/media/dvb/examples
media/uapi/dvb/fe-bandwidth-t userspace-api/media/dvb/fe-bandwidth-t
media/uapi/dvb/fe-diseqc-recv-slave-reply userspace-api/media/dvb/fe-diseqc-recv-slave-reply
media/uapi/dvb/fe-diseqc-reset-overload userspace-api/media/dvb/fe-diseqc-reset-overload
media/uapi/dvb/fe-diseqc-send-burst userspace-api/media/dvb/fe-diseqc-send-burst
media/uapi/dvb/fe-diseqc-send-master-cmd userspace-api/media/dvb/fe-diseqc-send-master-cmd
media/uapi/dvb/fe-dishnetwork-send-legacy-cmd userspace-api/media/dvb/fe-dishnetwork-send-legacy-cmd
media/uapi/dvb/fe-enable-high-lnb-voltage userspace-api/media/dvb/fe-enable-high-lnb-voltage
media/uapi/dvb/fe-get-event userspace-api/media/dvb/fe-get-event
media/uapi/dvb/fe-get-frontend userspace-api/media/dvb/fe-get-frontend
media/uapi/dvb/fe-get-info userspace-api/media/dvb/fe-get-info
media/uapi/dvb/fe-get-property userspace-api/media/dvb/fe-get-property
media/uapi/dvb/fe-read-ber userspace-api/media/dvb/fe-read-ber
media/uapi/dvb/fe-read-signal-strength userspace-api/media/dvb/fe-read-signal-strength
media/uapi/dvb/fe-read-snr userspace-api/media/dvb/fe-read-snr
media/uapi/dvb/fe-read-status userspace-api/media/dvb/fe-read-status
media/uapi/dvb/fe-read-uncorrected-blocks userspace-api/media/dvb/fe-read-uncorrected-blocks
media/uapi/dvb/fe-set-frontend userspace-api/media/dvb/fe-set-frontend
media/uapi/dvb/fe-set-frontend-tune-mode userspace-api/media/dvb/fe-set-frontend-tune-mode
media/uapi/dvb/fe-set-tone userspace-api/media/dvb/fe-set-tone
media/uapi/dvb/fe-set-voltage userspace-api/media/dvb/fe-set-voltage
media/uapi/dvb/fe-type-t userspace-api/media/dvb/fe-type-t
media/uapi/dvb/fe_property_parameters userspace-api/media/dvb/fe_property_parameters
media/uapi/dvb/frontend userspace-api/media/dvb/frontend
media/uapi/dvb/frontend-header userspace-api/media/dvb/frontend-header
media/uapi/dvb/frontend-property-cable-systems userspace-api/media/dvb/frontend-property-cable-systems
media/uapi/dvb/frontend-property-satellite-systems userspace-api/media/dvb/frontend-property-satellite-systems
media/uapi/dvb/frontend-property-terrestrial-systems userspace-api/media/dvb/frontend-property-terrestrial-systems
media/uapi/dvb/frontend-stat-properties userspace-api/media/dvb/frontend-stat-properties
media/uapi/dvb/frontend_f_close userspace-api/media/dvb/frontend_f_close
media/uapi/dvb/frontend_f_open userspace-api/media/dvb/frontend_f_open
media/uapi/dvb/frontend_fcalls userspace-api/media/dvb/frontend_fcalls
media/uapi/dvb/frontend_legacy_api userspace-api/media/dvb/frontend_legacy_api
media/uapi/dvb/frontend_legacy_dvbv3_api userspace-api/media/dvb/frontend_legacy_dvbv3_api
media/uapi/dvb/headers userspace-api/media/dvb/headers
media/uapi/dvb/intro userspace-api/media/dvb/intro
media/uapi/dvb/legacy_dvb_apis userspace-api/media/dvb/legacy_dvb_apis
media/uapi/dvb/net userspace-api/media/dvb/net
media/uapi/dvb/net-add-if userspace-api/media/dvb/net-add-if
media/uapi/dvb/net-get-if userspace-api/media/dvb/net-get-if
media/uapi/dvb/net-remove-if userspace-api/media/dvb/net-remove-if
media/uapi/dvb/net-types userspace-api/media/dvb/net-types
media/uapi/dvb/query-dvb-frontend-info userspace-api/media/dvb/query-dvb-frontend-info
media/uapi/fdl-appendix userspace-api/media/fdl-appendix
media/uapi/gen-errors userspace-api/media/gen-errors
media/uapi/mediactl/media-controller userspace-api/media/mediactl/media-controller
media/uapi/mediactl/media-controller-intro userspace-api/media/mediactl/media-controller-intro
media/uapi/mediactl/media-controller-model userspace-api/media/mediactl/media-controller-model
media/uapi/mediactl/media-func-close userspace-api/media/mediactl/media-func-close
media/uapi/mediactl/media-func-ioctl userspace-api/media/mediactl/media-func-ioctl
media/uapi/mediactl/media-func-open userspace-api/media/mediactl/media-func-open
media/uapi/mediactl/media-funcs userspace-api/media/mediactl/media-funcs
media/uapi/mediactl/media-header userspace-api/media/mediactl/media-header
media/uapi/mediactl/media-ioc-device-info userspace-api/media/mediactl/media-ioc-device-info
media/uapi/mediactl/media-ioc-enum-entities userspace-api/media/mediactl/media-ioc-enum-entities
media/uapi/mediactl/media-ioc-enum-links userspace-api/media/mediactl/media-ioc-enum-links
media/uapi/mediactl/media-ioc-g-topology userspace-api/media/mediactl/media-ioc-g-topology
media/uapi/mediactl/media-ioc-request-alloc userspace-api/media/mediactl/media-ioc-request-alloc
media/uapi/mediactl/media-ioc-setup-link userspace-api/media/mediactl/media-ioc-setup-link
media/uapi/mediactl/media-request-ioc-queue userspace-api/media/mediactl/media-request-ioc-queue
media/uapi/mediactl/media-request-ioc-reinit userspace-api/media/mediactl/media-request-ioc-reinit
media/uapi/mediactl/media-types userspace-api/media/mediactl/media-types
media/uapi/mediactl/request-api userspace-api/media/mediactl/request-api
media/uapi/mediactl/request-func-close userspace-api/media/mediactl/request-func-close
media/uapi/mediactl/request-func-ioctl userspace-api/media/mediactl/request-func-ioctl
media/uapi/mediactl/request-func-poll userspace-api/media/mediactl/request-func-poll
media/uapi/rc/keytable.c userspace-api/media/rc/keytable.c
media/uapi/rc/lirc-dev userspace-api/media/rc/lirc-dev
media/uapi/rc/lirc-dev-intro userspace-api/media/rc/lirc-dev-intro
media/uapi/rc/lirc-func userspace-api/media/rc/lirc-func
media/uapi/rc/lirc-get-features userspace-api/media/rc/lirc-get-features
media/uapi/rc/lirc-get-rec-mode userspace-api/media/rc/lirc-get-rec-mode
media/uapi/rc/lirc-get-rec-resolution userspace-api/media/rc/lirc-get-rec-resolution
media/uapi/rc/lirc-get-send-mode userspace-api/media/rc/lirc-get-send-mode
media/uapi/rc/lirc-get-timeout userspace-api/media/rc/lirc-get-timeout
media/uapi/rc/lirc-header userspace-api/media/rc/lirc-header
media/uapi/rc/lirc-read userspace-api/media/rc/lirc-read
media/uapi/rc/lirc-set-measure-carrier-mode userspace-api/media/rc/lirc-set-measure-carrier-mode
media/uapi/rc/lirc-set-rec-carrier userspace-api/media/rc/lirc-set-rec-carrier
media/uapi/rc/lirc-set-rec-carrier-range userspace-api/media/rc/lirc-set-rec-carrier-range
media/uapi/rc/lirc-set-rec-timeout userspace-api/media/rc/lirc-set-rec-timeout
media/uapi/rc/lirc-set-send-carrier userspace-api/media/rc/lirc-set-send-carrier
media/uapi/rc/lirc-set-send-duty-cycle userspace-api/media/rc/lirc-set-send-duty-cycle
media/uapi/rc/lirc-set-transmitter-mask userspace-api/media/rc/lirc-set-transmitter-mask
media/uapi/rc/lirc-set-wideband-receiver userspace-api/media/rc/lirc-set-wideband-receiver
media/uapi/rc/lirc-write userspace-api/media/rc/lirc-write
media/uapi/rc/rc-intro userspace-api/media/rc/rc-intro
media/uapi/rc/rc-protos userspace-api/media/rc/rc-protos
media/uapi/rc/rc-sysfs-nodes userspace-api/media/rc/rc-sysfs-nodes
media/uapi/rc/rc-table-change userspace-api/media/rc/rc-table-change
media/uapi/rc/rc-tables userspace-api/media/rc/rc-tables
media/uapi/rc/remote_controllers userspace-api/media/rc/remote_controllers
media/uapi/v4l/app-pri userspace-api/media/v4l/app-pri
media/uapi/v4l/audio userspace-api/media/v4l/audio
media/uapi/v4l/biblio userspace-api/media/v4l/biblio
media/uapi/v4l/buffer userspace-api/media/v4l/buffer
media/uapi/v4l/capture-example userspace-api/media/v4l/capture-example
media/uapi/v4l/capture.c userspace-api/media/v4l/capture.c
media/uapi/v4l/colorspaces userspace-api/media/v4l/colorspaces
media/uapi/v4l/colorspaces-defs userspace-api/media/v4l/colorspaces-defs
media/uapi/v4l/colorspaces-details userspace-api/media/v4l/colorspaces-details
media/uapi/v4l/common userspace-api/media/v4l/common
media/uapi/v4l/common-defs userspace-api/media/v4l/common-defs
media/uapi/v4l/compat userspace-api/media/v4l/compat
media/uapi/v4l/control userspace-api/media/v4l/control
media/uapi/v4l/crop userspace-api/media/v4l/crop
media/uapi/v4l/depth-formats userspace-api/media/v4l/depth-formats
media/uapi/v4l/dev-capture userspace-api/media/v4l/dev-capture
media/uapi/v4l/dev-codec userspace-api/media/v4l/dev-mem2mem
media/uapi/v4l/dev-decoder userspace-api/media/v4l/dev-decoder
media/uapi/v4l/dev-event userspace-api/media/v4l/dev-event
media/uapi/v4l/dev-mem2mem userspace-api/media/v4l/dev-mem2mem
media/uapi/v4l/dev-meta userspace-api/media/v4l/dev-meta
media/uapi/v4l/dev-osd userspace-api/media/v4l/dev-osd
media/uapi/v4l/dev-output userspace-api/media/v4l/dev-output
media/uapi/v4l/dev-overlay userspace-api/media/v4l/dev-overlay
media/uapi/v4l/dev-radio userspace-api/media/v4l/dev-radio
media/uapi/v4l/dev-raw-vbi userspace-api/media/v4l/dev-raw-vbi
media/uapi/v4l/dev-rds userspace-api/media/v4l/dev-rds
media/uapi/v4l/dev-sdr userspace-api/media/v4l/dev-sdr
media/uapi/v4l/dev-sliced-vbi userspace-api/media/v4l/dev-sliced-vbi
media/uapi/v4l/dev-stateless-decoder userspace-api/media/v4l/dev-stateless-decoder
media/uapi/v4l/dev-subdev userspace-api/media/v4l/dev-subdev
media/uapi/v4l/dev-touch userspace-api/media/v4l/dev-touch
media/uapi/v4l/devices userspace-api/media/v4l/devices
media/uapi/v4l/diff-v4l userspace-api/media/v4l/diff-v4l
media/uapi/v4l/dmabuf userspace-api/media/v4l/dmabuf
media/uapi/v4l/dv-timings userspace-api/media/v4l/dv-timings
media/uapi/v4l/ext-ctrls-camera userspace-api/media/v4l/ext-ctrls-camera
media/uapi/v4l/ext-ctrls-codec userspace-api/media/v4l/ext-ctrls-codec
media/uapi/v4l/ext-ctrls-detect userspace-api/media/v4l/ext-ctrls-detect
media/uapi/v4l/ext-ctrls-dv userspace-api/media/v4l/ext-ctrls-dv
media/uapi/v4l/ext-ctrls-flash userspace-api/media/v4l/ext-ctrls-flash
media/uapi/v4l/ext-ctrls-fm-rx userspace-api/media/v4l/ext-ctrls-fm-rx
media/uapi/v4l/ext-ctrls-fm-tx userspace-api/media/v4l/ext-ctrls-fm-tx
media/uapi/v4l/ext-ctrls-image-process userspace-api/media/v4l/ext-ctrls-image-process
media/uapi/v4l/ext-ctrls-image-source userspace-api/media/v4l/ext-ctrls-image-source
media/uapi/v4l/ext-ctrls-jpeg userspace-api/media/v4l/ext-ctrls-jpeg
media/uapi/v4l/ext-ctrls-rf-tuner userspace-api/media/v4l/ext-ctrls-rf-tuner
media/uapi/v4l/extended-controls userspace-api/media/v4l/extended-controls
media/uapi/v4l/field-order userspace-api/media/v4l/field-order
media/uapi/v4l/format userspace-api/media/v4l/format
media/uapi/v4l/func-close userspace-api/media/v4l/func-close
media/uapi/v4l/func-ioctl userspace-api/media/v4l/func-ioctl
media/uapi/v4l/func-mmap userspace-api/media/v4l/func-mmap
media/uapi/v4l/func-munmap userspace-api/media/v4l/func-munmap
media/uapi/v4l/func-open userspace-api/media/v4l/func-open
media/uapi/v4l/func-poll userspace-api/media/v4l/func-poll
media/uapi/v4l/func-read userspace-api/media/v4l/func-read
media/uapi/v4l/func-select userspace-api/media/v4l/func-select
media/uapi/v4l/func-write userspace-api/media/v4l/func-write
media/uapi/v4l/hist-v4l2 userspace-api/media/v4l/hist-v4l2
media/uapi/v4l/hsv-formats userspace-api/media/v4l/hsv-formats
media/uapi/v4l/io userspace-api/media/v4l/io
media/uapi/v4l/libv4l userspace-api/media/v4l/libv4l
media/uapi/v4l/libv4l-introduction userspace-api/media/v4l/libv4l-introduction
media/uapi/v4l/meta-formats userspace-api/media/v4l/meta-formats
media/uapi/v4l/mmap userspace-api/media/v4l/mmap
media/uapi/v4l/open userspace-api/media/v4l/open
media/uapi/v4l/pixfmt userspace-api/media/v4l/pixfmt
media/uapi/v4l/pixfmt-002 userspace-api/media/v4l/pixfmt-v4l2
media/uapi/v4l/pixfmt-003 userspace-api/media/v4l/pixfmt-v4l2-mplane
media/uapi/v4l/pixfmt-004 userspace-api/media/v4l/pixfmt-intro
media/uapi/v4l/pixfmt-006 userspace-api/media/v4l/colorspaces-defs
media/uapi/v4l/pixfmt-007 userspace-api/media/v4l/colorspaces-details
media/uapi/v4l/pixfmt-013 userspace-api/media/v4l/pixfmt-compressed
media/uapi/v4l/pixfmt-bayer userspace-api/media/v4l/pixfmt-bayer
media/uapi/v4l/pixfmt-cnf4 userspace-api/media/v4l/pixfmt-cnf4
media/uapi/v4l/pixfmt-compressed userspace-api/media/v4l/pixfmt-compressed
media/uapi/v4l/pixfmt-indexed userspace-api/media/v4l/pixfmt-indexed
media/uapi/v4l/pixfmt-intro userspace-api/media/v4l/pixfmt-intro
media/uapi/v4l/pixfmt-inzi userspace-api/media/v4l/pixfmt-inzi
media/uapi/v4l/pixfmt-m420 userspace-api/media/v4l/pixfmt-m420
media/uapi/v4l/pixfmt-meta-d4xx userspace-api/media/v4l/metafmt-d4xx
media/uapi/v4l/pixfmt-meta-intel-ipu3 userspace-api/media/v4l/metafmt-intel-ipu3
media/uapi/v4l/pixfmt-meta-uvc userspace-api/media/v4l/metafmt-uvc
media/uapi/v4l/pixfmt-meta-vivid userspace-api/media/v4l/metafmt-vivid
media/uapi/v4l/pixfmt-meta-vsp1-hgo userspace-api/media/v4l/metafmt-vsp1-hgo
media/uapi/v4l/pixfmt-meta-vsp1-hgt userspace-api/media/v4l/metafmt-vsp1-hgt
media/uapi/v4l/pixfmt-packed-hsv userspace-api/media/v4l/pixfmt-packed-hsv
media/uapi/v4l/pixfmt-packed-yuv userspace-api/media/v4l/pixfmt-packed-yuv
media/uapi/v4l/pixfmt-reserved userspace-api/media/v4l/pixfmt-reserved
media/uapi/v4l/pixfmt-rgb userspace-api/media/v4l/pixfmt-rgb
media/uapi/v4l/pixfmt-sbggr16 userspace-api/media/v4l/pixfmt-srggb16
media/uapi/v4l/pixfmt-sdr-cs08 userspace-api/media/v4l/pixfmt-sdr-cs08
media/uapi/v4l/pixfmt-sdr-cs14le userspace-api/media/v4l/pixfmt-sdr-cs14le
media/uapi/v4l/pixfmt-sdr-cu08 userspace-api/media/v4l/pixfmt-sdr-cu08
media/uapi/v4l/pixfmt-sdr-cu16le userspace-api/media/v4l/pixfmt-sdr-cu16le
media/uapi/v4l/pixfmt-sdr-pcu16be userspace-api/media/v4l/pixfmt-sdr-pcu16be
media/uapi/v4l/pixfmt-sdr-pcu18be userspace-api/media/v4l/pixfmt-sdr-pcu18be
media/uapi/v4l/pixfmt-sdr-pcu20be userspace-api/media/v4l/pixfmt-sdr-pcu20be
media/uapi/v4l/pixfmt-sdr-ru12le userspace-api/media/v4l/pixfmt-sdr-ru12le
media/uapi/v4l/pixfmt-srggb10 userspace-api/media/v4l/pixfmt-srggb10
media/uapi/v4l/pixfmt-srggb10-ipu3 userspace-api/media/v4l/pixfmt-srggb10-ipu3
media/uapi/v4l/pixfmt-srggb10alaw8 userspace-api/media/v4l/pixfmt-srggb10alaw8
media/uapi/v4l/pixfmt-srggb10dpcm8 userspace-api/media/v4l/pixfmt-srggb10dpcm8
media/uapi/v4l/pixfmt-srggb10p userspace-api/media/v4l/pixfmt-srggb10p
media/uapi/v4l/pixfmt-srggb12 userspace-api/media/v4l/pixfmt-srggb12
media/uapi/v4l/pixfmt-srggb12p userspace-api/media/v4l/pixfmt-srggb12p
media/uapi/v4l/pixfmt-srggb14 userspace-api/media/v4l/pixfmt-srggb14
media/uapi/v4l/pixfmt-srggb14p userspace-api/media/v4l/pixfmt-srggb14p
media/uapi/v4l/pixfmt-srggb16 userspace-api/media/v4l/pixfmt-srggb16
media/uapi/v4l/pixfmt-srggb8 userspace-api/media/v4l/pixfmt-srggb8
media/uapi/v4l/pixfmt-tch-td08 userspace-api/media/v4l/pixfmt-tch-td08
media/uapi/v4l/pixfmt-tch-td16 userspace-api/media/v4l/pixfmt-tch-td16
media/uapi/v4l/pixfmt-tch-tu08 userspace-api/media/v4l/pixfmt-tch-tu08
media/uapi/v4l/pixfmt-tch-tu16 userspace-api/media/v4l/pixfmt-tch-tu16
media/uapi/v4l/pixfmt-uv8 userspace-api/media/v4l/pixfmt-uv8
media/uapi/v4l/pixfmt-v4l2 userspace-api/media/v4l/pixfmt-v4l2
media/uapi/v4l/pixfmt-v4l2-mplane userspace-api/media/v4l/pixfmt-v4l2-mplane
media/uapi/v4l/pixfmt-y12i userspace-api/media/v4l/pixfmt-y12i
media/uapi/v4l/pixfmt-y8i userspace-api/media/v4l/pixfmt-y8i
media/uapi/v4l/pixfmt-z16 userspace-api/media/v4l/pixfmt-z16
media/uapi/v4l/planar-apis userspace-api/media/v4l/planar-apis
media/uapi/v4l/querycap userspace-api/media/v4l/querycap
media/uapi/v4l/rw userspace-api/media/v4l/rw
media/uapi/v4l/sdr-formats userspace-api/media/v4l/sdr-formats
media/uapi/v4l/selection-api userspace-api/media/v4l/selection-api
media/uapi/v4l/selection-api-002 userspace-api/media/v4l/selection-api-intro
media/uapi/v4l/selection-api-003 userspace-api/media/v4l/selection-api-targets
media/uapi/v4l/selection-api-004 userspace-api/media/v4l/selection-api-configuration
media/uapi/v4l/selection-api-005 userspace-api/media/v4l/selection-api-vs-crop-api
media/uapi/v4l/selection-api-006 userspace-api/media/v4l/selection-api-examples
media/uapi/v4l/selection-api-configuration userspace-api/media/v4l/selection-api-configuration
media/uapi/v4l/selection-api-examples userspace-api/media/v4l/selection-api-examples
media/uapi/v4l/selection-api-intro userspace-api/media/v4l/selection-api-intro
media/uapi/v4l/selection-api-targets userspace-api/media/v4l/selection-api-targets
media/uapi/v4l/selection-api-vs-crop-api userspace-api/media/v4l/selection-api-vs-crop-api
media/uapi/v4l/selections-common userspace-api/media/v4l/selections-common
media/uapi/v4l/standard userspace-api/media/v4l/standard
media/uapi/v4l/streaming-par userspace-api/media/v4l/streaming-par
media/uapi/v4l/subdev-formats userspace-api/media/v4l/subdev-formats
media/uapi/v4l/tch-formats userspace-api/media/v4l/tch-formats
media/uapi/v4l/tuner userspace-api/media/v4l/tuner
media/uapi/v4l/user-func userspace-api/media/v4l/user-func
media/uapi/v4l/userp userspace-api/media/v4l/userp
media/uapi/v4l/v4l2 userspace-api/media/v4l/v4l2
media/uapi/v4l/v4l2-selection-flags userspace-api/media/v4l/v4l2-selection-flags
media/uapi/v4l/v4l2-selection-targets userspace-api/media/v4l/v4l2-selection-targets
media/uapi/v4l/v4l2grab-example userspace-api/media/v4l/v4l2grab-example
media/uapi/v4l/v4l2grab.c userspace-api/media/v4l/v4l2grab.c
media/uapi/v4l/video userspace-api/media/v4l/video
media/uapi/v4l/videodev userspace-api/media/v4l/videodev
media/uapi/v4l/vidioc-create-bufs userspace-api/media/v4l/vidioc-create-bufs
media/uapi/v4l/vidioc-cropcap userspace-api/media/v4l/vidioc-cropcap
media/uapi/v4l/vidioc-dbg-g-chip-info userspace-api/media/v4l/vidioc-dbg-g-chip-info
media/uapi/v4l/vidioc-dbg-g-register userspace-api/media/v4l/vidioc-dbg-g-register
media/uapi/v4l/vidioc-decoder-cmd userspace-api/media/v4l/vidioc-decoder-cmd
media/uapi/v4l/vidioc-dqevent userspace-api/media/v4l/vidioc-dqevent
media/uapi/v4l/vidioc-dv-timings-cap userspace-api/media/v4l/vidioc-dv-timings-cap
media/uapi/v4l/vidioc-encoder-cmd userspace-api/media/v4l/vidioc-encoder-cmd
media/uapi/v4l/vidioc-enum-dv-timings userspace-api/media/v4l/vidioc-enum-dv-timings
media/uapi/v4l/vidioc-enum-fmt userspace-api/media/v4l/vidioc-enum-fmt
media/uapi/v4l/vidioc-enum-frameintervals userspace-api/media/v4l/vidioc-enum-frameintervals
media/uapi/v4l/vidioc-enum-framesizes userspace-api/media/v4l/vidioc-enum-framesizes
media/uapi/v4l/vidioc-enum-freq-bands userspace-api/media/v4l/vidioc-enum-freq-bands
media/uapi/v4l/vidioc-enumaudio userspace-api/media/v4l/vidioc-enumaudio
media/uapi/v4l/vidioc-enumaudioout userspace-api/media/v4l/vidioc-enumaudioout
media/uapi/v4l/vidioc-enuminput userspace-api/media/v4l/vidioc-enuminput
media/uapi/v4l/vidioc-enumoutput userspace-api/media/v4l/vidioc-enumoutput
media/uapi/v4l/vidioc-enumstd userspace-api/media/v4l/vidioc-enumstd
media/uapi/v4l/vidioc-expbuf userspace-api/media/v4l/vidioc-expbuf
media/uapi/v4l/vidioc-g-audio userspace-api/media/v4l/vidioc-g-audio
media/uapi/v4l/vidioc-g-audioout userspace-api/media/v4l/vidioc-g-audioout
media/uapi/v4l/vidioc-g-crop userspace-api/media/v4l/vidioc-g-crop
media/uapi/v4l/vidioc-g-ctrl userspace-api/media/v4l/vidioc-g-ctrl
media/uapi/v4l/vidioc-g-dv-timings userspace-api/media/v4l/vidioc-g-dv-timings
media/uapi/v4l/vidioc-g-edid userspace-api/media/v4l/vidioc-g-edid
media/uapi/v4l/vidioc-g-enc-index userspace-api/media/v4l/vidioc-g-enc-index
media/uapi/v4l/vidioc-g-ext-ctrls userspace-api/media/v4l/vidioc-g-ext-ctrls
media/uapi/v4l/vidioc-g-fbuf userspace-api/media/v4l/vidioc-g-fbuf
media/uapi/v4l/vidioc-g-fmt userspace-api/media/v4l/vidioc-g-fmt
media/uapi/v4l/vidioc-g-frequency userspace-api/media/v4l/vidioc-g-frequency
media/uapi/v4l/vidioc-g-input userspace-api/media/v4l/vidioc-g-input
media/uapi/v4l/vidioc-g-jpegcomp userspace-api/media/v4l/vidioc-g-jpegcomp
media/uapi/v4l/vidioc-g-modulator userspace-api/media/v4l/vidioc-g-modulator
media/uapi/v4l/vidioc-g-output userspace-api/media/v4l/vidioc-g-output
media/uapi/v4l/vidioc-g-parm userspace-api/media/v4l/vidioc-g-parm
media/uapi/v4l/vidioc-g-priority userspace-api/media/v4l/vidioc-g-priority
media/uapi/v4l/vidioc-g-selection userspace-api/media/v4l/vidioc-g-selection
media/uapi/v4l/vidioc-g-sliced-vbi-cap userspace-api/media/v4l/vidioc-g-sliced-vbi-cap
media/uapi/v4l/vidioc-g-std userspace-api/media/v4l/vidioc-g-std
media/uapi/v4l/vidioc-g-tuner userspace-api/media/v4l/vidioc-g-tuner
media/uapi/v4l/vidioc-log-status userspace-api/media/v4l/vidioc-log-status
media/uapi/v4l/vidioc-overlay userspace-api/media/v4l/vidioc-overlay
media/uapi/v4l/vidioc-prepare-buf userspace-api/media/v4l/vidioc-prepare-buf
media/uapi/v4l/vidioc-qbuf userspace-api/media/v4l/vidioc-qbuf
media/uapi/v4l/vidioc-query-dv-timings userspace-api/media/v4l/vidioc-query-dv-timings
media/uapi/v4l/vidioc-querybuf userspace-api/media/v4l/vidioc-querybuf
media/uapi/v4l/vidioc-querycap userspace-api/media/v4l/vidioc-querycap
media/uapi/v4l/vidioc-queryctrl userspace-api/media/v4l/vidioc-queryctrl
media/uapi/v4l/vidioc-querystd userspace-api/media/v4l/vidioc-querystd
media/uapi/v4l/vidioc-reqbufs userspace-api/media/v4l/vidioc-reqbufs
media/uapi/v4l/vidioc-s-hw-freq-seek userspace-api/media/v4l/vidioc-s-hw-freq-seek
media/uapi/v4l/vidioc-streamon userspace-api/media/v4l/vidioc-streamon
media/uapi/v4l/vidioc-subdev-enum-frame-interval userspace-api/media/v4l/vidioc-subdev-enum-frame-interval
media/uapi/v4l/vidioc-subdev-enum-frame-size userspace-api/media/v4l/vidioc-subdev-enum-frame-size
media/uapi/v4l/vidioc-subdev-enum-mbus-code userspace-api/media/v4l/vidioc-subdev-enum-mbus-code
media/uapi/v4l/vidioc-subdev-g-crop userspace-api/media/v4l/vidioc-subdev-g-crop
media/uapi/v4l/vidioc-subdev-g-fmt userspace-api/media/v4l/vidioc-subdev-g-fmt
media/uapi/v4l/vidioc-subdev-g-frame-interval userspace-api/media/v4l/vidioc-subdev-g-frame-interval
media/uapi/v4l/vidioc-subdev-g-selection userspace-api/media/v4l/vidioc-subdev-g-selection
media/uapi/v4l/vidioc-subscribe-event userspace-api/media/v4l/vidioc-subscribe-event
media/uapi/v4l/yuv-formats userspace-api/media/v4l/yuv-formats
media/v4l-drivers/au0828-cardlist admin-guide/media/au0828-cardlist
media/v4l-drivers/bttv admin-guide/media/bttv
media/v4l-drivers/bttv-cardlist admin-guide/media/bttv-cardlist
media/v4l-drivers/bttv-devel driver-api/media/drivers/bttv-devel
media/v4l-drivers/cafe_ccic admin-guide/media/cafe_ccic
media/v4l-drivers/cardlist admin-guide/media/cardlist
media/v4l-drivers/cx2341x driver-api/media/drivers/cx2341x-devel
media/v4l-drivers/cx2341x-devel driver-api/media/drivers/cx2341x-devel
media/v4l-drivers/cx2341x-uapi userspace-api/media/drivers/cx2341x-uapi
media/v4l-drivers/cx23885-cardlist admin-guide/media/cx23885-cardlist
media/v4l-drivers/cx88 admin-guide/media/cx88
media/v4l-drivers/cx88-cardlist admin-guide/media/cx88-cardlist
media/v4l-drivers/cx88-devel driver-api/media/drivers/cx88-devel
media/v4l-drivers/em28xx-cardlist admin-guide/media/em28xx-cardlist
media/v4l-drivers/fimc admin-guide/media/fimc
media/v4l-drivers/fimc-devel driver-api/media/drivers/fimc-devel
media/v4l-drivers/fourcc userspace-api/media/v4l/fourcc
media/v4l-drivers/gspca-cardlist admin-guide/media/gspca-cardlist
media/v4l-drivers/imx admin-guide/media/imx
media/v4l-drivers/imx-uapi userspace-api/media/drivers/imx-uapi
media/v4l-drivers/imx7 admin-guide/media/imx7
media/v4l-drivers/index userspace-api/media/drivers/index
media/v4l-drivers/ipu3 admin-guide/media/ipu3
media/v4l-drivers/ivtv admin-guide/media/ivtv
media/v4l-drivers/ivtv-cardlist admin-guide/media/ivtv-cardlist
media/v4l-drivers/max2175 userspace-api/media/drivers/max2175
media/v4l-drivers/omap3isp admin-guide/media/omap3isp
media/v4l-drivers/omap3isp-uapi userspace-api/media/drivers/omap3isp-uapi
media/v4l-drivers/philips admin-guide/media/philips
media/v4l-drivers/pvrusb2 driver-api/media/drivers/pvrusb2
media/v4l-drivers/pxa_camera driver-api/media/drivers/pxa_camera
media/v4l-drivers/qcom_camss admin-guide/media/qcom_camss
media/v4l-drivers/radiotrack driver-api/media/drivers/radiotrack
media/v4l-drivers/rcar-fdp1 admin-guide/media/rcar-fdp1
media/v4l-drivers/saa7134 admin-guide/media/saa7134
media/v4l-drivers/saa7134-cardlist admin-guide/media/saa7134-cardlist
media/v4l-drivers/saa7134-devel driver-api/media/drivers/saa7134-devel
media/v4l-drivers/saa7164-cardlist admin-guide/media/saa7164-cardlist
media/v4l-drivers/sh_mobile_ceu_camera driver-api/media/drivers/sh_mobile_ceu_camera
media/v4l-drivers/si470x admin-guide/media/si470x
media/v4l-drivers/si4713 admin-guide/media/si4713
media/v4l-drivers/si476x admin-guide/media/si476x
media/v4l-drivers/tuner-cardlist admin-guide/media/tuner-cardlist
media/v4l-drivers/tuners driver-api/media/drivers/tuners
media/v4l-drivers/uvcvideo userspace-api/media/drivers/uvcvideo
media/v4l-drivers/v4l-with-ir admin-guide/media/remote-controller
media/v4l-drivers/vimc admin-guide/media/vimc
media/v4l-drivers/vimc-devel driver-api/media/drivers/vimc-devel
media/v4l-drivers/vivid admin-guide/media/vivid
media/v4l-drivers/zoran driver-api/media/drivers/zoran
memory-devices/ti-emif driver-api/memory-devices/ti-emif
mips/booting arch/mips/booting
mips/features arch/mips/features
mips/index arch/mips/index
mips/ingenic-tcu arch/mips/ingenic-tcu
mm/slub admin-guide/mm/slab
mmc/index driver-api/mmc/index
mmc/mmc-async-req driver-api/mmc/mmc-async-req
mmc/mmc-dev-attrs driver-api/mmc/mmc-dev-attrs
mmc/mmc-dev-parts driver-api/mmc/mmc-dev-parts
mmc/mmc-tools driver-api/mmc/mmc-tools
mtd/index driver-api/mtd/index
mtd/intel-spi driver-api/mtd/spi-intel
mtd/nand_ecc driver-api/mtd/nand_ecc
mtd/spi-nor driver-api/mtd/spi-nor
namespaces/compatibility-list admin-guide/namespaces/compatibility-list
namespaces/index admin-guide/namespaces/index
namespaces/resource-control admin-guide/namespaces/resource-control
networking/altera_tse networking/device_drivers/ethernet/altera/altera_tse
networking/bpf_flow_dissector bpf/prog_flow_dissector
networking/cxacru networking/device_drivers/atm/cxacru
networking/defza networking/device_drivers/fddi/defza
networking/device_drivers/3com/3c509 networking/device_drivers/ethernet/3com/3c509
networking/device_drivers/3com/vortex networking/device_drivers/ethernet/3com/vortex
networking/device_drivers/amazon/ena networking/device_drivers/ethernet/amazon/ena
networking/device_drivers/aquantia/atlantic networking/device_drivers/ethernet/aquantia/atlantic
networking/device_drivers/chelsio/cxgb networking/device_drivers/ethernet/chelsio/cxgb
networking/device_drivers/cirrus/cs89x0 networking/device_drivers/ethernet/cirrus/cs89x0
networking/device_drivers/davicom/dm9000 networking/device_drivers/ethernet/davicom/dm9000
networking/device_drivers/dec/dmfe networking/device_drivers/ethernet/dec/dmfe
networking/device_drivers/dlink/dl2k networking/device_drivers/ethernet/dlink/dl2k
networking/device_drivers/freescale/dpaa networking/device_drivers/ethernet/freescale/dpaa
networking/device_drivers/freescale/dpaa2/dpio-driver networking/device_drivers/ethernet/freescale/dpaa2/dpio-driver
networking/device_drivers/freescale/dpaa2/ethernet-driver networking/device_drivers/ethernet/freescale/dpaa2/ethernet-driver
networking/device_drivers/freescale/dpaa2/index networking/device_drivers/ethernet/freescale/dpaa2/index
networking/device_drivers/freescale/dpaa2/mac-phy-support networking/device_drivers/ethernet/freescale/dpaa2/mac-phy-support
networking/device_drivers/freescale/dpaa2/overview networking/device_drivers/ethernet/freescale/dpaa2/overview
networking/device_drivers/freescale/gianfar networking/device_drivers/ethernet/freescale/gianfar
networking/device_drivers/google/gve networking/device_drivers/ethernet/google/gve
networking/device_drivers/intel/e100 networking/device_drivers/ethernet/intel/e100
networking/device_drivers/intel/e1000 networking/device_drivers/ethernet/intel/e1000
networking/device_drivers/intel/e1000e networking/device_drivers/ethernet/intel/e1000e
networking/device_drivers/intel/fm10k networking/device_drivers/ethernet/intel/fm10k
networking/device_drivers/intel/i40e networking/device_drivers/ethernet/intel/i40e
networking/device_drivers/intel/iavf networking/device_drivers/ethernet/intel/iavf
networking/device_drivers/intel/ice networking/device_drivers/ethernet/intel/ice
networking/device_drivers/intel/igb networking/device_drivers/ethernet/intel/igb
networking/device_drivers/intel/igbvf networking/device_drivers/ethernet/intel/igbvf
networking/device_drivers/intel/ipw2100 networking/device_drivers/wifi/intel/ipw2100
networking/device_drivers/intel/ipw2200 networking/device_drivers/wifi/intel/ipw2200
networking/device_drivers/intel/ixgbe networking/device_drivers/ethernet/intel/ixgbe
networking/device_drivers/intel/ixgbevf networking/device_drivers/ethernet/intel/ixgbevf
networking/device_drivers/marvell/octeontx2 networking/device_drivers/ethernet/marvell/octeontx2
networking/device_drivers/microsoft/netvsc networking/device_drivers/ethernet/microsoft/netvsc
networking/device_drivers/netronome/nfp networking/device_drivers/ethernet/netronome/nfp
networking/device_drivers/pensando/ionic networking/device_drivers/ethernet/pensando/ionic
networking/device_drivers/qualcomm/rmnet networking/device_drivers/cellular/qualcomm/rmnet
networking/device_drivers/stmicro/stmmac networking/device_drivers/ethernet/stmicro/stmmac
networking/device_drivers/ti/cpsw networking/device_drivers/ethernet/ti/cpsw
networking/device_drivers/ti/cpsw_switchdev networking/device_drivers/ethernet/ti/cpsw_switchdev
networking/device_drivers/ti/tlan networking/device_drivers/ethernet/ti/tlan
networking/devlink-trap networking/devlink/devlink-trap
networking/dpaa2/dpio-driver networking/device_drivers/ethernet/freescale/dpaa2/dpio-driver
networking/dpaa2/ethernet-driver networking/device_drivers/ethernet/freescale/dpaa2/ethernet-driver
networking/dpaa2/index networking/device_drivers/ethernet/freescale/dpaa2/index
networking/dpaa2/overview networking/device_drivers/ethernet/freescale/dpaa2/overview
networking/e100 networking/device_drivers/ethernet/intel/e100
networking/e1000 networking/device_drivers/ethernet/intel/e1000
networking/e1000e networking/device_drivers/ethernet/intel/e1000e
networking/fm10k networking/device_drivers/ethernet/intel/fm10k
networking/hinic networking/device_drivers/ethernet/huawei/hinic
networking/i40e networking/device_drivers/ethernet/intel/i40e
networking/iavf networking/device_drivers/ethernet/intel/iavf
networking/ice networking/device_drivers/ethernet/intel/ice
networking/igb networking/device_drivers/ethernet/intel/igb
networking/igbvf networking/device_drivers/ethernet/intel/igbvf
networking/ixgbe networking/device_drivers/ethernet/intel/ixgbe
networking/ixgbevf networking/device_drivers/ethernet/intel/ixgbevf
networking/netdev-FAQ process/maintainer-netdev
networking/skfp networking/device_drivers/fddi/skfp
nfc/index driver-api/nfc/index
nfc/nfc-hci driver-api/nfc/nfc-hci
nfc/nfc-pn544 driver-api/nfc/nfc-pn544
nios2/features arch/nios2/features
nios2/index arch/nios2/index
nios2/nios2 arch/nios2/nios2
nvdimm/btt driver-api/nvdimm/btt
nvdimm/index driver-api/nvdimm/index
nvdimm/nvdimm driver-api/nvdimm/nvdimm
nvdimm/security driver-api/nvdimm/security
nvmem/nvmem driver-api/nvmem
openrisc/features arch/openrisc/features
openrisc/index arch/openrisc/index
openrisc/openrisc_port arch/openrisc/openrisc_port
openrisc/todo arch/openrisc/todo
parisc/debugging arch/parisc/debugging
parisc/features arch/parisc/features
parisc/index arch/parisc/index
parisc/registers arch/parisc/registers
perf/arm-ccn admin-guide/perf/arm-ccn
perf/arm_dsu_pmu admin-guide/perf/arm_dsu_pmu
perf/hisi-pmu admin-guide/perf/hisi-pmu
perf/index admin-guide/perf/index
perf/qcom_l2_pmu admin-guide/perf/qcom_l2_pmu
perf/qcom_l3_pmu admin-guide/perf/qcom_l3_pmu
perf/thunderx2-pmu admin-guide/perf/thunderx2-pmu
perf/xgene-pmu admin-guide/perf/xgene-pmu
phy/samsung-usb2 driver-api/phy/samsung-usb2
powerpc/associativity arch/powerpc/associativity
powerpc/booting arch/powerpc/booting
powerpc/bootwrapper arch/powerpc/bootwrapper
powerpc/cpu_families arch/powerpc/cpu_families
powerpc/cpu_features arch/powerpc/cpu_features
powerpc/dawr-power9 arch/powerpc/dawr-power9
powerpc/dexcr arch/powerpc/dexcr
powerpc/dscr arch/powerpc/dscr
powerpc/eeh-pci-error-recovery arch/powerpc/eeh-pci-error-recovery
powerpc/elf_hwcaps arch/powerpc/elf_hwcaps
powerpc/elfnote arch/powerpc/elfnote
powerpc/features arch/powerpc/features
powerpc/firmware-assisted-dump arch/powerpc/firmware-assisted-dump
powerpc/hvcs arch/powerpc/hvcs
powerpc/imc arch/powerpc/imc
powerpc/index arch/powerpc/index
powerpc/isa-versions arch/powerpc/isa-versions
powerpc/kaslr-booke32 arch/powerpc/kaslr-booke32
powerpc/mpc52xx arch/powerpc/mpc52xx
powerpc/papr_hcalls arch/powerpc/papr_hcalls
powerpc/pci_iov_resource_on_powernv arch/powerpc/pci_iov_resource_on_powernv
powerpc/pmu-ebb arch/powerpc/pmu-ebb
powerpc/ptrace arch/powerpc/ptrace
powerpc/qe_firmware arch/powerpc/qe_firmware
powerpc/syscall64-abi arch/powerpc/syscall64-abi
powerpc/transactional_memory arch/powerpc/transactional_memory
powerpc/ultravisor arch/powerpc/ultravisor
powerpc/vas-api arch/powerpc/vas-api
powerpc/vcpudispatch_stats arch/powerpc/vcpudispatch_stats
powerpc/vmemmap_dedup arch/powerpc/vmemmap_dedup
process/clang-format dev-tools/clang-format
process/magic-number staging/magic-number
process/unaligned-memory-access core-api/unaligned-memory-access
rapidio/index driver-api/rapidio/index
rapidio/mport_cdev driver-api/rapidio/mport_cdev
rapidio/rapidio driver-api/rapidio/rapidio
rapidio/rio_cm driver-api/rapidio/rio_cm
rapidio/sysfs driver-api/rapidio/sysfs
rapidio/tsi721 driver-api/rapidio/tsi721
riscv/acpi arch/riscv/acpi
riscv/boot arch/riscv/boot
riscv/boot-image-header arch/riscv/boot-image-header
riscv/features arch/riscv/features
riscv/hwprobe arch/riscv/hwprobe
riscv/index arch/riscv/index
riscv/patch-acceptance arch/riscv/patch-acceptance
riscv/uabi arch/riscv/uabi
riscv/vector arch/riscv/vector
riscv/vm-layout arch/riscv/vm-layout
s390/3270 arch/s390/3270
s390/cds arch/s390/cds
s390/common_io arch/s390/common_io
s390/driver-model arch/s390/driver-model
s390/features arch/s390/features
s390/index arch/s390/index
s390/monreader arch/s390/monreader
s390/pci arch/s390/pci
s390/qeth arch/s390/qeth
s390/s390dbf arch/s390/s390dbf
s390/text_files arch/s390/text_files
s390/vfio-ap arch/s390/vfio-ap
s390/vfio-ap-locking arch/s390/vfio-ap-locking
s390/vfio-ccw arch/s390/vfio-ccw
s390/zfcpdump arch/s390/zfcpdump
security/LSM security/lsm-development
security/LSM-sctp security/SCTP
serial/driver driver-api/serial/driver
serial/index driver-api/serial/index
serial/moxa-smartio driver-api/tty/moxa-smartio
serial/n_gsm driver-api/tty/n_gsm
serial/serial-iso7816 driver-api/serial/serial-iso7816
serial/serial-rs485 driver-api/serial/serial-rs485
serial/tty driver-api/tty/tty_ldisc
sh/booting arch/sh/booting
sh/features arch/sh/features
sh/index arch/sh/index
sh/new-machine arch/sh/new-machine
sh/register-banks arch/sh/register-banks
sparc/adi arch/sparc/adi
sparc/console arch/sparc/console
sparc/features arch/sparc/features
sparc/index arch/sparc/index
sparc/oradax/oracle-dax arch/sparc/oradax/oracle-dax
staging/kprobes trace/kprobes
sysctl/abi admin-guide/sysctl/abi
sysctl/fs admin-guide/sysctl/fs
sysctl/index admin-guide/sysctl/index
sysctl/kernel admin-guide/sysctl/kernel
sysctl/net admin-guide/sysctl/net
sysctl/sunrpc admin-guide/sysctl/sunrpc
sysctl/user admin-guide/sysctl/user
sysctl/vm admin-guide/sysctl/vm
thermal/cpu-cooling-api driver-api/thermal/cpu-cooling-api
thermal/exynos_thermal driver-api/thermal/exynos_thermal
thermal/exynos_thermal_emulation driver-api/thermal/exynos_thermal_emulation
thermal/index driver-api/thermal/index
thermal/intel_powerclamp admin-guide/thermal/intel_powerclamp
thermal/nouveau_thermal driver-api/thermal/nouveau_thermal
thermal/power_allocator driver-api/thermal/power_allocator
thermal/sysfs-api driver-api/thermal/sysfs-api
thermal/x86_pkg_temperature_thermal driver-api/thermal/x86_pkg_temperature_thermal
tpm/index security/tpm/index
tpm/tpm_vtpm_proxy security/tpm/tpm_vtpm_proxy
trace/coresight trace/coresight/coresight
trace/coresight-cpu-debug trace/coresight/coresight-cpu-debug
trace/rv/da_monitor_synthesis trace/rv/monitor_synthesis
translations/it_IT/admin-guide/security-bugs translations/it_IT/process/security-bugs
translations/it_IT/process/clang-format translations/it_IT/dev-tools/clang-format
translations/it_IT/process/magic-number translations/it_IT/staging/magic-number
translations/it_IT/riscv/patch-acceptance translations/it_IT/arch/riscv/patch-acceptance
translations/ja_JP/howto translations/ja_JP/process/howto
translations/ko_KR/howto translations/ko_KR/process/howto
translations/sp_SP/howto translations/sp_SP/process/howto
translations/sp_SP/submitting-patches translations/sp_SP/process/submitting-patches
translations/zh_CN/admin-guide/security-bugs translations/zh_CN/process/security-bugs
translations/zh_CN/arch translations/zh_CN/arch/index
translations/zh_CN/arm64/amu translations/zh_CN/arch/arm64/amu
translations/zh_CN/arm64/elf_hwcaps translations/zh_CN/arch/arm64/elf_hwcaps
translations/zh_CN/arm64/hugetlbpage translations/zh_CN/arch/arm64/hugetlbpage
translations/zh_CN/arm64/index translations/zh_CN/arch/arm64/index
translations/zh_CN/arm64/perf translations/zh_CN/arch/arm64/perf
translations/zh_CN/coding-style translations/zh_CN/process/coding-style
translations/zh_CN/loongarch/booting translations/zh_CN/arch/loongarch/booting
translations/zh_CN/loongarch/features translations/zh_CN/arch/loongarch/features
translations/zh_CN/loongarch/index translations/zh_CN/arch/loongarch/index
translations/zh_CN/loongarch/introduction translations/zh_CN/arch/loongarch/introduction
translations/zh_CN/loongarch/irq-chip-model translations/zh_CN/arch/loongarch/irq-chip-model
translations/zh_CN/mips/booting translations/zh_CN/arch/mips/booting
translations/zh_CN/mips/features translations/zh_CN/arch/mips/features
translations/zh_CN/mips/index translations/zh_CN/arch/mips/index
translations/zh_CN/mips/ingenic-tcu translations/zh_CN/arch/mips/ingenic-tcu
translations/zh_CN/openrisc/index translations/zh_CN/arch/openrisc/index
translations/zh_CN/openrisc/openrisc_port translations/zh_CN/arch/openrisc/openrisc_port
translations/zh_CN/openrisc/todo translations/zh_CN/arch/openrisc/todo
translations/zh_CN/parisc/debugging translations/zh_CN/arch/parisc/debugging
translations/zh_CN/parisc/index translations/zh_CN/arch/parisc/index
translations/zh_CN/parisc/registers translations/zh_CN/arch/parisc/registers
translations/zh_CN/riscv/boot-image-header translations/zh_CN/arch/riscv/boot-image-header
translations/zh_CN/riscv/index translations/zh_CN/arch/riscv/index
translations/zh_CN/riscv/patch-acceptance translations/zh_CN/arch/riscv/patch-acceptance
translations/zh_CN/riscv/vm-layout translations/zh_CN/arch/riscv/vm-layout
translations/zh_CN/vm/active_mm translations/zh_CN/mm/active_mm
translations/zh_CN/vm/balance translations/zh_CN/mm/balance
translations/zh_CN/vm/damon/api translations/zh_CN/mm/damon/api
translations/zh_CN/vm/damon/design translations/zh_CN/mm/damon/design
translations/zh_CN/vm/damon/faq translations/zh_CN/mm/damon/faq
translations/zh_CN/vm/damon/index translations/zh_CN/mm/damon/index
translations/zh_CN/vm/free_page_reporting translations/zh_CN/mm/free_page_reporting
translations/zh_CN/vm/highmem translations/zh_CN/mm/highmem
translations/zh_CN/vm/hmm translations/zh_CN/mm/hmm
translations/zh_CN/vm/hugetlbfs_reserv translations/zh_CN/mm/hugetlbfs_reserv
translations/zh_CN/vm/hwpoison translations/zh_CN/mm/hwpoison
translations/zh_CN/vm/index translations/zh_CN/mm/index
translations/zh_CN/vm/ksm translations/zh_CN/mm/ksm
translations/zh_CN/vm/memory-model translations/zh_CN/mm/memory-model
translations/zh_CN/vm/mmu_notifier translations/zh_CN/mm/mmu_notifier
translations/zh_CN/vm/numa translations/zh_CN/mm/numa
translations/zh_CN/vm/overcommit-accounting translations/zh_CN/mm/overcommit-accounting
translations/zh_CN/vm/page_frags translations/zh_CN/mm/page_frags
translations/zh_CN/vm/page_owner translations/zh_CN/mm/page_owner
translations/zh_CN/vm/page_table_check translations/zh_CN/mm/page_table_check
translations/zh_CN/vm/remap_file_pages translations/zh_CN/mm/remap_file_pages
translations/zh_CN/vm/split_page_table_lock translations/zh_CN/mm/split_page_table_lock
translations/zh_CN/vm/zsmalloc translations/zh_CN/mm/zsmalloc
translations/zh_TW/arm64/amu translations/zh_TW/arch/arm64/amu
translations/zh_TW/arm64/elf_hwcaps translations/zh_TW/arch/arm64/elf_hwcaps
translations/zh_TW/arm64/hugetlbpage translations/zh_TW/arch/arm64/hugetlbpage
translations/zh_TW/arm64/index translations/zh_TW/arch/arm64/index
translations/zh_TW/arm64/perf translations/zh_TW/arch/arm64/perf
tty/device_drivers/oxsemi-tornado misc-devices/oxsemi-tornado
tty/index driver-api/tty/index
tty/n_tty driver-api/tty/n_tty
tty/tty_buffer driver-api/tty/tty_buffer
tty/tty_driver driver-api/tty/tty_driver
tty/tty_internals driver-api/tty/tty_internals
tty/tty_ldisc driver-api/tty/tty_ldisc
tty/tty_port driver-api/tty/tty_port
tty/tty_struct driver-api/tty/tty_struct
usb/typec driver-api/usb/typec
usb/usb3-debug-port driver-api/usb/usb3-debug-port
userspace-api/media/drivers/st-vgxy61 userspace-api/media/drivers/vgxy61
userspace-api/media/v4l/pixfmt-meta-d4xx userspace-api/media/v4l/metafmt-d4xx
userspace-api/media/v4l/pixfmt-meta-intel-ipu3 userspace-api/media/v4l/metafmt-intel-ipu3
userspace-api/media/v4l/pixfmt-meta-rkisp1 userspace-api/media/v4l/metafmt-rkisp1
userspace-api/media/v4l/pixfmt-meta-uvc userspace-api/media/v4l/metafmt-uvc
userspace-api/media/v4l/pixfmt-meta-vivid userspace-api/media/v4l/metafmt-vivid
userspace-api/media/v4l/pixfmt-meta-vsp1-hgo userspace-api/media/v4l/metafmt-vsp1-hgo
userspace-api/media/v4l/pixfmt-meta-vsp1-hgt userspace-api/media/v4l/metafmt-vsp1-hgt
virt/coco/sevguest virt/coco/sev-guest
virt/kvm/amd-memory-encryption virt/kvm/x86/amd-memory-encryption
virt/kvm/arm/psci virt/kvm/arm/fw-pseudo-registers
virt/kvm/cpuid virt/kvm/x86/cpuid
virt/kvm/hypercalls virt/kvm/x86/hypercalls
virt/kvm/mmu virt/kvm/x86/mmu
virt/kvm/msr virt/kvm/x86/msr
virt/kvm/nested-vmx virt/kvm/x86/nested-vmx
virt/kvm/running-nested-guests virt/kvm/x86/running-nested-guests
virt/kvm/s390-diag virt/kvm/s390/s390-diag
virt/kvm/s390-pv virt/kvm/s390/s390-pv
virt/kvm/s390-pv-boot virt/kvm/s390/s390-pv-boot
virt/kvm/timekeeping virt/kvm/x86/timekeeping
virt/kvm/x86/halt-polling virt/kvm/halt-polling
virtual/index virt/index
virtual/kvm/amd-memory-encryption virt/kvm/x86/amd-memory-encryption
virtual/kvm/cpuid virt/kvm/x86/cpuid
virtual/kvm/index virt/kvm/index
virtual/kvm/vcpu-requests virt/kvm/vcpu-requests
virtual/paravirt_ops virt/paravirt_ops
vm/active_mm mm/active_mm
vm/arch_pgtable_helpers mm/arch_pgtable_helpers
vm/balance mm/balance
vm/bootmem mm/bootmem
vm/damon/api mm/damon/api
vm/damon/design mm/damon/design
vm/damon/faq mm/damon/faq
vm/damon/index mm/damon/index
vm/free_page_reporting mm/free_page_reporting
vm/highmem mm/highmem
vm/hmm mm/hmm
vm/hugetlbfs_reserv mm/hugetlbfs_reserv
vm/hugetlbpage admin-guide/mm/hugetlbpage
vm/hwpoison mm/hwpoison
vm/idle_page_tracking admin-guide/mm/idle_page_tracking
vm/index mm/index
vm/ksm mm/ksm
vm/memory-model mm/memory-model
vm/mmu_notifier mm/mmu_notifier
vm/numa mm/numa
vm/numa_memory_policy admin-guide/mm/numa_memory_policy
vm/oom mm/oom
vm/overcommit-accounting mm/overcommit-accounting
vm/page_allocation mm/page_allocation
vm/page_cache mm/page_cache
vm/page_frags mm/page_frags
vm/page_migration mm/page_migration
vm/page_owner mm/page_owner
vm/page_reclaim mm/page_reclaim
vm/page_table_check mm/page_table_check
vm/page_tables mm/page_tables
vm/pagemap admin-guide/mm/pagemap
vm/physical_memory mm/physical_memory
vm/process_addrs mm/process_addrs
vm/remap_file_pages mm/remap_file_pages
vm/shmfs mm/shmfs
vm/slab mm/slab
vm/slub admin-guide/mm/slab
vm/soft-dirty admin-guide/mm/soft-dirty
vm/split_page_table_lock mm/split_page_table_lock
vm/swap mm/swap
vm/swap_numa admin-guide/mm/swap_numa
vm/transhuge mm/transhuge
vm/unevictable-lru mm/unevictable-lru
vm/userfaultfd admin-guide/mm/userfaultfd
vm/vmalloc mm/vmalloc
vm/vmalloced-kernel-stacks mm/vmalloced-kernel-stacks
vm/vmemmap_dedup mm/vmemmap_dedup
vm/zsmalloc mm/zsmalloc
vm/zswap admin-guide/mm/zswap
watch_queue core-api/watch_queue
x86/amd-memory-encryption arch/x86/amd-memory-encryption
x86/amd_hsmp arch/x86/amd_hsmp
x86/boot arch/x86/boot
x86/booting-dt arch/x86/booting-dt
x86/buslock arch/x86/buslock
x86/cpuinfo arch/x86/cpuinfo
x86/earlyprintk arch/x86/earlyprintk
x86/elf_auxvec arch/x86/elf_auxvec
x86/entry_64 arch/x86/entry_64
x86/exception-tables arch/x86/exception-tables
x86/features arch/x86/features
x86/i386/IO-APIC arch/x86/i386/IO-APIC
x86/i386/index arch/x86/i386/index
x86/ifs arch/x86/ifs
x86/index arch/x86/index
x86/intel-hfi arch/x86/intel-hfi
x86/intel_txt arch/x86/intel_txt
x86/iommu arch/x86/iommu
x86/kernel-stacks arch/x86/kernel-stacks
x86/mds arch/x86/mds
x86/microcode arch/x86/microcode
x86/mtrr arch/x86/mtrr
x86/orc-unwinder arch/x86/orc-unwinder
x86/pat arch/x86/pat
x86/protection-keys core-api/protection-keys
x86/pti arch/x86/pti
x86/resctrl filesystems/resctrl
x86/resctrl_ui filesystems/resctrl
x86/sgx arch/x86/sgx
x86/sva arch/x86/sva
x86/tdx arch/x86/tdx
x86/tlb arch/x86/tlb
x86/topology arch/x86/topology
x86/tsx_async_abort arch/x86/tsx_async_abort
x86/usb-legacy-support arch/x86/usb-legacy-support
x86/x86_64/5level-paging arch/x86/x86_64/5level-paging
x86/x86_64/cpu-hotplug-spec arch/x86/x86_64/cpu-hotplug-spec
x86/x86_64/fake-numa-for-cpusets arch/x86/x86_64/fake-numa-for-cpusets
x86/x86_64/fsgs arch/x86/x86_64/fsgs
x86/x86_64/index arch/x86/x86_64/index
x86/x86_64/machinecheck arch/x86/x86_64/machinecheck
x86/x86_64/mm arch/x86/x86_64/mm
x86/x86_64/uefi arch/x86/x86_64/uefi
x86/xstate arch/x86/xstate
x86/zero-page arch/x86/zero-page
xilinx/eemi driver-api/xilinx/eemi
xilinx/index driver-api/xilinx/index
xtensa/atomctl arch/xtensa/atomctl
xtensa/booting arch/xtensa/booting
xtensa/features arch/xtensa/features
xtensa/index arch/xtensa/index
xtensa/mmu arch/xtensa/mmu


Documentation Atomic Bitops (`Documentation/atomic_bitops.txt`)

============= Atomic bitops

While our bitmap_{}() functions are non-atomic, we have a number of operations
operating on single bits in a bitmap that are atomic.

API

The single bit operations are:

Non-RMW ops:

test_bit()

RMW atomic operations without return value:

{set,clear,change}_bit()
clear_bit_unlock()

RMW atomic operations with return value:

test_and_{set,clear,change}_bit()
test_and_set_bit_lock()

Barriers:

smp_mb__{before,after}_atomic()

All RMW atomic operations have a '__' prefixed variant which is non-atomic.

SEMANTICS

Non-atomic ops:

In particular __clear_bit_unlock() suffers the same issue as atomic_set(),
which is why the generic version maps to clear_bit_unlock(), see atomic_t.txt.

RMW ops:

The test_and_{}_bit() operations return the original value of the bit.

ORDERING

Like with atomic_t, the rule of thumb is:

  • non-RMW operations are unordered;

  • RMW operations that have no return value are unordered;

  • RMW operations that have a return value are fully ordered.

  • RMW operations that are conditional are fully ordered.

Except for a successful test_and_set_bit_lock() which has ACQUIRE semantics,
clear_bit_unlock() which has RELEASE semantics and test_bit_acquire which has
ACQUIRE semantics.

Since a platform only has a single means of achieving atomic operations
the same barriers as for atomic_t are used, see atomic_t.txt.


Documentation Atomic T (`Documentation/atomic_t.txt`)

On atomic types (atomic_t atomic64_t and atomic_long_t).

The atomic type provides an interface to the architecture's means of atomic
RMW operations between CPUs (atomic operations on MMIO are not supported and
can lead to fatal traps on some platforms).

API

The 'full' API consists of (atomic64_ and atomic_long_ prefixes omitted for
brevity):

Non-RMW ops:

atomic_read(), atomic_set()
atomic_read_acquire(), atomic_set_release()

RMW atomic operations:

Arithmetic:

atomic_{add,sub,inc,dec}()
atomic_{add,sub,inc,dec}_return{,_relaxed,_acquire,release}()
atomic_fetch
{add,sub,inc,dec}{,_relaxed,_acquire,_release}()

Bitwise:

atomic_{and,or,xor,andnot}()
atomic_fetch_{and,or,xor,andnot}{,_relaxed,_acquire,_release}()

Swap:

atomic_xchg{,_relaxed,_acquire,_release}()
atomic_cmpxchg{,_relaxed,_acquire,_release}()
atomic_try_cmpxchg{,_relaxed,_acquire,_release}()

Reference count (but please see refcount_t):

atomic_add_unless(), atomic_inc_not_zero()
atomic_sub_and_test(), atomic_dec_and_test()

Misc:

atomic_inc_and_test(), atomic_add_negative()
atomic_dec_unless_positive(), atomic_inc_unless_negative()

Barriers:

smp_mb__{before,after}_atomic()

TYPES (signed vs unsigned)

While atomic_t, atomic_long_t and atomic64_t use int, long and s64
respectively (for hysterical raisins), the kernel uses -fno-strict-overflow
(which implies -fwrapv) and defines signed overflow to behave like
2s-complement.

Therefore, an explicitly unsigned variant of the atomic ops is strictly
unnecessary and we can simply cast, there is no UB.

There was a bug in UBSAN prior to GCC-8 that would generate UB warnings for
signed types.

With this we also conform to the C/C++ _Atomic behaviour and things like
P1236R1.

SEMANTICS

Non-RMW ops:

The non-RMW ops are (typically) regular LOADs and STOREs and are canonically
implemented using READ_ONCE(), WRITE_ONCE(), smp_load_acquire() and
smp_store_release() respectively. Therefore, if you find yourself only using
the Non-RMW operations of atomic_t, you do not in fact need atomic_t at all
and are doing it wrong.

A note for the implementation of atomic_set{}() is that it must not break the
atomicity of the RMW ops. That is:

C Atomic-RMW-ops-are-atomic-WRT-atomic_set

{
atomic_t v = ATOMIC_INIT(1);
}

P0(atomic_t *v)
{
(void)atomic_add_unless(v, 1, 0);
}

P1(atomic_t *v)
{
atomic_set(v, 0);
}

exists
(v=2)

In this case we would expect the atomic_set() from CPU1 to either happen
before the atomic_add_unless(), in which case that latter one would no-op, or
after in which case we'd overwrite its result. In no case is "2" a valid
outcome.

This is typically true on 'normal' platforms, where a regular competing STORE
will invalidate a LL/SC or fail a CMPXCHG.

The obvious case where this is not so is when we need to implement atomic ops
with a lock:

CPU0 CPU1

atomic_add_unless(v, 1, 0);
lock();
ret = READ_ONCE(v->counter); // == 1
atomic_set(v, 0);
if (ret != u) WRITE_ONCE(v->counter, 0);
WRITE_ONCE(v->counter, ret + 1);
unlock();

the typical solution is to then implement atomic_set{}() with atomic_xchg().

RMW ops:

These come in various forms:

  • plain operations without return value: atomic_{}()

  • operations which return the modified value: atomic_{}_return()

    these are limited to the arithmetic operations because those are
    reversible. Bitops are irreversible and therefore the modified value
    is of dubious utility.

  • operations which return the original value: atomic_fetch_{}()

  • swap operations: xchg(), cmpxchg() and try_cmpxchg()

  • misc; the special purpose operations that are commonly used and would,
    given the interface, normally be implemented using (try_)cmpxchg loops but
    are time critical and can, (typically) on LL/SC architectures, be more
    efficiently implemented.

All these operations are SMP atomic; that is, the operations (for a single
atomic variable) can be fully ordered and no intermediate state is lost or
visible.

ORDERING (go read memory-barriers.txt first)

The rule of thumb:

  • non-RMW operations are unordered;

  • RMW operations that have no return value are unordered;

  • RMW operations that have a return value are fully ordered;

  • RMW operations that are conditional are unordered on FAILURE,
    otherwise the above rules apply.

Except of course when a successful operation has an explicit ordering like:

{}_relaxed: unordered
{}_acquire: the R of the RMW (or atomic_read) is an ACQUIRE
{}_release: the W of the RMW (or atomic_set) is a RELEASE

Where 'unordered' is against other memory locations. Address dependencies are
not defeated. Conditional operations are still unordered on FAILURE.

Fully ordered primitives are ordered against everything prior and everything
subsequent. Therefore a fully ordered primitive is like having an smp_mb()
before and an smp_mb() after the primitive.

The barriers:

smp_mb__{before,after}_atomic()

only apply to the RMW atomic ops and can be used to augment/upgrade the
ordering inherent to the op. These barriers act almost like a full smp_mb():
smp_mb__before_atomic() orders all earlier accesses against the RMW op
itself and all accesses following it, and smp_mb__after_atomic() orders all
later accesses against the RMW op and all accesses preceding it. However,
accesses between the smp_mb__{before,after}_atomic() and the RMW op are not
ordered, so it is advisable to place the barrier right next to the RMW atomic
op whenever possible.

These helper barriers exist because architectures have varying implicit
ordering on their SMP atomic primitives. For example our TSO architectures
provide full ordered atomics and these barriers are no-ops.

NOTE: when the atomic RmW ops are fully ordered, they should also imply a
compiler barrier.

Thus:

atomic_fetch_add();

is equivalent to:

smp_mb__before_atomic();
atomic_fetch_add_relaxed();
smp_mb__after_atomic();

However the atomic_fetch_add() might be implemented more efficiently.

Further, while something like:

smp_mb__before_atomic();
atomic_dec(&X);

is a 'typical' RELEASE pattern, the barrier is strictly stronger than
a RELEASE because it orders preceding instructions against both the read
and write parts of the atomic_dec(), and against all following instructions
as well. Similarly, something like:

atomic_inc(&X);
smp_mb__after_atomic();

is an ACQUIRE pattern (though very much not typical), but again the barrier is
strictly stronger than ACQUIRE. As illustrated:

C Atomic-RMW+mb__after_atomic-is-stronger-than-acquire

{
}

P0(int *x, atomic_t *y)
{
r0 = READ_ONCE(*x);
smp_rmb();
r1 = atomic_read(y);
}

P1(int *x, atomic_t *y)
{
atomic_inc(y);
smp_mb__after_atomic();
WRITE_ONCE(*x, 1);
}

exists
(0:r0=1 /\ 0:r1=0)

This should not happen; but a hypothetical atomic_inc_acquire() --
(void)atomic_fetch_inc_acquire() for instance -- would allow the outcome,
because it would not order the W part of the RMW against the following
WRITE_ONCE. Thus:

P0 P1

text
t = LL.acq *y (0)
		t++;
		*x = 1;

r0 = *x (1)
RMB
r1 = *y (0)
SC *y, t;

is allowed.

CMPXCHG vs TRY_CMPXCHG

int atomic_cmpxchg(atomic_t *ptr, int old, int new);
bool atomic_try_cmpxchg(atomic_t *ptr, int *oldp, int new);

Both provide the same functionality, but try_cmpxchg() can lead to more
compact code. The functions relate like:

bool atomic_try_cmpxchg(atomic_t *ptr, int *oldp, int new)
{
int ret, old = *oldp;
ret = atomic_cmpxchg(ptr, old, new);
if (ret != old)
*oldp = ret;
return ret == old;
}

and:

int atomic_cmpxchg(atomic_t *ptr, int old, int new)
{
(void)atomic_try_cmpxchg(ptr, &old, new);
return old;
}

Usage:

old = atomic_read(&v); old = atomic_read(&v);
for (;;) { do {
new = func(old); new = func(old);
tmp = atomic_cmpxchg(&v, old, new); } while (!atomic_try_cmpxchg(&v, &old, new));
if (tmp == old)
break;
old = tmp;
}

NB. try_cmpxchg() also generates better code on some platforms (notably x86)
where the function more closely matches the hardware instruction.

FORWARD PROGRESS

In general strong forward progress is expected of all unconditional atomic
operations -- those in the Arithmetic and Bitwise classes and xchg(). However
a fair amount of code also requires forward progress from the conditional
atomic operations.

Specifically 'simple' cmpxchg() loops are expected to not starve one another
indefinitely. However, this is not evident on LL/SC architectures, because
while an LL/SC architecture 'can/should/must' provide forward progress
guarantees between competing LL/SC sections, such a guarantee does not
transfer to cmpxchg() implemented using LL/SC. Consider:

old = atomic_read(&v);
do {
new = func(old);
} while (!atomic_try_cmpxchg(&v, &old, new));

which on LL/SC becomes something like:

old = atomic_read(&v);
do {
new = func(old);
} while (!({
volatile asm ("1: LL %[oldval], %[v]\n"
" CMP %[oldval], %[old]\n"
" BNE 2f\n"
" SC %[new], %[v]\n"
" BNE 1b\n"
"2:\n"
: [oldval] "=&r" (oldval), [v] "m" (v)
: [old] "r" (old), [new] "r" (new)
: "memory");
success = (oldval == old);
if (!success)
old = oldval;
success; }));

However, even the forward branch from the failed compare can cause the LL/SC
to fail on some architectures, let alone whatever the compiler makes of the C
loop body. As a result there is no guarantee what so ever the cacheline
containing @v will stay on the local CPU and progress is made.

Even native CAS architectures can fail to provide forward progress for their
primitive (See Sparc64 for an example).

Such implementations are strongly encouraged to add exponential backoff loops
to a failed CAS in order to ensure some progress. Affected architectures are
also strongly encouraged to inspect/audit the atomic fallbacks, refcount_t and
their locking primitives.


Documentation Index (`Documentation/index.rst`)

.. SPDX-License-Identifier: GPL-2.0

.. _linux_doc:

============================== The Linux Kernel documentation

This is the top level of the kernel's documentation tree. Kernel
documentation, like the kernel itself, is very much a work in progress;
that is especially true as we work to integrate our many scattered
documents into a coherent whole. Please note that improvements to the
documentation are welcome; join the linux-doc list at vger.kernel.org if
you want to help out.

Working with the development community

The essential guides for interacting with the kernel's development
community and getting your work upstream.

.. toctree::
:maxdepth: 1
:caption: Working with the development community

Development process
Submitting patches
Code of conduct
Maintainer handbook <maintainer/index>
All development-process docs

Internal API manuals

Manuals for use by developers working to interface with the rest of the
kernel.

.. toctree::
:maxdepth: 1
:caption: Internal API manuals

Core API <core-api/index>
Driver APIs <driver-api/index>
Subsystems
Locking <locking/index>

Development tools and processes

Various other manuals with useful information for all kernel developers.

.. toctree::
:maxdepth: 1
:caption: Development tools and processes

Licensing rules
Writing documentation <doc-guide/index>
Development tools <dev-tools/index>
Testing guide <dev-tools/testing-overview>
Hacking guide <kernel-hacking/index>
Tracing
Fault injection <fault-injection/index>
Livepatching <livepatch/index>
Rust <rust/index>

User-oriented documentation

The following manuals are written for users of the kernel โ€” those who are
trying to get it to work optimally on a given system and application
developers seeking information on the kernel's user-space APIs.

.. toctree::
:maxdepth: 1
:caption: User-oriented documentation

Administration <admin-guide/index>
Build system <kbuild/index>
Reporting issues <admin-guide/reporting-issues.rst>
Userspace tools <tools/index>
Userspace API

See also: the Linux man pages <https://www.kernel.org/doc/man-pages/>_,
which are kept separately from the kernel's own documentation.

The following holds information on the kernel's expectations regarding the
platform firmware.

.. toctree::
:maxdepth: 1
:caption: Firmware-related documentation

Firmware <firmware-guide/index>
Firmware and Devicetree <devicetree/index>

Architecture-specific documentation

.. toctree::
:maxdepth: 2
:caption: Architecture-specific documentation

CPU architectures <arch/index>

Other documentation

There are several unsorted documents that don't seem to fit on other parts
of the documentation body, or may require some adjustments and/or conversion
to reStructuredText format, or are simply too old.

.. toctree::
:maxdepth: 1
:caption: Other documentation

Unsorted documentation <staging/index>

Translations

.. toctree::
:maxdepth: 2
:caption: Translations

Translations

Indices and tables

  • :ref:genindex

Documentation Memory Barriers (`Documentation/memory-barriers.txt`)

============================
LINUX KERNEL MEMORY BARRIERS
============================

By: David Howells [email protected]
Paul E. McKenney
Will Deacon [email protected]
Peter Zijlstra

========== DISCLAIMER

This document is not a specification; it is intentionally (for the sake of
brevity) and unintentionally (due to being human) incomplete. This document is
meant as a guide to using the various memory barriers provided by Linux, but
in case of any doubt (and there are many) please ask. Some doubts may be
resolved by referring to the formal memory consistency model and related
documentation at tools/memory-model/. Nevertheless, even this memory
model should be viewed as the collective opinion of its maintainers rather
than as an infallible oracle.

To repeat, this document is not a specification of what Linux expects from
hardware.

The purpose of this document is twofold:

(1) to specify the minimum functionality that one can rely on for any
particular barrier, and

(2) to provide a guide as to how to use the barriers that are available.

Note that an architecture can provide more than the minimum requirement
for any particular barrier, but if the architecture provides less than
that, that architecture is incorrect.

Note also that it is possible that a barrier may be a no-op for an
architecture because the way that arch works renders an explicit barrier
unnecessary in that case.

======== CONTENTS

(*) Abstract memory access model.

text
- Device operations.
 - Guarantees.

(*) What are memory barriers?

text
- Varieties of memory barrier.
 - What may not be assumed about memory barriers?
 - Address-dependency barriers (historical).
 - Control dependencies.
 - SMP barrier pairing.
 - Examples of memory barrier sequences.
 - Read memory barriers vs load speculation.
 - Multicopy atomicity.

(*) Explicit kernel barriers.

text
- Compiler barrier.
 - CPU memory barriers.

(*) Implicit kernel memory barriers.

text
- Lock acquisition functions.
 - Interrupt disabling functions.
 - Sleep and wake-up functions.
 - Miscellaneous functions.

(*) Inter-CPU acquiring barrier effects.

text
- Acquires vs memory accesses.

(*) Where are memory barriers needed?

text
- Interprocessor interaction.
 - Atomic operations.
 - Accessing devices.
 - Interrupts.

(*) Kernel I/O barrier effects.

(*) Assumed minimum execution ordering model.

(*) The effects of the cpu cache.

text
- Cache coherency vs DMA.
 - Cache coherency vs MMIO.

(*) The things CPUs get up to.

text
- And then there's the Alpha.
 - Virtual Machine Guests.

(*) Example uses.

text
- Circular buffers.

(*) References.

============================ ABSTRACT MEMORY ACCESS MODEL

Consider the following abstract model of the system:

text
:                :
	            :                :
	            :                :
	+-------+   :   +--------+   :   +-------+
	|       |   :   |        |   :   |       |
	|       |   :   |        |   :   |       |
	| CPU 1 |<----->| Memory |<----->| CPU 2 |
	|       |   :   |        |   :   |       |
	|       |   :   |        |   :   |       |
	+-------+   :   +--------+   :   +-------+
	    ^       :       ^        :       ^
	    |       :       |        :       |
	    |       :       |        :       |
	    |       :       v        :       |
	    |       :   +--------+   :       |
	    |       :   |        |   :       |
	    |       :   |        |   :       |
	    +---------->| Device |<----------+
	            :   |        |   :
	            :   |        |   :
	            :   +--------+   :
	            :                :

Each CPU executes a program that generates memory access operations. In the
abstract CPU, memory operation ordering is very relaxed, and a CPU may actually
perform the memory operations in any order it likes, provided program causality
appears to be maintained. Similarly, the compiler may also arrange the
instructions it emits in any order it likes, provided it doesn't affect the
apparent operation of the program.

So in the above diagram, the effects of the memory operations performed by a
CPU are perceived by the rest of the system as the operations cross the
interface between the CPU and rest of the system (the dotted lines).

For example, consider the following sequence of events:

text
CPU 1		CPU 2
===============	===============
{ A == 1; B == 2 }
A = 3;		x = B;
B = 4;		y = A;

The set of accesses as seen by the memory system in the middle can be arranged
in 24 different combinations:

text
STORE A=3,	STORE B=4,	y=LOAD A->3,	x=LOAD B->4
STORE A=3,	STORE B=4,	x=LOAD B->4,	y=LOAD A->3
STORE A=3,	y=LOAD A->3,	STORE B=4,	x=LOAD B->4
STORE A=3,	y=LOAD A->3,	x=LOAD B->2,	STORE B=4
STORE A=3,	x=LOAD B->2,	STORE B=4,	y=LOAD A->3
STORE A=3,	x=LOAD B->2,	y=LOAD A->3,	STORE B=4
STORE B=4,	STORE A=3,	y=LOAD A->3,	x=LOAD B->4
STORE B=4, ...
...

and can thus result in four different combinations of values:

text
x == 2, y == 1
x == 2, y == 3
x == 4, y == 1
x == 4, y == 3

Furthermore, the stores committed by a CPU to the memory system may not be
perceived by the loads made by another CPU in the same order as the stores were
committed.

As a further example, consider this sequence of events:

text
CPU 1		CPU 2
===============	===============
{ A == 1, B == 2, C == 3, P == &A, Q == &C }
B = 4;		Q = P;
P = &B;		D = *Q;

There is an obvious address dependency here, as the value loaded into D depends
on the address retrieved from P by CPU 2. At the end of the sequence, any of
the following results are possible:

text
(Q == &A) and (D == 1)
(Q == &B) and (D == 2)
(Q == &B) and (D == 4)

Note that CPU 2 will never try and load C into D because the CPU will load P
into Q before issuing the load of *Q.

DEVICE OPERATIONS

Some devices present their control interfaces as collections of memory
locations, but the order in which the control registers are accessed is very
important. For instance, imagine an ethernet card with a set of internal
registers that are accessed through an address port register (A) and a data
port register (D). To read internal register 5, the following code might then
be used:

text
*A = 5;
x = *D;

but this might show up as either of the following two sequences:

text
STORE *A = 5, x = LOAD *D
x = LOAD *D, STORE *A = 5

the second of which will almost certainly result in a malfunction, since it set
the address after attempting to read the register.

GUARANTEES

There are some minimal guarantees that may be expected of a CPU:

(*) On any given CPU, dependent memory accesses will be issued in order, with
respect to itself. This means that for:

text
Q = READ_ONCE(P); D = READ_ONCE(*Q);

 the CPU will issue the following memory operations:

Q = LOAD P, D = LOAD *Q

 and always in that order.  However, on DEC Alpha, READ_ONCE() also
 emits a memory-barrier instruction, so that a DEC Alpha CPU will
 instead issue the following memory operations:

Q = LOAD P, MEMORY_BARRIER, D = LOAD *Q, MEMORY_BARRIER

 Whether on DEC Alpha or not, the READ_ONCE() also prevents compiler
 mischief.

(*) Overlapping loads and stores within a particular CPU will appear to be
ordered within that CPU. This means that for:

text
a = READ_ONCE(*X); WRITE_ONCE(*X, b);

 the CPU will only issue the following sequence of memory operations:

a = LOAD *X, STORE *X = b

 And for:

WRITE_ONCE(*X, c); d = READ_ONCE(*X);

 the CPU will only issue:

STORE *X = c, d = LOAD *X

 (Loads and stores overlap if they are targeted at overlapping pieces of
 memory).

And there are a number of things that must or must_not be assumed:

(*) It must_not be assumed that the compiler will do what you want
with memory references that are not protected by READ_ONCE() and
WRITE_ONCE(). Without them, the compiler is within its rights to
do all sorts of "creative" transformations, which are covered in
the COMPILER BARRIER section.

(*) It must_not be assumed that independent loads and stores will be issued
in the order given. This means that for:

text
X = *A; Y = *B; *D = Z;

 we may get any of the following sequences:

X = LOAD *A,  Y = LOAD *B,  STORE *D = Z
X = LOAD *A,  STORE *D = Z, Y = LOAD *B
Y = LOAD *B,  X = LOAD *A,  STORE *D = Z
Y = LOAD *B,  STORE *D = Z, X = LOAD *A
STORE *D = Z, X = LOAD *A,  Y = LOAD *B
STORE *D = Z, Y = LOAD *B,  X = LOAD *A

(*) It must be assumed that overlapping memory accesses may be merged or
discarded. This means that for:

text
X = *A; Y = *(A + 4);

 we may get any one of the following sequences:

X = LOAD *A; Y = LOAD *(A + 4);
Y = LOAD *(A + 4); X = LOAD *A;
{X, Y} = LOAD {*A, *(A + 4) };

 And for:

*A = X; *(A + 4) = Y;

 we may get any of:

STORE *A = X; STORE *(A + 4) = Y;
STORE *(A + 4) = Y; STORE *A = X;
STORE {*A, *(A + 4) } = {X, Y};

And there are anti-guarantees:

(*) These guarantees do not apply to bitfields, because compilers often
generate code to modify these using non-atomic read-modify-write
sequences. Do not attempt to use bitfields to synchronize parallel
algorithms.

(*) Even in cases where bitfields are protected by locks, all fields
in a given bitfield must be protected by one lock. If two fields
in a given bitfield are protected by different locks, the compiler's
non-atomic read-modify-write sequences can cause an update to one
field to corrupt the value of an adjacent field.

(*) These guarantees apply only to properly aligned and sized scalar
variables. "Properly sized" currently means variables that are
the same size as "char", "short", "int" and "long". "Properly
aligned" means the natural alignment, thus no constraints for
"char", two-byte alignment for "short", four-byte alignment for
"int", and either four-byte or eight-byte alignment for "long",
on 32-bit and 64-bit systems, respectively. Note that these
guarantees were introduced into the C11 standard, so beware when
using older pre-C11 compilers (for example, gcc 4.6). The portion
of the standard containing this guarantee is Section 3.14, which
defines "memory location" as follows:

text
memory location
	either an object of scalar type, or a maximal sequence
	of adjacent bit-fields all having nonzero width

	NOTE 1: Two threads of execution can update and access
	separate memory locations without interfering with
	each other.

	NOTE 2: A bit-field and an adjacent non-bit-field member
	are in separate memory locations. The same applies
	to two bit-fields, if one is declared inside a nested
	structure declaration and the other is not, or if the two
	are separated by a zero-length bit-field declaration,
	or if they are separated by a non-bit-field member
	declaration. It is not safe to concurrently update two
	bit-fields in the same structure if all members declared
	between them are also bit-fields, no matter what the
	sizes of those intervening bit-fields happen to be.

========================= WHAT ARE MEMORY BARRIERS?

As can be seen above, independent memory operations are effectively performed
in random order, but this can be a problem for CPU-CPU interaction and for I/O.
What is required is some way of intervening to instruct the compiler and the
CPU to restrict the order.

Memory barriers are such interventions. They impose a perceived partial
ordering over the memory operations on either side of the barrier.

Such enforcement is important because the CPUs and other devices in a system
can use a variety of tricks to improve performance, including reordering,
deferral and combination of memory operations; speculative loads; speculative
branch prediction and various types of caching. Memory barriers are used to
override or suppress these tricks, allowing the code to sanely control the
interaction of multiple CPUs and/or devices.

VARIETIES OF MEMORY BARRIER

Memory barriers come in four basic varieties:

(1) Write (or store) memory barriers.

text
A write memory barrier gives a guarantee that all the STORE operations
 specified before the barrier will appear to happen before all the STORE
 operations specified after the barrier with respect to the other
 components of the system.

 A write barrier is a partial ordering on stores only; it is not required
 to have any effect on loads.

 A CPU can be viewed as committing a sequence of store operations to the
 memory system as time progresses.  All stores _before_ a write barrier
 will occur _before_ all the stores after the write barrier.

 [!] Note that write barriers should normally be paired with read or
 address-dependency barriers; see the "SMP barrier pairing" subsection.

(2) Address-dependency barriers (historical).
[!] This section is marked as HISTORICAL: it covers the long-obsolete
smp_read_barrier_depends() macro, the semantics of which are now
implicit in all marked accesses. For more up-to-date information,
including how compiler transformations can sometimes break address
dependencies, see Documentation/RCU/rcu_dereference.rst.

text
An address-dependency barrier is a weaker form of read barrier.  In the
 case where two loads are performed such that the second depends on the
 result of the first (eg: the first load retrieves the address to which
 the second load will be directed), an address-dependency barrier would
 be required to make sure that the target of the second load is updated
 after the address obtained by the first load is accessed.

 An address-dependency barrier is a partial ordering on interdependent
 loads only; it is not required to have any effect on stores, independent
 loads or overlapping loads.

 As mentioned in (1), the other CPUs in the system can be viewed as
 committing sequences of stores to the memory system that the CPU being
 considered can then perceive.  An address-dependency barrier issued by
 the CPU under consideration guarantees that for any load preceding it,
 if that load touches one of a sequence of stores from another CPU, then
 by the time the barrier completes, the effects of all the stores prior to
 that touched by the load will be perceptible to any loads issued after
 the address-dependency barrier.

 See the "Examples of memory barrier sequences" subsection for diagrams
 showing the ordering constraints.

 [!] Note that the first load really has to have an _address_ dependency and
 not a control dependency.  If the address for the second load is dependent
 on the first load, but the dependency is through a conditional rather than
 actually loading the address itself, then it's a _control_ dependency and
 a full read barrier or better is required.  See the "Control dependencies"
 subsection for more information.

 [!] Note that address-dependency barriers should normally be paired with
 write barriers; see the "SMP barrier pairing" subsection.

 [!] Kernel release v5.9 removed kernel APIs for explicit address-
 dependency barriers.  Nowadays, APIs for marking loads from shared
 variables such as READ_ONCE() and rcu_dereference() provide implicit
 address-dependency barriers.

(3) Read (or load) memory barriers.

text
A read barrier is an address-dependency barrier plus a guarantee that all
 the LOAD operations specified before the barrier will appear to happen
 before all the LOAD operations specified after the barrier with respect to
 the other components of the system.

 A read barrier is a partial ordering on loads only; it is not required to
 have any effect on stores.

 Read memory barriers imply address-dependency barriers, and so can
 substitute for them.

 [!] Note that read barriers should normally be paired with write barriers;
 see the "SMP barrier pairing" subsection.

(4) General memory barriers.

text
A general memory barrier gives a guarantee that all the LOAD and STORE
 operations specified before the barrier will appear to happen before all
 the LOAD and STORE operations specified after the barrier with respect to
 the other components of the system.

 A general memory barrier is a partial ordering over both loads and stores.

 General memory barriers imply both read and write memory barriers, and so
 can substitute for either.

And a couple of implicit varieties:

(5) ACQUIRE operations.

text
This acts as a one-way permeable barrier.  It guarantees that all memory
 operations after the ACQUIRE operation will appear to happen after the
 ACQUIRE operation with respect to the other components of the system.
 ACQUIRE operations include LOCK operations and both smp_load_acquire()
 and smp_cond_load_acquire() operations.

 Memory operations that occur before an ACQUIRE operation may appear to
 happen after it completes.

 An ACQUIRE operation should almost always be paired with a RELEASE
 operation.

(6) RELEASE operations.

text
This also acts as a one-way permeable barrier.  It guarantees that all
 memory operations before the RELEASE operation will appear to happen
 before the RELEASE operation with respect to the other components of the
 system. RELEASE operations include UNLOCK operations and
 smp_store_release() operations.

 Memory operations that occur after a RELEASE operation may appear to
 happen before it completes.

 The use of ACQUIRE and RELEASE operations generally precludes the need
 for other sorts of memory barrier.  In addition, a RELEASE+ACQUIRE pair is
 -not- guaranteed to act as a full memory barrier.  However, after an
 ACQUIRE on a given variable, all memory accesses preceding any prior
 RELEASE on that same variable are guaranteed to be visible.  In other
 words, within a given variable's critical section, all accesses of all
 previous critical sections for that variable are guaranteed to have
 completed.

 This means that ACQUIRE acts as a minimal "acquire" operation and
 RELEASE acts as a minimal "release" operation.

A subset of the atomic operations described in atomic_t.txt have ACQUIRE and
RELEASE variants in addition to fully-ordered and relaxed (no barrier
semantics) definitions. For compound atomics performing both a load and a
store, ACQUIRE semantics apply only to the load and RELEASE semantics apply
only to the store portion of the operation.

Memory barriers are only required where there's a possibility of interaction
between two CPUs or between a CPU and a device. If it can be guaranteed that
there won't be any such interaction in any particular piece of code, then
memory barriers are unnecessary in that piece of code.

Note that these are the minimum guarantees. Different architectures may give
more substantial guarantees, but they may not be relied upon outside of arch
specific code.

WHAT MAY NOT BE ASSUMED ABOUT MEMORY BARRIERS?

There are certain things that the Linux kernel memory barriers do not guarantee:

(*) There is no guarantee that any of the memory accesses specified before a
memory barrier will be complete by the completion of a memory barrier
instruction; the barrier can be considered to draw a line in that CPU's
access queue that accesses of the appropriate type may not cross.

(*) There is no guarantee that issuing a memory barrier on one CPU will have
any direct effect on another CPU or any other hardware in the system. The
indirect effect will be the order in which the second CPU sees the effects
of the first CPU's accesses occur, but see the next point:

(*) There is no guarantee that a CPU will see the correct order of effects
from a second CPU's accesses, even if the second CPU uses a memory
barrier, unless the first CPU also uses a matching memory barrier (see
the subsection on "SMP Barrier Pairing").

() There is no guarantee that some intervening piece of off-the-CPU
hardware[
] will not reorder the memory accesses. CPU cache coherency
mechanisms should propagate the indirect effects of a memory barrier
between CPUs, but might not do so in order.

text
[*] For information on bus mastering DMA and coherency please read:

    Documentation/driver-api/pci/pci.rst
    Documentation/core-api/dma-api-howto.rst
    Documentation/core-api/dma-api.rst

ADDRESS-DEPENDENCY BARRIERS (HISTORICAL)

[!] This section is marked as HISTORICAL: it covers the long-obsolete
smp_read_barrier_depends() macro, the semantics of which are now implicit
in all marked accesses. For more up-to-date information, including
how compiler transformations can sometimes break address dependencies,
see Documentation/RCU/rcu_dereference.rst.

As of v4.15 of the Linux kernel, an smp_mb() was added to READ_ONCE() for
DEC Alpha, which means that about the only people who need to pay attention
to this section are those working on DEC Alpha architecture-specific code
and those working on READ_ONCE() itself. For those who need it, and for
those who are interested in the history, here is the story of
address-dependency barriers.

[!] While address dependencies are observed in both load-to-load and
load-to-store relations, address-dependency barriers are not necessary
for load-to-store situations.

The requirement of address-dependency barriers is a little subtle, and
it's not always obvious that they're needed. To illustrate, consider the
following sequence of events:

text
CPU 1		      CPU 2
===============	      ===============
{ A == 1, B == 2, C == 3, P == &A, Q == &C }
B = 4;
<write barrier>
WRITE_ONCE(P, &B);
		      Q = READ_ONCE_OLD(P);
		      D = *Q;

[!] READ_ONCE_OLD() corresponds to READ_ONCE() of pre-4.15 kernel, which
doesn't imply an address-dependency barrier.

There's a clear address dependency here, and it would seem that by the end of
the sequence, Q must be either &A or &B, and that:

text
(Q == &A) implies (D == 1)
(Q == &B) implies (D == 4)

But! CPU 2's perception of P may be updated before its perception of B, thus
leading to the following situation:

text
(Q == &B) and (D == 2) ????

While this may seem like a failure of coherency or causality maintenance, it
isn't, and this behaviour can be observed on certain real CPUs (such as the DEC
Alpha).

To deal with this, READ_ONCE() provides an implicit address-dependency barrier
since kernel release v4.15:

text
CPU 1		      CPU 2
===============	      ===============
{ A == 1, B == 2, C == 3, P == &A, Q == &C }
B = 4;
<write barrier>
WRITE_ONCE(P, &B);
		      Q = READ_ONCE(P);
		      
		      D = *Q;

This enforces the occurrence of one of the two implications, and prevents the
third possibility from arising.

[!] Note that this extremely counterintuitive situation arises most easily on
machines with split caches, so that, for example, one cache bank processes
even-numbered cache lines and the other bank processes odd-numbered cache
lines. The pointer P might be stored in an odd-numbered cache line, and the
variable B might be stored in an even-numbered cache line. Then, if the
even-numbered bank of the reading CPU's cache is extremely busy while the
odd-numbered bank is idle, one can see the new value of the pointer P (&B),
but the old value of the variable B (2).

An address-dependency barrier is not required to order dependent writes
because the CPUs that the Linux kernel supports don't do writes until they
are certain (1) that the write will actually happen, (2) of the location of
the write, and (3) of the value to be written.
But please carefully read the "CONTROL DEPENDENCIES" section and the
Documentation/RCU/rcu_dereference.rst file: The compiler can and does break
dependencies in a great many highly creative ways.

text
CPU 1		      CPU 2
===============	      ===============
{ A == 1, B == 2, C = 3, P == &A, Q == &C }
B = 4;
<write barrier>
WRITE_ONCE(P, &B);
		      Q = READ_ONCE_OLD(P);
		      WRITE_ONCE(*Q, 5);

Therefore, no address-dependency barrier is required to order the read into
Q with the store into *Q. In other words, this outcome is prohibited,
even without an implicit address-dependency barrier of modern READ_ONCE():

text
(Q == &B) && (B == 4)

Please note that this pattern should be rare. After all, the whole point
of dependency ordering is to -prevent- writes to the data structure, along
with the expensive cache misses associated with those writes. This pattern
can be used to record rare error conditions and the like, and the CPUs'
naturally occurring ordering prevents such records from being lost.

Note well that the ordering provided by an address dependency is local to
the CPU containing it. See the section on "Multicopy atomicity" for
more information.

The address-dependency barrier is very important to the RCU system,
for example. See rcu_assign_pointer() and rcu_dereference() in
include/linux/rcupdate.h. This permits the current target of an RCU'd
pointer to be replaced with a new modified target, without the replacement
target appearing to be incompletely initialised.

CONTROL DEPENDENCIES

Control dependencies can be a bit tricky because current compilers do
not understand them. The purpose of this section is to help you prevent
the compiler's ignorance from breaking your code.

A load-load control dependency requires a full read memory barrier, not
simply an (implicit) address-dependency barrier to make it work correctly.
Consider the following bit of code:

text
q = READ_ONCE(a);

if (q) {
	/* BUG: No address dependency!!! */
	p = READ_ONCE(b);
}

This will not have the desired effect because there is no actual address
dependency, but rather a control dependency that the CPU may short-circuit
by attempting to predict the outcome in advance, so that other CPUs see
the load from b as having happened before the load from a. In such a case
what's actually required is:

text
q = READ_ONCE(a);
if (q) {
	<read barrier>
	p = READ_ONCE(b);
}

However, stores are not speculated. This means that ordering -is- provided
for load-store control dependencies, as in the following example:

text
q = READ_ONCE(a);
if (q) {
	WRITE_ONCE(b, 1);
}

Control dependencies pair normally with other types of barriers.
That said, please note that neither READ_ONCE() nor WRITE_ONCE()
are optional! Without the READ_ONCE(), the compiler might combine the
load from 'a' with other loads from 'a'. Without the WRITE_ONCE(),
the compiler might combine the store to 'b' with other stores to 'b'.
Either can result in highly counterintuitive effects on ordering.

Worse yet, if the compiler is able to prove (say) that the value of
variable 'a' is always non-zero, it would be well within its rights
to optimize the original example by eliminating the "if" statement
as follows:

text
q = a;
b = 1;  /* BUG: Compiler and CPU can both reorder!!! */

So don't leave out the READ_ONCE().

It is tempting to try to enforce ordering on identical stores on both
branches of the "if" statement as follows:

text
q = READ_ONCE(a);
if (q) {
	barrier();
	WRITE_ONCE(b, 1);
	do_something();
} else {
	barrier();
	WRITE_ONCE(b, 1);
	do_something_else();
}

Unfortunately, current compilers will transform this as follows at high
optimization levels:

text
q = READ_ONCE(a);
barrier();
WRITE_ONCE(b, 1);  /* BUG: No ordering vs. load from a!!! */
if (q) {
	/* WRITE_ONCE(b, 1); -- moved up, BUG!!! */
	do_something();
} else {
	/* WRITE_ONCE(b, 1); -- moved up, BUG!!! */
	do_something_else();
}

Now there is no conditional between the load from 'a' and the store to
'b', which means that the CPU is within its rights to reorder them:
The conditional is absolutely required, and must be present in the
assembly code even after all compiler optimizations have been applied.
Therefore, if you need ordering in this example, you need explicit
memory barriers, for example, smp_store_release():

text
q = READ_ONCE(a);
if (q) {
	smp_store_release(&b, 1);
	do_something();
} else {
	smp_store_release(&b, 1);
	do_something_else();
}

In contrast, without explicit memory barriers, two-legged-if control
ordering is guaranteed only when the stores differ, for example:

text
q = READ_ONCE(a);
if (q) {
	WRITE_ONCE(b, 1);
	do_something();
} else {
	WRITE_ONCE(b, 2);
	do_something_else();
}

The initial READ_ONCE() is still required to prevent the compiler from
proving the value of 'a'.

In addition, you need to be careful what you do with the local variable 'q',
otherwise the compiler might be able to guess the value and again remove
the needed conditional. For example:

text
q = READ_ONCE(a);
if (q % MAX) {
	WRITE_ONCE(b, 1);
	do_something();
} else {
	WRITE_ONCE(b, 2);
	do_something_else();
}

If MAX is defined to be 1, then the compiler knows that (q % MAX) is
equal to zero, in which case the compiler is within its rights to
transform the above code into the following:

text
q = READ_ONCE(a);
WRITE_ONCE(b, 2);
do_something_else();

Given this transformation, the CPU is not required to respect the ordering
between the load from variable 'a' and the store to variable 'b'. It is
tempting to add a barrier(), but this does not help. The conditional
is gone, and the barrier won't bring it back. Therefore, if you are
relying on this ordering, you should make sure that MAX is greater than
one, perhaps as follows:

text
q = READ_ONCE(a);
BUILD_BUG_ON(MAX <= 1); /* Order load from a with store to b. */
if (q % MAX) {
	WRITE_ONCE(b, 1);
	do_something();
} else {
	WRITE_ONCE(b, 2);
	do_something_else();
}

Please note once again that the stores to 'b' differ. If they were
identical, as noted earlier, the compiler could pull this store outside
of the 'if' statement.

You must also be careful not to rely too much on boolean short-circuit
evaluation. Consider this example:

text
q = READ_ONCE(a);
if (q || 1 > 0)
	WRITE_ONCE(b, 1);

Because the first condition cannot fault and the second condition is
always true, the compiler can transform this example as following,
defeating control dependency:

text
q = READ_ONCE(a);
WRITE_ONCE(b, 1);

This example underscores the need to ensure that the compiler cannot
out-guess your code. More generally, although READ_ONCE() does force
the compiler to actually emit code for a given load, it does not force
the compiler to use the results.

In addition, control dependencies apply only to the then-clause and
else-clause of the if-statement in question. In particular, it does
not necessarily apply to code following the if-statement:

text
q = READ_ONCE(a);
if (q) {
	WRITE_ONCE(b, 1);
} else {
	WRITE_ONCE(b, 2);
}
WRITE_ONCE(c, 1);  /* BUG: No ordering against the read from 'a'. */

It is tempting to argue that there in fact is ordering because the
compiler cannot reorder volatile accesses and also cannot reorder
the writes to 'b' with the condition. Unfortunately for this line
of reasoning, the compiler might compile the two writes to 'b' as
conditional-move instructions, as in this fanciful pseudo-assembly
language:

text
ld r1,a
cmp r1,$0
cmov,ne r4,$1
cmov,eq r4,$2
st r4,b
st $1,c

A weakly ordered CPU would have no dependency of any sort between the load
from 'a' and the store to 'c'. The control dependencies would extend
only to the pair of cmov instructions and the store depending on them.
In short, control dependencies apply only to the stores in the then-clause
and else-clause of the if-statement in question (including functions
invoked by those two clauses), not to code following that if-statement.

Note well that the ordering provided by a control dependency is local
to the CPU containing it. See the section on "Multicopy atomicity"
for more information.

In summary:

(*) Control dependencies can order prior loads against later stores.
However, they do -not- guarantee any other sort of ordering:
Not prior loads against later loads, nor prior stores against
later anything. If you need these other forms of ordering,
use smp_rmb(), smp_wmb(), or, in the case of prior stores and
later loads, smp_mb().

(*) If both legs of the "if" statement begin with identical stores to
the same variable, then those stores must be ordered, either by
preceding both of them with smp_mb() or by using smp_store_release()
to carry out the stores. Please note that it is -not- sufficient
to use barrier() at beginning of each leg of the "if" statement
because, as shown by the example above, optimizing compilers can
destroy the control dependency while respecting the letter of the
barrier() law.

(*) Control dependencies require at least one run-time conditional
between the prior load and the subsequent store, and this
conditional must involve the prior load. If the compiler is able
to optimize the conditional away, it will have also optimized
away the ordering. Careful use of READ_ONCE() and WRITE_ONCE()
can help to preserve the needed conditional.

(*) Control dependencies require that the compiler avoid reordering the
dependency into nonexistence. Careful use of READ_ONCE() or
atomic{,64}_read() can help to preserve your control dependency.
Please see the COMPILER BARRIER section for more information.

(*) Control dependencies apply only to the then-clause and else-clause
of the if-statement containing the control dependency, including
any functions that these two clauses call. Control dependencies
do -not- apply to code following the if-statement containing the
control dependency.

(*) Control dependencies pair normally with other types of barriers.

(*) Control dependencies do -not- provide multicopy atomicity. If you
need all the CPUs to see a given store at the same time, use smp_mb().

(*) Compilers do not understand control dependencies. It is therefore
your job to ensure that they do not break your code.

SMP BARRIER PAIRING

When dealing with CPU-CPU interactions, certain types of memory barrier should
always be paired. A lack of appropriate pairing is almost certainly an error.

General barriers pair with each other, though they also pair with most
other types of barriers, albeit without multicopy atomicity. An acquire
barrier pairs with a release barrier, but both may also pair with other
barriers, including of course general barriers. A write barrier pairs
with an address-dependency barrier, a control dependency, an acquire barrier,
a release barrier, a read barrier, or a general barrier. Similarly a
read barrier, control dependency, or an address-dependency barrier pairs
with a write barrier, an acquire barrier, a release barrier, or a
general barrier:

text
CPU 1		      CPU 2
===============	      ===============
WRITE_ONCE(a, 1);
<write barrier>
WRITE_ONCE(b, 2);     x = READ_ONCE(b);
		      <read barrier>
		      y = READ_ONCE(a);

Or:

text
CPU 1		      CPU 2
===============	      ===============================
a = 1;
<write barrier>
WRITE_ONCE(b, &a);    x = READ_ONCE(b);
		      
		      y = *x;

Or even:

text
CPU 1		      CPU 2
===============	      ===============================
r1 = READ_ONCE(y);
<general barrier>
WRITE_ONCE(x, 1);     if (r2 = READ_ONCE(x)) {
		         
		         WRITE_ONCE(y, 1);
		      }

assert(r1 == 0 || r2 == 0);

Basically, the read barrier always has to be there, even though it can be of
the "weaker" type.

[!] Note that the stores before the write barrier would normally be expected to
match the loads after the read barrier or the address-dependency barrier, and
vice versa:

text
CPU 1                               CPU 2
===================                 ===================
WRITE_ONCE(a, 1);    }----   --->{  v = READ_ONCE(c);
WRITE_ONCE(b, 2);    }    \ /    {  w = READ_ONCE(d);
<write barrier>            \        <read barrier>
WRITE_ONCE(c, 3);    }    / \    {  x = READ_ONCE(a);
WRITE_ONCE(d, 4);    }----   --->{  y = READ_ONCE(b);

EXAMPLES OF MEMORY BARRIER SEQUENCES

Firstly, write barriers act as partial orderings on store operations.
Consider the following sequence of events:

text
CPU 1
=======================
STORE A = 1
STORE B = 2
STORE C = 3
<write barrier>
STORE D = 4
STORE E = 5

This sequence of events is committed to the memory coherence system in an order
that the rest of the system might perceive as the unordered set of { STORE A,
STORE B, STORE C } all occurring before the unordered set of { STORE D, STORE E
}:

text
+-------+       :      :
|       |       +------+
|       |------>| C=3  |     }     /\
|       |  :    +------+     }-----  \  -----> Events perceptible to
|       |  :    | A=1  |     }        \/       the rest of the system
|       |  :    +------+     }
| CPU 1 |  :    | B=2  |     }
|       |       +------+     }
|       |   wwwwwwwwwwwwwwww }   <--- At this point the write barrier
|       |       +------+     }        requires all stores prior to the
|       |  :    | E=5  |     }        barrier to be committed before
|       |  :    +------+     }        further stores may take place
|       |------>| D=4  |     }
|       |       +------+
+-------+       :      :
                   |
                   | Sequence in which stores are committed to the
                   | memory system by CPU 1
                   V

Secondly, address-dependency barriers act as partial orderings on address-
dependent loads. Consider the following sequence of events:

text
CPU 1			CPU 2
=======================	=======================
	{ B = 7; X = 9; Y = 8; C = &Y }
STORE A = 1
STORE B = 2
<write barrier>
STORE C = &B		LOAD X
STORE D = 4		LOAD C (gets &B)
			LOAD *C (reads B)

Without intervention, CPU 2 may perceive the events on CPU 1 in some
effectively random order, despite the write barrier issued by CPU 1:

text
+-------+       :      :                :       :
|       |       +------+                +-------+  | Sequence of update
|       |------>| B=2  |-----       --->| Y->8  |  | of perception on
|       |  :    +------+     \          +-------+  | CPU 2
| CPU 1 |  :    | A=1  |      \     --->| C->&Y |  V
|       |       +------+       |        +-------+
|       |   wwwwwwwwwwwwwwww   |        :       :
|       |       +------+       |        :       :
|       |  :    | C=&B |---    |        :       :       +-------+
|       |  :    +------+   \   |        +-------+       |       |
|       |------>| D=4  |    ----------->| C->&B |------>|       |
|       |       +------+       |        +-------+       |       |
+-------+       :      :       |        :       :       |       |
                               |        :       :       |       |
                               |        :       :       | CPU 2 |
                               |        +-------+       |       |
    Apparently incorrect --->  |        | B->7  |------>|       |
    perception of B (!)        |        +-------+       |       |
                               |        :       :       |       |
                               |        +-------+       |       |
    The load of X holds --->    \       | X->9  |------>|       |
    up the maintenance           \      +-------+       |       |
    of coherence of B             ----->| B->2  |       +-------+
                                        +-------+
                                        :       :

In the above example, CPU 2 perceives that B is 7, despite the load of *C
(which would be B) coming after the LOAD of C.

If, however, an address-dependency barrier were to be placed between the load
of C and the load of *C (ie: B) on CPU 2:

text
CPU 1			CPU 2
=======================	=======================
	{ B = 7; X = 9; Y = 8; C = &Y }
STORE A = 1
STORE B = 2
<write barrier>
STORE C = &B		LOAD X
STORE D = 4		LOAD C (gets &B)
			<address-dependency barrier>
			LOAD *C (reads B)

then the following will occur:

text
+-------+       :      :                :       :
|       |       +------+                +-------+
|       |------>| B=2  |-----       --->| Y->8  |
|       |  :    +------+     \          +-------+
| CPU 1 |  :    | A=1  |      \     --->| C->&Y |
|       |       +------+       |        +-------+
|       |   wwwwwwwwwwwwwwww   |        :       :
|       |       +------+       |        :       :
|       |  :    | C=&B |---    |        :       :       +-------+
|       |  :    +------+   \   |        +-------+       |       |
|       |------>| D=4  |    ----------->| C->&B |------>|       |
|       |       +------+       |        +-------+       |       |
+-------+       :      :       |        :       :       |       |
                               |        :       :       |       |
                               |        :       :       | CPU 2 |
                               |        +-------+       |       |
                               |        | X->9  |------>|       |
                               |        +-------+       |       |
  Makes sure all effects --->   \   aaaaaaaaaaaaaaaaa   |       |
  prior to the store of C        \      +-------+       |       |
  are perceptible to              ----->| B->2  |------>|       |
  subsequent loads                      +-------+       |       |
                                        :       :       +-------+

And thirdly, a read barrier acts as a partial order on loads. Consider the
following sequence of events:

text
CPU 1			CPU 2
=======================	=======================
	{ A = 0, B = 9 }
STORE A=1
<write barrier>
STORE B=2
			LOAD B
			LOAD A

Without intervention, CPU 2 may then choose to perceive the events on CPU 1 in
some effectively random order, despite the write barrier issued by CPU 1:

text
+-------+       :      :                :       :
|       |       +------+                +-------+
|       |------>| A=1  |------      --->| A->0  |
|       |       +------+      \         +-------+
| CPU 1 |   wwwwwwwwwwwwwwww   \    --->| B->9  |
|       |       +------+        |       +-------+
|       |------>| B=2  |---     |       :       :
|       |       +------+   \    |       :       :       +-------+
+-------+       :      :    \   |       +-------+       |       |
                             ---------->| B->2  |------>|       |
                                |       +-------+       | CPU 2 |
                                |       | A->0  |------>|       |
                                |       +-------+       |       |
                                |       :       :       +-------+
                                 \      :       :
                                  \     +-------+
                                   ---->| A->1  |
                                        +-------+
                                        :       :

If, however, a read barrier were to be placed between the load of B and the
load of A on CPU 2:

text
CPU 1			CPU 2
=======================	=======================
	{ A = 0, B = 9 }
STORE A=1
<write barrier>
STORE B=2
			LOAD B
			<read barrier>
			LOAD A

then the partial ordering imposed by CPU 1 will be perceived correctly by CPU
2:

text
+-------+       :      :                :       :
|       |       +------+                +-------+
|       |------>| A=1  |------      --->| A->0  |
|       |       +------+      \         +-------+
| CPU 1 |   wwwwwwwwwwwwwwww   \    --->| B->9  |
|       |       +------+        |       +-------+
|       |------>| B=2  |---     |       :       :
|       |       +------+   \    |       :       :       +-------+
+-------+       :      :    \   |       +-------+       |       |
                             ---------->| B->2  |------>|       |
                                |       +-------+       | CPU 2 |
                                |       :       :       |       |
                                |       :       :       |       |
  At this point the read ---->   \  rrrrrrrrrrrrrrrrr   |       |
  barrier causes all effects      \     +-------+       |       |
  prior to the storage of B        ---->| A->1  |------>|       |
  to be perceptible to CPU 2            +-------+       |       |
                                        :       :       +-------+

To illustrate this more completely, consider what could happen if the code
contained a load of A either side of the read barrier:

text
CPU 1			CPU 2
=======================	=======================
	{ A = 0, B = 9 }
STORE A=1
<write barrier>
STORE B=2
			LOAD B
			LOAD A [first load of A]
			<read barrier>
			LOAD A [second load of A]

Even though the two loads of A both occur after the load of B, they may both
come up with different values:

text
+-------+       :      :                :       :
|       |       +------+                +-------+
|       |------>| A=1  |------      --->| A->0  |
|       |       +------+      \         +-------+
| CPU 1 |   wwwwwwwwwwwwwwww   \    --->| B->9  |
|       |       +------+        |       +-------+
|       |------>| B=2  |---     |       :       :
|       |       +------+   \    |       :       :       +-------+
+-------+       :      :    \   |       +-------+       |       |
                             ---------->| B->2  |------>|       |
                                |       +-------+       | CPU 2 |
                                |       :       :       |       |
                                |       :       :       |       |
                                |       +-------+       |       |
                                |       | A->0  |------>| 1st   |
                                |       +-------+       |       |
  At this point the read ---->   \  rrrrrrrrrrrrrrrrr   |       |
  barrier causes all effects      \     +-------+       |       |
  prior to the storage of B        ---->| A->1  |------>| 2nd   |
  to be perceptible to CPU 2            +-------+       |       |
                                        :       :       +-------+

But it may be that the update to A from CPU 1 becomes perceptible to CPU 2
before the read barrier completes anyway:

text
+-------+       :      :                :       :
|       |       +------+                +-------+
|       |------>| A=1  |------      --->| A->0  |
|       |       +------+      \         +-------+
| CPU 1 |   wwwwwwwwwwwwwwww   \    --->| B->9  |
|       |       +------+        |       +-------+
|       |------>| B=2  |---     |       :       :
|       |       +------+   \    |       :       :       +-------+
+-------+       :      :    \   |       +-------+       |       |
                             ---------->| B->2  |------>|       |
                                |       +-------+       | CPU 2 |
                                |       :       :       |       |
                                 \      :       :       |       |
                                  \     +-------+       |       |
                                   ---->| A->1  |------>| 1st   |
                                        +-------+       |       |
                                    rrrrrrrrrrrrrrrrr   |       |
                                        +-------+       |       |
                                        | A->1  |------>| 2nd   |
                                        +-------+       |       |
                                        :       :       +-------+

The guarantee is that the second load will always come up with A == 1 if the
load of B came up with B == 2. No such guarantee exists for the first load of
A; that may come up with either A == 0 or A == 1.

READ MEMORY BARRIERS VS LOAD SPECULATION

Many CPUs speculate with loads: that is they see that they will need to load an
item from memory, and they find a time where they're not using the bus for any
other loads, and so do the load in advance - even though they haven't actually
got to that point in the instruction execution flow yet. This permits the
actual load instruction to potentially complete immediately because the CPU
already has the value to hand.

It may turn out that the CPU didn't actually need the value - perhaps because a
branch circumvented the load - in which case it can discard the value or just
cache it for later use.

Consider:

text
CPU 1			CPU 2
=======================	=======================
			LOAD B
			DIVIDE		} Divide instructions generally
			DIVIDE		} take a long time to perform
			LOAD A

Which might appear as this:

text
:       :       +-------+
                                        +-------+       |       |
                                    --->| B->2  |------>|       |
                                        +-------+       | CPU 2 |
                                        :       :DIVIDE |       |
                                        +-------+       |       |
The CPU being busy doing a --->     --->| A->0  |~~~~   |       |
division speculates on the              +-------+   ~   |       |
LOAD of A                               :       :   ~   |       |
                                        :       :DIVIDE |       |
                                        :       :   ~   |       |
Once the divisions are complete -->     :       :   ~-->|       |
the CPU can then perform the            :       :       |       |
LOAD with immediate effect              :       :       +-------+

Placing a read barrier or an address-dependency barrier just before the second
load:

text
CPU 1			CPU 2
=======================	=======================
			LOAD B
			DIVIDE
			DIVIDE
			<read barrier>
			LOAD A

will force any value speculatively obtained to be reconsidered to an extent
dependent on the type of barrier used. If there was no change made to the
speculated memory location, then the speculated value will just be used:

text
:       :       +-------+
                                        +-------+       |       |
                                    --->| B->2  |------>|       |
                                        +-------+       | CPU 2 |
                                        :       :DIVIDE |       |
                                        +-------+       |       |
The CPU being busy doing a --->     --->| A->0  |~~~~   |       |
division speculates on the              +-------+   ~   |       |
LOAD of A                               :       :   ~   |       |
                                        :       :DIVIDE |       |
                                        :       :   ~   |       |
                                        :       :   ~   |       |
                                    rrrrrrrrrrrrrrrr~   |       |
                                        :       :   ~   |       |
                                        :       :   ~-->|       |
                                        :       :       |       |
                                        :       :       +-------+

but if there was an update or an invalidation from another CPU pending, then
the speculation will be cancelled and the value reloaded:

text
:       :       +-------+
                                        +-------+       |       |
                                    --->| B->2  |------>|       |
                                        +-------+       | CPU 2 |
                                        :       :DIVIDE |       |
                                        +-------+       |       |
The CPU being busy doing a --->     --->| A->0  |~~~~   |       |
division speculates on the              +-------+   ~   |       |
LOAD of A                               :       :   ~   |       |
                                        :       :DIVIDE |       |
                                        :       :   ~   |       |
                                        :       :   ~   |       |
                                    rrrrrrrrrrrrrrrrr   |       |
                                        +-------+       |       |
The speculation is discarded --->   --->| A->1  |------>|       |
and an updated value is                 +-------+       |       |
retrieved                               :       :       +-------+

MULTICOPY ATOMICITY

Multicopy atomicity is a deeply intuitive notion about ordering that is
not always provided by real computer systems, namely that a given store
becomes visible at the same time to all CPUs, or, alternatively, that all
CPUs agree on the order in which all stores become visible. However,
support of full multicopy atomicity would rule out valuable hardware
optimizations, so a weaker form called other multicopy atomicity'' instead guarantees only that a given store becomes visible at the same time to all -other- CPUs. The remainder of this document discusses this weaker form, but for brevity will call it simply multicopy atomicity''.

The following example demonstrates multicopy atomicity:

text
CPU 1			CPU 2			CPU 3
=======================	=======================	=======================
	{ X = 0, Y = 0 }
STORE X=1		r1=LOAD X (reads 1)	LOAD Y (reads 1)
			<general barrier>	<read barrier>
			STORE Y=r1		LOAD X

Suppose that CPU 2's load from X returns 1, which it then stores to Y,
and CPU 3's load from Y returns 1. This indicates that CPU 1's store
to X precedes CPU 2's load from X and that CPU 2's store to Y precedes
CPU 3's load from Y. In addition, the memory barriers guarantee that
CPU 2 executes its load before its store, and CPU 3 loads from Y before
it loads from X. The question is then "Can CPU 3's load from X return 0?"

Because CPU 3's load from X in some sense comes after CPU 2's load, it
is natural to expect that CPU 3's load from X must therefore return 1.
This expectation follows from multicopy atomicity: if a load executing
on CPU B follows a load from the same variable executing on CPU A (and
CPU A did not originally store the value which it read), then on
multicopy-atomic systems, CPU B's load must return either the same value
that CPU A's load did or some later value. However, the Linux kernel
does not require systems to be multicopy atomic.

The use of a general memory barrier in the example above compensates
for any lack of multicopy atomicity. In the example, if CPU 2's load
from X returns 1 and CPU 3's load from Y returns 1, then CPU 3's load
from X must indeed also return 1.

However, dependencies, read barriers, and write barriers are not always
able to compensate for non-multicopy atomicity. For example, suppose
that CPU 2's general barrier is removed from the above example, leaving
only the data dependency shown below:

text
CPU 1			CPU 2			CPU 3
=======================	=======================	=======================
	{ X = 0, Y = 0 }
STORE X=1		r1=LOAD X (reads 1)	LOAD Y (reads 1)
			<data dependency>	<read barrier>
			STORE Y=r1		LOAD X (reads 0)

This substitution allows non-multicopy atomicity to run rampant: in
this example, it is perfectly legal for CPU 2's load from X to return 1,
CPU 3's load from Y to return 1, and its load from X to return 0.

The key point is that although CPU 2's data dependency orders its load
and store, it does not guarantee to order CPU 1's store. Thus, if this
example runs on a non-multicopy-atomic system where CPUs 1 and 2 share a
store buffer or a level of cache, CPU 2 might have early access to CPU 1's
writes. General barriers are therefore required to ensure that all CPUs
agree on the combined order of multiple accesses.

General barriers can compensate not only for non-multicopy atomicity,
but can also generate additional ordering that can ensure that -all-
CPUs will perceive the same order of -all- operations. In contrast, a
chain of release-acquire pairs do not provide this additional ordering,
which means that only those CPUs on the chain are guaranteed to agree
on the combined order of the accesses. For example, switching to C code
in deference to the ghost of Herman Hollerith:

text
int u, v, x, y, z;

void cpu0(void)
{
	r0 = smp_load_acquire(&x);
	WRITE_ONCE(u, 1);
	smp_store_release(&y, 1);
}

void cpu1(void)
{
	r1 = smp_load_acquire(&y);
	r4 = READ_ONCE(v);
	r5 = READ_ONCE(u);
	smp_store_release(&z, 1);
}

void cpu2(void)
{
	r2 = smp_load_acquire(&z);
	smp_store_release(&x, 1);
}

void cpu3(void)
{
	WRITE_ONCE(v, 1);
	smp_mb();
	r3 = READ_ONCE(u);
}

Because cpu0(), cpu1(), and cpu2() participate in a chain of
smp_store_release()/smp_load_acquire() pairs, the following outcome
is prohibited:

text
r0 == 1 && r1 == 1 && r2 == 1

Furthermore, because of the release-acquire relationship between cpu0()
and cpu1(), cpu1() must see cpu0()'s writes, so that the following
outcome is prohibited:

text
r1 == 1 && r5 == 0

However, the ordering provided by a release-acquire chain is local
to the CPUs participating in that chain and does not apply to cpu3(),
at least aside from stores. Therefore, the following outcome is possible:

text
r0 == 0 && r1 == 1 && r2 == 1 && r3 == 0 && r4 == 0

As an aside, the following outcome is also possible:

text
r0 == 0 && r1 == 1 && r2 == 1 && r3 == 0 && r4 == 0 && r5 == 1

Although cpu0(), cpu1(), and cpu2() will see their respective reads and
writes in order, CPUs not involved in the release-acquire chain might
well disagree on the order. This disagreement stems from the fact that
the weak memory-barrier instructions used to implement smp_load_acquire()
and smp_store_release() are not required to order prior stores against
subsequent loads in all cases. This means that cpu3() can see cpu0()'s
store to u as happening -after- cpu1()'s load from v, even though
both cpu0() and cpu1() agree that these two operations occurred in the
intended order.

However, please keep in mind that smp_load_acquire() is not magic.
In particular, it simply reads from its argument with ordering. It does
-not- ensure that any particular value will be read. Therefore, the
following outcome is possible:

text
r0 == 0 && r1 == 0 && r2 == 0 && r5 == 0

Note that this outcome can happen even on a mythical sequentially
consistent system where nothing is ever reordered.

To reiterate, if your code requires full ordering of all operations,
use general barriers throughout.

======================== EXPLICIT KERNEL BARRIERS

The Linux kernel has a variety of different barriers that act at different
levels:

(*) Compiler barrier.

(*) CPU memory barriers.

COMPILER BARRIER

The Linux kernel has an explicit compiler barrier function that prevents the
compiler from moving the memory accesses either side of it to the other side:

text
barrier();

This is a general barrier -- there are no read-read or write-write
variants of barrier(). However, READ_ONCE() and WRITE_ONCE() can be
thought of as weak forms of barrier() that affect only the specific
accesses flagged by the READ_ONCE() or WRITE_ONCE().

The barrier() function has the following effects:

(*) Prevents the compiler from reordering accesses following the
barrier() to precede any accesses preceding the barrier().
One example use for this property is to ease communication between
interrupt-handler code and the code that was interrupted.

(*) Within a loop, forces the compiler to load the variables used
in that loop's conditional on each pass through that loop.

The READ_ONCE() and WRITE_ONCE() functions can prevent any number of
optimizations that, while perfectly safe in single-threaded code, can
be fatal in concurrent code. Here are some examples of these sorts
of optimizations:

(*) The compiler is within its rights to reorder loads and stores
to the same variable, and in some cases, the CPU is within its
rights to reorder loads to the same variable. This means that
the following code:

text
a[0] = x;
a[1] = x;

 Might result in an older value of x stored in a[1] than in a[0].
 Prevent both the compiler and the CPU from doing this as follows:

a[0] = READ_ONCE(x);
a[1] = READ_ONCE(x);

 In short, READ_ONCE() and WRITE_ONCE() provide cache coherence for
 accesses from multiple CPUs to a single variable.

(*) The compiler is within its rights to merge successive loads from
the same variable. Such merging can cause the compiler to "optimize"
the following code:

text
while (tmp = a)
	do_something_with(tmp);

 into the following code, which, although in some sense legitimate
 for single-threaded code, is almost certainly not what the developer
 intended:

if (tmp = a)
	for (;;)
		do_something_with(tmp);

 Use READ_ONCE() to prevent the compiler from doing this to you:

while (tmp = READ_ONCE(a))
	do_something_with(tmp);

(*) The compiler is within its rights to reload a variable, for example,
in cases where high register pressure prevents the compiler from
keeping all data of interest in registers. The compiler might
therefore optimize the variable 'tmp' out of our previous example:

text
while (tmp = a)
	do_something_with(tmp);

 This could result in the following code, which is perfectly safe in
 single-threaded code, but can be fatal in concurrent code:

while (a)
	do_something_with(a);

 For example, the optimized version of this code could result in
 passing a zero to do_something_with() in the case where the variable
 a was modified by some other CPU between the "while" statement and
 the call to do_something_with().

 Again, use READ_ONCE() to prevent the compiler from doing this:

while (tmp = READ_ONCE(a))
	do_something_with(tmp);

 Note that if the compiler runs short of registers, it might save
 tmp onto the stack.  The overhead of this saving and later restoring
 is why compilers reload variables.  Doing so is perfectly safe for
 single-threaded code, so you need to tell the compiler about cases
 where it is not safe.

(*) The compiler is within its rights to omit a load entirely if it knows
what the value will be. For example, if the compiler can prove that
the value of variable 'a' is always zero, it can optimize this code:

text
while (tmp = a)
	do_something_with(tmp);

 Into this:

do { } while (0);

 This transformation is a win for single-threaded code because it
 gets rid of a load and a branch.  The problem is that the compiler
 will carry out its proof assuming that the current CPU is the only
 one updating variable 'a'.  If variable 'a' is shared, then the
 compiler's proof will be erroneous.  Use READ_ONCE() to tell the
 compiler that it doesn't know as much as it thinks it does:

while (tmp = READ_ONCE(a))
	do_something_with(tmp);

 But please note that the compiler is also closely watching what you
 do with the value after the READ_ONCE().  For example, suppose you
 do the following and MAX is a preprocessor macro with the value 1:

while ((tmp = READ_ONCE(a)) % MAX)
	do_something_with(tmp);

 Then the compiler knows that the result of the "%" operator applied
 to MAX will always be zero, again allowing the compiler to optimize
 the code into near-nonexistence.  (It will still load from the
 variable 'a'.)

(*) Similarly, the compiler is within its rights to omit a store entirely
if it knows that the variable already has the value being stored.
Again, the compiler assumes that the current CPU is the only one
storing into the variable, which can cause the compiler to do the
wrong thing for shared variables. For example, suppose you have
the following:

text
a = 0;
... Code that does not store to variable a ...
a = 0;

 The compiler sees that the value of variable 'a' is already zero, so
 it might well omit the second store.  This would come as a fatal
 surprise if some other CPU might have stored to variable 'a' in the
 meantime.

 Use WRITE_ONCE() to prevent the compiler from making this sort of
 wrong guess:

WRITE_ONCE(a, 0);
... Code that does not store to variable a ...
WRITE_ONCE(a, 0);

(*) The compiler is within its rights to reorder memory accesses unless
you tell it not to. For example, consider the following interaction
between process-level code and an interrupt handler:

text
void process_level(void)
{
	msg = get_message();
	flag = true;
}

void interrupt_handler(void)
{
	if (flag)
		process_message(msg);
}

 There is nothing to prevent the compiler from transforming
 process_level() to the following, in fact, this might well be a
 win for single-threaded code:

void process_level(void)
{
	flag = true;
	msg = get_message();
}

 If the interrupt occurs between these two statement, then
 interrupt_handler() might be passed a garbled msg.  Use WRITE_ONCE()
 to prevent this as follows:

void process_level(void)
{
	WRITE_ONCE(msg, get_message());
	WRITE_ONCE(flag, true);
}

void interrupt_handler(void)
{
	if (READ_ONCE(flag))
		process_message(READ_ONCE(msg));
}

 Note that the READ_ONCE() and WRITE_ONCE() wrappers in
 interrupt_handler() are needed if this interrupt handler can itself
 be interrupted by something that also accesses 'flag' and 'msg',
 for example, a nested interrupt or an NMI.  Otherwise, READ_ONCE()
 and WRITE_ONCE() are not needed in interrupt_handler() other than
 for documentation purposes.  (Note also that nested interrupts
 do not typically occur in modern Linux kernels, in fact, if an
 interrupt handler returns with interrupts enabled, you will get a
 WARN_ONCE() splat.)

 You should assume that the compiler can move READ_ONCE() and
 WRITE_ONCE() past code not containing READ_ONCE(), WRITE_ONCE(),
 barrier(), or similar primitives.

 This effect could also be achieved using barrier(), but READ_ONCE()
 and WRITE_ONCE() are more selective:  With READ_ONCE() and
 WRITE_ONCE(), the compiler need only forget the contents of the
 indicated memory locations, while with barrier() the compiler must
 discard the value of all memory locations that it has currently
 cached in any machine registers.  Of course, the compiler must also
 respect the order in which the READ_ONCE()s and WRITE_ONCE()s occur,
 though the CPU of course need not do so.

(*) The compiler is within its rights to invent stores to a variable,
as in the following example:

text
if (a)
	b = a;
else
	b = 42;

 The compiler might save a branch by optimizing this as follows:

b = 42;
if (a)
	b = a;

 In single-threaded code, this is not only safe, but also saves
 a branch.  Unfortunately, in concurrent code, this optimization
 could cause some other CPU to see a spurious value of 42 -- even
 if variable 'a' was never zero -- when loading variable 'b'.
 Use WRITE_ONCE() to prevent this as follows:

if (a)
	WRITE_ONCE(b, a);
else
	WRITE_ONCE(b, 42);

 The compiler can also invent loads.  These are usually less
 damaging, but they can result in cache-line bouncing and thus in
 poor performance and scalability.  Use READ_ONCE() to prevent
 invented loads.

(*) For aligned memory locations whose size allows them to be accessed
with a single memory-reference instruction, prevents "load tearing"
and "store tearing," in which a single large access is replaced by
multiple smaller accesses. For example, given an architecture having
16-bit store instructions with 7-bit immediate fields, the compiler
might be tempted to use two 16-bit store-immediate instructions to
implement the following 32-bit store:

text
p = 0x00010002;

 Please note that GCC really does use this sort of optimization,
 which is not surprising given that it would likely take more
 than two instructions to build the constant and then store it.
 This optimization can therefore be a win in single-threaded code.
 In fact, a recent bug (since fixed) caused GCC to incorrectly use
 this optimization in a volatile store.  In the absence of such bugs,
 use of WRITE_ONCE() prevents store tearing in the following example:

WRITE_ONCE(p, 0x00010002);

 Use of packed structures can also result in load and store tearing,
 as in this example:

struct __attribute__((__packed__)) foo {
	short a;
	int b;
	short c;
};
struct foo foo1, foo2;
...

foo2.a = foo1.a;
foo2.b = foo1.b;
foo2.c = foo1.c;

 Because there are no READ_ONCE() or WRITE_ONCE() wrappers and no
 volatile markings, the compiler would be well within its rights to
 implement these three assignment statements as a pair of 32-bit
 loads followed by a pair of 32-bit stores.  This would result in
 load tearing on 'foo1.b' and store tearing on 'foo2.b'.  READ_ONCE()
 and WRITE_ONCE() again prevent tearing in this example:

foo2.a = foo1.a;
WRITE_ONCE(foo2.b, READ_ONCE(foo1.b));
foo2.c = foo1.c;

All that aside, it is never necessary to use READ_ONCE() and
WRITE_ONCE() on a variable that has been marked volatile. For example,
because 'jiffies' is marked volatile, it is never necessary to
say READ_ONCE(jiffies). The reason for this is that READ_ONCE() and
WRITE_ONCE() are implemented as volatile casts, which has no effect when
its argument is already marked volatile.

Please note that these compiler barriers have no direct effect on the CPU,
which may then reorder things however it wishes.

CPU MEMORY BARRIERS

The Linux kernel has seven basic CPU memory barriers:

text
TYPE			MANDATORY	SMP CONDITIONAL
=======================	===============	===============
GENERAL			mb()		smp_mb()
WRITE			wmb()		smp_wmb()
READ			rmb()		smp_rmb()
ADDRESS DEPENDENCY			READ_ONCE()

All memory barriers except the address-dependency barriers imply a compiler
barrier. Address dependencies do not impose any additional compiler ordering.

Aside: In the case of address dependencies, the compiler would be expected
to issue the loads in the correct order (eg. a[b] would have to load
the value of b before loading a[b]), however there is no guarantee in
the C specification that the compiler may not speculate the value of b
(eg. is equal to 1) and load a[b] before b (eg. tmp = a[1]; if (b != 1)
tmp = a[b]; ). There is also the problem of a compiler reloading b after
having loaded a[b], thus having a newer copy of b than a[b]. A consensus
has not yet been reached about these problems, however the READ_ONCE()
macro is a good place to start looking.

SMP memory barriers are reduced to compiler barriers on uniprocessor compiled
systems because it is assumed that a CPU will appear to be self-consistent,
and will order overlapping accesses correctly with respect to itself.
However, see the subsection on "Virtual Machine Guests" below.

[!] Note that SMP memory barriers must be used to control the ordering of
references to shared memory on SMP systems, though the use of locking instead
is sufficient.

Mandatory barriers should not be used to control SMP effects, since mandatory
barriers impose unnecessary overhead on both SMP and UP systems. They may,
however, be used to control MMIO effects on accesses through relaxed memory I/O
windows. These barriers are required even on non-SMP systems as they affect
the order in which memory operations appear to a device by prohibiting both the
compiler and the CPU from reordering them.

There are some more advanced barrier functions:

(*) smp_store_mb(var, value)

text
This assigns the value to the variable and then inserts a full memory
 barrier after it.  It isn't guaranteed to insert anything more than a
 compiler barrier in a UP compilation.

() smp_mb__before_atomic();
(
) smp_mb__after_atomic();

text
These are for use with atomic RMW functions that do not imply memory
 barriers, but where the code needs a memory barrier. Examples for atomic
 RMW functions that do not imply a memory barrier are e.g. add,
 subtract, (failed) conditional operations, _relaxed functions,
 but not atomic_read or atomic_set. A common example where a memory
 barrier may be required is when atomic ops are used for reference
 counting.

 These are also used for atomic RMW bitop functions that do not imply a
 memory barrier (such as set_bit and clear_bit).

 As an example, consider a piece of code that marks an object as being dead
 and then decrements the object's reference count:

obj->dead = 1;
smp_mb__before_atomic();
atomic_dec(&obj->ref_count);

 This makes sure that the death mark on the object is perceived to be set
 *before* the reference counter is decremented.

 See Documentation/atomic_{t,bitops}.txt for more information.

() dma_wmb();
(
) dma_rmb();
(*) dma_mb();

text
These are for use with consistent memory to guarantee the ordering
 of writes or reads of shared memory accessible to both the CPU and a
 DMA capable device. See Documentation/core-api/dma-api.rst file for more
 information about consistent memory.

 For example, consider a device driver that shares memory with a device
 and uses a descriptor status value to indicate if the descriptor belongs
 to the device or the CPU, and a doorbell to notify it when new
 descriptors are available:

if (desc->status != DEVICE_OWN) {
	/* do not read data until we own descriptor */
	dma_rmb();

	/* read/modify data */
	read_data = desc->data;
	desc->data = write_data;

	/* flush modifications before status update */
	dma_wmb();

	/* assign ownership */
	desc->status = DEVICE_OWN;

	/* Make descriptor status visible to the device followed by
	 * notify device of new descriptor
	 */
	writel(DESC_NOTIFY, doorbell);
}

 The dma_rmb() allows us to guarantee that the device has released ownership
 before we read the data from the descriptor, and the dma_wmb() allows
 us to guarantee the data is written to the descriptor before the device
 can see it now has ownership.  The dma_mb() implies both a dma_rmb() and
 a dma_wmb().

 Note that the dma_*() barriers do not provide any ordering guarantees for
 accesses to MMIO regions.  See the later "KERNEL I/O BARRIER EFFECTS"
 subsection for more information about I/O accessors and MMIO ordering.

(*) pmem_wmb();

text
This is for use with persistent memory to ensure that stores for which
 modifications are written to persistent storage reached a platform
 durability domain.

 For example, after a non-temporal write to pmem region, we use pmem_wmb()
 to ensure that stores have reached a platform durability domain. This ensures
 that stores have updated persistent storage before any data access or
 data transfer caused by subsequent instructions is initiated. This is
 in addition to the ordering done by wmb().

 For load from persistent memory, existing read memory barriers are sufficient
 to ensure read ordering.

(*) io_stop_wc();

text
For memory accesses with write-combining attributes (e.g. those returned
 by ioremap_wc()), the CPU may wait for prior accesses to be merged with
 subsequent ones. io_stop_wc() can be used to prevent the merging of
 write-combining memory accesses before this macro with those after it when
 such wait has performance implications.

=============================== IMPLICIT KERNEL MEMORY BARRIERS

Some of the other functions in the linux kernel imply memory barriers, amongst
which are locking and scheduling functions.

This specification is a minimum guarantee; any particular architecture may
provide more substantial guarantees, but these may not be relied upon outside
of arch specific code.

LOCK ACQUISITION FUNCTIONS

The Linux kernel has a number of locking constructs:

() spin locks
(
) R/W spin locks
() mutexes
(
) semaphores
(*) R/W semaphores

In all cases there are variants on "ACQUIRE" operations and "RELEASE" operations
for each construct. These operations all imply certain barriers:

(1) ACQUIRE operation implication:

text
Memory operations issued after the ACQUIRE will be completed after the
 ACQUIRE operation has completed.

 Memory operations issued before the ACQUIRE may be completed after
 the ACQUIRE operation has completed.

(2) RELEASE operation implication:

text
Memory operations issued before the RELEASE will be completed before the
 RELEASE operation has completed.

 Memory operations issued after the RELEASE may be completed before the
 RELEASE operation has completed.

(3) ACQUIRE vs ACQUIRE implication:

text
All ACQUIRE operations issued before another ACQUIRE operation will be
 completed before that ACQUIRE operation.

(4) ACQUIRE vs RELEASE implication:

text
All ACQUIRE operations issued before a RELEASE operation will be
 completed before the RELEASE operation.

(5) Failed conditional ACQUIRE implication:

text
Certain locking variants of the ACQUIRE operation may fail, either due to
 being unable to get the lock immediately, or due to receiving an unblocked
 signal while asleep waiting for the lock to become available.  Failed
 locks do not imply any sort of barrier.

[!] Note: one of the consequences of lock ACQUIREs and RELEASEs being only
one-way barriers is that the effects of instructions outside of a critical
section may seep into the inside of the critical section.

An ACQUIRE followed by a RELEASE may not be assumed to be full memory barrier
because it is possible for an access preceding the ACQUIRE to happen after the
ACQUIRE, and an access following the RELEASE to happen before the RELEASE, and
the two accesses can themselves then cross:

text
*A = a;
ACQUIRE M
RELEASE M
*B = b;

may occur as:

text
ACQUIRE M, STORE *B, STORE *A, RELEASE M

When the ACQUIRE and RELEASE are a lock acquisition and release,
respectively, this same reordering can occur if the lock's ACQUIRE and
RELEASE are to the same lock variable, but only from the perspective of
another CPU not holding that lock. In short, a ACQUIRE followed by an
RELEASE may -not- be assumed to be a full memory barrier.

Similarly, the reverse case of a RELEASE followed by an ACQUIRE does
not imply a full memory barrier. Therefore, the CPU's execution of the
critical sections corresponding to the RELEASE and the ACQUIRE can cross,
so that:

text
*A = a;
RELEASE M
ACQUIRE N
*B = b;

could occur as:

text
ACQUIRE N, STORE *B, STORE *A, RELEASE M

It might appear that this reordering could introduce a deadlock.
However, this cannot happen because if such a deadlock threatened,
the RELEASE would simply complete, thereby avoiding the deadlock.

text
Why does this work?

One key point is that we are only talking about the CPU doing
the reordering, not the compiler.  If the compiler (or, for
that matter, the developer) switched the operations, deadlock
-could- occur.

But suppose the CPU reordered the operations.  In this case,
the unlock precedes the lock in the assembly code.  The CPU
simply elected to try executing the later lock operation first.
If there is a deadlock, this lock operation will simply spin (or
try to sleep, but more on that later).	The CPU will eventually
execute the unlock operation (which preceded the lock operation
in the assembly code), which will unravel the potential deadlock,
allowing the lock operation to succeed.

But what if the lock is a sleeplock?  In that case, the code will
try to enter the scheduler, where it will eventually encounter
a memory barrier, which will force the earlier unlock operation
to complete, again unraveling the deadlock.  There might be
a sleep-unlock race, but the locking primitive needs to resolve
such races properly in any case.

Locks and semaphores may not provide any guarantee of ordering on UP compiled
systems, and so cannot be counted on in such a situation to actually achieve
anything at all - especially with respect to I/O accesses - unless combined
with interrupt disabling operations.

See also the section on "Inter-CPU acquiring barrier effects".

As an example, consider the following:

text
*A = a;
*B = b;
ACQUIRE
*C = c;
*D = d;
RELEASE
*E = e;
*F = f;

The following sequence of events is acceptable:

text
ACQUIRE, {*F,*A}, *E, {*C,*D}, *B, RELEASE

[+] Note that {*F,*A} indicates a combined access.

But none of the following are:

text
{*F,*A}, *B,	ACQUIRE, *C, *D,	RELEASE, *E
*A, *B, *C,	ACQUIRE, *D,		RELEASE, *E, *F
*A, *B,		ACQUIRE, *C,		RELEASE, *D, *E, *F
*B,		ACQUIRE, *C, *D,	RELEASE, {*F,*A}, *E

INTERRUPT DISABLING FUNCTIONS

Functions that disable interrupts (ACQUIRE equivalent) and enable interrupts
(RELEASE equivalent) will act as compiler barriers only. So if memory or I/O
barriers are required in such a situation, they must be provided from some
other means.

SLEEP AND WAKE-UP FUNCTIONS

Sleeping and waking on an event flagged in global data can be viewed as an
interaction between two pieces of data: the task state of the task waiting for
the event and the global data used to indicate the event. To make sure that
these appear to happen in the right order, the primitives to begin the process
of going to sleep, and the primitives to initiate a wake up imply certain
barriers.

Firstly, the sleeper normally follows something like this sequence of events:

text
for (;;) {
	set_current_state(TASK_UNINTERRUPTIBLE);
	if (event_indicated)
		break;
	schedule();
}

A general memory barrier is interpolated automatically by set_current_state()
after it has altered the task state:

text
CPU 1
===============================
set_current_state();
  smp_store_mb();
    STORE current->state
    <general barrier>
LOAD event_indicated

set_current_state() may be wrapped by:

text
prepare_to_wait();
prepare_to_wait_exclusive();

which therefore also imply a general memory barrier after setting the state.
The whole sequence above is available in various canned forms, all of which
interpolate the memory barrier in the right place, for example:

text
wait_event();
wait_event_cmd();
wait_event_exclusive_cmd();
wait_event_interruptible();
wait_event_interruptible_exclusive();
wait_event_interruptible_timeout();
wait_event_killable();
wait_event_timeout();
wait_on_bit();
wait_on_bit_lock();

Secondly, code that performs a wake up normally follows something like this:

text
event_indicated = 1;
wake_up(&event_wait_queue);

or:

text
event_indicated = 1;
wake_up_process(event_daemon);

A general memory barrier is executed by wake_up() if it wakes something up.
If it doesn't wake anything up then a memory barrier may or may not be
executed; you must not rely on it. The barrier occurs before the task state
is accessed, in particular, it sits between the STORE to indicate the event
and the STORE to set TASK_RUNNING:

text
CPU 1 (Sleeper)			CPU 2 (Waker)
===============================	===============================
set_current_state();		STORE event_indicated
  smp_store_mb();		wake_up();
    STORE current->state	  ...
    <general barrier>		  <general barrier>
LOAD event_indicated		  if ((LOAD task->state) & TASK_NORMAL)
				    STORE task->state

where "task" is the thread being woken up and it equals CPU 1's "current".

To repeat, a general memory barrier is guaranteed to be executed by wake_up()
if something is actually awakened, but otherwise there is no such guarantee.
To see this, consider the following sequence of events, where X and Y are both
initially zero:

text
CPU 1				CPU 2
===============================	===============================
X = 1;				Y = 1;
smp_mb();			wake_up();
LOAD Y				LOAD X

If a wakeup does occur, one (at least) of the two loads must see 1. If, on
the other hand, a wakeup does not occur, both loads might see 0.

wake_up_process() always executes a general memory barrier. The barrier again
occurs before the task state is accessed. In particular, if the wake_up() in
the previous snippet were replaced by a call to wake_up_process() then one of
the two loads would be guaranteed to see 1.

The available waker functions include:

text
complete();
wake_up();
wake_up_all();
wake_up_bit();
wake_up_interruptible();
wake_up_interruptible_all();
wake_up_interruptible_nr();
wake_up_interruptible_poll();
wake_up_interruptible_sync();
wake_up_interruptible_sync_poll();
wake_up_locked();
wake_up_locked_poll();
wake_up_nr();
wake_up_poll();
wake_up_process();

In terms of memory ordering, these functions all provide the same guarantees of
a wake_up() (or stronger).

[!] Note that the memory barriers implied by the sleeper and the waker do not
order multiple stores before the wake-up with respect to loads of those stored
values after the sleeper has called set_current_state(). For instance, if the
sleeper does:

text
set_current_state(TASK_INTERRUPTIBLE);
if (event_indicated)
	break;
__set_current_state(TASK_RUNNING);
do_something(my_data);

and the waker does:

text
my_data = value;
event_indicated = 1;
wake_up(&event_wait_queue);

there's no guarantee that the change to event_indicated will be perceived by
the sleeper as coming after the change to my_data. In such a circumstance, the
code on both sides must interpolate its own memory barriers between the
separate data accesses. Thus the above sleeper ought to do:

text
set_current_state(TASK_INTERRUPTIBLE);
if (event_indicated) {
	smp_rmb();
	do_something(my_data);
}

and the waker should do:

text
my_data = value;
smp_wmb();
event_indicated = 1;
wake_up(&event_wait_queue);

MISCELLANEOUS FUNCTIONS

Other functions that imply barriers:

(*) schedule() and similar imply full memory barriers.

=================================== INTER-CPU ACQUIRING BARRIER EFFECTS

On SMP systems locking primitives give a more substantial form of barrier: one
that does affect memory access ordering on other CPUs, within the context of
conflict on any particular lock.

ACQUIRES VS MEMORY ACCESSES

Consider the following: the system has a pair of spinlocks (M) and (Q), and
three CPUs; then should the following sequence of events occur:

text
CPU 1				CPU 2
===============================	===============================
WRITE_ONCE(*A, a);		WRITE_ONCE(*E, e);
ACQUIRE M			ACQUIRE Q
WRITE_ONCE(*B, b);		WRITE_ONCE(*F, f);
WRITE_ONCE(*C, c);		WRITE_ONCE(*G, g);
RELEASE M			RELEASE Q
WRITE_ONCE(*D, d);		WRITE_ONCE(*H, h);

Then there is no guarantee as to what order CPU 3 will see the accesses to *A
through *H occur in, other than the constraints imposed by the separate locks
on the separate CPUs. It might, for example, see:

text
*E, ACQUIRE M, ACQUIRE Q, *G, *C, *F, *A, *B, RELEASE Q, *D, *H, RELEASE M

But it won't see any of:

text
*B, *C or *D preceding ACQUIRE M
*A, *B or *C following RELEASE M
*F, *G or *H preceding ACQUIRE Q
*E, *F or *G following RELEASE Q

================================= WHERE ARE MEMORY BARRIERS NEEDED?

Under normal operation, memory operation reordering is generally not going to
be a problem as a single-threaded linear piece of code will still appear to
work correctly, even if it's in an SMP kernel. There are, however, four
circumstances in which reordering definitely could be a problem:

(*) Interprocessor interaction.

(*) Atomic operations.

(*) Accessing devices.

(*) Interrupts.

INTERPROCESSOR INTERACTION

When there's a system with more than one processor, more than one CPU in the
system may be working on the same data set at the same time. This can cause
synchronisation problems, and the usual way of dealing with them is to use
locks. Locks, however, are quite expensive, and so it may be preferable to
operate without the use of a lock if at all possible. In such a case
operations that affect both CPUs may have to be carefully ordered to prevent
a malfunction.

Consider, for example, the R/W semaphore slow path. Here a waiting process is
queued on the semaphore, by virtue of it having a piece of its stack linked to
the semaphore's list of waiting processes:

text
struct rw_semaphore {
	...
	spinlock_t lock;
	struct list_head waiters;
};

struct rwsem_waiter {
	struct list_head list;
	struct task_struct *task;
};

To wake up a particular waiter, the up_read() or up_write() functions have to:

(1) read the next pointer from this waiter's record to know as to where the
next waiter record is;

(2) read the pointer to the waiter's task structure;

(3) clear the task pointer to tell the waiter it has been given the semaphore;

(4) call wake_up_process() on the task; and

(5) release the reference held on the waiter's task struct.

In other words, it has to perform this sequence of events:

text
LOAD waiter->list.next;
LOAD waiter->task;
STORE waiter->task;
CALL wakeup
RELEASE task

and if any of these steps occur out of order, then the whole thing may
malfunction.

Once it has queued itself and dropped the semaphore lock, the waiter does not
get the lock again; it instead just waits for its task pointer to be cleared
before proceeding. Since the record is on the waiter's stack, this means that
if the task pointer is cleared before the next pointer in the list is read,
another CPU might start processing the waiter and might clobber the waiter's
stack before the up*() function has a chance to read the next pointer.

Consider then what might happen to the above sequence of events:

text
CPU 1				CPU 2
===============================	===============================
				down_xxx()
				Queue waiter
				Sleep
up_yyy()
LOAD waiter->task;
STORE waiter->task;
				Woken up by other event
<preempt>
				Resume processing
				down_xxx() returns
				call foo()
				foo() clobbers *waiter
</preempt>
LOAD waiter->list.next;
--- OOPS ---

This could be dealt with using the semaphore lock, but then the down_xxx()
function has to needlessly get the spinlock again after being woken up.

The way to deal with this is to insert a general SMP memory barrier:

text
LOAD waiter->list.next;
LOAD waiter->task;
smp_mb();
STORE waiter->task;
CALL wakeup
RELEASE task

In this case, the barrier makes a guarantee that all memory accesses before the
barrier will appear to happen before all the memory accesses after the barrier
with respect to the other CPUs on the system. It does not guarantee that all
the memory accesses before the barrier will be complete by the time the barrier
instruction itself is complete.

On a UP system - where this wouldn't be a problem - the smp_mb() is just a
compiler barrier, thus making sure the compiler emits the instructions in the
right order without actually intervening in the CPU. Since there's only one
CPU, that CPU's dependency ordering logic will take care of everything else.

ATOMIC OPERATIONS

While they are technically interprocessor interaction considerations, atomic
operations are noted specially as some of them imply full memory barriers and
some don't, but they're very heavily relied on as a group throughout the
kernel.

See Documentation/atomic_t.txt for more information.

ACCESSING DEVICES

Many devices can be memory mapped, and so appear to the CPU as if they're just
a set of memory locations. To control such a device, the driver usually has to
make the right memory accesses in exactly the right order.

However, having a clever CPU or a clever compiler creates a potential problem
in that the carefully sequenced accesses in the driver code won't reach the
device in the requisite order if the CPU or the compiler thinks it is more
efficient to reorder, combine or merge accesses - something that would cause
the device to malfunction.

Inside of the Linux kernel, I/O should be done through the appropriate accessor
routines - such as inb() or writel() - which know how to make such accesses
appropriately sequential. While this, for the most part, renders the explicit
use of memory barriers unnecessary, if the accessor functions are used to refer
to an I/O memory window with relaxed memory access properties, then mandatory
memory barriers are required to enforce ordering.

See Documentation/driver-api/device-io.rst for more information.

INTERRUPTS

A driver may be interrupted by its own interrupt service routine, and thus the
two parts of the driver may interfere with each other's attempts to control or
access the device.

This may be alleviated - at least in part - by disabling local interrupts (a
form of locking), such that the critical operations are all contained within
the interrupt-disabled section in the driver. While the driver's interrupt
routine is executing, the driver's core may not run on the same CPU, and its
interrupt is not permitted to happen again until the current interrupt has been
handled, thus the interrupt handler does not need to lock against that.

However, consider a driver that was talking to an ethernet card that sports an
address register and a data register. If that driver's core talks to the card
under interrupt-disablement and then the driver's interrupt handler is invoked:

text
LOCAL IRQ DISABLE
writew(ADDR, 3);
writew(DATA, y);
LOCAL IRQ ENABLE
<interrupt>
writew(ADDR, 4);
q = readw(DATA);
</interrupt>

The store to the data register might happen after the second store to the
address register if ordering rules are sufficiently relaxed:

text
STORE *ADDR = 3, STORE *ADDR = 4, STORE *DATA = y, q = LOAD *DATA

If ordering rules are relaxed, it must be assumed that accesses done inside an
interrupt disabled section may leak outside of it and may interleave with
accesses performed in an interrupt - and vice versa - unless implicit or
explicit barriers are used.

Normally this won't be a problem because the I/O accesses done inside such
sections will include synchronous load operations on strictly ordered I/O
registers that form implicit I/O barriers.

A similar situation may occur between an interrupt routine and two routines
running on separate CPUs that communicate with each other. If such a case is
likely, then interrupt-disabling locks should be used to guarantee ordering.

========================== KERNEL I/O BARRIER EFFECTS

Interfacing with peripherals via I/O accesses is deeply architecture and device
specific. Therefore, drivers which are inherently non-portable may rely on
specific behaviours of their target systems in order to achieve synchronization
in the most lightweight manner possible. For drivers intending to be portable
between multiple architectures and bus implementations, the kernel offers a
series of accessor functions that provide various degrees of ordering
guarantees:

(*) readX(), writeX():

text
The readX() and writeX() MMIO accessors take a pointer to the
peripheral being accessed as an __iomem * parameter. For pointers
mapped with the default I/O attributes (e.g. those returned by
ioremap()), the ordering guarantees are as follows:

1. All readX() and writeX() accesses to the same peripheral are ordered
   with respect to each other. This ensures that MMIO register accesses
   by the same CPU thread to a particular device will arrive in program
   order.

2. A writeX() issued by a CPU thread holding a spinlock is ordered
   before a writeX() to the same peripheral from another CPU thread
   issued after a later acquisition of the same spinlock. This ensures
   that MMIO register writes to a particular device issued while holding
   a spinlock will arrive in an order consistent with acquisitions of
   the lock.

3. A writeX() by a CPU thread to the peripheral will first wait for the
   completion of all prior writes to memory either issued by, or
   propagated to, the same thread. This ensures that writes by the CPU
   to an outbound DMA buffer allocated by dma_alloc_coherent() will be
   visible to a DMA engine when the CPU writes to its MMIO control
   register to trigger the transfer.

4. A readX() by a CPU thread from the peripheral will complete before
   any subsequent reads from memory by the same thread can begin. This
   ensures that reads by the CPU from an incoming DMA buffer allocated
   by dma_alloc_coherent() will not see stale data after reading from
   the DMA engine's MMIO status register to establish that the DMA
   transfer has completed.

5. A readX() by a CPU thread from the peripheral will complete before
   any subsequent delay() loop can begin execution on the same thread.
   This ensures that two MMIO register writes by the CPU to a peripheral
   will arrive at least 1us apart if the first write is immediately read
   back with readX() and udelay(1) is called prior to the second
   writeX():

	writel(42, DEVICE_REGISTER_0); // Arrives at the device...
	readl(DEVICE_REGISTER_0);
	udelay(1);
	writel(42, DEVICE_REGISTER_1); // ...at least 1us before this.

The ordering properties of __iomem pointers obtained with non-default
attributes (e.g. those returned by ioremap_wc()) are specific to the
underlying architecture and therefore the guarantees listed above cannot
generally be relied upon for accesses to these types of mappings.

(*) readX_relaxed(), writeX_relaxed():

text
These are similar to readX() and writeX(), but provide weaker memory
ordering guarantees. Specifically, they do not guarantee ordering with
respect to locking, normal memory accesses or delay() loops (i.e.
bullets 2-5 above) but they are still guaranteed to be ordered with
respect to other accesses from the same CPU thread to the same
peripheral when operating on __iomem pointers mapped with the default
I/O attributes.

(*) readsX(), writesX():

text
The readsX() and writesX() MMIO accessors are designed for accessing
register-based, memory-mapped FIFOs residing on peripherals that are not
capable of performing DMA. Consequently, they provide only the ordering
guarantees of readX_relaxed() and writeX_relaxed(), as documented above.

(*) inX(), outX():

text
The inX() and outX() accessors are intended to access legacy port-mapped
I/O peripherals, which may require special instructions on some
architectures (notably x86). The port number of the peripheral being
accessed is passed as an argument.

Since many CPU architectures ultimately access these peripherals via an
internal virtual memory mapping, the portable ordering guarantees
provided by inX() and outX() are the same as those provided by readX()
and writeX() respectively when accessing a mapping with the default I/O
attributes.

Device drivers may expect outX() to emit a non-posted write transaction
that waits for a completion response from the I/O peripheral before
returning. This is not guaranteed by all architectures and is therefore
not part of the portable ordering semantics.

(*) insX(), outsX():

text
As above, the insX() and outsX() accessors provide the same ordering
guarantees as readsX() and writesX() respectively when accessing a
mapping with the default I/O attributes.

(*) ioreadX(), iowriteX():

text
These will perform appropriately for the type of access they're actually
doing, be it inX()/outX() or readX()/writeX().

With the exception of the string accessors (insX(), outsX(), readsX() and
writesX()), all of the above assume that the underlying peripheral is
little-endian and will therefore perform byte-swapping operations on big-endian
architectures.

======================================== ASSUMED MINIMUM EXECUTION ORDERING MODEL

It has to be assumed that the conceptual CPU is weakly-ordered but that it will
maintain the appearance of program causality with respect to itself. Some CPUs
(such as i386 or x86_64) are more constrained than others (such as powerpc or
frv), and so the most relaxed case (namely DEC Alpha) must be assumed outside
of arch-specific code.

This means that it must be considered that the CPU will execute its instruction
stream in any order it feels like - or even in parallel - provided that if an
instruction in the stream depends on an earlier instruction, then that
earlier instruction must be sufficiently complete[*] before the later
instruction may proceed; in other words: provided that the appearance of
causality is maintained.

[*] Some instructions have more than one effect - such as changing the
condition codes, changing registers or changing memory - and different
instructions may depend on different effects.

A CPU may also discard any instruction sequence that winds up having no
ultimate effect. For example, if two adjacent instructions both load an
immediate value into the same register, the first may be discarded.

Similarly, it has to be assumed that compiler might reorder the instruction
stream in any way it sees fit, again provided the appearance of causality is
maintained.

============================ THE EFFECTS OF THE CPU CACHE

The way cached memory operations are perceived across the system is affected to
a certain extent by the caches that lie between CPUs and memory, and by the
memory coherence system that maintains the consistency of state in the system.

As far as the way a CPU interacts with another part of the system through the
caches goes, the memory system has to include the CPU's caches, and memory
barriers for the most part act at the interface between the CPU and its cache
(memory barriers logically act on the dotted line in the following diagram):

text
<--- CPU --->         :       <----------- Memory ----------->
                          :
+--------+    +--------+  :   +--------+    +-----------+
|        |    |        |  :   |        |    |           |    +--------+
|  CPU   |    | Memory |  :   | CPU    |    |           |    |        |
|  Core  |--->| Access |----->| Cache  |<-->|           |    |        |
|        |    | Queue  |  :   |        |    |           |--->| Memory |
|        |    |        |  :   |        |    |           |    |        |
+--------+    +--------+  :   +--------+    |           |    |        |
                          :                 | Cache     |    +--------+
                          :                 | Coherency |
                          :                 | Mechanism |    +--------+
+--------+    +--------+  :   +--------+    |           |    |	      |
|        |    |        |  :   |        |    |           |    |        |
|  CPU   |    | Memory |  :   | CPU    |    |           |--->| Device |
|  Core  |--->| Access |----->| Cache  |<-->|           |    |        |
|        |    | Queue  |  :   |        |    |           |    |        |
|        |    |        |  :   |        |    |           |    +--------+
+--------+    +--------+  :   +--------+    +-----------+
                          :
                          :

Although any particular load or store may not actually appear outside of the
CPU that issued it since it may have been satisfied within the CPU's own cache,
it will still appear as if the full memory access had taken place as far as the
other CPUs are concerned since the cache coherency mechanisms will migrate the
cacheline over to the accessing CPU and propagate the effects upon conflict.

The CPU core may execute instructions in any order it deems fit, provided the
expected program causality appears to be maintained. Some of the instructions
generate load and store operations which then go into the queue of memory
accesses to be performed. The core may place these in the queue in any order
it wishes, and continue execution until it is forced to wait for an instruction
to complete.

What memory barriers are concerned with is controlling the order in which
accesses cross from the CPU side of things to the memory side of things, and
the order in which the effects are perceived to happen by the other observers
in the system.

[!] Memory barriers are not needed within a given CPU, as CPUs always see
their own loads and stores as if they had happened in program order.

[!] MMIO or other device accesses may bypass the cache system. This depends on
the properties of the memory window through which devices are accessed and/or
the use of any special device communication instructions the CPU may have.

CACHE COHERENCY VS DMA

Not all systems maintain cache coherency with respect to devices doing DMA. In
such cases, a device attempting DMA may obtain stale data from RAM because
dirty cache lines may be resident in the caches of various CPUs, and may not
have been written back to RAM yet. To deal with this, the appropriate part of
the kernel must flush the overlapping bits of cache on each CPU (and maybe
invalidate them as well).

In addition, the data DMA'd to RAM by a device may be overwritten by dirty
cache lines being written back to RAM from a CPU's cache after the device has
installed its own data, or cache lines present in the CPU's cache may simply
obscure the fact that RAM has been updated, until at such time as the cacheline
is discarded from the CPU's cache and reloaded. To deal with this, the
appropriate part of the kernel must invalidate the overlapping bits of the
cache on each CPU.

See Documentation/core-api/cachetlb.rst for more information on cache
management.

CACHE COHERENCY VS MMIO

Memory mapped I/O usually takes place through memory locations that are part of
a window in the CPU's memory space that has different properties assigned than
the usual RAM directed window.

Amongst these properties is usually the fact that such accesses bypass the
caching entirely and go directly to the device buses. This means MMIO accesses
may, in effect, overtake accesses to cached memory that were emitted earlier.
A memory barrier isn't sufficient in such a case, but rather the cache must be
flushed between the cached memory write and the MMIO access if the two are in
any way dependent.

========================= THE THINGS CPUS GET UP TO

A programmer might take it for granted that the CPU will perform memory
operations in exactly the order specified, so that if the CPU is, for example,
given the following piece of code to execute:

text
a = READ_ONCE(*A);
WRITE_ONCE(*B, b);
c = READ_ONCE(*C);
d = READ_ONCE(*D);
WRITE_ONCE(*E, e);

they would then expect that the CPU will complete the memory operation for each
instruction before moving on to the next one, leading to a definite sequence of
operations as seen by external observers in the system:

text
LOAD *A, STORE *B, LOAD *C, LOAD *D, STORE *E.

Reality is, of course, much messier. With many CPUs and compilers, the above
assumption doesn't hold because:

(*) loads are more likely to need to be completed immediately to permit
execution progress, whereas stores can often be deferred without a
problem;

(*) loads may be done speculatively, and the result discarded should it prove
to have been unnecessary;

(*) loads may be done speculatively, leading to the result having been fetched
at the wrong time in the expected sequence of events;

(*) the order of the memory accesses may be rearranged to promote better use
of the CPU buses and caches;

(*) loads and stores may be combined to improve performance when talking to
memory or I/O hardware that can do batched accesses of adjacent locations,
thus cutting down on transaction setup costs (memory and PCI devices may
both be able to do this); and

(*) the CPU's data cache may affect the ordering, and while cache-coherency
mechanisms may alleviate this - once the store has actually hit the cache
- there's no guarantee that the coherency management will be propagated in
order to other CPUs.

So what another CPU, say, might actually observe from the above piece of code
is:

text
LOAD *A, ..., LOAD {*C,*D}, STORE *E, STORE *B

(Where "LOAD {*C,*D}" is a combined load)

However, it is guaranteed that a CPU will be self-consistent: it will see its
own accesses appear to be correctly ordered, without the need for a memory
barrier. For instance with the following code:

text
U = READ_ONCE(*A);
WRITE_ONCE(*A, V);
WRITE_ONCE(*A, W);
X = READ_ONCE(*A);
WRITE_ONCE(*A, Y);
Z = READ_ONCE(*A);

and assuming no intervention by an external influence, it can be assumed that
the final result will appear to be:

text
U == the original value of *A
X == W
Z == Y
*A == Y

The code above may cause the CPU to generate the full sequence of memory
accesses:

text
U=LOAD *A, STORE *A=V, STORE *A=W, X=LOAD *A, STORE *A=Y, Z=LOAD *A

in that order, but, without intervention, the sequence may have almost any
combination of elements combined or discarded, provided the program's view
of the world remains consistent. Note that READ_ONCE() and WRITE_ONCE()
are -not- optional in the above example, as there are architectures
where a given CPU might reorder successive loads to the same location.
On such architectures, READ_ONCE() and WRITE_ONCE() do whatever is
necessary to prevent this, for example, on Itanium the volatile casts
used by READ_ONCE() and WRITE_ONCE() cause GCC to emit the special ld.acq
and st.rel instructions (respectively) that prevent such reordering.

The compiler may also combine, discard or defer elements of the sequence before
the CPU even sees them.

For instance:

text
*A = V;
*A = W;

may be reduced to:

text
*A = W;

since, without either a write barrier or an WRITE_ONCE(), it can be
assumed that the effect of the storage of V to *A is lost. Similarly:

text
*A = Y;
Z = *A;

may, without a memory barrier or an READ_ONCE() and WRITE_ONCE(), be
reduced to:

text
*A = Y;
Z = Y;

and the LOAD operation never appear outside of the CPU.

AND THEN THERE'S THE ALPHA

The DEC Alpha CPU is one of the most relaxed CPUs there is. Not only that,
some versions of the Alpha CPU have a split data cache, permitting them to have
two semantically-related cache lines updated at separate times. This is where
the address-dependency barrier really becomes necessary as this synchronises
both caches with the memory coherence system, thus making it seem like pointer
changes vs new data occur in the right order.

The Alpha defines the Linux kernel's memory model, although as of v4.15
the Linux kernel's addition of smp_mb() to READ_ONCE() on Alpha greatly
reduced its impact on the memory model.

VIRTUAL MACHINE GUESTS

Guests running within virtual machines might be affected by SMP effects even if
the guest itself is compiled without SMP support. This is an artifact of
interfacing with an SMP host while running an UP kernel. Using mandatory
barriers for this use-case would be possible but is often suboptimal.

To handle this case optimally, low-level virt_mb() etc macros are available.
These have the same effect as smp_mb() etc when SMP is enabled, but generate
identical code for SMP and non-SMP systems. For example, virtual machine guests
should use virt_mb() rather than smp_mb() when synchronizing against a
(possibly SMP) host.

These are equivalent to smp_mb() etc counterparts in all other respects,
in particular, they do not control MMIO effects: to control
MMIO effects, use mandatory barriers.

============ EXAMPLE USES

CIRCULAR BUFFERS

Memory barriers can be used to implement circular buffering without the need
of a lock to serialise the producer with the consumer. See:

text
Documentation/core-api/circular-buffers.rst

for details.

========== REFERENCES

Alpha AXP Architecture Reference Manual, Second Edition (Sites & Witek,
Digital Press)
Chapter 5.2: Physical Address Space Characteristics
Chapter 5.4: Caches and Write Buffers
Chapter 5.5: Data Sharing
Chapter 5.6: Read/Write Ordering

AMD64 Architecture Programmer's Manual Volume 2: System Programming
Chapter 7.1: Memory-Access Ordering
Chapter 7.4: Buffering and Combining Memory Writes

ARM Architecture Reference Manual (ARMv8, for ARMv8-A architecture profile)
Chapter B2: The AArch64 Application Level Memory Model

IA-32 Intel Architecture Software Developer's Manual, Volume 3:
System Programming Guide
Chapter 7.1: Locked Atomic Operations
Chapter 7.2: Memory Ordering
Chapter 7.4: Serializing Instructions

The SPARC Architecture Manual, Version 9
Chapter 8: Memory Models
Appendix D: Formal Specification of the Memory Models
Appendix J: Programming with the Memory Models

Storage in the PowerPC (Stone and Fitzgerald)

UltraSPARC Programmer Reference Manual
Chapter 5: Memory Accesses and Cacheability
Chapter 15: Sparc-V9 Memory Models

UltraSPARC III Cu User's Manual
Chapter 9: Memory Models

UltraSPARC IIIi Processor User's Manual
Chapter 8: Memory Models

UltraSPARC Architecture 2005
Chapter 9: Memory
Appendix D: Formal Specifications of the Memory Models

UltraSPARC T1 Supplement to the UltraSPARC Architecture 2005
Chapter 8: Memory Models
Appendix F: Caches and Cache Coherency

Solaris Internals, Core Kernel Architecture, p63-68:
Chapter 3.3: Hardware Considerations for Locks and
Synchronization

Unix Systems for Modern Architectures, Symmetric Multiprocessing and Caching
for Kernel Programmers:
Chapter 13: Other Memory Models

Intel Itanium Architecture Software Developer's Manual: Volume 1:
Section 2.6: Speculation
Section 4.4: Memory Access


Documentation Subsystem Apis (`Documentation/subsystem-apis.rst`)

.. SPDX-License-Identifier: GPL-2.0

============================== Kernel subsystem documentation

These books get into the details of how specific kernel subsystems work
from the point of view of a kernel developer. Much of the information here
is taken directly from the kernel source, with supplemental material added
as needed (or at least as we managed to add it โ€” probably not all that is
needed).

Core subsystems

.. toctree::
:maxdepth: 1

core-api/index
driver-api/index
mm/index
power/index
scheduler/index
timers/index
locking/index

Human interfaces

.. toctree::
:maxdepth: 1

input/index
hid/index
sound/index
gpu/index
fb/index
leds/index

Networking interfaces

.. toctree::
:maxdepth: 1

networking/index
netlabel/index
infiniband/index
mhi/index

Storage interfaces

.. toctree::
:maxdepth: 1

filesystems/index
block/index
cdrom/index
scsi/index
target/index
nvme/index

Other subsystems

Fixme: much more organizational work is needed here.

.. toctree::
:maxdepth: 1

accounting/index
cpu-freq/index
edac/index
fpga/index
i2c/index
iio/index
pcmcia/index
spi/index
w1/index
watchdog/index
virt/index
hwmon/index
accel/index
security/index
crypto/index
bpf/index
usb/index
PCI/index
misc-devices/index
peci/index
wmi/index
tee/index


Documentation PCI Acpi Info (`Documentation/PCI/acpi-info.rst`)

.. SPDX-License-Identifier: GPL-2.0

======================================== ACPI considerations for PCI host bridges

The general rule is that the ACPI namespace should describe everything the
OS might use unless there's another way for the OS to find it [1, 2].

For example, there's no standard hardware mechanism for enumerating PCI
host bridges, so the ACPI namespace must describe each host bridge, the
method for accessing PCI config space below it, the address space windows
the host bridge forwards to PCI (using _CRS), and the routing of legacy
INTx interrupts (using _PRT).

PCI devices, which are below the host bridge, generally do not need to be
described via ACPI. The OS can discover them via the standard PCI
enumeration mechanism, using config accesses to discover and identify
devices and read and size their BARs. However, ACPI may describe PCI
devices if it provides power management or hotplug functionality for them
or if the device has INTx interrupts connected by platform interrupt
controllers and a _PRT is needed to describe those connections.

ACPI resource description is done via _CRS objects of devices in the ACPI
namespace [2]. The _CRS is like a generalized PCI BAR: the OS can read
_CRS and figure out what resource is being consumed even if it doesn't have
a driver for the device [3]. That's important because it means an old OS
can work correctly even on a system with new devices unknown to the OS.
The new devices might not do anything, but the OS can at least make sure no
resources conflict with them.

Static tables like MCFG, HPET, ECDT, etc., are not mechanisms for
reserving address space. The static tables are for things the OS needs to
know early in boot, before it can parse the ACPI namespace. If a new table
is defined, an old OS needs to operate correctly even though it ignores the
table. _CRS allows that because it is generic and understood by the old
OS; a static table does not.

If the OS is expected to manage a non-discoverable device described via
ACPI, that device will have a specific _HID/_CID that tells the OS what
driver to bind to it, and the _CRS tells the OS and the driver where the
device's registers are.

PCI host bridges are PNP0A03 or PNP0A08 devices. Their _CRS should
describe all the address space they consume. This includes all the windows
they forward down to the PCI bus, as well as registers of the host bridge
itself that are not forwarded to PCI. The host bridge registers include
things like secondary/subordinate bus registers that determine the bus
range below the bridge, window registers that describe the apertures, etc.
These are all device-specific, non-architected things, so the only way a
PNP0A03/PNP0A08 driver can manage them is via _PRS/_CRS/_SRS, which contain
the device-specific details. The host bridge registers also include ECAM
space, since it is consumed by the host bridge.

ACPI defines a Consumer/Producer bit to distinguish the bridge registers
("Consumer") from the bridge apertures ("Producer") [4, 5], but early
BIOSes didn't use that bit correctly. The result is that the current ACPI
spec defines Consumer/Producer only for the Extended Address Space
descriptors; the bit should be ignored in the older QWord/DWord/Word
Address Space descriptors. Consequently, OSes have to assume all
QWord/DWord/Word descriptors are windows.

Prior to the addition of Extended Address Space descriptors, the failure of
Consumer/Producer meant there was no way to describe bridge registers in
the PNP0A03/PNP0A08 device itself. The workaround was to describe the
bridge registers (including ECAM space) in PNP0C02 catch-all devices [6].
With the exception of ECAM, the bridge register space is device-specific
anyway, so the generic PNP0A03/PNP0A08 driver (pci_root.c) has no need to
know about it.

New architectures should be able to use "Consumer" Extended Address Space
descriptors in the PNP0A03 device for bridge registers, including ECAM,
although a strict interpretation of [6] might prohibit this. Old x86 and
ia64 kernels assume all address space descriptors, including "Consumer"
Extended Address Space ones, are windows, so it would not be safe to
describe bridge registers this way on those architectures.

PNP0C02 "motherboard" devices are basically a catch-all. There's no
programming model for them other than "don't use these resources for
anything else." So a PNP0C02 _CRS should claim any address space that is
(1) not claimed by _CRS under any other device object in the ACPI namespace
and (2) should not be assigned by the OS to something else.

The PCIe spec requires the Enhanced Configuration Access Method (ECAM)
unless there's a standard firmware interface for config access, e.g., the
ia64 SAL interface [7]. A host bridge consumes ECAM memory address space
and converts memory accesses into PCI configuration accesses. The spec
defines the ECAM address space layout and functionality; only the base of
the address space is device-specific. An ACPI OS learns the base address
from either the static MCFG table or a _CBA method in the PNP0A03 device.

The MCFG table must describe the ECAM space of non-hot pluggable host
bridges [8]. Since MCFG is a static table and can't be updated by hotplug,
a _CBA method in the PNP0A03 device describes the ECAM space of a
hot-pluggable host bridge [9]. Note that for both MCFG and _CBA, the base
address always corresponds to bus 0, even if the bus range below the bridge
(which is reported via _CRS) doesn't start at 0.

[1] ACPI 6.2, sec 6.1:
For any device that is on a non-enumerable type of bus (for example, an
ISA bus), OSPM enumerates the devices' identifier(s) and the ACPI
system firmware must supply an _HID object ... for each device to
enable OSPM to do that.

[2] ACPI 6.2, sec 3.7:
The OS enumerates motherboard devices simply by reading through the
ACPI Namespace looking for devices with hardware IDs.

text
Each device enumerated by ACPI includes ACPI-defined objects in the
ACPI Namespace that report the hardware resources the device could
occupy [_PRS], an object that reports the resources that are currently
used by the device [_CRS], and objects for configuring those resources
[_SRS].  The information is used by the Plug and Play OS (OSPM) to
configure the devices.

[3] ACPI 6.2, sec 6.2:
OSPM uses device configuration objects to configure hardware resources
for devices enumerated via ACPI. Device configuration objects provide
information about current and possible resource requirements, the
relationship between shared resources, and methods for configuring
hardware resources.

text
When OSPM enumerates a device, it calls _PRS to determine the resource
requirements of the device.  It may also call _CRS to find the current
resource settings for the device.  Using this information, the Plug and
Play system determines what resources the device should consume and
sets those resources by calling the deviceโ€™s _SRS control method.

In ACPI, devices can consume resources (for example, legacy keyboards),
provide resources (for example, a proprietary PCI bridge), or do both.
Unless otherwise specified, resources for a device are assumed to be
taken from the nearest matching resource above the device in the device
hierarchy.

[4] ACPI 6.2, sec 6.4.3.5.1, 2, 3, 4:
QWord/DWord/Word Address Space Descriptor (.1, .2, .3)
General Flags: Bit [0] Ignored

text
Extended Address Space Descriptor (.4)
  General Flags: Bit [0] Consumer/Producer:

    * 1 โ€“ This device consumes this resource
    * 0 โ€“ This device produces and consumes this resource

[5] ACPI 6.2, sec 19.6.43:
ResourceUsage specifies whether the Memory range is consumed by
this device (ResourceConsumer) or passed on to child devices
(ResourceProducer). If nothing is specified, then
ResourceConsumer is assumed.

[6] PCI Firmware 3.2, sec 4.1.2:
If the operating system does not natively comprehend reserving the
MMCFG region, the MMCFG region must be reserved by firmware. The
address range reported in the MCFG table or by _CBA method (see Section
4.1.3) must be reserved by declaring a motherboard resource. For most
systems, the motherboard resource would appear at the root of the ACPI
namespace (under _SB) in a node with a _HID of EISAID (PNP0C02), and
the resources in this case should not be claimed in the root PCI busโ€™s
_CRS. The resources can optionally be returned in Int15 E820 or
EFIGetMemoryMap as reserved memory but must always be reported through
ACPI as a motherboard resource.

[7] PCI Express 4.0, sec 7.2.2:
For systems that are PC-compatible, or that do not implement a
processor-architecture-specific firmware interface standard that allows
access to the Configuration Space, the ECAM is required as defined in
this section.

[8] PCI Firmware 3.2, sec 4.1.2:
The MCFG table is an ACPI table that is used to communicate the base
addresses corresponding to the non-hot removable PCI Segment Groups
range within a PCI Segment Group available to the operating system at
boot. This is required for the PC-compatible systems.

text
The MCFG table is only used to communicate the base addresses
corresponding to the PCI Segment Groups available to the system at
boot.

[9] PCI Firmware 3.2, sec 4.1.3:
The _CBA (Memory mapped Configuration Base Address) control method is
an optional ACPI object that returns the 64-bit memory mapped
configuration base address for the hot plug capable host bridge. The
base address returned by _CBA is processor-relative address. The _CBA
control method evaluates to an Integer.

text
This control method appears under a host bridge object. When the _CBA
method appears under an active host bridge object, the operating system
evaluates this structure to identify the memory mapped configuration
base address corresponding to the PCI Segment Group for the bus number
range specified in _CRS method. An ACPI name space object that contains
the _CBA method must also contain a corresponding _SEG method.

Documentation PCI Boot Interrupts (`Documentation/PCI/boot-interrupts.rst`)

.. SPDX-License-Identifier: GPL-2.0

=============== Boot Interrupts

:Author: - Sean V Kelley [email protected]

Overview

On PCI Express, interrupts are represented with either MSI or inbound
interrupt messages (Assert_INTx/Deassert_INTx). The integrated IO-APIC in a
given Core IO converts the legacy interrupt messages from PCI Express to
MSI interrupts. If the IO-APIC is disabled (via the mask bits in the
IO-APIC table entries), the messages are routed to the legacy PCH. This
in-band interrupt mechanism was traditionally necessary for systems that
did not support the IO-APIC and for boot. Intel in the past has used the
term "boot interrupts" to describe this mechanism. Further, the PCI Express
protocol describes this in-band legacy wire-interrupt INTx mechanism for
I/O devices to signal PCI-style level interrupts. The subsequent paragraphs
describe problems with the Core IO handling of INTx message routing to the
PCH and mitigation within BIOS and the OS.

Issue

When in-band legacy INTx messages are forwarded to the PCH, they in turn
trigger a new interrupt for which the OS likely lacks a handler. When an
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::

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:

? dump_stack+0x46/0x5e ? __report_bad_irq+0x2e/0xb0 ? note_interrupt+0x242/0x290 ? nNIKAL100_memoryRead16+0x8/0x10 [nikal] ? handle_irq_event_percpu+0x55/0x70 ? handle_irq_event+0x4f/0x80 ? handle_fasteoi_irq+0x81/0x180 ? handle_irq+0x1c/0x30 ? do_IRQ+0x41/0xd0 ? common_interrupt+0x84/0x84

handlers:
irq_default_primary_handler threaded usb_hcd_irq
Disabling IRQ #19

Conditions

The use of threaded interrupts is the most likely condition to trigger
this problem today. Threaded interrupts may not be re-enabled after the IRQ
handler wakes. These "one shot" conditions mean that the threaded interrupt
needs to keep the interrupt line masked until the threaded handler has run.
Especially when dealing with high data rate interrupts, the thread needs to
run to completion; otherwise some handlers will end up in stack overflows
since the interrupt of the issuing device is still active.

Affected Chipsets

The legacy interrupt forwarding mechanism exists today in a number of
devices including but not limited to chipsets from AMD/ATI, Broadcom, and
Intel. Changes made through the mitigations below have been applied to
drivers/pci/quirks.c

Starting with ICX there are no longer any IO-APICs in the Core IO's
devices. IO-APIC is only in the PCH. Devices connected to the Core IO's
PCIe Root Ports will use native MSI/MSI-X mechanisms.

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]_

Intelยฎ 6300ESB I/O Controller Hub
Alternate Base Address Register:
BIE: Boot Interrupt Enable

text
==  ===========================
  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
Intelยฎ Quick Data DMA/PCI Express ports are not routed to legacy
PCH - they are either converted into MSI via the integrated IO-APIC
(if the IO-APIC mask bit is clear in the appropriate entries)
or cause no further action (when mask bit is set)

In the absence of a way to directly disable the routing, another approach
has been to make use of PCI Interrupt pin to INTx routing tables for
purposes of redirecting the interrupt handler to the rerouted interrupt
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]_

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]_

More Documentation

There is an overview of the legacy interrupt handling in several datasheets
(6300ESB and 6700PXH below). While largely the same, it provides insight
into the evolution of its handling with chipsets.

Example of disabling of the boot interrupt

text
- 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)
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

text
- 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

If you have any legacy PCI interrupt questions that aren't answered, email me.

Cheers,
Sean V Kelley
[email protected]

.. [1] https://lore.kernel.org/r/[email protected]/
.. [2] https://lore.kernel.org/r/[email protected]/
.. [3] https://lore.kernel.org/r/[email protected]/


Documentation PCI Index (`Documentation/PCI/index.rst`)

.. SPDX-License-Identifier: GPL-2.0

================= PCI Bus Subsystem

.. toctree::
:maxdepth: 2
:numbered:

pci
pciebus-howto
pci-iov-howto
msi-howto
sysfs-pci
acpi-info
pci-error-recovery
pcieaer-howto
endpoint/index
controller/index
boot-interrupts
tph


Documentation PCI Msi Howto (`Documentation/PCI/msi-howto.rst`)

.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>

========================== The MSI Driver Guide HOWTO

:Authors: Tom L Nguyen; Martine Silbermann; Matthew Wilcox

:Copyright: 2003, 2008 Intel Corporation

About this guide

This guide describes the basics of Message Signaled Interrupts (MSIs),
the advantages of using MSI over traditional interrupt mechanisms, how
to change your driver to use MSI or MSI-X and some basic diagnostics to
try if a device doesn't support MSIs.

What are MSIs?

A Message Signaled Interrupt is a write from the device to a special
address which causes an interrupt to be received by the CPU.

The MSI capability was first specified in PCI 2.2 and was later enhanced
in PCI 3.0 to allow each interrupt to be masked individually. The MSI-X
capability was also introduced with PCI 3.0. It supports more interrupts
per device than MSI and allows interrupts to be independently configured.

Devices may support both MSI and MSI-X, but only one can be enabled at
a time.

Why use MSIs?

There are three reasons why using MSIs can give an advantage over
traditional pin-based interrupts.

Pin-based PCI interrupts are often shared amongst several devices.
To support this, the kernel must call each interrupt handler associated
with an interrupt, which leads to reduced performance for the system as
a whole. MSIs are never shared, so this problem cannot arise.

When a device writes data to memory, then raises a pin-based interrupt,
it is possible that the interrupt may arrive before all the data has
arrived in memory (this becomes more likely with devices behind PCI-PCI
bridges). In order to ensure that all the data has arrived in memory,
the interrupt handler must read a register on the device which raised
the interrupt. PCI transaction ordering rules require that all the data
arrive in memory before the value may be returned from the register.
Using MSIs avoids this problem as the interrupt-generating write cannot
pass the data writes, so by the time the interrupt is raised, the driver
knows that all the data has arrived in memory.

PCI devices can only support a single pin-based interrupt per function.
Often drivers have to query the device to find out what event has
occurred, slowing down interrupt handling for the common case. With
MSIs, a device can support more interrupts, allowing each interrupt
to be specialised to a different purpose. One possible design gives
infrequent conditions (such as errors) their own interrupt which allows
the driver to handle the normal interrupt handling path more efficiently.
Other possible designs include giving one interrupt to each packet queue
in a network card or each port in a storage controller.

How to use MSIs

PCI devices are initialised to use pin-based interrupts. The device
driver has to set up the device to use MSI or MSI-X. Not all machines
support MSIs correctly, and for those machines, the APIs described below
will simply fail and the device will continue to use pin-based interrupts.

Include kernel support for MSIs

To support MSI or MSI-X, the kernel must be built with the CONFIG_PCI_MSI
option enabled. This option is only available on some architectures,
and it may depend on some other options also being set. For example,
on x86, you must also enable X86_UP_APIC or SMP in order to see the
CONFIG_PCI_MSI option.

Using MSI

Most of the hard work is done for the driver in the PCI layer. The driver
simply has to request that the PCI layer set up the MSI capability for this
device.

To automatically use MSI or MSI-X interrupt vectors, use the following
function::

int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,
unsigned int max_vecs, unsigned int flags);

which allocates up to max_vecs interrupt vectors for a PCI device. It
returns the number of vectors allocated or a negative error. If the device
has a requirement for a minimum number of vectors the driver can pass a
min_vecs argument set to this limit, and the PCI core will return -ENOSPC
if it can't meet the minimum number of vectors.

The flags argument is used to specify which type of interrupt can be used
by the device and the driver (PCI_IRQ_INTX, PCI_IRQ_MSI, PCI_IRQ_MSIX).
A convenient short-hand (PCI_IRQ_ALL_TYPES) is also available to ask for
any possible kind of interrupt. If the PCI_IRQ_AFFINITY flag is set,
pci_alloc_irq_vectors() will spread the interrupts around the available CPUs.

To get the Linux IRQ numbers passed to request_irq() and free_irq() and the
vectors, use the following function::

int pci_irq_vector(struct pci_dev *dev, unsigned int nr);

If the driver enables the device using pcim_enable_device(), the driver
shouldn't call pci_free_irq_vectors() because pcim_enable_device()
activates automatic management for IRQ vectors. Otherwise, the driver should
free any allocated IRQ vectors before removing the device using the following
function::

void pci_free_irq_vectors(struct pci_dev *dev);

If a device supports both MSI-X and MSI capabilities, this API will use the
MSI-X facilities in preference to the MSI facilities. MSI-X supports any
number of interrupts between 1 and 2048. In contrast, MSI is restricted to
a maximum of 32 interrupts (and must be a power of two). In addition, the
MSI interrupt vectors must be allocated consecutively, so the system might
not be able to allocate as many vectors for MSI as it could for MSI-X. On
some platforms, MSI interrupts must all be targeted at the same set of CPUs
whereas MSI-X interrupts can all be targeted at different CPUs.

If a device supports neither MSI-X nor MSI it will fall back to a single
legacy IRQ vector.

The typical usage of MSI or MSI-X interrupts is to allocate as many vectors
as possible, likely up to the limit supported by the device. If nvec is
larger than the number supported by the device it will automatically be
capped to the supported limit, so there is no need to query the number of
vectors supported beforehand::

text
nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_ALL_TYPES)
if (nvec < 0)
	goto out_err;

If a driver is unable or unwilling to deal with a variable number of MSI
interrupts it can request a particular number of interrupts by passing that
number to pci_alloc_irq_vectors() function as both 'min_vecs' and
'max_vecs' parameters::

text
ret = pci_alloc_irq_vectors(pdev, nvec, nvec, PCI_IRQ_ALL_TYPES);
if (ret < 0)
	goto out_err;

The most notorious example of the request type described above is enabling
the single MSI mode for a device. It could be done by passing two 1s as
'min_vecs' and 'max_vecs'::

text
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (ret < 0)
	goto out_err;

Some devices might not support using legacy line interrupts, in which case
the driver can specify that only MSI or MSI-X is acceptable::

text
nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_MSI | PCI_IRQ_MSIX);
if (nvec < 0)
	goto out_err;

Legacy APIs

The following old APIs to enable and disable MSI or MSI-X interrupts should
not be used in new code::

pci_enable_msi() /* deprecated /
pci_disable_msi() /
deprecated /
pci_enable_msix_range() /
deprecated /
pci_enable_msix_exact() /
deprecated /
pci_disable_msix() /
deprecated */

Additionally there are APIs to provide the number of supported MSI or MSI-X
vectors: pci_msi_vec_count() and pci_msix_vec_count(). In general these
should be avoided in favor of letting pci_alloc_irq_vectors() cap the
number of vectors. If you have a legitimate special use case for the count
of vectors we might have to revisit that decision and add a
pci_nr_irq_vectors() helper that handles MSI and MSI-X transparently.

Considerations when using MSIs

Spinlocks

text
Most device drivers have a per-device spinlock which is taken in the
interrupt handler.  With pin-based interrupts or a single MSI, it is not
necessary to disable interrupts (Linux guarantees the same interrupt will
not be re-entered).  If a device uses multiple interrupts, the driver
must disable interrupts while the lock is held.  If the device sends
a different interrupt, the driver will deadlock trying to recursively
acquire the spinlock.  Such deadlocks can be avoided by using
spin_lock_irqsave() or spin_lock_irq() which disable local interrupts
and acquire the lock (see Documentation/kernel-hacking/locking.rst).

How to tell whether MSI/MSI-X is enabled on a device
----------------------------------------------------

Using 'lspci -v' (as root) may show some devices with "MSI", "Message
Signaled Interrupts" or "MSI-X" capabilities.  Each of these capabilities
has an 'Enable' flag which is followed with either "+" (enabled)
or "-" (disabled).


MSI quirks
==========

Several PCI chipsets or devices are known not to support MSIs.
The PCI stack provides three ways to disable MSIs:

1. globally
2. on all devices behind a specific bridge
3. on a single device

Disabling MSIs globally
-----------------------

Some host chipsets simply don't support MSIs properly.  If we're
lucky, the manufacturer knows this and has indicated it in the ACPI
FADT table.  In this case, Linux automatically disables MSIs.
Some boards don't include this information in the table and so we have
to detect them ourselves.  The complete list of these is found near the
quirk_disable_all_msi() function in drivers/pci/quirks.c.

If you have a board which has problems with MSIs, you can pass pci=nomsi
on the kernel command line to disable MSIs on all devices.  It would be
in your best interests to report the problem to [email protected]
including a full 'lspci -v' so we can add the quirks to the kernel.

Disabling MSIs below a bridge
-----------------------------

Some PCI bridges are not able to route MSIs between buses properly.
In this case, MSIs must be disabled on all devices behind the bridge.

Some bridges allow you to enable MSIs by changing some bits in their
PCI configuration space (especially the Hypertransport chipsets such
as the nVidia nForce and Serverworks HT2000).  As with host chipsets,
Linux mostly knows about them and automatically enables MSIs if it can.
If you have a bridge unknown to Linux, you can enable
MSIs in configuration space using whatever method you know works, then
enable MSIs on that bridge by doing::

       echo 1 > /sys/bus/pci/devices/$bridge/msi_bus

where $bridge is the PCI address of the bridge you've enabled (eg
0000:00:0e.0).

To disable MSIs, echo 0 instead of 1.  Changing this value should be
done with caution as it could break interrupt handling for all devices
below this bridge.

Again, please notify [email protected] of any bridges that need
special handling.

Disabling MSIs on a single device
---------------------------------

Some devices are known to have faulty MSI implementations.  Usually this
is handled in the individual device driver, but occasionally it's necessary
to handle this with a quirk.  Some drivers have an option to disable use
of MSI.  While this is a convenient workaround for the driver author,
it is not good practice, and should not be emulated.

Finding why MSIs are disabled on a device
-----------------------------------------

From the above three sections, you can see that there are many reasons
why MSIs may not be enabled for a given device.  Your first step should
be to examine your dmesg carefully to determine whether MSIs are enabled
for your machine.  You should also check your .config to be sure you
have enabled CONFIG_PCI_MSI.

Then, 'lspci -t' gives the list of bridges above a device. Reading
`/sys/bus/pci/devices/*/msi_bus` will tell you whether MSIs are enabled (1)
or disabled (0).  If 0 is found in any of the msi_bus files belonging
to bridges between the PCI root and the device, MSIs are disabled.

It is also worth checking the device driver to see whether it supports MSIs.
For example, it may contain calls to pci_alloc_irq_vectors() with the
PCI_IRQ_MSI or PCI_IRQ_MSIX flags.


List of device drivers MSI(-X) APIs
===================================

The PCI/MSI subsystem has a dedicated C file for its exported device driver
APIs โ€” `drivers/pci/msi/api.c`. The following functions are exported:

.. kernel-doc:: drivers/pci/msi/api.c
   :export:

---

### Documentation PCI Pci Error Recovery (`Documentation/PCI/pci-error-recovery.rst`)

.. SPDX-License-Identifier: GPL-2.0

==================
PCI Error Recovery
==================


:Authors: - Linas Vepstas <[email protected]>
          - Richard Lary <[email protected]>
          - Mike Mason <[email protected]>


Many PCI bus controllers are able to detect a variety of hardware
PCI errors on the bus, such as parity errors on the data and address
buses, as well as SERR and PERR errors.  Some of the more advanced
chipsets are able to deal with these errors; these include PCIe chipsets,
and the PCI-host bridges found on IBM Power4, Power5 and Power6-based
pSeries boxes. A typical action taken is to disconnect the affected device,
halting all I/O to it.  The goal of a disconnection is to avoid system
corruption; for example, to halt system memory corruption due to DMAs
to "wild" addresses. Typically, a reconnection mechanism is also
offered, so that the affected PCI device(s) are reset and put back
into working condition. The reset phase requires coordination
between the affected device drivers and the PCI controller chip.
This document describes a generic API for notifying device drivers
of a bus disconnection, and then performing error recovery.
This API is currently implemented in the 2.6.16 and later kernels.

Reporting and recovery is performed in several steps. First, when
a PCI hardware error has resulted in a bus disconnect, that event
is reported as soon as possible to all affected device drivers,
including multiple instances of a device driver on multi-function
cards. This allows device drivers to avoid deadlocking in spinloops,
waiting for some i/o-space register to change, when it never will.
It also gives the drivers a chance to defer incoming I/O as
needed.

Next, recovery is performed in several stages. Most of the complexity
is forced by the need to handle multi-function devices, that is,
devices that have multiple device drivers associated with them.
In the first stage, each driver is allowed to indicate what type
of reset it desires, the choices being a simple re-enabling of I/O
or requesting a slot reset.

If any driver requests a slot reset, that is what will be done.

After a reset and/or a re-enabling of I/O, all drivers are
again notified, so that they may then perform any device setup/config
that may be required.  After these have all completed, a final
"resume normal operations" event is sent out.

The biggest reason for choosing a kernel-based implementation rather
than a user-space implementation was the need to deal with bus
disconnects of PCI devices attached to storage media, and, in particular,
disconnects from devices holding the root file system.  If the root
file system is disconnected, a user-space mechanism would have to go
through a large number of contortions to complete recovery. Almost all
of the current Linux file systems are not tolerant of disconnection
from/reconnection to their underlying block device. By contrast,
bus errors are easy to manage in the device driver. Indeed, most
device drivers already handle very similar recovery procedures;
for example, the SCSI-generic layer already provides significant
mechanisms for dealing with SCSI bus errors and SCSI bus resets.


Detailed Design
===============

Design and implementation details below, based on a chain of
public email discussions with Ben Herrenschmidt, circa 5 April 2005.

The error recovery API support is exposed to the driver in the form of
a structure of function pointers pointed to by a new field in struct
pci_driver. A driver that fails to provide the structure is "non-aware",
and the actual recovery steps taken are platform dependent.  The
arch/powerpc implementation will simulate a PCI hotplug remove/add.

This structure has the form::

	struct pci_error_handlers
	{
		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);
		void (*cor_error_detected)(struct pci_dev *dev);
	};

The possible channel states are::

	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::

	enum pci_ers_result {
		PCI_ERS_RESULT_NONE,        /* no result/none/not supported in device driver */
		PCI_ERS_RESULT_CAN_RECOVER, /* Device driver can recover without slot reset */
		PCI_ERS_RESULT_NEED_RESET,  /* Device driver wants slot to be reset. */
		PCI_ERS_RESULT_DISCONNECT,  /* Device has completely failed, is unrecoverable */
		PCI_ERS_RESULT_RECOVERED,   /* Device driver is fully recovered and operational */
	};

A driver does not have to implement all of these callbacks; however,
if it implements any, it must implement error_detected(). If a callback
is not implemented, the corresponding feature is considered unsupported.
For example, if mmio_enabled() and resume() aren't there, then it
is assumed that the driver does not need these callbacks
for recovery.  Typically a driver will want to know about
a slot_reset().

The actual steps taken by a platform to recover from a PCI error
event will be platform-dependent, but will follow the general
sequence described below.

STEP 0: Error Event
-------------------
A PCI bus error is detected by the PCI hardware.  On powerpc, the slot
is isolated, in that all I/O is blocked: all reads return 0xffffffff,
all writes are ignored.

Similarly, on platforms supporting Downstream Port Containment
(PCIe r7.0 sec 6.2.11), the link to the sub-hierarchy with the
faulting device is disabled. Any device in the sub-hierarchy
becomes inaccessible.

STEP 1: Notification
--------------------
Platform calls the error_detected() callback on every instance of
every driver affected by the error.

At this point, the device might not be accessible anymore, depending on
the platform (the slot will be isolated on powerpc). The driver may
already have "noticed" the error because of a failing I/O, but this
is the proper "synchronization point", that is, it gives the driver
a chance to cleanup, waiting for pending stuff (timers, whatever, etc...)
to complete; it can take semaphores, schedule, etc... everything but
touch the device. Within this function and after it returns, the driver
shouldn't do any new IOs. Called in task context. This is sort of a
"quiesce" point. See note about interrupts at the end of this doc.

All drivers participating in this system must implement this call.
The driver must return one of the following result codes:

  - PCI_ERS_RESULT_RECOVERED
      Driver returns this if it thinks the device is usable despite
      the error and does not need further intervention.
  - PCI_ERS_RESULT_CAN_RECOVER
      Driver returns this if it thinks it might be able to recover
      the HW by just banging IOs or if it wants to be given
      a chance to extract some diagnostic information (see
      mmio_enable, below).
  - PCI_ERS_RESULT_NEED_RESET
      Driver returns this if it can't recover without a
      slot reset.
  - PCI_ERS_RESULT_DISCONNECT
      Driver returns this if it doesn't want to recover at all.

The next step taken will depend on the result codes returned by the
drivers.

If all drivers on the segment/slot return PCI_ERS_RESULT_CAN_RECOVER,
then the platform should re-enable IOs on the slot (or do nothing in
particular, if the platform doesn't isolate slots), and recovery
proceeds to STEP 2 (MMIO Enable).

If any driver requested a slot reset (by returning PCI_ERS_RESULT_NEED_RESET),
then recovery proceeds to STEP 4 (Slot Reset).

If the platform is unable to recover the slot, the next step
is STEP 6 (Permanent Failure).

.. note::

   The current powerpc implementation assumes that a device driver will
   *not* schedule or semaphore in this routine; the current powerpc
   implementation uses one kernel thread to notify all devices;
   thus, if one device sleeps/schedules, all devices are affected.
   Doing better requires complex multi-threaded logic in the error
   recovery implementation (e.g. waiting for all notification threads
   to "join" before proceeding with recovery.)  This seems excessively
   complex and not worth implementing.

   The current powerpc implementation doesn't much care if the device
   attempts I/O at this point, or not.  I/Os will fail, returning
   a value of 0xff on read, and writes will be dropped. If more than
   EEH_MAX_FAILS I/Os are attempted to a frozen adapter, EEH
   assumes that the device driver has gone into an infinite loop
   and prints an error to syslog.  A reboot is then required to
   get the device working again.

STEP 2: MMIO Enabled
--------------------
The platform re-enables MMIO to the device (but typically not the
DMA), and then calls the mmio_enabled() callback on all affected
device drivers.

This is the "early recovery" call. IOs are allowed again, but DMA is
not, with some restrictions. This is NOT a callback for the driver to
start operations again, only to peek/poke at the device, extract diagnostic
information, if any, and eventually do things like trigger a device local
reset or some such, but not restart operations. This callback is made if
all drivers on a segment agree that they can try to recover and if no automatic
link reset was performed by the HW. If the platform can't just re-enable IOs
without a slot reset or a link reset, it will not call this callback, and
instead will have gone directly to STEP 3 (Link Reset) or STEP 4 (Slot Reset).

.. note::

   On platforms supporting Advanced Error Reporting (PCIe r7.0 sec 6.2),
   the faulting device may already be accessible in STEP 1 (Notification).
   Drivers should nevertheless defer accesses to STEP 2 (MMIO Enabled)
   to be compatible with EEH on powerpc and with s390 (where devices are
   inaccessible until STEP 2).

   On platforms supporting Downstream Port Containment, the link to the
   sub-hierarchy with the faulting device is re-enabled in STEP 3 (Link
   Reset). Hence devices in the sub-hierarchy are inaccessible until
   STEP 4 (Slot Reset).

   For errors such as Surprise Down (PCIe r7.0 sec 6.2.7), the device
   may not even be accessible in STEP 4 (Slot Reset). Drivers can detect
   accessibility by checking whether reads from the device return all 1's
   (PCI_POSSIBLE_ERROR()).

.. note::

   The following is proposed; no platform implements this yet:
   Proposal: All I/Os should be done _synchronously_ from within
   this callback, errors triggered by them will be returned via
   the normal pci_check_whatever() API, no new error_detected()
   callback will be issued due to an error happening here. However,
   such an error might cause IOs to be re-blocked for the whole
   segment, and thus invalidate the recovery that other devices
   on the same segment might have done, forcing the whole segment
   into one of the next states, that is, link reset or slot reset.

The driver should return one of the following result codes:
  - PCI_ERS_RESULT_RECOVERED
      Driver returns this if it thinks the device is fully
      functional and thinks it is ready to start
      normal driver operations again. There is no
      guarantee that the driver will actually be
      allowed to proceed, as another driver on the
      same segment might have failed and thus triggered a
      slot reset on platforms that support it.

  - PCI_ERS_RESULT_NEED_RESET
      Driver returns this if it thinks the device is not
      recoverable in its current state and it needs a slot
      reset to proceed.

  - PCI_ERS_RESULT_DISCONNECT
      Same as above. Total failure, no recovery even after
      reset driver dead. (To be defined more precisely)

The next step taken depends on the results returned by the drivers.
If all drivers returned PCI_ERS_RESULT_RECOVERED, then the platform
proceeds to either STEP 3 (Link Reset) or to STEP 5 (Resume Operations).

If any driver returned PCI_ERS_RESULT_NEED_RESET, then the platform
proceeds to STEP 4 (Slot Reset)

STEP 3: Link Reset
------------------
The platform resets the link.  This is a PCIe specific step
and is done whenever a fatal error has been detected that can be
"solved" by resetting the link.

STEP 4: Slot Reset
------------------

In response to a return value of PCI_ERS_RESULT_NEED_RESET, the
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.

Powerpc platforms implement two levels of slot reset:
soft reset(default) and fundamental(optional) reset.

Powerpc soft reset consists of asserting the adapter #RST line and then
restoring the PCI BARs and PCI configuration header to a state
that is equivalent to what it would be after a fresh system
power-on followed by power-on BIOS/system firmware initialization.
Soft reset is also known as hot-reset.

Powerpc fundamental reset is supported by PCIe cards only
and results in device's state machines, hardware logic, port states and
configuration registers to initialize to their default conditions.

For most PCI devices, a soft reset will be sufficient for recovery.
Optional fundamental reset is provided to support a limited number
of PCIe devices for which a soft reset is not sufficient
for recovery.

If the platform supports PCI hotplug, then the reset might be
performed by toggling the slot electrical power off/on.

It is important for the platform to restore the PCI config space
to the "fresh poweron" state, rather than the "last state". After
a slot reset, the device driver will almost always use its standard
device initialization routines, and an unusual config space setup
may result in hung devices, kernel panics, or silent data corruption.

This call gives drivers the chance to re-initialize the hardware
(re-download firmware, etc.).  At this point, the driver may assume
that the card is in a fresh state and is fully functional. The slot
is unfrozen and the driver has full access to PCI config space,
memory mapped I/O space and DMA. Interrupts (Legacy, MSI, or MSI-X)
will also be available.

Drivers should not restart normal I/O processing operations
at this point.  If all device drivers report success on this
callback, the platform will call resume() to complete the sequence,
and let the driver restart normal I/O processing.

A driver can still return a critical failure for this function if
it can't get the device operational after reset.  If the platform
previously tried a soft reset, it might now try a hard reset (power
cycle) and then call slot_reset() again.  If the device still can't
be recovered, there is nothing more that can be done;  the platform
will typically report a "permanent failure" in such a case.  The
device will be considered "dead" in this case.

Drivers typically need to call pci_restore_state() after reset to
re-initialize the device's config space registers and thereby
bring it from D0\ :sub:`uninitialized` into D0\ :sub:`active` state
(PCIe r7.0 sec 5.3.1.1).  The PCI core invokes pci_save_state()
on enumeration after initializing config space to ensure that a
saved state is available for subsequent error recovery.
Drivers which modify config space on probe may need to invoke
pci_save_state() afterwards to record those changes for later
error recovery.  When going into system suspend, pci_save_state()
is called for every PCI device and that state will be restored
not only on resume, but also on any subsequent error recovery.
In the unlikely event that the saved state recorded on suspend
is unsuitable for error recovery, drivers should call
pci_save_state() on resume.

Drivers for multi-function cards will need to coordinate among
themselves as to which driver instance will perform any "one-shot"
or global device initialization. For example, the Symbios sym53cxx2
driver performs device init only from PCI function 0::

	+       if (PCI_FUNC(pdev->devfn) == 0)
	+               sym_reset_scsi_bus(np, 0);

Result codes:
	- PCI_ERS_RESULT_DISCONNECT
	  Same as above.

Drivers for PCIe cards that require a fundamental reset must
set the needs_freset bit in the pci_dev structure in their probe function.
For example, the QLogic qla2xxx driver sets the needs_freset bit for certain
PCI card types::

	+	/* Set EEH reset type to fundamental if required by hba  */
	+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha))
	+		pdev->needs_freset = 1;
	+

Platform proceeds either to STEP 5 (Resume Operations) or STEP 6 (Permanent
Failure).

.. note::

   The current powerpc implementation does not try a power-cycle
   reset if the driver returned PCI_ERS_RESULT_DISCONNECT.
   However, it probably should.


STEP 5: Resume Operations
-------------------------
The platform will call the resume() callback on all affected device
drivers if all drivers on the segment have returned
PCI_ERS_RESULT_RECOVERED from one of the 3 previous callbacks.
The goal of this callback is to tell the driver to restart activity,
that everything is back and running. This callback does not return
a result code.

At this point, if a new error happens, the platform will restart
a new error recovery sequence.

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_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
higher layers. The device driver should then clean up all of its
memory and remove itself from kernel operations, much as it would
during system shutdown.

The platform will typically notify the system operator of the
permanent failure in some way.  If the device is hotplug-capable,
the operator will probably want to remove and replace the device.
Note, however, not all failures are truly "permanent". Some are
caused by over-heating, some by a poorly seated card. Many
PCI error events are caused by software bugs, e.g. DMAs to
wild addresses or bogus split transactions due to programming
errors. See the discussion in Documentation/arch/powerpc/eeh-pci-error-recovery.rst
for additional detail on real-life experience of the causes of
software errors.


Conclusion; General Remarks
---------------------------
The way the callbacks are called is platform policy. A platform with
no slot reset capability may want to just "ignore" drivers that can't
recover (disconnect them) and try to let other cards on the same segment
recover. Keep in mind that in most real life cases, though, there will
be only one driver per segment.

Now, a note about interrupts. If you get an interrupt and your
device is dead or has been isolated, there is a problem :)
The current policy is to turn this into a platform policy.
That is, the recovery API only requires that:

 - There is no guarantee that interrupt delivery can proceed from any
   device on the segment starting from the error detection and until the
   slot_reset callback is called, at which point interrupts are expected
   to be fully operational.

 - There is no guarantee that interrupt delivery is stopped, that is,
   a driver that gets an interrupt after detecting an error, or that detects
   an error within the interrupt handler such that it prevents proper
   ack'ing of the interrupt (and thus removal of the source) should just
   return IRQ_NOTHANDLED. It's up to the platform to deal with that
   condition, typically by masking the IRQ source during the duration of
   the error handling. It is expected that the platform "knows" which
   interrupts are routed to error-management capable slots and can deal
   with temporarily disabling that IRQ number during error processing (this
   isn't terribly complex). That means some IRQ latency for other devices
   sharing the interrupt, but there is simply no other way. High end
   platforms aren't supposed to share interrupts between many devices
   anyway :)

.. note::

   Implementation details for the powerpc platform are discussed in
   the file Documentation/arch/powerpc/eeh-pci-error-recovery.rst

   As of this writing, there is a growing list of device drivers with
   patches implementing error recovery. Not all of these patches are in
   mainline yet. These may be used as "examples":

   - drivers/scsi/ipr
   - drivers/scsi/sym53c8xx_2
   - drivers/scsi/qla2xxx
   - drivers/scsi/lpfc
   - drivers/next/bnx2.c
   - drivers/next/e100.c
   - drivers/net/e1000
   - drivers/net/e1000e
   - drivers/net/ixgbe
   - drivers/net/cxgb3

   The cor_error_detected() callback is invoked in handle_error_source() when
   the error severity is "correctable". The callback is optional and allows
   additional logging to be done if desired. See example:

   - drivers/cxl/pci.c

The End
-------

---

### Documentation PCI Pci Iov Howto (`Documentation/PCI/pci-iov-howto.rst`)

.. SPDX-License-Identifier: GPL-2.0
.. include:: 

====================================
PCI Express I/O Virtualization Howto
====================================

:Copyright: |copy| 2009 Intel Corporation
:Authors: - Yu Zhao <[email protected]>
          - Donald Dutile <[email protected]>

Overview
========

What is SR-IOV
--------------

Single Root I/O Virtualization (SR-IOV) is a PCI Express Extended
capability which makes one physical device appear as multiple virtual
devices. The physical device is referred to as Physical Function (PF)
while the virtual devices are referred to as Virtual Functions (VF).
Allocation of the VF can be dynamically controlled by the PF via
registers encapsulated in the capability. By default, this feature is
not enabled and the PF behaves as traditional PCIe device. Once it's
turned on, each VF's PCI configuration space can be accessed by its own
Bus, Device and Function Number (Routing ID). And each VF also has PCI
Memory Space, which is used to map its register set. VF device driver
operates on the register set so it can be functional and appear as a
real existing PCI device.

User Guide
==========

How can I enable SR-IOV capability
----------------------------------

Multiple methods are available for SR-IOV enablement.
In the first method, the device driver (PF driver) will control the
enabling and disabling of the capability via API provided by SR-IOV core.
If the hardware has SR-IOV capability, loading its PF driver would
enable it and all VFs associated with the PF.  Some PF drivers require
a module parameter to be set to determine the number of VFs to enable.
In the second method, a write to the sysfs file sriov_numvfs will
enable and disable the VFs associated with a PCIe PF.  This method
enables per-PF, VF enable/disable values versus the first method,
which applies to all PFs of the same device.  Additionally, the
PCI SRIOV core support ensures that enable/disable operations are
valid to reduce duplication in multiple drivers for the same
checks, e.g., check numvfs == 0 if enabling VFs, ensure
numvfs <= totalvfs.
The second method is the recommended method for new/future VF devices.

How can I use the Virtual Functions
-----------------------------------

The VF is treated as hot-plugged PCI devices in the kernel, so they
should be able to work in the same way as real PCI devices. The VF
requires device driver that is same as a normal PCI device's.

Developer Guide
===============

SR-IOV API
----------

To enable SR-IOV capability:

(a) For the first method, in the driver::

	int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);

'nr_virtfn' is number of VFs to be enabled.

(b) For the second method, from sysfs::

	echo 'nr_virtfn' > \
        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs

To disable SR-IOV capability:

(a) For the first method, in the driver::

	void pci_disable_sriov(struct pci_dev *dev);

(b) For the second method, from sysfs::

	echo  0 > \
        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs

To enable auto probing VFs by a compatible driver on the host, run
command below before enabling SR-IOV capabilities. This is the
default behavior.
::

	echo 1 > \
        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe

To disable auto probing VFs by a compatible driver on the host, run
command below before enabling SR-IOV capabilities. Updating this
entry will not affect VFs which are already probed.
::

	echo  0 > \
        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe

Usage example
-------------

Following piece of code illustrates the usage of the SR-IOV API.
::

	static int dev_probe(struct pci_dev *dev, const struct pci_device_id *id)
	{
		pci_enable_sriov(dev, NR_VIRTFN);

		...

		return 0;
	}

	static void dev_remove(struct pci_dev *dev)
	{
		pci_disable_sriov(dev);

		...
	}

	static int dev_suspend(struct device *dev)
	{
		...

		return 0;
	}

	static int dev_resume(struct device *dev)
	{
		...

		return 0;
	}

	static void dev_shutdown(struct pci_dev *dev)
	{
		...
	}

	static int dev_sriov_configure(struct pci_dev *dev, int numvfs)
	{
		if (numvfs > 0) {
			...
			pci_enable_sriov(dev, numvfs);
			...
			return numvfs;
		}
		if (numvfs == 0) {
			....
			pci_disable_sriov(dev);
			...
			return 0;
		}
	}

	static struct pci_driver dev_driver = {
		.name =		"SR-IOV Physical Function driver",
		.id_table =	dev_id_table,
		.probe =	dev_probe,
		.remove =	dev_remove,
		.driver.pm =	&dev_pm_ops,
		.shutdown =	dev_shutdown,
		.sriov_configure = dev_sriov_configure,
	};

---

### Documentation PCI Pci (`Documentation/PCI/pci.rst`)

.. SPDX-License-Identifier: GPL-2.0

==============================
How To Write Linux PCI Drivers
==============================

:Authors: - Martin Mares <[email protected]>
          - Grant Grundler <[email protected]>

The world of PCI is vast and full of (mostly unpleasant) surprises.
Since each CPU architecture implements different chip-sets and PCI devices
have different requirements (erm, "features"), the result is the PCI support
in the Linux kernel is not as trivial as one would wish. This short paper
tries to introduce all potential driver authors to Linux APIs for
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:
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.

Please send questions/comments/patches about Linux PCI API to the
"Linux PCI" <[email protected]> mailing list.


Structure of PCI drivers
========================
PCI drivers "discover" PCI devices in a system via pci_register_driver().
Actually, it's the other way around. When the PCI generic code discovers
a new device, the driver with a matching "description" will be notified.
Details on this below.

pci_register_driver() leaves most of the probing for devices to
the PCI layer and supports online insertion/removal of devices [thus
supporting hot-pluggable PCI, CardBus, and Express-Card in a single driver].
pci_register_driver() call requires passing in a table of function
pointers and thus dictates the high level structure of a driver.

Once the driver knows about a PCI device and takes ownership, the
driver generally needs to perform the following initialization:

  - Enable the device
  - Request MMIO/IOP resources
  - Set the DMA mask size (for both coherent and streaming DMA)
  - Allocate and initialize shared control data (pci_allocate_coherent())
  - Access device configuration space (if needed)
  - Register IRQ handler (request_irq())
  - Initialize non-PCI (i.e. LAN/SCSI/etc parts of the chip)
  - Enable DMA/processing engines

When done using the device, and perhaps the module needs to be unloaded,
the driver needs to take the following steps:

  - Disable the device from generating IRQs
  - Release the IRQ (free_irq())
  - Stop all DMA activity
  - Release DMA buffers (both streaming and coherent)
  - Unregister from other subsystems (e.g. scsi or netdev)
  - Release MMIO/IOP resources
  - Disable the device

Most of these topics are covered in the following sections.
For the rest look at LDD3 or <linux/pci.h> .

If the PCI subsystem is not configured (CONFIG_PCI is not set), most of
the PCI functions described below are defined as inline functions either
completely empty or just returning an appropriate error codes to avoid
lots of ifdefs in the drivers.


pci_register_driver() call
==========================

PCI device drivers call ``pci_register_driver()`` during their
initialization with a pointer to a structure describing the driver
(``struct pci_driver``):

.. kernel-doc:: include/linux/pci.h
   :functions: pci_driver

The ID table is an array of ``struct pci_device_id`` entries ending with an
all-zero entry.  Definitions with static const are generally preferred.

.. kernel-doc:: include/linux/mod_devicetable.h
   :functions: pci_device_id

Most drivers only need ``PCI_DEVICE()`` or ``PCI_DEVICE_CLASS()`` to set up
a pci_device_id table.

New PCI IDs may be added to a device driver pci_ids table at runtime
as shown below::

  echo "vendor device subvendor subdevice class class_mask driver_data" > \
  /sys/bus/pci/drivers/{driver}/new_id

All fields are passed in as hexadecimal values (no leading 0x).
The vendor and device fields are mandatory, the others are optional. Users
need pass only as many optional fields as necessary:

  - subvendor and subdevice fields default to PCI_ANY_ID (FFFFFFFF)
  - class and classmask fields default to 0
  - driver_data defaults to 0UL.
  - override_only field defaults to 0.

Note that driver_data must match the value used by any of the pci_device_id
entries defined in the driver. This makes the driver_data field mandatory
if all the pci_device_id entries have a non-zero driver_data value.

Once added, the driver probe routine will be invoked for any unclaimed
PCI devices listed in its (newly updated) pci_ids list.

When the driver exits, it just calls pci_unregister_driver() and the PCI layer
automatically calls the remove hook for all devices handled by the driver.


"Attributes" for driver functions/data
--------------------------------------

Please mark the initialization and cleanup functions where appropriate
(the corresponding macros are defined in <linux/init.h>):

	======		=================================================
	__init		Initialization code. Thrown away after the driver
			initializes.
	__exit		Exit code. Ignored for non-modular drivers.
	======		=================================================

Tips on when/where to use the above attributes:
	- The module_init()/module_exit() functions (and all
	  initialization functions called _only_ from these)
	  should be marked __init/__exit.

	- Do not mark the struct pci_driver.

	- Do NOT mark a function if you are not sure which mark to use.
	  Better to not mark the function than mark the function wrong.


How to find PCI devices manually
================================

PCI drivers should have a really good reason for not using the
pci_register_driver() interface to search for PCI devices.
The main reason PCI devices are controlled by multiple drivers
is because one PCI device implements several different HW services.
E.g. combined serial/parallel port/floppy controller.

A manual search may be performed using the following constructs:

Searching by vendor and device ID::

	struct pci_dev *dev = NULL;
	while (dev = pci_get_device(VENDOR_ID, DEVICE_ID, dev))
		configure_device(dev);

Searching by class ID (iterate in a similar way)::

	pci_get_class(CLASS_ID, dev)

Searching by both vendor/device and subsystem vendor/device ID::

	pci_get_subsys(VENDOR_ID,DEVICE_ID, SUBSYS_VENDOR_ID, SUBSYS_DEVICE_ID, dev).

You can use the constant PCI_ANY_ID as a wildcard replacement for
VENDOR_ID or DEVICE_ID.  This allows searching for any device from a
specific vendor, for example.

These functions are hotplug-safe. They increment the reference count on
the pci_dev that they return. You must eventually (possibly at module unload)
decrement the reference count on these devices by calling pci_dev_put().


Device Initialization Steps
===========================

As noted in the introduction, most PCI drivers need the following steps
for device initialization:

  - Enable the device
  - Request MMIO/IOP resources
  - Set the DMA mask size (for both coherent and streaming DMA)
  - Allocate and initialize shared control data (pci_allocate_coherent())
  - Access device configuration space (if needed)
  - Register IRQ handler (request_irq())
  - Initialize non-PCI (i.e. LAN/SCSI/etc parts of the chip)
  - Enable DMA/processing engines.

The driver can access PCI config space registers at any time.
(Well, almost. When running BIST, config space can go away...but
that will just result in a PCI Bus Master Abort and config reads
will return garbage).


Enable the PCI device
---------------------
Before touching any device registers, the driver needs to enable
the PCI device by calling pci_enable_device(). This will:

  - wake up the device if it was in suspended state,
  - allocate I/O and memory regions of the device (if BIOS did not),
  - allocate an IRQ (if BIOS did not).

.. note::
   pci_enable_device() can fail! Check the return value.

.. warning::
   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 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:
   https://lore.kernel.org/r/[email protected]/


pci_set_master() will enable DMA by setting the bus master bit
in the PCI_COMMAND register. It also fixes the latency timer value if
it's set to something bogus by the BIOS.  pci_clear_master() will
disable DMA by clearing the bus master bit.

If the PCI device can use the PCI Memory-Write-Invalidate transaction,
call pci_set_mwi().  This enables the PCI_COMMAND bit for Mem-Wr-Inval
and also ensures that the cache line size register is set correctly.
Check the return value of pci_set_mwi() as not all architectures
or chip-sets may support Memory-Write-Invalidate.  Alternatively,
if Mem-Wr-Inval would be nice to have but is not required, call
pci_try_set_mwi() to have the system do its best effort at enabling
Mem-Wr-Inval.


Request MMIO/IOP resources
--------------------------
Memory (MMIO), and I/O port addresses should NOT be read directly
from the PCI device config space. Use the values in the pci_dev structure
as the PCI "bus address" might have been remapped to a "host physical"
address by the arch/chip-set specific kernel support.

See Documentation/driver-api/io-mapping.rst for how to access device registers
or device memory.

The device driver needs to call pci_request_region() to verify
no other device is already using the same address resource.
Conversely, drivers should call pci_release_region() AFTER
calling pci_disable_device().
The idea is to prevent two devices colliding on the same address range.

.. tip::
   See OS BUG comment above. Currently (2.6.19), The driver can only
   determine MMIO and IO Port resource availability _after_ calling
   pci_enable_device().

Generic flavors of pci_request_region() are request_mem_region()
(for MMIO ranges) and request_region() (for IO Port ranges).
Use these for address resources that are not described by "normal" PCI
BARs.

Also see pci_request_selected_regions() below.


Set the DMA mask size
---------------------
.. note::
   If anything below doesn't make sense, please refer to
   Documentation/core-api/dma-api.rst. 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.

While all drivers should explicitly indicate the DMA capability
(e.g. 32 or 64 bit) of the PCI bus master, devices with more than
32-bit bus master capability for streaming data need the driver
to "register" this capability by calling dma_set_mask() with
appropriate parameters.  In general this allows more efficient DMA
on systems where System RAM exists above 4G _physical_ address.

Drivers for all PCI-X and PCIe compliant devices must call
dma_set_mask() as they are 64-bit DMA devices.

Similarly, drivers must also "register" this capability if the device
can directly address "coherent memory" in System RAM above 4G physical
address by calling dma_set_coherent_mask().
Again, this includes drivers for all PCI-X and PCIe compliant devices.
Many 64-bit "PCI" devices (before PCI-X) and some PCI-X devices are
64-bit DMA capable for payload ("streaming") data but not control
("coherent") data.


Setup shared control data
-------------------------
Once the DMA masks are set, the driver can allocate "coherent" (a.k.a. shared)
memory.  See Documentation/core-api/dma-api.rst 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.


Initialize device registers
---------------------------
Some drivers will need specific "capability" fields programmed
or other "vendor specific" register initialized or reset.
E.g. clearing pending interrupts.


Register IRQ handler
--------------------
While calling request_irq() is the last step described here,
this is often just another intermediate step to initialize a device.
This step can often be deferred until the device is opened for use.

All interrupt handlers for IRQ lines should be registered with IRQF_SHARED
and use the devid to map IRQs to devices (remember that all PCI IRQ lines
can be shared).

request_irq() will associate an interrupt handler and device handle
with an interrupt number. Historically interrupt numbers represent
IRQ lines which run from the PCI device to the Interrupt controller.
With MSI and MSI-X (more below) the interrupt number is a CPU "vector".

request_irq() also enables the interrupt. Make sure the device is
quiesced and does not have any interrupts pending before registering
the interrupt handler.

MSI and MSI-X are PCI capabilities. Both are "Message Signaled Interrupts"
which deliver interrupts to the CPU via a DMA write to a Local APIC.
The fundamental difference between MSI and MSI-X is how multiple
"vectors" get allocated. MSI requires contiguous blocks of vectors
while MSI-X can allocate several individual ones.

MSI capability can be enabled by calling pci_alloc_irq_vectors() with the
PCI_IRQ_MSI and/or PCI_IRQ_MSIX flags before calling request_irq(). This
causes the PCI support to program CPU vector data into the PCI device
capability registers. Many architectures, chip-sets, or BIOSes do NOT
support MSI or MSI-X and a call to pci_alloc_irq_vectors with just
the PCI_IRQ_MSI and PCI_IRQ_MSIX flags will fail, so try to always
specify PCI_IRQ_INTX as well.

Drivers that have different interrupt handlers for MSI/MSI-X and
legacy INTx should choose the right one based on the msi_enabled
and msix_enabled flags in the pci_dev structure after calling
pci_alloc_irq_vectors.

There are (at least) two really good reasons for using MSI:

1) MSI is an exclusive interrupt vector by definition.
   This means the interrupt handler doesn't have to verify
   its device caused the interrupt.

2) MSI avoids DMA/IRQ race conditions. DMA to host memory is guaranteed
   to be visible to the host CPU(s) when the MSI is delivered. This
   is important for both data coherency and avoiding stale control data.
   This guarantee allows the driver to omit MMIO reads to flush
   the DMA stream.

See drivers/infiniband/hw/mthca/ or drivers/net/tg3.c for examples
of MSI/MSI-X usage.


PCI device shutdown
===================

When a PCI device driver is being unloaded, most of the following
steps need to be performed:

  - Disable the device from generating IRQs
  - Release the IRQ (free_irq())
  - Stop all DMA activity
  - Release DMA buffers (both streaming and coherent)
  - Unregister from other subsystems (e.g. scsi or netdev)
  - Disable device from responding to MMIO/IO Port addresses
  - Release MMIO/IO Port resource(s)


Stop IRQs on the device
-----------------------
How to do this is chip/device specific. If it's not done, it opens
the possibility of a "screaming interrupt" if (and only if)
the IRQ is shared with another device.

When the shared IRQ handler is "unhooked", the remaining devices
using the same IRQ line will still need the IRQ enabled. Thus if the
"unhooked" device asserts IRQ line, the system will respond assuming
it was one of the remaining devices asserted the IRQ line. Since none
of the other devices will handle the IRQ, the system will "hang" until
it decides the IRQ isn't going to get handled and masks the IRQ (100,000
iterations later). Once the shared IRQ is masked, the remaining devices
will stop functioning properly. Not a nice situation.

This is another reason to use MSI or MSI-X if it's available.
MSI and MSI-X are defined to be exclusive interrupts and thus
are not susceptible to the "screaming interrupt" problem.


Release the IRQ
---------------
Once the device is quiesced (no more IRQs), one can call free_irq().
This function will return control once any pending IRQs are handled,
"unhook" the drivers IRQ handler from that IRQ, and finally release
the IRQ if no one else is using it.


Stop all DMA activity
---------------------
It's extremely important to stop all DMA operations BEFORE attempting
to deallocate DMA control data. Failure to do so can result in memory
corruption, hangs, and on some chip-sets a hard crash.

Stopping DMA after stopping the IRQs can avoid races where the
IRQ handler might restart DMA engines.

While this step sounds obvious and trivial, several "mature" drivers
didn't get this step right in the past.


Release DMA buffers
-------------------
Once DMA is stopped, clean up streaming DMA first.
I.e. unmap data buffers and return buffers to "upstream"
owners if there is one.

Then clean up "coherent" buffers which contain the control data.

See Documentation/core-api/dma-api.rst for details on unmapping interfaces.


Unregister from other subsystems
--------------------------------
Most low level PCI device drivers support some other subsystem
like USB, ALSA, SCSI, NetDev, Infiniband, etc. Make sure your
driver isn't losing resources from that other subsystem.
If this happens, typically the symptom is an Oops (panic) when
the subsystem attempts to call into a driver that has been unloaded.


Disable Device from responding to MMIO/IO Port addresses
--------------------------------------------------------
io_unmap() MMIO or IO Port resources and then call pci_disable_device().
This is the symmetric opposite of pci_enable_device().
Do not access device registers after calling pci_disable_device().


Release MMIO/IO Port Resource(s)
--------------------------------
Call pci_release_region() to mark the MMIO or IO Port range as available.
Failure to do so usually results in the inability to reload the driver.


How to access PCI config space
==============================

You can use `pci_(read|write)_config_(byte|word|dword)` to access the config
space of a device represented by `struct pci_dev *`. All these functions return
0 when successful or an error code (`PCIBIOS_...`) which can be translated to a
text string by pcibios_strerror. Most drivers expect that accesses to valid PCI
devices don't fail.

If you don't have a struct pci_dev available, you can call
`pci_bus_(read|write)_config_(byte|word|dword)` to access a given device
and function on that bus.

If you access fields in the standard portion of the config header, please
use symbolic names of locations and bits declared in <linux/pci.h>.

If you need to access Extended PCI Capability registers, just call
pci_find_capability() for the particular capability and it will find the
corresponding register block for you.


Other interesting functions
===========================

=============================	================================================
pci_get_domain_bus_and_slot()	Find pci_dev corresponding to given domain,
				bus and slot and number. If the device is
				found, its reference count is increased.
pci_set_power_state()		Set PCI Power Management state (0=D0 ... 3=D3)
pci_find_capability()		Find specified capability in device's capability
				list.
pci_resource_start()		Returns bus start address for a given PCI region
pci_resource_end()		Returns bus end address for a given PCI region
pci_resource_len()		Returns the byte length of a PCI region
pci_set_drvdata()		Set private driver data pointer for a pci_dev
pci_get_drvdata()		Return private driver data pointer for a pci_dev
pci_set_mwi()			Enable Memory-Write-Invalidate transactions.
pci_clear_mwi()			Disable Memory-Write-Invalidate transactions.
=============================	================================================


Miscellaneous hints
===================

When displaying PCI device names to the user (for example when a driver wants
to tell the user what card has it found), please use pci_name(pci_dev).

Always refer to the PCI devices by a pointer to the pci_dev structure.
All PCI layer functions use this identification and it's the only
reasonable one. Don't use bus/slot/function numbers except for very
special purposes -- on systems with multiple primary buses their semantics
can be pretty complex.

Don't try to turn on Fast Back to Back writes in your driver.  All devices
on the bus need to be capable of doing it, so this is something which needs
to be handled by platform and generic code, not individual drivers.


Vendor and device identifications
=================================

Do not add new device or vendor IDs to include/linux/pci_ids.h unless they
are shared across multiple drivers.  You can add private definitions in
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 https://pci-ids.ucw.cz/.
There's a mirror of the pci.ids file at https://github.com/pciutils/pciids.


Obsolete functions
==================

There are several functions which you might come across when trying to
port an old driver to the new PCI interface.  They are no longer present
in the kernel as they aren't compatible with hotplug or PCI domains or
having sane locking.

=================	===========================================
pci_find_device()	Superseded by pci_get_device()
pci_find_subsys()	Superseded by pci_get_subsys()
pci_find_slot()		Superseded by pci_get_domain_bus_and_slot()
pci_get_slot()		Superseded by pci_get_domain_bus_and_slot()
=================	===========================================

The alternative is the traditional PCI device driver that walks PCI
device lists. This is still possible but discouraged.


MMIO Space and "Write Posting"
==============================

Converting a driver from using I/O Port space to using MMIO space
often requires some additional changes. Specifically, "write posting"
needs to be handled. Many drivers (e.g. tg3, acenic, sym53c8xx_2)
already do this. I/O Port space guarantees write transactions reach the PCI
device before the CPU can continue. Writes to MMIO space allow the CPU
to continue before the transaction reaches the PCI device. HW weenies
call this "Write Posting" because the write completion is "posted" to
the CPU before the transaction has reached its destination.

Thus, timing sensitive code should add readl() where the CPU is
expected to wait before doing other work.  The classic "bit banging"
sequence works fine for I/O Port space::

       for (i = 8; --i; val >>= 1) {
               outb(val & 1, ioport_reg);      /* write bit */
               udelay(10);
       }

The same sequence for MMIO space should be::

       for (i = 8; --i; val >>= 1) {
               writeb(val & 1, mmio_reg);      /* write bit */
               readb(safe_mmio_reg);           /* flush posted write */
               udelay(10);
       }

It is important that "safe_mmio_reg" not have any side effects that
interferes with the correct operation of the device.

Another case to watch out for is when resetting a PCI device. Use PCI
Configuration space reads to flush the writel(). This will gracefully
handle the PCI master abort on all platforms if the PCI device is
expected to not respond to a readl().  Most x86 platforms will allow
MMIO reads to master abort (a.k.a. "Soft Fail") and return garbage
(e.g. ~0). But many RISC platforms will crash (a.k.a."Hard Fail").

---

### Documentation PCI Pcieaer Howto (`Documentation/PCI/pcieaer-howto.rst`)

.. SPDX-License-Identifier: GPL-2.0
.. include:: 

===========================================================
The PCI Express Advanced Error Reporting Driver Guide HOWTO
===========================================================

:Authors: - T. Long Nguyen <[email protected]>
          - Yanmin Zhang <[email protected]>

:Copyright: |copy| 2006 Intel Corporation

Overview
===========

About this guide
----------------

This guide describes the basics of the PCI Express (PCIe) Advanced Error
Reporting (AER) driver and provides information on how to use it, as
well as how to enable the drivers of Endpoint devices to conform with
the PCIe AER driver.


What is the PCIe AER Driver?
----------------------------

PCIe error signaling can occur on the PCIe link itself
or on behalf of transactions initiated on the link. PCIe
defines two error reporting paradigms: the baseline capability and
the Advanced Error Reporting capability. The baseline capability is
required of all PCIe components providing a minimum defined
set of error reporting requirements. Advanced Error Reporting
capability is implemented with a PCIe Advanced Error Reporting
extended capability structure providing more robust error reporting.

The PCIe AER driver provides the infrastructure to support PCIe Advanced
Error Reporting capability. The PCIe AER driver provides three basic
functions:

  - Gathers the comprehensive error information if errors occurred.
  - Reports error to the users.
  - Performs error recovery actions.

The AER driver only attaches to Root Ports and RCECs that support the PCIe
AER capability.


User Guide
==========

Include the PCIe AER Root Driver into the Linux Kernel
------------------------------------------------------

The PCIe AER driver is a Root Port service driver attached
via the PCIe Port Bus driver. If a user wants to use it, the driver
must be compiled. It is enabled with CONFIG_PCIEAER, which
depends on CONFIG_PCIEPORTBUS.

Load PCIe AER Root Driver
-------------------------

Some systems have AER support in firmware. Enabling Linux AER support at
the same time the firmware handles AER would result in unpredictable
behavior. Therefore, Linux does not handle AER events unless the firmware
grants AER control to the OS via the ACPI _OSC method. See the PCI Firmware
Specification for details regarding _OSC usage.

AER error output
----------------

When a PCIe AER error is captured, an error message will be output to
console. If it's a correctable error, it is output as a warning message.
Otherwise, it is printed as an error. So users could choose different
log level to filter out correctable error messages.

Below shows an example::

  0000:50:00.0: PCIe Bus Error: severity=Uncorrectable (Fatal), type=Transaction Layer, (Requester ID)
  0000:50:00.0:   device [8086:0329] error status/mask=00100000/00000000
  0000:50:00.0:    [20] UnsupReq               (First)
  0000:50:00.0:   TLP Header: 0x04000001 0x00200a03 0x05010000 0x00050100

In the example, 'Requester ID' means the ID of the device that sent
the error message to the Root Port. Please refer to PCIe specs for other
fields.

The 'TLP Header' is the prefix/header of the TLP that caused the error
in raw hex format. To decode the TLP Header into human-readable form
one may use tlp-tool:

https://github.com/mmpg-x86/tlp-tool

Example usage::

  curl -L https://git.kernel.org/linus/2ca1c94ce0b6 | rtlp-tool --aer

AER Ratelimits
--------------

Since error messages can be generated for each transaction, we may see
large volumes of errors reported. To prevent spammy devices from flooding
the console/stalling execution, messages are throttled by device and error
type (correctable vs. non-fatal uncorrectable).  Fatal errors, including
DPC errors, are not ratelimited.

AER uses the default ratelimit of DEFAULT_RATELIMIT_BURST (10 events) over
DEFAULT_RATELIMIT_INTERVAL (5 seconds).

Ratelimits are exposed in the form of sysfs attributes and configurable.
See Documentation/ABI/testing/sysfs-bus-pci-devices-aer.

AER Statistics / Counters
-------------------------

When PCIe AER errors are captured, the counters / statistics are also exposed
in the form of sysfs attributes which are documented at
Documentation/ABI/testing/sysfs-bus-pci-devices-aer.

Developer Guide
===============

To enable error recovery, a software driver must provide callbacks.

To support AER better, developers need to understand how AER works.

PCIe errors are classified into two types: correctable errors
and uncorrectable errors. This classification is based on the impact
of those errors, which may result in degraded performance or function
failure.

Correctable errors pose no impacts on the functionality of the
interface. The PCIe protocol can recover without any software
intervention or any loss of data. These errors are detected and
corrected by hardware.

Unlike correctable errors, uncorrectable
errors impact functionality of the interface. Uncorrectable errors
can cause a particular transaction or a particular PCIe link
to be unreliable. Depending on those error conditions, uncorrectable
errors are further classified into non-fatal errors and fatal errors.
Non-fatal errors cause the particular transaction to be unreliable,
but the PCIe link itself is fully functional. Fatal errors, on
the other hand, cause the link to be unreliable.

When PCIe error reporting is enabled, a device will automatically send an
error message to the Root Port above it when it captures
an error. The Root Port, upon receiving an error reporting message,
internally processes and logs the error message in its AER
Capability structure. Error information being logged includes storing
the error reporting agent's Requester ID into the Error Source
Identification Registers and setting the error bits of the Root Error
Status Register accordingly. If AER error reporting is enabled in the Root
Error Command Register, the Root Port generates an interrupt when an
error is detected.

Note that the errors as described above are related to the PCIe
hierarchy and links. These errors do not include any device specific
errors because device specific errors will still get sent directly to
the device driver.

Provide callbacks
-----------------

PCI error-recovery callbacks

The PCIe AER Root driver uses error callbacks to coordinate
with downstream device drivers associated with a hierarchy in question
when performing error recovery actions.

Data struct pci_driver has a pointer, err_handler, to point to
pci_error_handlers who consists of a couple of callback function
pointers. The AER driver follows the rules defined in
pci-error-recovery.rst except PCIe-specific parts (see
below). Please refer to pci-error-recovery.rst for detailed
definitions of the callbacks.

The sections below specify when to call the error callback functions.

Correctable errors

text
Correctable errors pose no impacts on the functionality of
the interface. The PCIe protocol can recover without any
software intervention or any loss of data. These errors do not
require any recovery actions. The AER driver clears the device's
correctable error status register accordingly and logs these errors.

Uncorrectable (non-fatal and fatal) errors

The AER driver performs a Secondary Bus Reset to recover from
uncorrectable errors. The reset is applied at the port above
the originating device: If the originating device is an Endpoint,
only the Endpoint is reset. If on the other hand the originating
device has subordinate devices, those are all affected by the
reset as well.

If the originating device is a Root Complex Integrated Endpoint,
there's no port above where a Secondary Bus Reset could be applied.
In this case, the AER driver instead applies a Function Level Reset.

If an error message indicates a non-fatal error, performing a reset
at upstream is not required. The AER driver calls error_detected(dev,
pci_channel_io_normal) to all drivers associated within a hierarchy in
question. For example::

Endpoint <==> Downstream Port B <==> Upstream Port A <==> Root Port

If Upstream Port A captures an AER error, the hierarchy consists of
Downstream Port B and Endpoint.

A driver may return PCI_ERS_RESULT_CAN_RECOVER,
PCI_ERS_RESULT_DISCONNECT, or PCI_ERS_RESULT_NEED_RESET, depending on
whether it can recover without a reset, considers the device unrecoverable
or needs a reset for recovery. If all affected drivers agree that they can
recover without a reset, it is skipped. Should one driver request a reset,
it overrides all other drivers.

If an error message indicates a fatal error, kernel will broadcast
error_detected(dev, pci_channel_io_frozen) to all drivers within
a hierarchy in question. Then, performing a reset at upstream is
necessary. If error_detected returns PCI_ERS_RESULT_CAN_RECOVER
to indicate that recovery without a reset is possible, the error
handling goes to mmio_enabled, but afterwards a reset is still
performed.

In other words, for non-fatal errors, drivers may opt in to a reset.
But for fatal errors, they cannot opt out of a reset, based on the
assumption that the link is unreliable.

Frequently Asked Questions

Q:
What happens if a PCIe device driver does not provide an
error recovery handler (pci_driver->err_handler is equal to NULL)?

A:
The devices attached with the driver won't be recovered.
The kernel will print out informational messages to identify
unrecoverable devices.

Software error injection

Debugging PCIe AER error recovery code is quite difficult because it
is hard to trigger real hardware errors. Software based error
injection can be used to fake various kinds of PCIe errors.

First you should enable PCIe AER software error injection in kernel
configuration, that is, following item should be in your .config.

CONFIG_PCIEAER_INJECT=y or CONFIG_PCIEAER_INJECT=m

After reboot with new kernel or insert the module, a device file named
/dev/aer_inject should be created.

Then, you need a user space tool named aer-inject, which can be gotten
from:

text
https://github.com/intel/aer-inject.git

More information about aer-inject can be found in the document in
its source code.


Documentation PCI Pciebus Howto (`Documentation/PCI/pciebus-howto.rst`)

.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>

=========================================== The PCI Express Port Bus Driver Guide HOWTO

:Author: Tom L Nguyen [email protected] 11/03/2004
:Copyright: |copy| 2004 Intel Corporation

About this guide

This guide describes the basics of the PCI Express Port Bus driver
and provides information on how to enable the service drivers to
register/unregister with the PCI Express Port Bus Driver.

What is the PCI Express Port Bus Driver

A PCI Express Port is a logical PCI-PCI Bridge structure. There
are two types of PCI Express Port: the Root Port and the Switch
Port. The Root Port originates a PCI Express link from a PCI Express
Root Complex and the Switch Port connects PCI Express links to
internal logical PCI buses. The Switch Port, which has its secondary
bus representing the switch's internal routing logic, is called the
switch's Upstream Port. The switch's Downstream Port is bridging from
switch's internal routing bus to a bus representing the downstream
PCI Express link from the PCI Express Switch.

A PCI Express Port can provide up to four distinct functions,
referred to in this document as services, depending on its port type.
PCI Express Port's services include native hotplug support (HP),
power management event support (PME), advanced error reporting
support (AER), and virtual channel support (VC). These services may
be handled by a single complex driver or be individually distributed
and handled by corresponding service drivers.

Why use the PCI Express Port Bus Driver?

In existing Linux kernels, the Linux Device Driver Model allows a
physical device to be handled by only a single driver. The PCI
Express Port is a PCI-PCI Bridge device with multiple distinct
services. To maintain a clean and simple solution each service
may have its own software service driver. In this case several
service drivers will compete for a single PCI-PCI Bridge device.
For example, if the PCI Express Root Port native hotplug service
driver is loaded first, it claims a PCI-PCI Bridge Root Port. The
kernel therefore does not load other service drivers for that Root
Port. In other words, it is impossible to have multiple service
drivers load and run on a PCI-PCI Bridge device simultaneously
using the current driver model.

To enable multiple service drivers running simultaneously requires
having a PCI Express Port Bus driver, which manages all populated
PCI Express Ports and distributes all provided service requests
to the corresponding service drivers as required. Some key
advantages of using the PCI Express Port Bus driver are listed below:

  • Allow multiple service drivers to run simultaneously on
    a PCI-PCI Bridge Port device.

  • Allow service drivers implemented in an independent
    staged approach.

  • Allow one service driver to run on multiple PCI-PCI Bridge
    Port devices.

  • Manage and distribute resources of a PCI-PCI Bridge Port
    device to requested service drivers.

Configuring the PCI Express Port Bus Driver vs. Service Drivers

Including the PCI Express Port Bus Driver Support into the Kernel

Including the PCI Express Port Bus driver depends on whether the PCI
Express support is included in the kernel config. The kernel will
automatically include the PCI Express Port Bus driver as a kernel
driver when the PCI Express support is enabled in the kernel.

Enabling Service Driver Support

PCI device drivers are implemented based on Linux Device Driver Model.
All service drivers are PCI device drivers. As discussed above, it is
impossible to load any service driver once the kernel has loaded the
PCI Express Port Bus Driver. To meet the PCI Express Port Bus Driver
Model requires some minimal changes on existing service drivers that
imposes no impact on the functionality of existing service drivers.

A service driver is required to use the two APIs shown below to
register its service with the PCI Express Port Bus driver (see
section 5.2.1 & 5.2.2). It is important that a service driver
initializes the pcie_port_service_driver data structure, included in
header file /include/linux/pcieport_if.h, before calling these APIs.
Failure to do so will result in an identity mismatch, which prevents
the PCI Express Port Bus driver from loading a service driver.

pcie_port_service_register

text
::

  int pcie_port_service_register(struct pcie_port_service_driver *new)

This API replaces the Linux Driver Model's pci_register_driver API. A
service driver should always calls pcie_port_service_register at
module init. Note that after service driver being loaded, calls
such as pci_enable_device(dev) and pci_set_master(dev) are no longer
necessary since these calls are executed by the PCI Port Bus driver.

pcie_port_service_unregister

::

void pcie_port_service_unregister(struct pcie_port_service_driver *new)

pcie_port_service_unregister replaces the Linux Driver Model's
pci_unregister_driver. It's always called by service driver when a
module exits.

Sample Code

text
Below is sample service driver code to initialize the port service
driver data structure.
::

  static struct pcie_port_service_id service_id[] = { {
    .vendor = PCI_ANY_ID,
    .device = PCI_ANY_ID,
    .port_type = PCIE_RC_PORT,
    .service_type = PCIE_PORT_SERVICE_AER,
    }, { /* end: all zeroes */ }
  };

  static struct pcie_port_service_driver root_aerdrv = {
    .name		= (char *)device_name,
    .id_table	= service_id,

    .probe		= aerdrv_load,
    .remove		= aerdrv_unload,

    .suspend	= aerdrv_suspend,
    .resume		= aerdrv_resume,
  };

Below is a sample code for registering/unregistering a service
driver.
::

  static int __init aerdrv_service_init(void)
  {
    int retval = 0;

    retval = pcie_port_service_register(&root_aerdrv);
    if (!retval) {
      /*
      * FIX ME
      */
    }
    return retval;
  }

  static void __exit aerdrv_service_exit(void)
  {
    pcie_port_service_unregister(&root_aerdrv);
  }

  module_init(aerdrv_service_init);
  module_exit(aerdrv_service_exit);

Possible Resource Conflicts
===========================

Since all service drivers of a PCI-PCI Bridge Port device are
allowed to run simultaneously, below lists a few of possible resource
conflicts with proposed solutions.

MSI and MSI-X Vector Resource
-----------------------------

Once MSI or MSI-X interrupts are enabled on a device, it stays in this
mode until they are disabled again.  Since service drivers of the same
PCI-PCI Bridge port share the same physical device, if an individual
service driver enables or disables MSI/MSI-X mode it may result
unpredictable behavior.

To avoid this situation all service drivers are not permitted to
switch interrupt mode on its device. The PCI Express Port Bus driver
is responsible for determining the interrupt mode and this should be
transparent to service drivers. Service drivers need to know only
the vector IRQ assigned to the field irq of struct pcie_device, which
is passed in when the PCI Express Port Bus driver probes each service
driver. Service drivers should use (struct pcie_device*)dev->irq to
call request_irq/free_irq. In addition, the interrupt mode is stored
in the field interrupt_mode of struct pcie_device.

PCI Memory/IO Mapped Regions
----------------------------

Service drivers for PCI Express Power Management (PME), Advanced
Error Reporting (AER), Hot-Plug (HP) and Virtual Channel (VC) access
PCI configuration space on the PCI Express port. In all cases the
registers accessed are independent of each other. This patch assumes
that all service drivers will be well behaved and not overwrite
other service driver's configuration settings.

PCI Config Registers
--------------------

Each service driver runs its PCI config operations on its own
capability structure except the PCI Express capability structure,
that is shared between many drivers including the service drivers.
RMW Capability accessors (pcie_capability_clear_and_set_word(),
pcie_capability_set_word(), and pcie_capability_clear_word()) protect
a selected set of PCI Express Capability Registers:

* Link Control Register
* Root Control Register
* Link Control 2 Register

Any change to those registers should be performed using RMW accessors to
avoid problems due to concurrent updates. For the up-to-date list of
protected registers, see pcie_capability_clear_and_set_word().

---

### Documentation PCI Sysfs Pci (`Documentation/PCI/sysfs-pci.rst`)

.. SPDX-License-Identifier: GPL-2.0

============================================
Accessing PCI device resources through sysfs
============================================

sysfs, usually mounted at /sys, provides access to PCI resources on platforms
that support it.  For example, a given bus might look like this::

     /sys/devices/pci0000:17
     |-- 0000:17:00.0
     |   |-- class
     |   |-- config
     |   |-- device
     |   |-- enable
     |   |-- irq
     |   |-- local_cpus
     |   |-- remove
     |   |-- resource
     |   |-- resource0
     |   |-- resource1
     |   |-- resource2
     |   |-- revision
     |   |-- rom
     |   |-- subsystem_device
     |   |-- subsystem_vendor
     |   `-- vendor
     `-- ...

The topmost element describes the PCI domain and bus number.  In this case,
the domain number is 0000 and the bus number is 17 (both values are in hex).
This bus contains a single function device in slot 0.  The domain and bus
numbers are reproduced for convenience.  Under the device directory are several
files, each with their own function.

       =================== =====================================================
       file		   function
       =================== =====================================================
       class		   PCI class (ascii, ro)
       config		   PCI config space (binary, rw)
       device		   PCI device (ascii, ro)
       enable	           Whether the device is enabled (ascii, rw)
       irq		   IRQ number (ascii, ro)
       local_cpus	   nearby CPU mask (cpumask, ro)
       remove		   remove device from kernel's list (ascii, wo)
       resource		   PCI resource host addresses (ascii, ro)
       resource0..N	   PCI resource N, if present (binary, mmap, rw\ [1]_)
       resource0_wc..N_wc  PCI WC map resource N, if prefetchable (binary, mmap)
       revision		   PCI revision (ascii, ro)
       rom		   PCI ROM resource, if present (binary, ro)
       subsystem_device	   PCI subsystem device (ascii, ro)
       subsystem_vendor	   PCI subsystem vendor (ascii, ro)
       vendor		   PCI vendor (ascii, ro)
       =================== =====================================================

::

  ro - read only file
  rw - file is readable and writable
  wo - write only file
  mmap - file is mmapable
  ascii - file contains ascii text
  binary - file contains binary data
  cpumask - file contains a cpumask type

.. [1] rw for IORESOURCE_IO (I/O port) regions only

The read only files are informational, writes to them will be ignored, with
the exception of the 'rom' file.  Writable files can be used to perform
actions on the device (e.g. changing config space, detaching a device).
mmapable files are available via an mmap of the file at offset 0 and can be
used to do actual device programming from userspace.  Note that some platforms
don't support mmapping of certain resources, so be sure to check the return
value from any attempted mmap.  The most notable of these are I/O port
resources, which also provide read/write access.

The 'enable' file provides a counter that indicates how many times the device
has been enabled.  If the 'enable' file currently returns '4', and a '1' is
echoed into it, it will then return '5'.  Echoing a '0' into it will decrease
the count.  Even when it returns to 0, though, some of the initialisation
may not be reversed.

The 'rom' file is special in that it provides read-only access to the device's
ROM file, if available.  It's disabled by default, however, so applications
should write the string "1" to the file to enable it before attempting a read
call, and disable it following the access by writing "0" to the file.  Note
that the device must be enabled for a rom read to return data successfully.
In the event a driver is not bound to the device, it can be enabled using the
'enable' file, documented above.

The 'remove' file is used to remove the PCI device, by writing a non-zero
integer to the file.  This does not involve any kind of hot-plug functionality,
e.g. powering off the device.  The device is removed from the kernel's list of
PCI devices, the sysfs directory for it is removed, and the device will be
removed from any drivers attached to it. Removal of PCI root buses is
disallowed.

Accessing legacy resources through sysfs
----------------------------------------

Legacy I/O port and ISA memory resources are also provided in sysfs if the
underlying platform supports them.  They're located in the PCI class hierarchy,
e.g.::

	/sys/class/pci_bus/0000:17/
	|-- bridge -> ../../../devices/pci0000:17
	|-- cpuaffinity
	|-- legacy_io
	`-- legacy_mem

The legacy_io file is a read/write file that can be used by applications to
do legacy port I/O.  The application should open the file, seek to the desired
port (e.g. 0x3e8) and do a read or a write of 1, 2 or 4 bytes.  The legacy_mem
file should be mmapped with an offset corresponding to the memory offset
desired, e.g. 0xa0000 for the VGA frame buffer.  The application can then
simply dereference the returned pointer (after checking for errors of course)
to access legacy memory space.

Supporting PCI access on new platforms
--------------------------------------

In order to support PCI resource mapping as described above, Linux platform
code should ideally define ARCH_GENERIC_PCI_MMAP_RESOURCE and use the generic
implementation of that functionality. To support the historical interface of
mmap() through files in /proc/bus/pci, platforms may also set HAVE_PCI_MMAP.

Alternatively, platforms which set HAVE_PCI_MMAP may provide their own
implementation of pci_mmap_resource_range() instead of defining
ARCH_GENERIC_PCI_MMAP_RESOURCE.

Platforms which support write-combining maps of PCI resources must define
arch_can_pci_mmap_wc() which shall evaluate to non-zero at runtime when
write-combining is permitted. Platforms which support maps of I/O resources
define arch_can_pci_mmap_io() similarly.

Legacy resources are protected by the HAVE_PCI_LEGACY define.  Platforms
wishing to support legacy functionality should define it and provide
pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.

---

### Documentation PCI Tph (`Documentation/PCI/tph.rst`)

.. SPDX-License-Identifier: GPL-2.0


===========
TPH Support
===========

:Copyright: 2024 Advanced Micro Devices, Inc.
:Authors: - Eric van Tassell <[email protected]>
          - Wei Huang <[email protected]>


Overview
========

TPH (TLP Processing Hints) is a PCIe feature that allows endpoint devices
to provide optimization hints for requests that target memory space.
These hints, in a format called Steering Tags (STs), are embedded in the
requester's TLP headers, enabling the system hardware, such as the Root
Complex, to better manage platform resources for these requests.

For example, on platforms with TPH-based direct data cache injection
support, an endpoint device can include appropriate STs in its DMA
traffic to specify which cache the data should be written to. This allows
the CPU core to have a higher probability of getting data from cache,
potentially improving performance and reducing latency in data
processing.


How to Use TPH
==============

TPH is presented as an optional extended capability in PCIe. The Linux
kernel handles TPH discovery during boot, but it is up to the device
driver to request TPH enablement if it is to be utilized. Once enabled,
the driver uses the provided API to obtain the Steering Tag for the
target memory and to program the ST into the device's ST table.

Enable TPH support in Linux
---------------------------

To support TPH, the kernel must be built with the CONFIG_PCIE_TPH option
enabled.

Manage TPH
----------

To enable TPH for a device, use the following function::

  int pcie_enable_tph(struct pci_dev *pdev, int mode);

This function enables TPH support for device with a specific ST mode.
Current supported modes include:

  * PCI_TPH_ST_NS_MODE - NO ST Mode
  * PCI_TPH_ST_IV_MODE - Interrupt Vector Mode
  * PCI_TPH_ST_DS_MODE - Device Specific Mode

`pcie_enable_tph()` checks whether the requested mode is actually
supported by the device before enabling. The device driver can figure out
which TPH mode is supported and can be properly enabled based on the
return value of `pcie_enable_tph()`.

To disable TPH, use the following function::

  void pcie_disable_tph(struct pci_dev *pdev);

Manage ST
---------

Steering Tags are platform specific. PCIe spec does not specify where STs
are from. Instead PCI Firmware Specification defines an ACPI _DSM method
(see the `Revised _DSM for Cache Locality TPH Features ECN
<https://members.pcisig.com/wg/PCI-SIG/document/15470>`_) for retrieving
STs for a target memory of various properties. This method is what is
supported in this implementation.

To retrieve a Steering Tag for a target memory associated with a specific
CPU, use the following function::

  int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type type,
                          unsigned int cpu, u16 *tag);

The `type` argument is used to specify the memory type, either volatile
or persistent, of the target memory. The `cpu` argument specifies the
CPU where the memory is associated to.

After the ST value is retrieved, the device driver can use the following
function to write the ST into the device::

  int pcie_tph_set_st_entry(struct pci_dev *pdev, unsigned int index,
                            u16 tag);

The `index` argument is the ST table entry index the ST tag will be
written into. `pcie_tph_set_st_entry()` will figure out the proper
location of ST table, either in the MSI-X table or in the TPH Extended
Capability space, and write the Steering Tag into the ST entry pointed by
the `index` argument.

It is completely up to the driver to decide how to use these TPH
functions. For example a network device driver can use the TPH APIs above
to update the Steering Tag when interrupt affinity of a RX/TX queue has
been changed. Here is a sample code for IRQ affinity notifier:

.. code-block:: c

    static void irq_affinity_notified(struct irq_affinity_notify *notify,
                                      const cpumask_t *mask)
    {
         struct drv_irq *irq;
         unsigned int cpu_id;
         u16 tag;

         irq = container_of(notify, struct drv_irq, affinity_notify);
         cpumask_copy(irq->cpu_mask, mask);

         /* Pick a right CPU as the target - here is just an example */
         cpu_id = cpumask_first(irq->cpu_mask);

         if (pcie_tph_get_cpu_st(irq->pdev, TPH_MEM_TYPE_VM, cpu_id,
                                 &tag))
             return;

         if (pcie_tph_set_st_entry(irq->pdev, irq->msix_nr, tag))
             return;
    }

Disable TPH system-wide
-----------------------

There is a kernel command line option available to control TPH feature:
    * "notph": TPH will be disabled for all endpoint devices.

---

### Documentation RCU NMI RCU (`Documentation/RCU/NMI-RCU.rst`)

.. _NMI_rcu_doc:

Using RCU to Protect Dynamic NMI Handlers
=========================================


Although RCU is usually used to protect read-mostly data structures,
it is possible to use RCU to provide dynamic non-maskable interrupt
handlers, as well as dynamic irq handlers.  This document describes
how to do this, drawing loosely from Zwane Mwaikambo's NMI-timer
work in an old version of "arch/x86/kernel/traps.c".

The relevant pieces of code are listed below, each followed by a
brief explanation::

	static int dummy_nmi_callback(struct pt_regs *regs, int cpu)
	{
		return 0;
	}

The dummy_nmi_callback() function is a "dummy" NMI handler that does
nothing, but returns zero, thus saying that it did nothing, allowing
the NMI handler to take the default machine-specific action::

	static nmi_callback_t nmi_callback = dummy_nmi_callback;

This nmi_callback variable is a global function pointer to the current
NMI handler::

	void do_nmi(struct pt_regs * regs, long error_code)
	{
		int cpu;

		nmi_enter();

		cpu = smp_processor_id();
		++nmi_count(cpu);

		if (!rcu_dereference_sched(nmi_callback)(regs, cpu))
			default_do_nmi(regs);

		nmi_exit();
	}

The do_nmi() function processes each NMI.  It first disables preemption
in the same way that a hardware irq would, then increments the per-CPU
count of NMIs.  It then invokes the NMI handler stored in the nmi_callback
function pointer.  If this handler returns zero, do_nmi() invokes the
default_do_nmi() function to handle a machine-specific NMI.  Finally,
preemption is restored.

In theory, rcu_dereference_sched() is not needed, since this code runs
only on i386, which in theory does not need rcu_dereference_sched()
anyway.  However, in practice it is a good documentation aid, particularly
for anyone attempting to do something similar on Alpha or on systems
with aggressive optimizing compilers.

Quick Quiz:
		Why might the rcu_dereference_sched() be necessary on Alpha, given that the code referenced by the pointer is read-only?

:ref:`Answer to Quick Quiz <answer_quick_quiz_NMI>`

Back to the discussion of NMI and RCU::

	void set_nmi_callback(nmi_callback_t callback)
	{
		rcu_assign_pointer(nmi_callback, callback);
	}

The set_nmi_callback() function registers an NMI handler.  Note that any
data that is to be used by the callback must be initialized up -before-
the call to set_nmi_callback().  On architectures that do not order
writes, the rcu_assign_pointer() ensures that the NMI handler sees the
initialized values::

	void unset_nmi_callback(void)
	{
		rcu_assign_pointer(nmi_callback, dummy_nmi_callback);
	}

This function unregisters an NMI handler, restoring the original
dummy_nmi_handler().  However, there may well be an NMI handler
currently executing on some other CPU.  We therefore cannot free
up any data structures used by the old NMI handler until execution
of it completes on all other CPUs.

One way to accomplish this is via synchronize_rcu(), perhaps as
follows::

	unset_nmi_callback();
	synchronize_rcu();
	kfree(my_nmi_data);

This works because (as of v4.20) synchronize_rcu() blocks until all
CPUs complete any preemption-disabled segments of code that they were
executing.
Since NMI handlers disable preemption, synchronize_rcu() is guaranteed
not to return until all ongoing NMI handlers exit.  It is therefore safe
to free up the handler's data as soon as synchronize_rcu() returns.

Important note: for this to work, the architecture in question must
invoke nmi_enter() and nmi_exit() on NMI entry and exit, respectively.

.. _answer_quick_quiz_NMI:

Answer to Quick Quiz:
	Why might the rcu_dereference_sched() be necessary on Alpha, given that the code referenced by the pointer is read-only?

	The caller to set_nmi_callback() might well have
	initialized some data that is to be used by the new NMI
	handler.  In this case, the rcu_dereference_sched() would
	be needed, because otherwise a CPU that received an NMI
	just after the new handler was set might see the pointer
	to the new NMI handler, but the old pre-initialized
	version of the handler's data.

	This same sad story can happen on other CPUs when using
	a compiler with aggressive pointer-value speculation
	optimizations.  (But please don't!)

	More important, the rcu_dereference_sched() makes it
	clear to someone reading the code that the pointer is
	being protected by RCU-sched.

---

### Documentation RCU RTFP (`Documentation/RCU/RTFP.txt`)

Read the Fscking Papers!


This document describes RCU-related publications, and is followed by
the corresponding bibtex entries.  A number of the publications may
be found at http://www.rdrop.com/users/paulmck/RCU/.  For others, browsers
and search engines will usually find what you are looking for.

The first thing resembling RCU was published in 1980, when Kung and Lehman
[Kung80] recommended use of a garbage collector to defer destruction
of nodes in a parallel binary search tree in order to simplify its
implementation.  This works well in environments that have garbage
collectors, but most production garbage collectors incur significant
overhead.

In 1982, Manber and Ladner [Manber82,Manber84] recommended deferring
destruction until all threads running at that time have terminated, again
for a parallel binary search tree.  This approach works well in systems
with short-lived threads, such as the K42 research operating system.
However, Linux has long-lived tasks, so more is needed.

In 1986, Hennessy, Osisek, and Seigh [Hennessy89] introduced passive
serialization, which is an RCU-like mechanism that relies on the presence
of "quiescent states" in the VM/XA hypervisor that are guaranteed not
to be referencing the data structure.  However, this mechanism was not
optimized for modern computer systems, which is not surprising given
that these overheads were not so expensive in the mid-80s.  Nonetheless,
passive serialization appears to be the first deferred-destruction
mechanism to be used in production.  Furthermore, the relevant patent
has lapsed, so this approach may be used in non-GPL software, if desired.
(In contrast, implementation of RCU is permitted only in software licensed
under either GPL or LGPL.  Sorry!!!)

In 1987, Rashid et al. described lazy TLB-flush [RichardRashid87a].
At first glance, this has nothing to do with RCU, but nevertheless
this paper helped inspire the update-side batching used in the later
RCU implementation in DYNIX/ptx.  In 1988, Barbara Liskov published
a description of Argus that noted that use of out-of-date values can
be tolerated in some situations.  Thus, this paper provides some early
theoretical justification for use of stale data.

In 1990, Pugh [Pugh90] noted that explicitly tracking which threads
were reading a given data structure permitted deferred free to operate
in the presence of non-terminating threads.  However, this explicit
tracking imposes significant read-side overhead, which is undesirable
in read-mostly situations.  This algorithm does take pains to avoid
write-side contention and parallelize the other write-side overheads by
providing a fine-grained locking design, however, it would be interesting
to see how much of the performance advantage reported in 1990 remains
today.

At about this same time, Andrews [Andrews91textbook] described ``chaotic
relaxation'', where the normal barriers between successive iterations
of convergent numerical algorithms are relaxed, so that iteration $n$
might use data from iteration $n-1$ or even $n-2$.  This introduces
error, which typically slows convergence and thus increases the number of
iterations required.  However, this increase is sometimes more than made
up for by a reduction in the number of expensive barrier operations,
which are otherwise required to synchronize the threads at the end
of each iteration.  Unfortunately, chaotic relaxation requires highly
structured data, such as the matrices used in scientific programs, and
is thus inapplicable to most data structures in operating-system kernels.

In 1992, Henry (now Alexia) Massalin completed a dissertation advising
parallel programmers to defer processing when feasible to simplify
synchronization [HMassalinPhD].  RCU makes extremely heavy use of
this advice.

In 1993, Jacobson [Jacobson93] verbally described what is perhaps the
simplest deferred-free technique: simply waiting a fixed amount of time
before freeing blocks awaiting deferred free.  Jacobson did not describe
any write-side changes he might have made in this work using SGI's Irix
kernel.  Aju John published a similar technique in 1995 [AjuJohn95].
This works well if there is a well-defined upper bound on the length of
time that reading threads can hold references, as there might well be in
hard real-time systems.  However, if this time is exceeded, perhaps due
to preemption, excessive interrupts, or larger-than-anticipated load,
memory corruption can ensue, with no reasonable means of diagnosis.
Jacobson's technique is therefore inappropriate for use in production
operating-system kernels, except when such kernels can provide hard
real-time response guarantees for all operations.

Also in 1995, Pu et al. [Pu95a] applied a technique similar to that of Pugh's
read-side-tracking to permit replugging of algorithms within a commercial
Unix operating system.  However, this replugging permitted only a single
reader at a time.  The following year, this same group of researchers
extended their technique to allow for multiple readers [Cowan96a].
Their approach requires memory barriers (and thus pipeline stalls),
but reduces memory latency, contention, and locking overheads.

1995 also saw the first publication of DYNIX/ptx's RCU mechanism
[Slingwine95], which was optimized for modern CPU architectures,
and was successfully applied to a number of situations within the
DYNIX/ptx kernel.  The corresponding conference paper appeared in 1998
[McKenney98].

In 1999, the Tornado and K42 groups described their "generations"
mechanism, which is quite similar to RCU [Gamsa99].  These operating
systems made pervasive use of RCU in place of "existence locks", which
greatly simplifies locking hierarchies and helps avoid deadlocks.

The year 2000 saw an email exchange that would likely have
led to yet another independent invention of something like RCU
[RustyRussell2000a,RustyRussell2000b].  Instead, 2001 saw the first
RCU presentation involving Linux [McKenney01a] at OLS.  The resulting
abundance of RCU patches was presented the following year [McKenney02a],
and use of RCU in dcache was first described that same year [Linder02a].

Also in 2002, Michael [Michael02b,Michael02a] presented "hazard-pointer"
techniques that defer the destruction of data structures to simplify
non-blocking synchronization (wait-free synchronization, lock-free
synchronization, and obstruction-free synchronization are all examples of
non-blocking synchronization).  The corresponding journal article appeared
in 2004 [MagedMichael04a].  This technique eliminates locking, reduces
contention, reduces memory latency for readers, and parallelizes pipeline
stalls and memory latency for writers.  However, these techniques still
impose significant read-side overhead in the form of memory barriers.
Researchers at Sun worked along similar lines in the same timeframe
[HerlihyLM02].  These techniques can be thought of as inside-out reference
counts, where the count is represented by the number of hazard pointers
referencing a given data structure rather than the more conventional
counter field within the data structure itself.  The key advantage
of inside-out reference counts is that they can be stored in immortal
variables, thus allowing races between access and deletion to be avoided.

By the same token, RCU can be thought of as a "bulk reference count",
where some form of reference counter covers all reference by a given CPU
or thread during a set timeframe.  This timeframe is related to, but
not necessarily exactly the same as, an RCU grace period.  In classic
RCU, the reference counter is the per-CPU bit in the "bitmask" field,
and each such bit covers all references that might have been made by
the corresponding CPU during the prior grace period.  Of course, RCU
can be thought of in other terms as well.

In 2003, the K42 group described how RCU could be used to create
hot-pluggable implementations of operating-system functions [Appavoo03a].
Later that year saw a paper describing an RCU implementation
of System V IPC [Arcangeli03] (following up on a suggestion by
Hugh Dickins [Dickins02a] and an implementation by Mingming Cao
[MingmingCao2002IPCRCU]), and an introduction to RCU in Linux Journal
[McKenney03a].

2004 has seen a Linux-Journal article on use of RCU in dcache
[McKenney04a], a performance comparison of locking to RCU on several
different CPUs [McKenney04b], a dissertation describing use of RCU in a
number of operating-system kernels [PaulEdwardMcKenneyPhD], a paper
describing how to make RCU safe for soft-realtime applications [Sarma04c],
and a paper describing SELinux performance with RCU [JamesMorris04b].

2005 brought further adaptation of RCU to realtime use, permitting
preemption of RCU realtime critical sections [PaulMcKenney05a,
PaulMcKenney05b].

2006 saw the first best-paper award for an RCU paper [ThomasEHart2006a],
as well as further work on efficient implementations of preemptible
RCU [PaulEMcKenney2006b], but priority-boosting of RCU read-side critical
sections proved elusive.  An RCU implementation permitting general
blocking in read-side critical sections appeared [PaulEMcKenney2006c],
Robert Olsson described an RCU-protected trie-hash combination
[RobertOlsson2006a].

2007 saw the journal version of the award-winning RCU paper from 2006
[ThomasEHart2007a], as well as a paper demonstrating use of Promela
and Spin to mechanically verify an optimization to Oleg Nesterov's
QRCU [PaulEMcKenney2007QRCUspin], a design document describing
preemptible RCU [PaulEMcKenney2007PreemptibleRCU], and the three-part
LWN "What is RCU?" series [PaulEMcKenney2007WhatIsRCUFundamentally,
PaulEMcKenney2008WhatIsRCUUsage, and PaulEMcKenney2008WhatIsRCUAPI].

2008 saw a journal paper on real-time RCU [DinakarGuniguntala2008IBMSysJ],
a history of how Linux changed RCU more than RCU changed Linux
[PaulEMcKenney2008RCUOSR], and a design overview of hierarchical RCU
[PaulEMcKenney2008HierarchicalRCU].

2009 introduced user-level RCU algorithms [PaulEMcKenney2009MaliciousURCU],
which Mathieu Desnoyers is now maintaining [MathieuDesnoyers2009URCU]
[MathieuDesnoyersPhD].  TINY_RCU [PaulEMcKenney2009BloatWatchRCU] made
its appearance, as did expedited RCU [PaulEMcKenney2009expeditedRCU].
The problem of resizable RCU-protected hash tables may now be on a path
to a solution [JoshTriplett2009RPHash].  A few academic researchers are now
using RCU to solve their parallel problems [HariKannan2009DynamicAnalysisRCU].

2010 produced a simpler preemptible-RCU implementation
based on TREE_RCU [PaulEMcKenney2010SimpleOptRCU], lockdep-RCU
[PaulEMcKenney2010LockdepRCU], another resizable RCU-protected hash
table [HerbertXu2010RCUResizeHash] (this one consuming more memory,
but allowing arbitrary changes in hash function, as required for DoS
avoidance in the networking code), realization of the 2009 RCU-protected
hash table with atomic node move [JoshTriplett2010RPHash], an update on
the RCU API [PaulEMcKenney2010RCUAPI].

2011 marked the inclusion of Nick Piggin's fully lockless dentry search
[LinusTorvalds2011Linux2:6:38:rc1:NPigginVFS], an RCU-protected red-black
tree using software transactional memory to protect concurrent updates
(strange, but true!) [PhilHoward2011RCUTMRBTree], yet another variant of
RCU-protected resizable hash tables [Triplett:2011:RPHash], the 3.0 RCU
trainwreck [PaulEMcKenney2011RCU3.0trainwreck], and Neil Brown's "Meet the
Lockers" LWN article [NeilBrown2011MeetTheLockers].  Some academic
work looked at debugging uses of RCU [Seyster:2011:RFA:2075416.2075425].

In 2012, Josh Triplett received his Ph.D. with his dissertation
covering RCU-protected resizable hash tables and the relationship
between memory barriers and read-side traversal order:  If the updater
is making changes in the opposite direction from the read-side traversal
order, the updater need only execute a memory-barrier instruction,
but if in the same direction, the updater needs to wait for a grace
period between the individual updates [JoshTriplettPhD].  Also in 2012,
after seventeen years of attempts, an RCU paper made it into a top-flight
academic journal, IEEE Transactions on Parallel and Distributed Systems
[MathieuDesnoyers2012URCU].  A group of researchers in Spain applied
user-level RCU to crowd simulation [GuillermoVigueras2012RCUCrowd], and
another group of researchers in Europe produced a formal description of
RCU based on separation logic [AlexeyGotsman2012VerifyGraceExtended],
which was published in the 2013 European Symposium on Programming
[AlexeyGotsman2013ESOPRCU].



Bibtex Entries

@article{Kung80
,author="H. T. Kung and Q. Lehman"
,title="Concurrent Manipulation of Binary Search Trees"
,Year="1980"
,Month="September"
,journal="ACM Transactions on Database Systems"
,volume="5"
,number="3"
,pages="354-382"
,annotation={
	Use garbage collector to clean up data after everyone is done with it.
	.
	Oldest use of something vaguely resembling RCU that I have found.
	http://portal.acm.org/citation.cfm?id=320619&dl=GUIDE,
	[Viewed December 3, 2007]
}
}

@techreport{Manber82
,author="Udi Manber and Richard E. Ladner"
,title="Concurrency Control in a Dynamic Search Structure"
,institution="Department of Computer Science, University of Washington"
,address="Seattle, Washington"
,year="1982"
,number="82-01-01"
,month="January"
,pages="28"
,annotation={
	.
	Superseded by Manber84.
	.
	Describes concurrent AVL tree implementation.  Uses a
	garbage-collection mechanism to handle concurrent use and deletion
	of nodes in the tree, but lacks the summary-of-execution-history
	concept of read-copy locking.
	.
	Keeps full list of processes that were active when a given
	node was to be deleted, and waits until all such processes have
	-terminated- before allowing this node to be reused.  This is
	not described in great detail -- one could imagine using process
	IDs for this if the ID space was large enough that overlapping
	never occurred.
	.
	This restriction makes this algorithm unsuitable for use in
	systems comprised of long-lived processes.  It also produces
	completely unacceptable overhead in systems with large numbers
	of processes.  Finally, it is specific to AVL trees.
	.
	Cites Kung80, so not an independent invention, but the first
	RCU-like usage that does not rely on an automatic garbage
	collector.
}
}

@article{Manber84
,author="Udi Manber and Richard E. Ladner"
,title="Concurrency Control in a Dynamic Search Structure"
,Year="1984"
,Month="September"
,journal="ACM Transactions on Database Systems"
,volume="9"
,number="3"
,pages="439-455"
,annotation={
	Describes concurrent AVL tree implementation.  Uses a
	garbage-collection mechanism to handle concurrent use and deletion
	of nodes in the tree, but lacks the summary-of-execution-history
	concept of read-copy locking.
	.
	Keeps full list of processes that were active when a given
	node was to be deleted, and waits until all such processes have
	-terminated- before allowing this node to be reused.  This is
	not described in great detail -- one could imagine using process
	IDs for this if the ID space was large enough that overlapping
	never occurred.
	.
	This restriction makes this algorithm unsuitable for use in
	systems comprised of long-lived processes.  It also produces
	completely unacceptable overhead in systems with large numbers
	of processes.  Finally, it is specific to AVL trees.
}
}

@Conference{RichardRashid87a
,Author="Richard Rashid and Avadis Tevanian and Michael Young and
David Golub and Robert Baron and David Black and William Bolosky and
Jonathan Chew"
,Title="Machine-Independent Virtual Memory Management for Paged
Uniprocessor and Multiprocessor Architectures"
,Booktitle="{2\textsuperscript{nd} Symposium on Architectural Support
for Programming Languages and Operating Systems}"
,Publisher="Association for Computing Machinery"
,Month="October"
,Year="1987"
,pages="31-39"
,Address="Palo Alto, CA"
,note="Available:
\url{http://www.cse.ucsc.edu/~randal/221/rashid-machvm.pdf}
[Viewed February 17, 2005]"
,annotation={
	Describes lazy TLB flush, where one waits for each CPU to pass
	through a scheduling-clock interrupt before reusing a given range
	of virtual address.  Does not describe how one determines that
	all CPUs have in fact taken such an interrupt, though there are
	no shortage of straightforward methods for accomplishing this.
	.
	Note that it does not make sense to just wait a fixed amount of
	time, since a given CPU might have interrupts disabled for an
	extended amount of time.
}
}

@article{BarbaraLiskov1988ArgusCACM
,author = {Barbara Liskov}
,title = {Distributed programming in {Argus}}
,journal = {Commun. ACM}
,volume = {31}
,number = {3}
,year = {1988}
,issn = {0001-0782}
,pages = {300--312}
,doi = {http://doi.acm.org/10.1145/42392.42399}
,publisher = {ACM}
,address = {New York, NY, USA}
,annotation={
	At the top of page 307: "Conflicts with deposits and withdrawals
	are necessary if the reported total is to be up to date.  They
	could be avoided by having total return a sum that is slightly
	out of date."  Relies on semantics -- approximate numerical
	values sometimes OK.
}
}

@techreport{Hennessy89
,author="James P. Hennessy and Damian L. Osisek and Joseph W. {Seigh II}"
,title="Passive Serialization in a Multitasking Environment"
,institution="US Patent and Trademark Office"
,address="Washington, DC"
,year="1989"
,number="US Patent 4,809,168 (lapsed)"
,month="February"
,pages="11"
}

@techreport{Pugh90
,author="William Pugh"
,title="Concurrent Maintenance of Skip Lists"
,institution="Institute of Advanced Computer Science Studies, Department of Computer Science, University of Maryland"
,address="College Park, Maryland"
,year="1990"
,number="CS-TR-2222.1"
,month="June"
,annotation={
	Concurrent access to skip lists.  Has both weak and strong search.
	Uses concept of ``garbage queue'', but has no real way of cleaning
	the garbage efficiently.
	.
	Appears to be an independent invention of an RCU-like mechanism.
}
}

# Was Adams91, see also syncrefs.bib.
@Book{Andrews91textbook
,Author="Gregory R. Andrews"
,title="Concurrent Programming, Principles, and Practices"
,Publisher="Benjamin Cummins"
,Year="1991"
,annotation={
	Has a few paragraphs describing ``chaotic relaxation'', a
	numerical analysis technique that allows multiprocessors to
	avoid synchronization overhead by using possibly-stale data.
	.
	Seems like this is descended from yet another independent
	invention of RCU-like function -- but this is restricted
	in that reclamation is not necessary.
}
}

@phdthesis{HMassalinPhD
,author="H. Massalin"
,title="Synthesis: An Efficient Implementation of Fundamental Operating
System Services"
,school="Columbia University"
,address="New York, NY"
,year="1992"
,annotation={
	Mondo optimizing compiler.
	Wait-free stuff.
	Good advice: defer work to avoid synchronization.  See page 90
		(PDF page 106), Section 5.4, fourth bullet point.
}
}

@unpublished{Jacobson93
,author="Van Jacobson"
,title="Avoid Read-Side Locking Via Delayed Free"
,year="1993"
,month="September"
,note="private communication"
,annotation={
	Use fixed time delay to approximate grace period.  Very simple,
	but subject to random memory corruption under heavy load.
	.
	Independent invention of RCU-like mechanism.
}
}

@Conference{AjuJohn95
,Author="Aju John"
,Title="Dynamic vnodes -- Design and Implementation"
,Booktitle="{USENIX Winter 1995}"
,Publisher="USENIX Association"
,Month="January"
,Year="1995"
,pages="11-23"
,Address="New Orleans, LA"
,note="Available:
\url{https://www.usenix.org/publications/library/proceedings/neworl/full_papers/john.a}
[Viewed October 1, 2010]"
,annotation={
	Age vnodes out of the cache, and have a fixed time set by a kernel
	parameter.  Not clear that all races were in fact correctly handled.
	Used a 20-minute time by default, which would most definitely not
	be suitable during DoS attacks or virus scans.
	.
	Apparently independent invention of RCU-like mechanism.
}
}

@conference{Pu95a
,Author = "Calton Pu and Tito Autrey and Andrew Black and Charles Consel and
Crispin Cowan and Jon Inouye and Lakshmi Kethana and Jonathan Walpole and
Ke Zhang"
,Title = "Optimistic Incremental Specialization: Streamlining a Commercial
,Operating System"
,Booktitle = "15\textsuperscript{th} ACM Symposium on
,Operating Systems Principles (SOSP'95)"
,address = "Copper Mountain, CO"
,month="December"
,year="1995"
,pages="314-321"
,annotation={
	Uses a replugger, but with a flag to signal when people are
	using the resource at hand.  Only one reader at a time.
}
}

@conference{Cowan96a
,Author = "Crispin Cowan and Tito Autrey and Charles Krasic and
,Calton Pu and Jonathan Walpole"
,Title = "Fast Concurrent Dynamic Linking for an Adaptive Operating System"
,Booktitle = "International Conference on Configurable Distributed Systems
(ICCDS'96)"
,address = "Annapolis, MD"
,month="May"
,year="1996"
,pages="108"
,isbn="0-8186-7395-8"
,annotation={
	Uses a replugger, but with a counter to signal when people are
	using the resource at hand.  Allows multiple readers.
}
}

@techreport{Slingwine95
,author="John D. Slingwine and Paul E. McKenney"
,title="Apparatus and Method for Achieving Reduced Overhead Mutual
Exclusion and Maintaining Coherency in a Multiprocessor System
Utilizing Execution History and Thread Monitoring"
,institution="US Patent and Trademark Office"
,address="Washington, DC"
,year="1995"
,number="US Patent 5,442,758"
,month="August"
,annotation={
	Describes the parallel RCU infrastructure.  Includes NUMA aspect
	(structure of bitmap can reflect bus structure of computer system).
	.
	Another independent invention of an RCU-like mechanism, but the
	"real" RCU this time!
}
}

@techreport{Slingwine97
,author="John D. Slingwine and Paul E. McKenney"
,title="Method for Maintaining Data Coherency Using Thread Activity
Summaries in a Multicomputer System"
,institution="US Patent and Trademark Office"
,address="Washington, DC"
,year="1997"
,number="US Patent 5,608,893"
,month="March"
,pages="19"
,annotation={
	Describes use of RCU to synchronize data between a pair of
	SMP/NUMA computer systems.
}
}

@techreport{Slingwine98
,author="John D. Slingwine and Paul E. McKenney"
,title="Apparatus and Method for Achieving Reduced Overhead Mutual
Exclusion and Maintaining Coherency in a Multiprocessor System
Utilizing Execution History and Thread Monitoring"
,institution="US Patent and Trademark Office"
,address="Washington, DC"
,year="1998"
,number="US Patent 5,727,209"
,month="March"
,annotation={
	Describes doing an atomic update by copying the data item and
	then substituting it into the data structure.
}
}

@Conference{McKenney98
,Author="Paul E. McKenney and John D. Slingwine"
,Title="Read-Copy Update: Using Execution History to Solve Concurrency
Problems"
,Booktitle="{Parallel and Distributed Computing and Systems}"
,Month="October"
,Year="1998"
,pages="509-518"
,Address="Las Vegas, NV"
,annotation={
	Describes and analyzes RCU mechanism in DYNIX/ptx.  Describes
	application to linked list update and log-buffer flushing.
	Defines 'quiescent state'.  Includes both measured and analytic
	evaluation.
	http://www.rdrop.com/users/paulmck/RCU/rclockpdcsproof.pdf
	[Viewed December 3, 2007]
}
}

@Conference{Gamsa99
,Author="Ben Gamsa and Orran Krieger and Jonathan Appavoo and Michael Stumm"
,Title="Tornado: Maximizing Locality and Concurrency in a Shared Memory
Multiprocessor Operating System"
,Booktitle="{Proceedings of the 3\textsuperscript{rd} Symposium on
Operating System Design and Implementation}"
,Month="February"
,Year="1999"
,pages="87-100"
,Address="New Orleans, LA"
,annotation={
	Use of RCU-like facility in K42/Tornado.  Another independent
	invention of RCU.
	See especially pages 7-9 (Section 5).
	http://www.usenix.org/events/osdi99/full_papers/gamsa/gamsa.pdf
	[Viewed August 30, 2006]
}
}

@unpublished{RustyRussell2000a
,Author="Rusty Russell"
,Title="Re: modular net drivers"
,month="June"
,year="2000"
,day="23"
,note="Available:
\url{http://oss.sgi.com/projects/netdev/archive/2000-06/msg00250.html}
[Viewed April 10, 2006]"
,annotation={
	Proto-RCU proposal from Phil Rumpf and Rusty Russell.
	Yet another independent invention of RCU.
	Outline of algorithm to unload modules...
	.
	Appeared on net-dev mailing list.
}
}

@unpublished{RustyRussell2000b
,Author="Rusty Russell"
,Title="Re: modular net drivers"
,month="June"
,year="2000"
,day="24"
,note="Available:
\url{http://oss.sgi.com/projects/netdev/archive/2000-06/msg00254.html}
[Viewed April 10, 2006]"
,annotation={
	Proto-RCU proposal from Phil Rumpf and Rusty Russell.
	.
	Appeared on net-dev mailing list.
}
}

@unpublished{McKenney01b
,Author="Paul E. McKenney and Dipankar Sarma"
,Title="Read-Copy Update Mutual Exclusion in {Linux}"
,month="February"
,year="2001"
,note="Available:
\url{http://lse.sourceforge.net/locking/rcu/rcupdate_doc.html}
[Viewed October 18, 2004]"
,annotation={
	Prototypical Linux documentation for RCU.
}
}

@techreport{Slingwine01
,author="John D. Slingwine and Paul E. McKenney"
,title="Apparatus and Method for Achieving Reduced Overhead Mutual
Exclusion and Maintaining Coherency in a Multiprocessor System
Utilizing Execution History and Thread Monitoring"
,institution="US Patent and Trademark Office"
,address="Washington, DC"
,year="2001"
,number="US Patent 6,219,690"
,month="April"
,annotation={
	'Change in mode' aspect of RCU.  Can be thought of as a lazy barrier.
}
}

@Conference{McKenney01a
,Author="Paul E. McKenney and Jonathan Appavoo and Andi Kleen and
Orran Krieger and Rusty Russell and Dipankar Sarma and Maneesh Soni"
,Title="Read-Copy Update"
,Booktitle="{Ottawa Linux Symposium}"
,Month="July"
,Year="2001"
,note="Available:
\url{https://kernel.org/doc/ols/2001/read-copy.pdf}
\url{http://www.rdrop.com/users/paulmck/RCU/rclock_OLS.2001.05.01c.pdf}
[Viewed June 23, 2004]"
,annotation={
	Described RCU, and presented some patches implementing and using
	it in the Linux kernel.
}
}

@unpublished{McKenney01f
,Author="Paul E. McKenney"
,Title="{RFC:} patch to allow lock-free traversal of lists with insertion"
,month="October"
,year="2001"
,note="Available:
\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=100259266316456&w=2}
[Viewed June 23, 2004]"
,annotation={
	Memory-barrier and Alpha thread.  100 messages, not too bad...
}
}

@unpublished{Spraul01
,Author="Manfred Spraul"
,Title="Re: {RFC:} patch to allow lock-free traversal of lists with insertion"
,month="October"
,year="2001"
,note="Available:
\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=100264675012867&w=2}
[Viewed June 23, 2004]"
,annotation={
	Suggested burying memory barriers in Linux's list-manipulation
	primitives.
}
}

@unpublished{LinusTorvalds2001a
,Author="Linus Torvalds"
,Title="{Re:} {[Lse-tech]} {Re:} {RFC:} patch to allow lock-free traversal of lists with insertion"
,month="October"
,year="2001"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed August 21, 2004]"
,annotation={
}
}

@unpublished{Blanchard02a
,Author="Anton Blanchard"
,Title="some RCU dcache and ratcache results"
,month="March"
,year="2002"
,note="Available:
\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=101637107412972&w=2}
[Viewed October 18, 2004]"
}

@conference{Michael02b
,author="Maged M. Michael"
,title="High Performance Dynamic Lock-Free Hash Tables and List-Based Sets"
,Year="2002"
,Month="August"
,booktitle="{Proceedings of the 14\textsuperscript{th} Annual ACM
Symposium on Parallel
Algorithms and Architecture}"
,pages="73-82"
,annotation={
Like the title says...
}
}

@Conference{Linder02a
,Author="Hanna Linder and Dipankar Sarma and Maneesh Soni"
,Title="Scalability of the Directory Entry Cache"
,Booktitle="{Ottawa Linux Symposium}"
,Month="June"
,Year="2002"
,pages="289-300"
,annotation={
	Measured scalability of Linux 2.4 kernel's directory-entry cache
	(dcache), and measured some scalability enhancements.
}
}

@Conference{McKenney02a
,Author="Paul E. McKenney and Dipankar Sarma and
Andrea Arcangeli and Andi Kleen and Orran Krieger and Rusty Russell"
,Title="Read-Copy Update"
,Booktitle="{Ottawa Linux Symposium}"
,Month="June"
,Year="2002"
,pages="338-367"
,note="Available:
\url{http://www.linux.org.uk/~ajh/ols2002_proceedings.pdf.gz}
[Viewed June 23, 2004]"
,annotation={
	Presented and compared a number of RCU implementations for the
	Linux kernel.
}
}

@unpublished{Sarma02a
,Author="Dipankar Sarma"
,Title="specweb99: dcache scalability results"
,month="July"
,year="2002"
,note="Available:
\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=102645767914212&w=2}
[Viewed June 23, 2004]"
,annotation={
	Compare fastwalk and RCU for dcache.  RCU won.
}
}

@unpublished{Barbieri02
,Author="Luca Barbieri"
,Title="Re: {[PATCH]} Initial support for struct {vfs\_cred}"
,month="August"
,year="2002"
,note="Available:
\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=103082050621241&w=2}
[Viewed: June 23, 2004]"
,annotation={
	Suggested RCU for vfs\_shared\_cred.
}
}

@conference{Michael02a
,author="Maged M. Michael"
,title="Safe Memory Reclamation for Dynamic Lock-Free Objects Using Atomic
Reads and Writes"
,Year="2002"
,Month="August"
,booktitle="{Proceedings of the 21\textsuperscript{st} Annual ACM
Symposium on Principles of Distributed Computing}"
,pages="21-30"
,annotation={
	Each thread keeps an array of pointers to items that it is
	currently referencing.	Sort of an inside-out garbage collection
	mechanism, but one that requires the accessing code to explicitly
	state its needs.  Also requires read-side memory barriers on
	most architectures.
}
}

@unpublished{Dickins02a
,author="Hugh Dickins"
,title="Use RCU for System-V IPC"
,year="2002"
,month="October"
,note="private communication"
}

@InProceedings{HerlihyLM02
,author={Maurice Herlihy and Victor Luchangco and Mark Moir}
,title="The Repeat Offender Problem: A Mechanism for Supporting Dynamic-Sized,
Lock-Free Data Structures"
,booktitle={Proceedings of 16\textsuperscript{th} International
Symposium on Distributed Computing}
,year=2002
,month="October"
,pages="339-353"
}

@unpublished{Sarma02b
,Author="Dipankar Sarma"
,Title="Some dcache\_rcu benchmark numbers"
,month="October"
,year="2002"
,note="Available:
\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=103462075416638&w=2}
[Viewed June 23, 2004]"
,annotation={
	Performance of dcache RCU on kernbench for 16x NUMA-Q and 1x,
	2x, and 4x systems.  RCU does no harm, and helps on 16x.
}
}

@unpublished{MingmingCao2002IPCRCU
,Author="Mingming Cao"
,Title="[PATCH]updated ipc lock patch"
,month="October"
,year="2002"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed February 15, 2014]"
,annotation={
	Mingming Cao's patch to introduce RCU to SysV IPC.
}
}

@unpublished{LinusTorvalds2003a
,Author="Linus Torvalds"
,Title="Re: {[PATCH]} small fixes in brlock.h"
,month="March"
,year="2003"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed March 13, 2006]"
,annotation={
	Linus suggests replacing brlock with RCU and/or seqlocks:
	.
	'It's entirely possible that the current user could be replaced
	by RCU and/or seqlocks, and we could get rid of brlocks entirely.'
	.
	Stephen Hemminger responds by replacing them with RCU.
}
}

@article{Appavoo03a
,author="J. Appavoo and K. Hui and C. A. N. Soules and R. W. Wisniewski and
D. M. {Da Silva} and O. Krieger and M. A. Auslander and D. J. Edelsohn and
B. Gamsa and G. R. Ganger and P. McKenney and M. Ostrowski and
B. Rosenburg and M. Stumm and J. Xenidis"
,title="Enabling Autonomic Behavior in Systems Software With Hot Swapping"
,Year="2003"
,Month="January"
,journal="IBM Systems Journal"
,volume="42"
,number="1"
,pages="60-76"
,annotation={
	Use of RCU to enable hot-swapping for autonomic behavior in K42.
}
}

@unpublished{Seigh03
,author="Joseph W. {Seigh II}"
,title="Read Copy Update"
,Year="2003"
,Month="March"
,note="email correspondence"
,annotation={
	Described the relationship of the VM/XA passive serialization to RCU.
}
}

@Conference{Arcangeli03
,Author="Andrea Arcangeli and Mingming Cao and Paul E. McKenney and
Dipankar Sarma"
,Title="Using Read-Copy Update Techniques for {System V IPC} in the
{Linux} 2.5 Kernel"
,Booktitle="Proceedings of the 2003 USENIX Annual Technical Conference
(FREENIX Track)"
,Publisher="USENIX Association"
,year="2003"
,month="June"
,pages="297-310"
,annotation={
	Compared updated RCU implementations for the Linux kernel, and
	described System V IPC use of RCU, including order-of-magnitude
	performance improvements.
	http://www.rdrop.com/users/paulmck/RCU/rcu.FREENIX.2003.06.14.pdf
}
}

@Conference{Soules03a
,Author="Craig A. N. Soules and Jonathan Appavoo and Kevin Hui and
Dilma {Da Silva} and Gregory R. Ganger and Orran Krieger and
Michael Stumm and Robert W. Wisniewski and Marc Auslander and
Michal Ostrowski and Bryan Rosenburg and Jimi Xenidis"
,Title="System Support for Online Reconfiguration"
,Booktitle="Proceedings of the 2003 USENIX Annual Technical Conference"
,Publisher="USENIX Association"
,year="2003"
,month="June"
,pages="141-154"
}

@article{McKenney03a
,author="Paul E. McKenney"
,title="Using {RCU} in the {Linux} 2.5 Kernel"
,Year="2003"
,Month="October"
,journal="Linux Journal"
,volume="1"
,number="114"
,pages="18-26"
,note="Available:
\url{http://www.linuxjournal.com/article/6993}
[Viewed November 14, 2007]"
,annotation={
	Reader-friendly intro to RCU, with the infamous old-man-and-brat
	cartoon.
}
}

@unpublished{Sarma03a
,Author="Dipankar Sarma"
,Title="RCU low latency patches"
,month="December"
,year="2003"
,note="Message ID: [email protected]"
,annotation={
	dipankar/ct.2004.03.27/RCUll.2003.12.22.patch
}
}

@techreport{Friedberg03a
,author="Stuart A. Friedberg"
,title="Lock-Free Wild Card Search Data Structure and Method"
,institution="US Patent and Trademark Office"
,address="Washington, DC"
,year="2003"
,number="US Patent 6,662,184"
,month="December"
,pages="112"
,annotation={
	Applies RCU to a wildcard-search Patricia tree in order to permit
	synchronization-free lookup.  RCU is used to retain removed nodes
	for a grace period before freeing them.
}
}

@article{McKenney04a
,author="Paul E. McKenney and Dipankar Sarma and Maneesh Soni"
,title="Scaling dcache with {RCU}"
,Year="2004"
,Month="January"
,journal="Linux Journal"
,volume="1"
,number="118"
,pages="38-46"
,annotation={
	Reader friendly intro to dcache and RCU.
	http://www.linuxjournal.com/node/7124
	[Viewed December 26, 2010]
}
}

@Conference{McKenney04b
,Author="Paul E. McKenney"
,Title="{RCU} vs. Locking Performance on Different {CPUs}"
,Booktitle="{linux.conf.au}"
,Month="January"
,Year="2004"
,Address="Adelaide, Australia"
,note="Available:
\url{http://www.linux.org.au/conf/2004/abstracts.html#90}
\url{http://www.rdrop.com/users/paulmck/RCU/lockperf.2004.01.17a.pdf}
[Viewed June 23, 2004]"
,annotation={
	Compares performance of RCU to that of other locking primitives
	over a number of CPUs (x86, Opteron, Itanium, and PPC).
}
}

@unpublished{Sarma04a
,Author="Dipankar Sarma"
,Title="{[PATCH]} {RCU} for low latency (experimental)"
,month="March"
,year="2004"
,note="\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=108003746402892&w=2}"
,annotation={
	Head of thread: dipankar/2004.03.23/rcu-low-lat.1.patch
}
}

@unpublished{Sarma04b
,Author="Dipankar Sarma"
,Title="Re: {[PATCH]} {RCU} for low latency (experimental)"
,month="March"
,year="2004"
,note="\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=108016474829546&w=2}"
,annotation={
	dipankar/rcuth.2004.03.24/rcu-throttle.patch
}
}

@unpublished{Spraul04a
,Author="Manfred Spraul"
,Title="[RFC] 0/5 rcu lock update"
,month="May"
,year="2004"
,note="Available:
\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=108546407726602&w=2}
[Viewed June 23, 2004]"
,annotation={
	Hierarchical-bitmap patch for RCU infrastructure.
}
}

@unpublished{Steiner04a
,Author="Jack Steiner"
,Title="Re: [Lse-tech] [RFC, PATCH] 1/5 rcu lock update:
Add per-cpu batch counter"
,month="May"
,year="2004"
,note="Available:
\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=108551764515332&w=2}
[Viewed June 23, 2004]"
,annotation={
	RCU runs reasonably on a 512-CPU SGI using Manfred Spraul's patches,
	which may be found at:
	https://lore.kernel.org/r/[email protected] (split vars into cachelines)
	https://lore.kernel.org/r/[email protected] (cpu_quiet() patch)
	https://lore.kernel.org/r/[email protected] (0/5)
	https://lore.kernel.org/r/[email protected] (1/5)
		https://lore.kernel.org/r/[email protected] (works for Jack)
	https://lore.kernel.org/r/[email protected] (2/5)
	https://lore.kernel.org/r/[email protected] (3/5)
	https://lore.kernel.org/r/[email protected] (4/5)
	https://lore.kernel.org/r/[email protected] (5/5)
}
}

@Conference{Sarma04c
,Author="Dipankar Sarma and Paul E. McKenney"
,Title="Making {RCU} Safe for Deep Sub-Millisecond Response
Realtime Applications"
,Booktitle="Proceedings of the 2004 USENIX Annual Technical Conference
(FREENIX Track)"
,Publisher="USENIX Association"
,year="2004"
,month="June"
,pages="182-191"
,annotation={
	Describes and compares a number of modifications to the Linux RCU
	implementation that make it friendly to realtime applications.
	https://www.usenix.org/conference/2004-usenix-annual-technical-conference/making-rcu-safe-deep-sub-millisecond-response
	[Viewed July 26, 2012]
}
}

@article{MagedMichael04a
,author="Maged M. Michael"
,title="Hazard Pointers: Safe Memory Reclamation for Lock-Free Objects"
,Year="2004"
,Month="June"
,journal="IEEE Transactions on Parallel and Distributed Systems"
,volume="15"
,number="6"
,pages="491-504"
,url="Available:
\url{http://www.research.ibm.com/people/m/michael/ieeetpds-2004.pdf}
[Viewed March 1, 2005]"
,annotation={
	New canonical hazard-pointer citation.
}
}

@phdthesis{PaulEdwardMcKenneyPhD
,author="Paul E. McKenney"
,title="Exploiting Deferred Destruction:
An Analysis of Read-Copy-Update Techniques
in Operating System Kernels"
,school="OGI School of Science and Engineering at
Oregon Health and Sciences University"
,year="2004"
,annotation={
	Describes RCU implementations and presents design patterns
	corresponding to common uses of RCU in several operating-system
	kernels.
	http://www.rdrop.com/users/paulmck/RCU/RCUdissertation.2004.07.14e1.pdf
	[Viewed October 15, 2004]
}
}

@unpublished{PaulEMcKenney2004rcu:dereference
,Author="Dipankar Sarma"
,Title="{Re: RCU : Abstracted RCU dereferencing [5/5]}"
,month="August"
,year="2004"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed June 8, 2010]"
,annotation={
	Introduce rcu_dereference().
}
}

@unpublished{JimHouston04a
,Author="Jim Houston"
,Title="{[RFC\&PATCH] Alternative {RCU} implementation}"
,month="August"
,year="2004"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed February 17, 2005]"
,annotation={
	Uses active code in rcu_read_lock() and rcu_read_unlock() to
	make RCU happen, allowing RCU to function on CPUs that do not
	receive a scheduling-clock interrupt.
}
}

@unpublished{TomHart04a
,Author="Thomas E. Hart"
,Title="Master's Thesis: Applying Lock-free Techniques to the {Linux} Kernel"
,month="October"
,year="2004"
,note="Available:
\url{http://www.cs.toronto.edu/~tomhart/masters_thesis.html}
[Viewed October 15, 2004]"
,annotation={
	Proposes comparing RCU to lock-free methods for the Linux kernel.
}
}

@unpublished{Vaddagiri04a
,Author="Srivatsa Vaddagiri"
,Title="Subject: [RFC] Use RCU for tcp\_ehash lookup"
,month="October"
,year="2004"
,note="Available:
\url{http://marc.theaimsgroup.com/?t=109395731700004&r=1&w=2}
[Viewed October 18, 2004]"
,annotation={
	Srivatsa's RCU patch for tcp_ehash lookup.
}
}

@unpublished{Thirumalai04a
,Author="Ravikiran Thirumalai"
,Title="Subject: [patchset] Lockfree fd lookup 0 of 5"
,month="October"
,year="2004"
,note="Available:
\url{http://marc.theaimsgroup.com/?t=109144217400003&r=1&w=2}
[Viewed October 18, 2004]"
,annotation={
	Ravikiran's lockfree FD patch.
}
}

@unpublished{Thirumalai04b
,Author="Ravikiran Thirumalai"
,Title="Subject: Re: [patchset] Lockfree fd lookup 0 of 5"
,month="October"
,year="2004"
,note="Available:
\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=109152521410459&w=2}
[Viewed October 18, 2004]"
,annotation={
	Ravikiran's lockfree FD patch.
}
}

@unpublished{PaulEMcKenney2004rcu:assign:pointer
,Author="Paul E. McKenney"
,Title="{[PATCH 1/3] RCU: \url{rcu_assign_pointer()} removal of memory barriers}"
,month="October"
,year="2004"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed June 8, 2010]"
,annotation={
	Introduce rcu_assign_pointer().
}
}

@unpublished{JamesMorris04a
,Author="James Morris"
,Title="{[PATCH 2/3] SELinux} scalability - convert {AVC} to {RCU}"
,day="15"
,month="November"
,year="2004"
,note="\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=110054979416004&w=2}"
,annotation={
	James Morris posts Kaigai Kohei's patch to LKML.
	[Viewed December 10, 2004]
	Kaigai's patch is at https://lore.kernel.org/r/[email protected]
}
}

@unpublished{JamesMorris04b
,Author="James Morris"
,Title="Recent Developments in {SELinux} Kernel Performance"
,month="December"
,year="2004"
,note="Available:
\url{http://www.livejournal.com/users/james_morris/2153.html}
[Viewed December 10, 2004]"
,annotation={
	RCU helps SELinux performance.  ;-)  Made LWN.
}
}

@unpublished{PaulMcKenney2005RCUSemantics
,Author="Paul E. McKenney and Jonathan Walpole"
,Title="{RCU} Semantics: A First Attempt"
,month="January"
,year="2005"
,day="30"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/RCU/rcu-semantics.2005.01.30a.pdf}
[Viewed December 6, 2009]"
,annotation={
	Early derivation of RCU semantics.
}
}

@unpublished{PaulMcKenney2005e
,Author="Paul E. McKenney"
,Title="Real-Time Preemption and {RCU}"
,month="March"
,year="2005"
,day="17"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed September 5, 2005]"
,annotation={
	First posting showing how RCU can be safely adapted for
	preemptible RCU read side critical sections.
}
}

@unpublished{EsbenNeilsen2005a
,Author="Esben Neilsen"
,Title="Re: Real-Time Preemption and {RCU}"
,month="March"
,year="2005"
,day="18"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed March 30, 2006]"
,annotation={
	Esben Neilsen suggests read-side suppression of grace-period
	processing for crude-but-workable realtime RCU.  The downside
	is indefinite grace periods...  But this is OK for experimentation
	and testing.
}
}

@unpublished{TomHart05a
,Author="Thomas E. Hart and Paul E. McKenney and Angela Demke Brown"
,Title="Efficient Memory Reclamation is Necessary for Fast Lock-Free
Data Structures"
,month="March"
,year="2005"
,note="Available:
\url{ftp://ftp.cs.toronto.edu/csrg-technical-reports/515/}
[Viewed March 4, 2005]"
,annotation={
	Comparison of RCU, QBSR, and EBSR.  RCU wins for read-mostly
	workloads.  ;-)
}
}

@unpublished{JonCorbet2005DeprecateSyncKernel
,Author="Jonathan Corbet"
,Title="API change: synchronize_kernel() deprecated"
,month="May"
,day="3"
,year="2005"
,note="Available:
\url{http://lwn.net/Articles/134484/}
[Viewed May 3, 2005]"
,annotation={
	Jon Corbet describes deprecation of synchronize_kernel()
	in favor of synchronize_rcu() and synchronize_sched().
}
}

@unpublished{PaulMcKenney05a
,Author="Paul E. McKenney"
,Title="{[RFC]} {RCU} and {CONFIG\_PREEMPT\_RT} progress"
,month="May"
,year="2005"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed May 13, 2005]"
,annotation={
	First publication of working lock-based deferred free patches
	for the CONFIG_PREEMPT_RT environment.
}
}

@conference{PaulMcKenney05b
,Author="Paul E. McKenney and Dipankar Sarma"
,Title="Towards Hard Realtime Response from the {Linux} Kernel on {SMP} Hardware"
,Booktitle="linux.conf.au 2005"
,month="April"
,year="2005"
,address="Canberra, Australia"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/RCU/realtimeRCU.2005.04.23a.pdf}
[Viewed May 13, 2005]"
,annotation={
	Realtime turns into making RCU yet more realtime friendly.
	http://lca2005.linux.org.au/Papers/Paul%20McKenney/Towards%20Hard%20Realtime%20Response%20from%20the%20Linux%20Kernel/LKS.2005.04.22a.pdf
}
}

@unpublished{PaulEMcKenneyHomePage
,Author="Paul E. McKenney"
,Title="{Paul} {E.} {McKenney}"
,month="May"
,year="2005"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/}
[Viewed May 25, 2005]"
,annotation={
	Paul McKenney's home page.
}
}

@unpublished{PaulEMcKenneyRCUPage
,Author="Paul E. McKenney"
,Title="Read-Copy Update {(RCU)}"
,month="May"
,year="2005"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/RCU}
[Viewed May 25, 2005]"
,annotation={
	Paul McKenney's RCU page.
}
}

@unpublished{JosephSeigh2005a
,Author="Joseph Seigh"
,Title="{RCU}+{SMR} (hazard pointers)"
,month="July"
,year="2005"
,note="Personal communication"
,annotation={
	Joe Seigh announcing his atomic-ptr-plus project.
	http://sourceforge.net/projects/atomic-ptr-plus/
}
}

@unpublished{JosephSeigh2005b
,Author="Joseph Seigh"
,Title="Lock-free synchronization primitives"
,month="July"
,day="6"
,year="2005"
,note="Available:
\url{http://sourceforge.net/projects/atomic-ptr-plus/}
[Viewed August 8, 2005]"
,annotation={
	Joe Seigh's atomic-ptr-plus project.
}
}

@unpublished{PaulMcKenney2005c
,Author="Paul E.McKenney"
,Title="{[RFC,PATCH] RCU} and {CONFIG\_PREEMPT\_RT} sane patch"
,month="August"
,day="1"
,year="2005"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed March 14, 2006]"
,annotation={
	First operating counter-based realtime RCU patch posted to LKML.
}
}

@unpublished{PaulMcKenney2005d
,Author="Paul E. McKenney"
,Title="Re: [Fwd: Re: [patch] Real-Time Preemption, -RT-2.6.13-rc4-V0.7.52-01]"
,month="August"
,day="8"
,year="2005"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed March 14, 2006]"
,annotation={
	First operating counter-based realtime RCU patch posted to LKML,
	but fixed so that various unusual combinations of configuration
	parameters all function properly.
}
}

@unpublished{PaulMcKenney2005rcutorture
,Author="Paul E. McKenney"
,Title="{[PATCH]} {RCU} torture testing"
,month="October"
,day="1"
,year="2005"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed March 14, 2006]"
,annotation={
	First rcutorture patch.
}
}

@unpublished{DavidSMiller2006HashedLocking
,Author="David S. Miller"
,Title="Re: [{PATCH}, {RFC}] {RCU} : {OOM} avoidance and lower latency"
,month="January"
,day="6"
,year="2006"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed February 29, 2012]"
,annotation={
	David Miller's view on hashed arrays of locks: used to really
	like it, but time he saw an opportunity for this technique,
	something else always proved superior.  Partitioning or RCU.  ;-)
}
}

@conference{ThomasEHart2006a
,Author="Thomas E. Hart and Paul E. McKenney and Angela Demke Brown"
,Title="Making Lockless Synchronization Fast: Performance Implications
of Memory Reclamation"
,Booktitle="20\textsuperscript{th} {IEEE} International Parallel and
Distributed Processing Symposium"
,month="April"
,year="2006"
,day="25-29"
,address="Rhodes, Greece"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/RCU/hart_ipdps06.pdf}
[Viewed April 28, 2008]"
,annotation={
	Compares QSBR, HPBR, EBR, and lock-free reference counting.
	http://www.cs.toronto.edu/~tomhart/perflab/ipdps06.tgz
}
}

@unpublished{NickPiggin2006radixtree
,Author="Nick Piggin"
,Title="[patch 3/3] radix-tree: {RCU} lockless readside"
,month="June"
,day="20"
,year="2006"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed March 25, 2008]"
,annotation={
	RCU-protected radix tree.
}
}

@Conference{PaulEMcKenney2006b
,Author="Paul E. McKenney and Dipankar Sarma and Ingo Molnar and
Suparna Bhattacharya"
,Title="Extending {RCU} for Realtime and Embedded Workloads"
,Booktitle="{Ottawa Linux Symposium}"
,Month="July"
,Year="2006"
,pages="v2 123-138"
,note="Available:
\url{https://kernel.org/doc/ols/2006/ols2006v2-pages-131-146.pdf}
\url{http://www.rdrop.com/users/paulmck/RCU/OLSrtRCU.2006.08.11a.pdf}
[Viewed January 1, 2007]"
,annotation={
	Described how to improve the -rt implementation of realtime RCU.
}
}

@unpublished{WikipediaRCU
,Author="Paul E. McKenney and Chris Purcell and Algae and Ben Schumin and
Gaius Cornelius and Qwertyus and Neil Conway and Sbw and Blainster and
Canis Rufus and Zoicon5 and Anome and Hal Eisen"
,Title="Read-Copy Update"
,month="July"
,day="8"
,year="2006"
,note="\url{https://en.wikipedia.org/wiki/Read-copy-update}"
,annotation={
	Wikipedia RCU page as of July 8 2006.
	[Viewed August 21, 2006]
}
}

@Conference{NickPiggin2006LocklessPageCache
,Author="Nick Piggin"
,Title="A Lockless Pagecache in Linux---Introduction, Progress, Performance"
,Booktitle="{Ottawa Linux Symposium}"
,Month="July"
,Year="2006"
,pages="v2 249-254"
,note="Available:
\url{https://kernel.org/doc/ols/2006/ols2006v2-pages-249-262.pdf}
[Viewed January 11, 2009]"
,annotation={
	Uses RCU-protected radix tree for a lockless page cache.
}
}

@unpublished{PaulEMcKenney2006c
,Author="Paul E. McKenney"
,Title="Sleepable {RCU}"
,month="October"
,day="9"
,year="2006"
,note="Available:
\url{http://lwn.net/Articles/202847/}
Revised:
\url{http://www.rdrop.com/users/paulmck/RCU/srcu.2007.01.14a.pdf}
[Viewed August 21, 2006]"
,annotation={
	LWN article introducing SRCU.
}
}

@unpublished{RobertOlsson2006a
,Author="Robert Olsson and Stefan Nilsson"
,Title="{TRASH}: A dynamic {LC}-trie and hash data structure"
,month="August"
,day="18"
,year="2006"
,note="\url{http://www.nada.kth.se/~snilsson/publications/TRASH/trash.pdf}"
,annotation={
	RCU-protected dynamic trie-hash combination.
	[Viewed March 4, 2011]
}
}

@unpublished{ChristophHellwig2006RCU2SRCU
,Author="Christoph Hellwig"
,Title="Re: {[-mm PATCH 1/4]} {RCU}: split classic rcu"
,month="September"
,day="28"
,year="2006"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed March 27, 2008]"
}

@unpublished{PaulEMcKenneyRCUusagePage
,Author="Paul E. McKenney"
,Title="{RCU} {Linux} Usage"
,month="October"
,year="2006"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/RCU/linuxusage.html}
[Viewed January 14, 2007]"
,annotation={
	Paul McKenney's RCU page showing graphs plotting Linux-kernel
	usage of RCU.
}
}

@unpublished{PaulEMcKenneyRCUusageRawDataPage
,Author="Paul E. McKenney"
,Title="Read-Copy Update {(RCU)} Usage in {Linux} Kernel"
,month="October"
,year="2006"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/RCU/linuxusage/rculocktab.html}
[Viewed January 14, 2007]"
,annotation={
	Paul McKenney's RCU page showing Linux usage of RCU in tabular
	form, with links to corresponding cscope databases.
}
}

@unpublished{GauthamShenoy2006RCUrwlock
,Author="Gautham R. Shenoy"
,Title="[PATCH 4/5] lock\_cpu\_hotplug: Redesign - Lightweight implementation of lock\_cpu\_hotplug"
,month="October"
,year="2006"
,day=26
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed January 26, 2009]"
,annotation={
	RCU-based reader-writer lock that allows readers to proceed with
	no memory barriers or atomic instruction in absence of writers.
	If writer do show up, readers must of course wait as required by
	the semantics of reader-writer locking.  This is a recursive
	lock.
}
}

@unpublished{JensAxboe2006SlowSRCU
,Author="Jens Axboe"
,Title="Re: [patch] cpufreq: mark \url{cpufreq_tsc()} as
\url{core_initcall_sync}"
,month="November"
,year="2006"
,day=17
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed May 28, 2007]"
,annotation={
	SRCU's grace periods are too slow for Jens, even after a
	factor-of-three speedup.
	Sped-up version of SRCU at https://lore.kernel.org/r/[email protected].
}
}

@unpublished{OlegNesterov2006QRCU
,Author="Oleg Nesterov"
,Title="Re: [patch] cpufreq: mark {\tt cpufreq\_tsc()} as
{\tt core\_initcall\_sync}"
,month="November"
,year="2006"
,day=19
,note="Available:
\url{https://lore.kernel.org/r/20061119190027.GA3676@oleg}
[Viewed May 28, 2007]"
,annotation={
	First cut of QRCU.  Expanded/corrected versions followed.
	Used to be OlegNesterov2007QRCU, now time-corrected.
}
}

@unpublished{OlegNesterov2006aQRCU
,Author="Oleg Nesterov"
,Title="Re: [RFC, PATCH 1/2] qrcu: {"quick"} srcu implementation"
,month="November"
,year="2006"
,day=30
,note="Available:
\url{https://lore.kernel.org/r/20061130015714.GC1350@oleg}
[Viewed November 26, 2008]"
,annotation={
	Expanded/corrected version of QRCU.
	Used to be OlegNesterov2007aQRCU, now time-corrected.
}
}

@unpublished{EvgeniyPolyakov2006RCUslowdown
,Author="Evgeniy Polyakov"
,Title="Badness in postponing work"
,month="December"
,year="2006"
,day=05
,note="Available:
\url{http://www.ioremap.net/node/41}
[Viewed October 28, 2008]"
,annotation={
	Using RCU as a pure delay leads to a 2.5x slowdown in skbs in
	the Linux kernel.
}
}

@inproceedings{ChrisMatthews2006ClusteredObjectsRCU
,author = {Matthews, Chris and Coady, Yvonne and Appavoo, Jonathan}
,title = {Portability events: a programming model for scalable system infrastructures}
,booktitle = {PLOS '06: Proceedings of the 3rd workshop on Programming languages and operating systems}
,year = {2006}
,isbn = {1-59593-577-0}
,pages = {11}
,location = {San Jose, California}
,doi = {http://doi.acm.org/10.1145/1215995.1216006}
,publisher = {ACM}
,address = {New York, NY, USA}
,annotation={
	Uses K42's RCU-like functionality to manage clustered-object
	lifetimes.
}
}

@article{DilmaDaSilva2006K42
,author = {Silva, Dilma Da and Krieger, Orran and Wisniewski, Robert W. and Waterland, Amos and Tam, David and Baumann, Andrew}
,title = {K42: an infrastructure for operating system research}
,journal = {SIGOPS Oper. Syst. Rev.}
,volume = {40}
,number = {2}
,year = {2006}
,issn = {0163-5980}
,pages = {34--42}
,doi = {http://doi.acm.org/10.1145/1131322.1131333}
,publisher = {ACM}
,address = {New York, NY, USA}
,annotation={
	Describes relationship of K42 generations to RCU.
}
}

# CoreyMinyard2007list_splice_rcu
@unpublished{CoreyMinyard2007list:splice:rcu
,Author="Corey Minyard and Paul E. McKenney"
,Title="{[PATCH]} add an {RCU} version of list splicing"
,month="January"
,year="2007"
,day=3
,note="Available:
\url{https://lore.kernel.org/r/20070103152738.GA16063@localdomain}
[Viewed May 28, 2007]"
,annotation={
	Patch for list_splice_rcu().
}
}

@unpublished{PaulEMcKenney2007rcubarrier
,Author="Paul E. McKenney"
,Title="{RCU} and Unloadable Modules"
,month="January"
,day="14"
,year="2007"
,note="Available:
\url{http://lwn.net/Articles/217484/}
[Viewed November 22, 2007]"
,annotation={
	LWN article introducing the rcu_barrier() primitive.
}
}

@unpublished{PeterZijlstra2007SyncBarrier
,Author="Peter Zijlstra and Ingo Molnar"
,Title="{[PATCH 3/7]} barrier: a scalable synchonisation barrier"
,month="January"
,year="2007"
,day=28
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed March 27, 2008]"
,annotation={
	RCU-like implementation for frequent updaters and rare readers(!).
	Subsumed into QRCU.  Maybe...
}
}

@unpublished{PaulEMcKenney2007BoostRCU
,Author="Paul E. McKenney"
,Title="Priority-Boosting {RCU} Read-Side Critical Sections"
,month="February"
,day="5"
,year="2007"
,note="\url{http://lwn.net/Articles/220677/}"
,annotation={
	LWN article introducing RCU priority boosting.
	Revised:
	http://www.rdrop.com/users/paulmck/RCU/RCUbooststate.2007.04.16a.pdf
	[Viewed September 7, 2007]
}
}

@unpublished{PaulMcKenney2007QRCUpatch
,Author="Paul E. McKenney"
,Title="{[PATCH]} {QRCU} with lockless fastpath"
,month="February"
,year="2007"
,day=24
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed March 27, 2008]"
,annotation={
	Patch for QRCU supplying lock-free fast path.
}
}

@article{JonathanAppavoo2007K42RCU
,author = {Appavoo, Jonathan and Silva, Dilma Da and Krieger, Orran and Auslander, Marc and Ostrowski, Michal and Rosenburg, Bryan and Waterland, Amos and Wisniewski, Robert W. and Xenidis, Jimi and Stumm, Michael and Soares, Livio}
,title = {Experience distributing objects in an SMMP OS}
,journal = {ACM Trans. Comput. Syst.}
,volume = {25}
,number = {3}
,year = {2007}
,issn = {0734-2071}
,pages = {6/1--6/52}
,doi = {http://doi.acm.org/10.1145/1275517.1275518}
,publisher = {ACM}
,address = {New York, NY, USA}
,annotation={
	Role of RCU in K42.
}
}

@conference{RobertOlsson2007Trash
,Author="Robert Olsson and Stefan Nilsson"
,Title="{TRASH}: A dynamic {LC}-trie and hash data structure"
,booktitle="Workshop on High Performance Switching and Routing (HPSR'07)"
,month="May"
,year="2007"
,note="Available:
\url{http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=4281239}
[Viewed October 1, 2010]"
,annotation={
	RCU-protected dynamic trie-hash combination.
}
}

@conference{PeterZijlstra2007ConcurrentPagecacheRCU
,Author="Peter Zijlstra"
,Title="Concurrent Pagecache"
,Booktitle="Linux Symposium"
,month="June"
,year="2007"
,address="Ottawa, Canada"
,note="Available:
\url{http://ols.108.redhat.com/2007/Reprints/zijlstra-Reprint.pdf}
[Viewed April 14, 2008]"
,annotation={
	Page-cache modifications permitting RCU readers and concurrent
	updates.
}
}

@unpublished{PaulEMcKenney2007whatisRCU
,Author="Paul E. McKenney"
,Title="What is {RCU}?"
,year="2007"
,month="07"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/RCU/whatisRCU.html}
[Viewed July 6, 2007]"
,annotation={
	Describes RCU in Linux kernel.
}
}

@unpublished{PaulEMcKenney2007QRCUspin
,Author="Paul E. McKenney"
,Title="Using {Promela} and {Spin} to verify parallel algorithms"
,month="August"
,day="1"
,year="2007"
,note="Available:
\url{http://lwn.net/Articles/243851/}
[Viewed September 8, 2007]"
,annotation={
	LWN article describing Promela and spin, and also using Oleg
	Nesterov's QRCU as an example (with Paul McKenney's fastpath).
	Merged patch at: https://lore.kernel.org/r/[email protected]
}
}

@unpublished{PaulEMcKenney2007WG21DDOatomics
,Author="Paul E. McKenney and Hans-J. Boehm and Lawrence Crowl"
,Title="C++ Data-Dependency Ordering: Atomics and Memory Model"
,month="August"
,day="3"
,year="2007"
,note="Available:
\url{http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2664.htm}
[Viewed December 7, 2009]"
,annotation={
	RCU for C++, parts 1 and 2.
}
}

@unpublished{PaulEMcKenney2007WG21DDOannotation
,Author="Paul E. McKenney and Lawrence Crowl"
,Title="C++ Data-Dependency Ordering: Function Annotation"
,month="September"
,day="18"
,year="2008"
,note="Available:
\url{http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2782.htm}
[Viewed December 7, 2009]"
,annotation={
	RCU for C++, part 2, updated many times.
}
}

@unpublished{PaulEMcKenney2007PreemptibleRCUPatch
,Author="Paul E. McKenney"
,Title="[PATCH RFC 0/9] {RCU}: Preemptible {RCU}"
,month="September"
,day="10"
,year="2007"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed October 25, 2007]"
,annotation={
	Final patch for preemptible RCU to -rt.  (Later patches were
	to mainline, eventually incorporated.)
}
}

@unpublished{PaulEMcKenney2007PreemptibleRCU
,Author="Paul E. McKenney"
,Title="The design of preemptible read-copy-update"
,month="October"
,day="8"
,year="2007"
,note="Available:
\url{http://lwn.net/Articles/253651/}
[Viewed October 25, 2007]"
,annotation={
	LWN article describing the design of preemptible RCU.
}
}

@article{ThomasEHart2007a
,Author="Thomas E. Hart and Paul E. McKenney and Angela Demke Brown and Jonathan Walpole"
,Title="Performance of memory reclamation for lockless synchronization"
,journal="J. Parallel Distrib. Comput."
,volume={67}
,number="12"
,year="2007"
,issn="0743-7315"
,pages="1270--1285"
,doi="http://dx.doi.org/10.1016/j.jpdc.2007.04.010"
,publisher="Academic Press, Inc."
,address="Orlando, FL, USA"
,annotation={
	Compares QSBR, HPBR, EBR, and lock-free reference counting.
	Journal version of ThomasEHart2006a.
}
}

# MathieuDesnoyers2007call_rcu_schedNeeded
@unpublished{MathieuDesnoyers2007call:rcu:schedNeeded
,Author="Mathieu Desnoyers"
,Title="Re: [patch 1/2] {Linux} Kernel Markers - Support Multiple Probes"
,month="December"
,day="20"
,year="2007"
,note="Available:
\url{https://lore.kernel.org/r/20071220142540.GB22523@Krystal}
[Viewed March 27, 2008]"
,annotation={
	Request for call_rcu_sched() and rcu_barrier_sched().
}
}


########################################################################
#
#	"What is RCU?" LWN series.
#
#	http://lwn.net/Articles/262464/ (What is RCU, Fundamentally?)
#	http://lwn.net/Articles/263130/ (What is RCU's Usage?)
#	http://lwn.net/Articles/264090/ (What is RCU's API?)

@unpublished{PaulEMcKenney2007WhatIsRCUFundamentally
,Author="Paul E. McKenney and Jonathan Walpole"
,Title="What is {RCU}, Fundamentally?"
,month="December"
,day="17"
,year="2007"
,note="Available:
\url{http://lwn.net/Articles/262464/}
[Viewed December 27, 2007]"
,annotation={
	Lays out the three basic components of RCU: (1) publish-subscribe,
	(2) wait for pre-existing readers to complete, and (2) maintain
	multiple versions.
}
}

@unpublished{PaulEMcKenney2008WhatIsRCUUsage
,Author="Paul E. McKenney"
,Title="What is {RCU}? Part 2: Usage"
,month="January"
,day="4"
,year="2008"
,note="Available:
\url{http://lwn.net/Articles/263130/}
[Viewed January 4, 2008]"
,annotation={
	Lays out six uses of RCU:
	1. RCU is a Reader-Writer Lock Replacement
	2. RCU is a Restricted Reference-Counting Mechanism
	3. RCU is a Bulk Reference-Counting Mechanism
	4. RCU is a Poor Man's Garbage Collector
	5. RCU is a Way of Providing Existence Guarantees
	6. RCU is a Way of Waiting for Things to Finish
}
}

@unpublished{PaulEMcKenney2008WhatIsRCUAPI
,Author="Paul E. McKenney"
,Title="{RCU} part 3: the {RCU} {API}"
,month="January"
,day="17"
,year="2008"
,note="Available:
\url{http://lwn.net/Articles/264090/}
[Viewed January 10, 2008]"
,annotation={
	Gives an overview of the Linux-kernel RCU API and a brief annotated RCU
	bibliography.
}
}

#
#	"What is RCU?" LWN series.
#
########################################################################


@unpublished{SteveRostedt2008dyntickRCUpatch
,Author="Steven Rostedt and Paul E. McKenney"
,Title="{[PATCH]} add support for dynamic ticks and preempt rcu"
,month="January"
,day="29"
,year="2008"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed March 27, 2008]"
,annotation={
	Patch that prevents preemptible RCU from unnecessarily waking
	up dynticks-idle CPUs.
}
}

@unpublished{PaulEMcKenney2008LKMLDependencyOrdering
,Author="Paul E. McKenney"
,Title="Re: [PATCH 02/22 -v7] Add basic support for gcc profiler instrumentation"
,month="February"
,day="1"
,year="2008"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed October 18, 2008]"
,annotation={
	Explanation of compilers violating dependency ordering.
}
}

@Conference{PaulEMcKenney2008Beijing
,Author="Paul E. McKenney"
,Title="Introducing Technology Into {Linux} Or:
Introducing your technology Into {Linux} will require introducing a
lot of {Linux} into your technology!!!"
,Booktitle="2008 Linux Developer Symposium - China"
,Publisher="OSS China"
,Month="February"
,Year="2008"
,Address="Beijing, China"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/RCU/TechIntroLinux.2008.02.19a.pdf}
[Viewed August 12, 2008]"
}

@unpublished{PaulEMcKenney2008dynticksRCU
,Author="Paul E. McKenney and Steven Rostedt"
,Title="Integrating and Validating dynticks and Preemptable RCU"
,month="April"
,day="24"
,year="2008"
,note="Available:
\url{http://lwn.net/Articles/279077/}
[Viewed April 24, 2008]"
,annotation={
	Describes use of Promela and Spin to validate (and fix!) the
	dynticks/RCU interface.
}
}

@article{DinakarGuniguntala2008IBMSysJ
,author="D. Guniguntala and P. E. McKenney and J. Triplett and J. Walpole"
,title="The read-copy-update mechanism for supporting real-time applications on shared-memory multiprocessor systems with {Linux}"
,Year="2008"
,Month="May"
,journal="IBM Systems Journal"
,volume="47"
,number="2"
,pages="221-236"
,annotation={
	RCU, realtime RCU, sleepable RCU, performance.
	http://www.research.ibm.com/journal/sj/472/guniguntala.pdf
	[Viewed April 24, 2008]
}
}

@unpublished{LaiJiangshan2008NewClassicAlgorithm
,Author="Lai Jiangshan"
,Title="[{RFC}][{PATCH}] rcu classic: new algorithm for callbacks-processing"
,month="June"
,day="3"
,year="2008"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed December 10, 2008]"
,annotation={
	Updated RCU classic algorithm.  Introduced multi-tailed list
	for RCU callbacks and also pulling common code into
	__call_rcu().
}
}

@article{PaulEMcKenney2008RCUOSR
,author="Paul E. McKenney and Jonathan Walpole"
,title="Introducing technology into the {Linux} kernel: a case study"
,Year="2008"
,journal="SIGOPS Oper. Syst. Rev."
,volume="42"
,number="5"
,pages="4--17"
,issn="0163-5980"
,doi={http://doi.acm.org/10.1145/1400097.1400099}
,publisher="ACM"
,address="New York, NY, USA"
,annotation={
	Linux changed RCU to a far greater degree than RCU has changed Linux.
	http://portal.acm.org/citation.cfm?doid=1400097.1400099
}
}

@unpublished{ManfredSpraul2008StateMachineRCU
,Author="Manfred Spraul"
,Title="[{RFC}, {PATCH}] state machine based rcu"
,month="August"
,day="21"
,year="2008"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed December 8, 2008]"
,annotation={
	State-based RCU.  One key thing that this patch does is to
	separate the dynticks handling of NMIs and IRQs.
}
}

@unpublished{ManfredSpraul2008dyntickIRQNMI
,Author="Manfred Spraul"
,Title="Re: [{RFC}, {PATCH}] v4 scalable classic {RCU} implementation"
,month="September"
,day="6"
,year="2008"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed December 8, 2008]"
,annotation={
	Manfred notes a fix required to my attempt to separate irq
	and NMI processing for hierarchical RCU's dynticks interface.
}
}

# Was PaulEMcKenney2011cyclicRCU
@techreport{PaulEMcKenney2008cyclicRCU
,author="Paul E. McKenney"
,title="Efficient Support of Consistent Cyclic Search With Read-Copy Update"
,institution="US Patent and Trademark Office"
,address="Washington, DC"
,year="2008"
,number="US Patent 7,426,511"
,month="September"
,pages="23"
,annotation={
	Maintains an additional level of indirection to allow
	readers to confine themselves to the desired snapshot of the
	data structure.  Only permits one update at a time.
}
}

@unpublished{PaulEMcKenney2008HierarchicalRCU
,Author="Paul E. McKenney"
,Title="Hierarchical {RCU}"
,month="November"
,day="3"
,year="2008"
,note="\url{http://lwn.net/Articles/305782/}"
,annotation={
	RCU with combining-tree-based grace-period detection,
	permitting it to handle thousands of CPUs.
	[Viewed November 6, 2008]
}
}

@unpublished{PaulEMcKenney2009BloatwatchRCU
,Author="Paul E. McKenney"
,Title="Re: [PATCH fyi] RCU: the bloatwatch edition"
,month="January"
,day="14"
,year="2009"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed January 15, 2009]"
,annotation={
	Small-footprint implementation of RCU for uniprocessor
	embedded applications -- and also for exposition purposes.
}
}

@conference{PaulEMcKenney2009MaliciousURCU
,Author="Paul E. McKenney"
,Title="Using a Malicious User-Level {RCU} to Torture {RCU}-Based Algorithms"
,Booktitle="linux.conf.au 2009"
,month="January"
,year="2009"
,address="Hobart, Australia"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/RCU/urcutorture.2009.01.22a.pdf}
[Viewed February 2, 2009]"
,annotation={
	Realtime RCU and torture-testing RCU uses.
}
}

@unpublished{MathieuDesnoyers2009URCU
,Author="Mathieu Desnoyers"
,Title="[{RFC} git tree] Userspace {RCU} (urcu) for {Linux}"
,month="February"
,day="5"
,year="2009"
,note="\url{http://lttng.org/urcu}"
,annotation={
	Mathieu Desnoyers's user-space RCU implementation.
	git://lttng.org/userspace-rcu.git
	http://lttng.org/cgi-bin/gitweb.cgi?p=userspace-rcu.git
	http://lttng.org/urcu
	https://lore.kernel.org/r/20090206030543.GB8560@Krystal
}
}

@unpublished{PaulEMcKenney2009LWNBloatWatchRCU
,Author="Paul E. McKenney"
,Title="{RCU}: The {Bloatwatch} Edition"
,month="March"
,day="17"
,year="2009"
,note="Available:
\url{http://lwn.net/Articles/323929/}
[Viewed March 20, 2009]"
,annotation={
	Uniprocessor assumptions allow simplified RCU implementation.
}
}

@unpublished{EvgeniyPolyakov2009EllipticsNetwork
,Author="Evgeniy Polyakov"
,Title="The Elliptics Network"
,month="April"
,day="17"
,year="2009"
,note="Available:
\url{http://www.ioremap.net/projects/elliptics}
[Viewed April 30, 2009]"
,annotation={
	Distributed hash table with transactions, using elliptic
	hash functions to distribute data.
}
}

@unpublished{PaulEMcKenney2009expeditedRCU
,Author="Paul E. McKenney"
,Title="[{PATCH} -tip 0/3] expedited 'big hammer' {RCU} grace periods"
,month="June"
,day="25"
,year="2009"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed August 16, 2009]"
,annotation={
	First posting of expedited RCU to be accepted into -tip.
}
}

@unpublished{PaulEMcKenney2009fastRTRCU
,Author="Paul E. McKenney"
,Title="[{PATCH} {RFC} -tip 0/4] {RCU} cleanups and simplified preemptable {RCU}"
,month="July"
,day="23"
,year="2009"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed August 15, 2009]"
,annotation={
	First posting of simple and fast preemptible RCU.
}
}

@unpublished{JoshTriplett2009RPHash
,Author="Josh Triplett"
,Title="Scalable concurrent hash tables via relativistic programming"
,month="September"
,year="2009"
,note="Linux Plumbers Conference presentation"
,annotation={
	RP fun with hash tables.
	Superseded by JoshTriplett2010RPHash
}
}

@phdthesis{MathieuDesnoyersPhD
, title  = "Low-Impact Operating System Tracing"
, author = "Mathieu Desnoyers"
, school = "Ecole Polytechnique de Montr\'{e}al"
, month  = "December"
, year   = 2009
,note="Available:
\url{http://www.lttng.org/pub/thesis/desnoyers-dissertation-2009-12.pdf}
[Viewed December 9, 2009]"
,annotation={
	Chapter 6 (page 97) covers user-level RCU.
}
}

@unpublished{RelativisticProgrammingWiki
,Author="Josh Triplett and Paul E. McKenney and Jonathan Walpole"
,Title="Relativistic Programming"
,month="September"
,year="2009"
,note="Available:
\url{http://wiki.cs.pdx.edu/rp/}
[Viewed December 9, 2009]"
,annotation={
	Main Relativistic Programming Wiki.
}
}

@conference{PaulEMcKenney2009DeterministicRCU
,Author="Paul E. McKenney"
,Title="Deterministic Synchronization in Multicore Systems: the Role of {RCU}"
,Booktitle="Eleventh Real Time Linux Workshop"
,month="September"
,year="2009"
,address="Dresden, Germany"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/realtime/paper/DetSyncRCU.2009.08.18a.pdf}
[Viewed January 14, 2009]"
}

@unpublished{PaulEMcKenney2009HuntingHeisenbugs
,Author="Paul E. McKenney"
,Title="Hunting Heisenbugs"
,month="November"
,year="2009"
,day="1"
,note="Available:
\url{http://paulmck.livejournal.com/14639.html}
[Viewed June 4, 2010]"
,annotation={
	Day-one bug in Tree RCU that took forever to track down.
}
}

@unpublished{MathieuDesnoyers2009defer:rcu
,Author="Mathieu Desnoyers"
,Title="Kernel RCU: shrink the size of the struct rcu\_head"
,month="December"
,year="2009"
,note="Available:
\url{https://lore.kernel.org/r/20091018232918.GA7385@Krystal}
[Viewed December 29, 2009]"
,annotation={
	Mathieu proposed defer_rcu() with fixed-size per-thread pool
	of RCU callbacks.
}
}

@unpublished{MathieuDesnoyers2009VerifPrePub
,Author="Mathieu Desnoyers and Paul E. McKenney and Michel R. Dagenais"
,Title="Multi-Core Systems Modeling for Formal Verification of Parallel Algorithms"
,month="December"
,year="2009"
,note="Submitted to IEEE TPDS"
,annotation={
	OOMem model for Mathieu's user-level RCU mechanical proof of
	correctness.
}
}

@unpublished{MathieuDesnoyers2009URCUPrePub
,Author="Mathieu Desnoyers and Paul E. McKenney and Alan Stern and Michel R. Dagenais and Jonathan Walpole"
,Title="User-Level Implementations of Read-Copy Update"
,month="December"
,year="2010"
,url={\url{http://www.computer.org/csdl/trans/td/2012/02/ttd2012020375-abs.html}}
,annotation={
	RCU overview, desiderata, semi-formal semantics, user-level RCU
	usage scenarios, three classes of RCU implementation, wait-free
	RCU updates, RCU grace-period batching, update overhead,
	http://www.rdrop.com/users/paulmck/RCU/urcu-main-accepted.2011.08.30a.pdf
	http://www.rdrop.com/users/paulmck/RCU/urcu-supp-accepted.2011.08.30a.pdf
	Superseded by MathieuDesnoyers2012URCU.
}
}

@inproceedings{HariKannan2009DynamicAnalysisRCU
,author = {Kannan, Hari}
,title = {Ordering decoupled metadata accesses in multiprocessors}
,booktitle = {MICRO 42: Proceedings of the 42nd Annual IEEE/ACM International Symposium on Microarchitecture}
,year = {2009}
,isbn = {978-1-60558-798-1}
,pages = {381--390}
,location = {New York, New York}
,doi = {http://doi.acm.org/10.1145/1669112.1669161}
,publisher = {ACM}
,address = {New York, NY, USA}
,annotation={
	Uses RCU to protect metadata used in dynamic analysis.
}
}

@conference{PaulEMcKenney2010SimpleOptRCU
,Author="Paul E. McKenney"
,Title="Simplicity Through Optimization"
,Booktitle="linux.conf.au 2010"
,month="January"
,year="2010"
,address="Wellington, New Zealand"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/RCU/SimplicityThruOptimization.2010.01.21f.pdf}
[Viewed October 10, 2010]"
,annotation={
	TREE_PREEMPT_RCU optimizations greatly simplified the old
	PREEMPT_RCU implementation.
}
}

@unpublished{PaulEMcKenney2010LockdepRCU
,Author="Paul E. McKenney"
,Title="Lockdep-{RCU}"
,month="February"
,year="2010"
,day="1"
,note="\url{https://lwn.net/Articles/371986/}"
,annotation={
	CONFIG_PROVE_RCU, or at least an early version.
	[Viewed June 4, 2010]
}
}

@unpublished{AviKivity2010KVM2RCU
,Author="Avi Kivity"
,Title="[{PATCH} 37/40] {KVM}: Bump maximum vcpu count to 64"
,month="February"
,year="2010"
,note="Available:
\url{http://www.mail-archive.com/[email protected]/msg28640.html}
[Viewed March 20, 2010]"
,annotation={
	Use of RCU permits KVM to increase the size of guest OSes from
	16 CPUs to 64 CPUs.
}
}

@unpublished{HerbertXu2010RCUResizeHash
,Author="Herbert Xu"
,Title="bridge: Add core IGMP snooping support"
,month="February"
,year="2010"
,note="Available:
\url{http://thread.gmane.org/gmane.linux.network/153338}
[Viewed June 9, 2014]"
,annotation={
	Use a pair of list_head structures to support RCU-protected
	resizable hash tables.
}
}

@mastersthesis{AbhinavDuggal2010Masters
,author="Abhinav Duggal"
,title="Stopping Data Races Using Redflag"
,school="Stony Brook University"
,year="2010"
,annotation={
	Data-race detector incorporating RCU.
	http://www.filesystems.org/docs/abhinav-thesis/abhinav_thesis.pdf
}
}

@article{JoshTriplett2010RPHash
,author="Josh Triplett and Paul E. McKenney and Jonathan Walpole"
,title="Scalable Concurrent Hash Tables via Relativistic Programming"
,journal="ACM Operating Systems Review"
,year=2010
,volume=44
,number=3
,month="July"
,annotation={
	RP fun with hash tables.
	http://portal.acm.org/citation.cfm?id=1842733.1842750
}
}

@unpublished{PaulEMcKenney2010RCUAPI
,Author="Paul E. McKenney"
,Title="The {RCU} {API}, 2010 Edition"
,month="December"
,day="8"
,year="2010"
,note="\url{http://lwn.net/Articles/418853/}"
,annotation={
	Includes updated software-engineering features.
	[Viewed December 8, 2010]
}
}

@mastersthesis{AndrejPodzimek2010masters
,author="Andrej Podzimek"
,title="Read-Copy-Update for OpenSolaris"
,school="Charles University in Prague"
,year="2010"
,note="Available:
\url{https://andrej.podzimek.org/thesis.pdf}
[Viewed January 31, 2011]"
,annotation={
	Reviews RCU implementations and creates a few for OpenSolaris.
	Drives quiescent-state detection from RCU read-side primitives,
	in a manner roughly similar to that of Jim Houston.
}
}

@unpublished{LinusTorvalds2011Linux2:6:38:rc1:NPigginVFS
,Author="Linus Torvalds"
,Title="Linux 2.6.38-rc1"
,month="January"
,year="2011"
,note="Available:
\url{https://lore.kernel.org/r/[email protected]}
[Viewed March 4, 2011]"
,annotation={
	"The RCU-based name lookup is at the other end of the spectrum - the
	absolute anti-gimmick. It's some seriously good stuff, and gets rid of
	the last main global lock that really tends to hurt some kernel loads.
	The dentry lock is no longer a big serializing issue. What's really
	nice about it is that it actually improves performance a lot even for
	single-threaded loads (on an SMP kernel), because it gets rid of some
	of the most expensive parts of path component lookup, which was the
	d_lock on every component lookup. So I'm seeing improvements of 30-50%
	on some seriously pathname-lookup intensive loads."
}
}

@techreport{JoshTriplett2011RPScalableCorrectOrdering
,author = {Josh Triplett and Philip W. Howard and Paul E. McKenney and Jonathan Walpole}
,title = {Scalable Correct Memory Ordering via Relativistic Programming}
,year = {2011}
,number = {11-03}
,institution = {Portland State University}
,note = {\url{http://www.cs.pdx.edu/pdfs/tr1103.pdf}}
}

@inproceedings{PhilHoward2011RCUTMRBTree
,author = {Philip W. Howard and Jonathan Walpole}
,title = {A Relativistic Enhancement to Software Transactional Memory}
,booktitle = {Proceedings of the 3rd USENIX conference on Hot topics in parallelism}
,series = {HotPar'11}
,year = {2011}
,location = {Berkeley, CA}
,pages = {1--6}
,numpages = {6}
,url = {http://www.usenix.org/event/hotpar11/tech/final_files/Howard.pdf}
,publisher = {USENIX Association}
,address = {Berkeley, CA, USA}
}

@techreport{PaulEMcKenney2011cyclicparallelRCU
,author="Paul E. McKenney and Jonathan Walpole"
,title="Efficient Support of Consistent Cyclic Search With Read-Copy Update and Parallel Updates"
,institution="US Patent and Trademark Office"
,address="Washington, DC"
,year="2011"
,number="US Patent 7,953,778"
,month="May"
,pages="34"
,annotation={
	Maintains an array of generation numbers to track in-flight
	updates and keeps an additional level of indirection to allow
	readers to confine themselves to the desired snapshot of the
	data structure.
}
}

@inproceedings{Triplett:2011:RPHash
,author = {Triplett, Josh and McKenney, Paul E. and Walpole, Jonathan}
,title = {Resizable, Scalable, Concurrent Hash Tables via Relativistic Programming}
,booktitle = {Proceedings of the 2011 USENIX Annual Technical Conference}
,month = {June}
,year = {2011}
,pages = {145--158}
,numpages = {14}
,url={http://www.usenix.org/event/atc11/tech/final_files/Triplett.pdf}
,publisher = {The USENIX Association}
,address = {Portland, OR USA}
}

@unpublished{PaulEMcKenney2011RCU3.0trainwreck
,Author="Paul E. McKenney"
,Title="3.0 and {RCU:} what went wrong"
,month="July"
,day="27"
,year="2011"
,note="\url{http://lwn.net/Articles/453002/}"
,annotation={
	Analysis of the RCU trainwreck in Linux kernel 3.0.
	[Viewed July 27, 2011]
}
}

@unpublished{NeilBrown2011MeetTheLockers
,Author="Neil Brown"
,Title="Meet the {Lockers}"
,month="August"
,day="3"
,year="2011"
,note="Available:
\url{http://lwn.net/Articles/453685/}
[Viewed September 2, 2011]"
,annotation={
	The Locker family as an analogy for locking, reference counting,
	RCU, and seqlock.
}
}

@inproceedings{Seyster:2011:RFA:2075416.2075425
,author = {Seyster, Justin and Radhakrishnan, Prabakar and Katoch, Samriti and Duggal, Abhinav and Stoller, Scott D. and Zadok, Erez}
,title = {Redflag: a framework for analysis of Kernel-level concurrency}
,booktitle = {Proceedings of the 11th international conference on Algorithms and architectures for parallel processing - Volume Part I}
,series = {ICA3PP'11}
,year = {2011}
,isbn = {978-3-642-24649-4}
,location = {Melbourne, Australia}
,pages = {66--79}
,numpages = {14}
,url = {http://dl.acm.org/citation.cfm?id=2075416.2075425}
,acmid = {2075425}
,publisher = {Springer-Verlag}
,address = {Berlin, Heidelberg}
}

@phdthesis{JoshTriplettPhD
,author="Josh Triplett"
,title="Relativistic Causal Ordering: A Memory Model for Scalable Concurrent Data Structures"
,school="Portland State University"
,year="2012"
,annotation={
	RCU-protected hash tables, barriers vs. read-side traversal order.
	.
	If the updater is making changes in the opposite direction from
	the read-side traversal order, the updater need only execute a
	memory-barrier instruction, but if in the same direction, the
	updater needs to wait for a grace period between the individual
	updates.
}
}

@article{MathieuDesnoyers2012URCU
,Author="Mathieu Desnoyers and Paul E. McKenney and Alan Stern and Michel R. Dagenais and Jonathan Walpole"
,Title="User-Level Implementations of Read-Copy Update"
,journal="IEEE Transactions on Parallel and Distributed Systems"
,volume={23}
,year="2012"
,issn="1045-9219"
,pages="375-382"
,doi="http://doi.ieeecomputersociety.org/10.1109/TPDS.2011.159"
,publisher="IEEE Computer Society"
,address="Los Alamitos, CA, USA"
,annotation={
	RCU overview, desiderata, semi-formal semantics, user-level RCU
	usage scenarios, three classes of RCU implementation, wait-free
	RCU updates, RCU grace-period batching, update overhead,
	http://www.rdrop.com/users/paulmck/RCU/urcu-main-accepted.2011.08.30a.pdf
	http://www.rdrop.com/users/paulmck/RCU/urcu-supp-accepted.2011.08.30a.pdf
	http://www.computer.org/cms/Computer.org/dl/trans/td/2012/02/extras/ttd2012020375s.pdf
}
}

@inproceedings{AustinClements2012RCULinux:mmapsem
,author = {Austin Clements and Frans Kaashoek and Nickolai Zeldovich}
,title = {Scalable Address Spaces Using {RCU} Balanced Trees}
,booktitle = {Architectural Support for Programming Languages and Operating Systems (ASPLOS 2012)}
,month = {March}
,year = {2012}
,pages = {199--210}
,numpages = {12}
,publisher = {ACM}
,address = {London, UK}
,url="http://people.csail.mit.edu/nickolai/papers/clements-bonsai.pdf"
}

@unpublished{PaulEMcKenney2012ELCbattery
,Author="Paul E. McKenney"
,Title="Making {RCU} Safe For Battery-Powered Devices"
,month="February"
,day="15"
,year="2012"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/RCU/RCUdynticks.2012.02.15b.pdf}
[Viewed March 1, 2012]"
,annotation={
	RCU_FAST_NO_HZ, round 2.
}
}

@article{GuillermoVigueras2012RCUCrowd
,author = {Vigueras, Guillermo and Ordu\~{n}a, Juan M. and Lozano, Miguel}
,day = {25}
,doi = {10.1007/s11227-012-0766-x}
,issn = {0920-8542}
,journal = {The Journal of Supercomputing}
,keywords = {linux, simulation}
,month = apr
,posted-at = {2012-05-03 09:12:04}
,priority = {2}
,title = {{A Read-Copy Update based parallel server for distributed crowd simulations}}
,url = {http://dx.doi.org/10.1007/s11227-012-0766-x}
,year = {2012}
}


@unpublished{JonCorbet2012ACCESS:ONCE
,Author="Jon Corbet"
,Title="{ACCESS\_ONCE()}"
,month="August"
,day="1"
,year="2012"
,note="\url{http://lwn.net/Articles/508991/}"
,annotation={
	A couple of simple specific compiler optimizations that motivate
	ACCESS_ONCE().
}
}

@unpublished{AlexeyGotsman2012VerifyGraceExtended
,Author="Alexey Gotsman and Noam Rinetzky and Hongseok Yang"
,Title="Verifying Highly Concurrent Algorithms with Grace (extended version)"
,month="July"
,day="10"
,year="2012"
,note="\url{http://software.imdea.org/~gotsman/papers/recycling-esop13-ext.pdf}"
,annotation={
	Separation-logic formulation of RCU uses.
}
}

@unpublished{PaulMcKenney2012RCUUsage
,Author="Paul E. McKenney and Silas Boyd-Wickizer and Jonathan Walpole"
,Title="{RCU} Usage In the Linux Kernel: One Decade Later"
,month="September"
,day="17"
,year="2012"
,url=http://rdrop.com/users/paulmck/techreports/survey.2012.09.17a.pdf
,note="Technical report paulmck.2012.09.17"
,annotation={
	Overview of the first variant of no-CBs CPUs for RCU.
}
}

@unpublished{JonCorbet2012NOCB
,Author="Jon Corbet"
,Title="Relocating RCU callbacks"
,month="October"
,day="31"
,year="2012"
,note="\url{http://lwn.net/Articles/522262/}"
,annotation={
	Overview of the first variant of no-CBs CPUs for RCU.
}
}

@phdthesis{JustinSeyster2012PhD
,author="Justin Seyster"
,title="Runtime Verification of Kernel-Level Concurrency Using Compiler-Based Instrumentation"
,school="Stony Brook University"
,year="2012"
,annotation={
	Looking for data races, including those involving RCU.
	Proposal:
	http://www.fsl.cs.sunysb.edu/docs/jseyster-proposal/redflag.pdf
	Dissertation:
	http://www.fsl.cs.sunysb.edu/docs/jseyster-dissertation/redflag.pdf
}
}

@unpublished{PaulEMcKenney2013RCUUsage
,Author="Paul E. McKenney and Silas Boyd-Wickizer and Jonathan Walpole"
,Title="{RCU} Usage in the {Linux} Kernel: One Decade Later"
,month="February"
,day="24"
,year="2013"
,note="\url{http://rdrop.com/users/paulmck/techreports/RCUUsage.2013.02.24a.pdf}"
,annotation={
	Usage of RCU within the Linux kernel.
}
}

@inproceedings{AlexeyGotsman2013ESOPRCU
,author = {Alexey Gotsman and Noam Rinetzky and Hongseok Yang}
,title = {Verifying concurrent memory reclamation algorithms with grace}
,booktitle = {ESOP'13: European Symposium on Programming}
,year = {2013}
,pages = {249--269}
,publisher = {Springer}
,address = {Rome, Italy}
,annotation={
	http://software.imdea.org/~gotsman/papers/recycling-esop13.pdf
}
}

@unpublished{PaulEMcKenney2013NoTinyPreempt
,Author="Paul E. McKenney"
,Title="Simplifying RCU"
,month="March"
,day="6"
,year="2013"
,note="\url{http://lwn.net/Articles/541037/}"
,annotation={
	Getting rid of TINY_PREEMPT_RCU.
}
}

---

### Documentation RCU UP (`Documentation/RCU/UP.rst`)

.. _up_doc:

RCU on Uniprocessor Systems
===========================

A common misconception is that, on UP systems, the call_rcu() primitive
may immediately invoke its function.  The basis of this misconception
is that since there is only one CPU, it should not be necessary to
wait for anything else to get done, since there are no other CPUs for
anything else to be happening on.  Although this approach will *sort of*
work a surprising amount of the time, it is a very bad idea in general.
This document presents three examples that demonstrate exactly how bad
an idea this is.

Example 1: softirq Suicide
--------------------------

Suppose that an RCU-based algorithm scans a linked list containing
elements A, B, and C in process context, and can delete elements from
this same list in softirq context.  Suppose that the process-context scan
is referencing element B when it is interrupted by softirq processing,
which deletes element B, and then invokes call_rcu() to free element B
after a grace period.

Now, if call_rcu() were to directly invoke its arguments, then upon return
from softirq, the list scan would find itself referencing a newly freed
element B.  This situation can greatly decrease the life expectancy of
your kernel.

This same problem can occur if call_rcu() is invoked from a hardware
interrupt handler.

Example 2: Function-Call Fatality
---------------------------------

Of course, one could avert the suicide described in the preceding example
by having call_rcu() directly invoke its arguments only if it was called
from process context.  However, this can fail in a similar manner.

Suppose that an RCU-based algorithm again scans a linked list containing
elements A, B, and C in process context, but that it invokes a function
on each element as it is scanned.  Suppose further that this function
deletes element B from the list, then passes it to call_rcu() for deferred
freeing.  This may be a bit unconventional, but it is perfectly legal
RCU usage, since call_rcu() must wait for a grace period to elapse.
Therefore, in this case, allowing call_rcu() to immediately invoke
its arguments would cause it to fail to make the fundamental guarantee
underlying RCU, namely that call_rcu() defers invoking its arguments until
all RCU read-side critical sections currently executing have completed.

Quick Quiz #1:
	Why is it *not* legal to invoke synchronize_rcu() in this case?

:ref:`Answers to Quick Quiz <answer_quick_quiz_up>`

Example 3: Death by Deadlock
----------------------------

Suppose that call_rcu() is invoked while holding a lock, and that the
callback function must acquire this same lock.  In this case, if
call_rcu() were to directly invoke the callback, the result would
be self-deadlock *even if* this invocation occurred from a later
call_rcu() invocation a full grace period later.

In some cases, it would possible to restructure to code so that
the call_rcu() is delayed until after the lock is released.  However,
there are cases where this can be quite ugly:

1.	If a number of items need to be passed to call_rcu() within
	the same critical section, then the code would need to create
	a list of them, then traverse the list once the lock was
	released.

2.	In some cases, the lock will be held across some kernel API,
	so that delaying the call_rcu() until the lock is released
	requires that the data item be passed up via a common API.
	It is far better to guarantee that callbacks are invoked
	with no locks held than to have to modify such APIs to allow
	arbitrary data items to be passed back up through them.

If call_rcu() directly invokes the callback, painful locking restrictions
or API changes would be required.

Quick Quiz #2:
	What locking restriction must RCU callbacks respect?

:ref:`Answers to Quick Quiz <answer_quick_quiz_up>`

It is important to note that userspace RCU implementations *do*
permit call_rcu() to directly invoke callbacks, but only if a full
grace period has elapsed since those callbacks were queued.  This is
the case because some userspace environments are extremely constrained.
Nevertheless, people writing userspace RCU implementations are strongly
encouraged to avoid invoking callbacks from call_rcu(), thus obtaining
the deadlock-avoidance benefits called out above.

Summary
-------

Permitting call_rcu() to immediately invoke its arguments breaks RCU,
even on a UP system.  So do not do it!  Even on a UP system, the RCU
infrastructure *must* respect grace periods, and *must* invoke callbacks
from a known environment in which no locks are held.

Note that it *is* safe for synchronize_rcu() to return immediately on
UP systems, including PREEMPT SMP builds running on UP systems.

Quick Quiz #3:
	Why can't synchronize_rcu() return immediately on UP systems running
	preemptible RCU?

.. _answer_quick_quiz_up:

Answer to Quick Quiz #1:
	Why is it *not* legal to invoke synchronize_rcu() in this case?

	Because the calling function is scanning an RCU-protected linked
	list, and is therefore within an RCU read-side critical section.
	Therefore, the called function has been invoked within an RCU
	read-side critical section, and is not permitted to block.

Answer to Quick Quiz #2:
	What locking restriction must RCU callbacks respect?

	Any lock that is acquired within an RCU callback must be acquired
	elsewhere using an _bh variant of the spinlock primitive.
	For example, if "mylock" is acquired by an RCU callback, then
	a process-context acquisition of this lock must use something
	like spin_lock_bh() to acquire the lock.  Please note that
	it is also OK to use _irq variants of spinlocks, for example,
	spin_lock_irqsave().

	If the process-context code were to simply use spin_lock(),
	then, since RCU callbacks can be invoked from softirq context,
	the callback might be called from a softirq that interrupted
	the process-context critical section.  This would result in
	self-deadlock.

	This restriction might seem gratuitous, since very few RCU
	callbacks acquire locks directly.  However, a great many RCU
	callbacks do acquire locks *indirectly*, for example, via
	the kfree() primitive.

Answer to Quick Quiz #3:
	Why can't synchronize_rcu() return immediately on UP systems
	running preemptible RCU?

	Because some other task might have been preempted in the middle
	of an RCU read-side critical section.  If synchronize_rcu()
	simply immediately returned, it would prematurely signal the
	end of the grace period, which would come as a nasty shock to
	that other thread when it started running again.

---

### Documentation RCU Checklist (`Documentation/RCU/checklist.rst`)

.. 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 can provide the same simplifications to certain types
	of lockless algorithms 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 large systems (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.
	Explicit disabling of preemption (preempt_disable(), for example)
	can serve as rcu_read_lock_sched(), but is less readable and
	prevents lockdep from detecting locking issues.  Acquiring a
	raw spinlock also enters an RCU read-side critical section.

	The guard(rcu)() and scoped_guard(rcu) primitives designate
	the remainder of the current scope or the next statement,
	respectively, as the RCU read-side critical section.  Use of
	these guards can be less error-prone than rcu_read_lock(),
	rcu_read_unlock(), and friends.

	Please note that you *cannot* rely on code known to be built
	only in non-preemptible kernels.  Such code can and will break,
	especially in kernels built with CONFIG_PREEMPT_COUNT=y.

	Letting RCU-protected pointers "leak" out of an RCU read-side
	critical section is every bit 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.  Fields that the readers
		refrain from accessing can be guarded by some other lock
		acquired only by updaters, if desired.

		This also works quite well.

	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.	One alternative is to
		move multiple individual fields to a separate structure,
		thus solving the multiple-field problem by imposing an
		additional level of indirection.

		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-ordering operations
		through the code, making it difficult to understand and
		to test.  Where it works, it is better to use things
		like smp_store_release() and smp_load_acquire(), but in
		some cases the smp_mb() full memory barrier is required.

		As noted earlier, 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.

		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.rst 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.rst
		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 any of call_rcu(), call_srcu(), call_rcu_tasks(), or
	call_rcu_tasks_trace() is used, the callback function may be
	invoked from softirq context, and in any case with bottom halves
	disabled.  In particular, this callback function cannot block.
	If you need the callback to block, run that code in a workqueue
	handler scheduled from the callback.  The queue_rcu_work()
	function does this for you in the case of call_rcu().

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(),
	synchronize_srcu_expedited(), synchronize_rcu_tasks(),
	synchronize_rcu_tasks_rude(), and synchronize_rcu_tasks_trace().

	The expedited forms of these primitives have the same semantics
	as the non-expedited forms, but expediting is more CPU intensive.
	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.  Note that
	IPI-sensitive real-time workloads can use the 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.  Alternatively, instead use asynchronous
	primitives such as call_rcu().

7.	As of v4.20, a given kernel implements only one RCU flavor, which
	is RCU-sched for PREEMPTION=n and RCU-preempt for PREEMPTION=y.
	If the updater uses call_rcu() or synchronize_rcu(), then
	the corresponding readers may use:  (1) rcu_read_lock() and
	rcu_read_unlock(), (2) any pair of primitives that disables
	and re-enables softirq, for example, rcu_read_lock_bh() and
	rcu_read_unlock_bh(), or (3) 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 RCU grace-period-wait
	primitives are the same as for their non-expedited counterparts.

	Similarly, it is necessary to correctly use the RCU Tasks flavors:

	a.	If the updater uses synchronize_rcu_tasks() or
		call_rcu_tasks(), then the readers must refrain from
		executing voluntary context switches, that is, from
		blocking.

	b.	If the updater uses call_rcu_tasks_trace()
		or synchronize_rcu_tasks_trace(), then the
		corresponding readers must use rcu_read_lock_trace()
		and rcu_read_unlock_trace().

	c.	If an updater uses synchronize_rcu_tasks_rude(),
		then the corresponding readers must use anything that
		disables preemption, for example, preempt_disable()
		and preempt_enable().

	Mixing things up will result in confusion and broken kernels, and
	has even resulted in an exploitable security issue.  Therefore,
	when using non-obvious pairs of primitives, commenting is
	of course a must.  One example of non-obvious pairing is
	the XDP feature in networking, which calls BPF programs from
	network-driver NAPI (softirq) context.	BPF relies heavily on RCU
	protection for its data structures, but because the BPF program
	invocation happens entirely within a single local_bh_disable()
	section in a NAPI poll cycle, this usage is safe.  The reason
	that this usage is safe is that readers can use anything that
	disables BH when updaters use call_rcu() or synchronize_rcu().

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() and kvfree_rcu() usually result
	in even simpler code than does synchronize_rcu() without
	synchronize_rcu()'s multi-millisecond latency.	So please take
	advantage of kfree_rcu()'s and kvfree_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(),
	kfree_rcu(), or kvfree_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 rcu_barrier(), permitting a limited
		number of updates per grace period.

	The same cautions apply to call_srcu(), call_rcu_tasks(), and
	call_rcu_tasks_trace().  This is why there is an srcu_barrier(),
	rcu_barrier_tasks(), and rcu_barrier_tasks_trace(), respectively.

	Note that although these primitives do take action to avoid
	memory exhaustion when any given CPU has too many callbacks,
	a determined user or administrator can 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.rst.

	One exception to this rule is when data is only ever added to
	the linked data structure, and is never removed during any
	time that readers might be accessing that structure.  In such
	cases, READ_ONCE() may be used in place of rcu_dereference()
	and the read-side markers (rcu_read_lock() and rcu_read_unlock(),
	for example) may be omitted.

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 understand your code.

11.	Any lock acquired by an RCU callback must be acquired elsewhere
	with softirq disabled, e.g., via spin_lock_bh().  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(), call_srcu(),
	call_rcu_tasks(), or call_rcu_tasks_trace().  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.

	In addition, do not assume that callbacks queued in a given order
	will be invoked in that order, even if they all are queued on the
	same CPU.  Furthermore, do not assume that same-CPU callbacks will
	be invoked serially.  For example, in recent kernels, CPUs can be
	switched between offloaded and de-offloaded callback invocation,
	and while a given CPU is undergoing such a switch, its callbacks
	might be concurrently invoked by that CPU's softirq handler and
	that CPU's rcuo kthread.  At such times, that CPU's callbacks
	might be executed both concurrently and out of order.

13.	Unlike most flavors 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".
	As with RCU, guard(srcu)() and scoped_guard(srcu) forms are
	available, and often provide greater ease of use.  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(), DEFINE_STATIC_SRCU(), DEFINE_SRCU_FAST(),
	or DEFINE_STATIC_SRCU_FAST() or at runtime via either
	init_srcu_struct() or init_srcu_struct_fast() and
	cleanup_srcu_struct().	These last three 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().

	It is also permissible to sleep in RCU Tasks Trace read-side
	critical section, which are delimited by rcu_read_lock_trace()
	and rcu_read_unlock_trace().  However, this is a specialized
	flavor of RCU, and you should not use it without first checking
	with its current users.  In most cases, you should instead
	use SRCU.  As with RCU and SRCU, guard(rcu_tasks_trace)() and
	scoped_guard(rcu_tasks_trace) are available, and often provide
	greater ease of use.

	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).

	CONFIG_RCU_STRICT_GRACE_PERIOD:
		combine with KASAN to check for pointers leaked out
		of RCU read-side critical sections.  This Kconfig
		option is tough on both performance and scalability,
		and so is limited to four-CPU systems.

	__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 pass a callback function defined within a module
	to one of call_rcu(), call_srcu(), call_rcu_tasks(), or
	call_rcu_tasks_trace(), then it is necessary to wait for all
	pending callbacks to be invoked before unloading that module.
	Note that it is absolutely *not* sufficient to wait for a grace
	period!  For example, synchronize_rcu() implementation is *not*
	guaranteed to wait for callbacks registered on other CPUs via
	call_rcu().  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()
	-	call_rcu_tasks() -> rcu_barrier_tasks()
	-	call_rcu_tasks_trace() -> rcu_barrier_tasks_trace()

	However, these barrier functions are absolutely *not* guaranteed
	to wait for a grace period.  For example, if there are no
	call_rcu() callbacks queued anywhere in the system, rcu_barrier()
	can and will return immediately.

	So if you need to wait for both a grace period and for all
	pre-existing callbacks, you will need to invoke both functions,
	with the pair depending on the flavor of RCU:

	-	Either synchronize_rcu() or synchronize_rcu_expedited(),
		together with rcu_barrier()
	-	Either synchronize_srcu() or synchronize_srcu_expedited(),
		together with and srcu_barrier()
	-	synchronize_rcu_tasks() and rcu_barrier_tasks()
	-	synchronize_tasks_trace() and rcu_barrier_tasks_trace()

	If necessary, you can use something like workqueues to execute
	the requisite pair of functions concurrently.

	See rcubarrier.rst for more information.

---

### Documentation RCU Index (`Documentation/RCU/index.rst`)

.. SPDX-License-Identifier: GPL-2.0

.. _rcu_handbook:

============
RCU Handbook
============

.. toctree::
   :maxdepth: 2

   checklist
   lockdep
   lockdep-splat
   rcubarrier
   rcu_dereference
   whatisRCU
   rcu
   rculist_nulls
   rcuref
   torture
   stallwarn
   listRCU
   NMI-RCU
   UP

   Design/Memory-Ordering/Tree-RCU-Memory-Ordering
   Design/Expedited-Grace-Periods/Expedited-Grace-Periods
   Design/Requirements/Requirements
   Design/Data-Structures/Data-Structures

---

### Documentation RCU ListRCU (`Documentation/RCU/listRCU.rst`)

.. _list_rcu_doc:

Using RCU to Protect Read-Mostly Linked Lists
=============================================

One of the most common uses of RCU is protecting read-mostly linked lists
(``struct list_head`` in list.h).  One big advantage of this approach is
that all of the required memory ordering is provided by the list macros.
This document describes several list-based RCU use cases.

When iterating a list while holding the rcu_read_lock(), writers may
modify the list.  The reader is guaranteed to see all of the elements
which were added to the list before they acquired the rcu_read_lock()
and are still on the list when they drop the rcu_read_unlock().
Elements which are added to, or removed from the list may or may not
be seen.  If the writer calls list_replace_rcu(), the reader may see
either the old element or the new element; they will not see both,
nor will they see neither.


Example 1: Read-mostly list: Deferred Destruction
-------------------------------------------------

A widely used usecase for RCU lists in the kernel is lockless iteration over
all processes in the system. ``task_struct::tasks`` represents the list node that
links all the processes. The list can be traversed in parallel to any list
additions or removals.

The traversal of the list is done using ``for_each_process()`` which is defined
by the 2 macros::

	#define next_task(p) \
		list_entry_rcu((p)->tasks.next, struct task_struct, tasks)

	#define for_each_process(p) \
		for (p = &init_task ; (p = next_task(p)) != &init_task ; )

The code traversing the list of all processes typically looks like::

	rcu_read_lock();
	for_each_process(p) {
		/* Do something with p */
	}
	rcu_read_unlock();

The simplified and heavily inlined code for removing a process from a
task list is::

	void release_task(struct task_struct *p)
	{
		write_lock(&tasklist_lock);
		list_del_rcu(&p->tasks);
		write_unlock(&tasklist_lock);
		call_rcu(&p->rcu, delayed_put_task_struct);
	}

When a process exits, ``release_task()`` calls ``list_del_rcu(&p->tasks)``
via __exit_signal() and __unhash_process() under ``tasklist_lock``
writer lock protection.  The list_del_rcu() invocation removes
the task from the list of all tasks. The ``tasklist_lock``
prevents concurrent list additions/removals from corrupting the
list. Readers using ``for_each_process()`` are not protected with the
``tasklist_lock``. To prevent readers from noticing changes in the list
pointers, the ``task_struct`` object is freed only after one or more
grace periods elapse, with the help of call_rcu(), which is invoked via
put_task_struct_rcu_user(). This deferring of destruction ensures that
any readers traversing the list will see valid ``p->tasks.next`` pointers
and deletion/freeing can happen in parallel with traversal of the list.
This pattern is also called an **existence lock**, since RCU refrains
from invoking the delayed_put_task_struct() callback function until
all existing readers finish, which guarantees that the ``task_struct``
object in question will remain in existence until after the completion
of all RCU readers that might possibly have a reference to that object.


Example 2: Read-Side Action Taken Outside of Lock: No In-Place Updates
----------------------------------------------------------------------

Some reader-writer locking use cases compute a value while holding
the read-side lock, but continue to use that value after that lock is
released.  These use cases are often good candidates for conversion
to RCU.  One prominent example involves network packet routing.
Because the packet-routing data tracks the state of equipment outside
of the computer, it will at times contain stale data.  Therefore, once
the route has been computed, there is no need to hold the routing table
static during transmission of the packet.  After all, you can hold the
routing table static all you want, but that won't keep the external
Internet from changing, and it is the state of the external Internet
that really matters.  In addition, routing entries are typically added
or deleted, rather than being modified in place.  This is a rare example
of the finite speed of light and the non-zero size of atoms actually
helping make synchronization be lighter weight.

A straightforward example of this type of RCU use case may be found in
the system-call auditing support.  For example, a reader-writer locked
implementation of ``audit_filter_task()`` might be as follows::

	static enum audit_state audit_filter_task(struct task_struct *tsk, char **key)
	{
		struct audit_entry *e;
		enum audit_state   state;

		read_lock(&auditsc_lock);
		/* Note: audit_filter_mutex held by caller. */
		list_for_each_entry(e, &audit_tsklist, list) {
			if (audit_filter_rules(tsk, &e->rule, NULL, &state)) {
				if (state == AUDIT_STATE_RECORD)
					*key = kstrdup(e->rule.filterkey, GFP_ATOMIC);
				read_unlock(&auditsc_lock);
				return state;
			}
		}
		read_unlock(&auditsc_lock);
		return AUDIT_BUILD_CONTEXT;
	}

Here the list is searched under the lock, but the lock is dropped before
the corresponding value is returned.  By the time that this value is acted
on, the list may well have been modified.  This makes sense, since if
you are turning auditing off, it is OK to audit a few extra system calls.

This means that RCU can be easily applied to the read side, as follows::

	static enum audit_state audit_filter_task(struct task_struct *tsk, char **key)
	{
		struct audit_entry *e;
		enum audit_state   state;

		rcu_read_lock();
		/* Note: audit_filter_mutex held by caller. */
		list_for_each_entry_rcu(e, &audit_tsklist, list) {
			if (audit_filter_rules(tsk, &e->rule, NULL, &state)) {
				if (state == AUDIT_STATE_RECORD)
					*key = kstrdup(e->rule.filterkey, GFP_ATOMIC);
				rcu_read_unlock();
				return state;
			}
		}
		rcu_read_unlock();
		return AUDIT_BUILD_CONTEXT;
	}

The read_lock() and read_unlock() calls have become rcu_read_lock()
and rcu_read_unlock(), respectively, and the list_for_each_entry()
has become list_for_each_entry_rcu().  The **_rcu()** list-traversal
primitives add READ_ONCE() and diagnostic checks for incorrect use
outside of an RCU read-side critical section.

The changes to the update side are also straightforward. A reader-writer lock
might be used as follows for deletion and insertion in these simplified
versions of audit_del_rule() and audit_add_rule()::

	static inline int audit_del_rule(struct audit_rule *rule,
					 struct list_head *list)
	{
		struct audit_entry *e;

		write_lock(&auditsc_lock);
		list_for_each_entry(e, list, list) {
			if (!audit_compare_rule(rule, &e->rule)) {
				list_del(&e->list);
				write_unlock(&auditsc_lock);
				return 0;
			}
		}
		write_unlock(&auditsc_lock);
		return -EFAULT;		/* No matching rule */
	}

	static inline int audit_add_rule(struct audit_entry *entry,
					 struct list_head *list)
	{
		write_lock(&auditsc_lock);
		if (entry->rule.flags & AUDIT_PREPEND) {
			entry->rule.flags &= ~AUDIT_PREPEND;
			list_add(&entry->list, list);
		} else {
			list_add_tail(&entry->list, list);
		}
		write_unlock(&auditsc_lock);
		return 0;
	}

Following are the RCU equivalents for these two functions::

	static inline int audit_del_rule(struct audit_rule *rule,
					 struct list_head *list)
	{
		struct audit_entry *e;

		/* No need to use the _rcu iterator here, since this is the only
		 * deletion routine. */
		list_for_each_entry(e, list, list) {
			if (!audit_compare_rule(rule, &e->rule)) {
				list_del_rcu(&e->list);
				call_rcu(&e->rcu, audit_free_rule);
				return 0;
			}
		}
		return -EFAULT;		/* No matching rule */
	}

	static inline int audit_add_rule(struct audit_entry *entry,
					 struct list_head *list)
	{
		if (entry->rule.flags & AUDIT_PREPEND) {
			entry->rule.flags &= ~AUDIT_PREPEND;
			list_add_rcu(&entry->list, list);
		} else {
			list_add_tail_rcu(&entry->list, list);
		}
		return 0;
	}

Normally, the write_lock() and write_unlock() would be replaced by a
spin_lock() and a spin_unlock(). But in this case, all callers hold
``audit_filter_mutex``, so no additional locking is required. The
auditsc_lock can therefore be eliminated, since use of RCU eliminates the
need for writers to exclude readers.

The list_del(), list_add(), and list_add_tail() primitives have been
replaced by list_del_rcu(), list_add_rcu(), and list_add_tail_rcu().
The **_rcu()** list-manipulation primitives add memory barriers that are
needed on weakly ordered CPUs.  The list_del_rcu() primitive omits the
pointer poisoning debug-assist code that would otherwise cause concurrent
readers to fail spectacularly.

So, when readers can tolerate stale data and when entries are either added or
deleted, without in-place modification, it is very easy to use RCU!


Example 3: Handling In-Place Updates
------------------------------------

The system-call auditing code does not update auditing rules in place.  However,
if it did, the reader-writer-locked code to do so might look as follows
(assuming only ``field_count`` is updated, otherwise, the added fields would
need to be filled in)::

	static inline int audit_upd_rule(struct audit_rule *rule,
					 struct list_head *list,
					 __u32 newaction,
					 __u32 newfield_count)
	{
		struct audit_entry *e;
		struct audit_entry *ne;

		write_lock(&auditsc_lock);
		/* Note: audit_filter_mutex held by caller. */
		list_for_each_entry(e, list, list) {
			if (!audit_compare_rule(rule, &e->rule)) {
				e->rule.action = newaction;
				e->rule.field_count = newfield_count;
				write_unlock(&auditsc_lock);
				return 0;
			}
		}
		write_unlock(&auditsc_lock);
		return -EFAULT;		/* No matching rule */
	}

The RCU version creates a copy, updates the copy, then replaces the old
entry with the newly updated entry.  This sequence of actions, allowing
concurrent reads while making a copy to perform an update, is what gives
RCU (*read-copy update*) its name.

The RCU version of audit_upd_rule() is as follows::

	static inline int audit_upd_rule(struct audit_rule *rule,
					 struct list_head *list,
					 __u32 newaction,
					 __u32 newfield_count)
	{
		struct audit_entry *e;
		struct audit_entry *ne;

		list_for_each_entry(e, list, list) {
			if (!audit_compare_rule(rule, &e->rule)) {
				ne = kmalloc_obj(*entry, GFP_ATOMIC);
				if (ne == NULL)
					return -ENOMEM;
				audit_copy_rule(&ne->rule, &e->rule);
				ne->rule.action = newaction;
				ne->rule.field_count = newfield_count;
				list_replace_rcu(&e->list, &ne->list);
				call_rcu(&e->rcu, audit_free_rule);
				return 0;
			}
		}
		return -EFAULT;		/* No matching rule */
	}

Again, this assumes that the caller holds ``audit_filter_mutex``.  Normally, the
writer lock would become a spinlock in this sort of code.

The update_lsm_rule() does something very similar, for those who would
prefer to look at real Linux-kernel code.

Another use of this pattern can be found in the openswitch driver's *connection
tracking table* code in ``ct_limit_set()``.  The table holds connection tracking
entries and has a limit on the maximum entries.  There is one such table
per-zone and hence one *limit* per zone.  The zones are mapped to their limits
through a hashtable using an RCU-managed hlist for the hash chains. When a new
limit is set, a new limit object is allocated and ``ct_limit_set()`` is called
to replace the old limit object with the new one using list_replace_rcu().
The old limit object is then freed after a grace period using kfree_rcu().


Example 4: Eliminating Stale Data
---------------------------------

The auditing example above tolerates stale data, as do most algorithms
that are tracking external state.  After all, given there is a delay
from the time the external state changes before Linux becomes aware
of the change, and so as noted earlier, a small quantity of additional
RCU-induced staleness is generally not a problem.

However, there are many examples where stale data cannot be tolerated.
One example in the Linux kernel is the System V IPC (see the shm_lock()
function in ipc/shm.c).  This code checks a *deleted* flag under a
per-entry spinlock, and, if the *deleted* flag is set, pretends that the
entry does not exist.  For this to be helpful, the search function must
return holding the per-entry spinlock, as shm_lock() does in fact do.

.. _quick_quiz:

Quick Quiz:
	For the deleted-flag technique to be helpful, why is it necessary
	to hold the per-entry lock while returning from the search function?

:ref:`Answer to Quick Quiz <quick_quiz_answer>`

If the system-call audit module were to ever need to reject stale data, one way
to accomplish this would be to add a ``deleted`` flag and a ``lock`` spinlock to the
``audit_entry`` structure, and modify audit_filter_task() as follows::

	static struct audit_entry *audit_filter_task(struct task_struct *tsk, char **key)
	{
		struct audit_entry *e;
		enum audit_state   state;

		rcu_read_lock();
		list_for_each_entry_rcu(e, &audit_tsklist, list) {
			if (audit_filter_rules(tsk, &e->rule, NULL, &state)) {
				spin_lock(&e->lock);
				if (e->deleted) {
					spin_unlock(&e->lock);
					rcu_read_unlock();
					return NULL;
				}
				rcu_read_unlock();
				if (state == AUDIT_STATE_RECORD)
					*key = kstrdup(e->rule.filterkey, GFP_ATOMIC);
				/* As long as e->lock is held, e is valid and
				 * its value is not stale */
				return e;
			}
		}
		rcu_read_unlock();
		return NULL;
	}

The ``audit_del_rule()`` function would need to set the ``deleted`` flag under the
spinlock as follows::

	static inline int audit_del_rule(struct audit_rule *rule,
					 struct list_head *list)
	{
		struct audit_entry *e;

		/* No need to use the _rcu iterator here, since this
		 * is the only deletion routine. */
		list_for_each_entry(e, list, list) {
			if (!audit_compare_rule(rule, &e->rule)) {
				spin_lock(&e->lock);
				list_del_rcu(&e->list);
				e->deleted = 1;
				spin_unlock(&e->lock);
				call_rcu(&e->rcu, audit_free_rule);
				return 0;
			}
		}
		return -EFAULT;		/* No matching rule */
	}

This too assumes that the caller holds ``audit_filter_mutex``.

Note that this example assumes that entries are only added and deleted.
Additional mechanism is required to deal correctly with the update-in-place
performed by audit_upd_rule().  For one thing, audit_upd_rule() would
need to hold the locks of both the old ``audit_entry`` and its replacement
while executing the list_replace_rcu().


Example 5: Skipping Stale Objects
---------------------------------

For some use cases, reader performance can be improved by skipping
stale objects during read-side list traversal, where stale objects
are those that will be removed and destroyed after one or more grace
periods. One such example can be found in the timerfd subsystem. When a
``CLOCK_REALTIME`` clock is reprogrammed (for example due to setting
of the system time) then all programmed ``timerfds`` that depend on
this clock get triggered and processes waiting on them are awakened in
advance of their scheduled expiry. To facilitate this, all such timers
are added to an RCU-managed ``cancel_list`` when they are setup in
``timerfd_setup_cancel()``::

	static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
	{
		spin_lock(&ctx->cancel_lock);
		if ((ctx->clockid == CLOCK_REALTIME ||
		     ctx->clockid == CLOCK_REALTIME_ALARM) &&
		    (flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) {
			if (!ctx->might_cancel) {
				ctx->might_cancel = true;
				spin_lock(&cancel_lock);
				list_add_rcu(&ctx->clist, &cancel_list);
				spin_unlock(&cancel_lock);
			}
		} else {
			__timerfd_remove_cancel(ctx);
		}
		spin_unlock(&ctx->cancel_lock);
	}

When a timerfd is freed (fd is closed), then the ``might_cancel``
flag of the timerfd object is cleared, the object removed from the
``cancel_list`` and destroyed, as shown in this simplified and inlined
version of timerfd_release()::

	int timerfd_release(struct inode *inode, struct file *file)
	{
		struct timerfd_ctx *ctx = file->private_data;

		spin_lock(&ctx->cancel_lock);
		if (ctx->might_cancel) {
			ctx->might_cancel = false;
			spin_lock(&cancel_lock);
			list_del_rcu(&ctx->clist);
			spin_unlock(&cancel_lock);
		}
		spin_unlock(&ctx->cancel_lock);

		if (isalarm(ctx))
			alarm_cancel(&ctx->t.alarm);
		else
			hrtimer_cancel(&ctx->t.tmr);
		kfree_rcu(ctx, rcu);
		return 0;
	}

If the ``CLOCK_REALTIME`` clock is set, for example by a time server, the
hrtimer framework calls ``timerfd_clock_was_set()`` which walks the
``cancel_list`` and wakes up processes waiting on the timerfd. While iterating
the ``cancel_list``, the ``might_cancel`` flag is consulted to skip stale
objects::

	void timerfd_clock_was_set(void)
	{
		ktime_t moffs = ktime_mono_to_real(0);
		struct timerfd_ctx *ctx;
		unsigned long flags;

		rcu_read_lock();
		list_for_each_entry_rcu(ctx, &cancel_list, clist) {
			if (!ctx->might_cancel)
				continue;
			spin_lock_irqsave(&ctx->wqh.lock, flags);
			if (ctx->moffs != moffs) {
				ctx->moffs = KTIME_MAX;
				ctx->ticks++;
				wake_up_locked_poll(&ctx->wqh, EPOLLIN);
			}
			spin_unlock_irqrestore(&ctx->wqh.lock, flags);
		}
		rcu_read_unlock();
	}

The key point is that because RCU-protected traversal of the
``cancel_list`` happens concurrently with object addition and removal,
sometimes the traversal can access an object that has been removed from
the list. In this example, a flag is used to skip such objects.


Summary
-------

Read-mostly list-based data structures that can tolerate stale data are
the most amenable to use of RCU.  The simplest case is where entries are
either added or deleted from the data structure (or atomically modified
in place), but non-atomic in-place modifications can be handled by making
a copy, updating the copy, then replacing the original with the copy.
If stale data cannot be tolerated, then a *deleted* flag may be used
in conjunction with a per-entry spinlock in order to allow the search
function to reject newly deleted data.

.. _quick_quiz_answer:

Answer to Quick Quiz:
	For the deleted-flag technique to be helpful, why is it necessary
	to hold the per-entry lock while returning from the search function?

	If the search function drops the per-entry lock before returning,
	then the caller will be processing stale data in any case.  If it
	is really OK to be processing stale data, then you don't need a
	*deleted* flag.  If processing stale data really is a problem,
	then you need to hold the per-entry lock across all of the code
	that uses the value that was returned.

:ref:`Back to Quick Quiz <quick_quiz>`

---

### Documentation RCU Lockdep Splat (`Documentation/RCU/lockdep-splat.rst`)

.. 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 splat 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.

---

### Documentation RCU Lockdep (`Documentation/RCU/lockdep.rst`)

.. 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.
	rcu_read_lock_any_held() for any of normal RCU, RCU-bh, and RCU-sched.
	srcu_read_lock_held() for SRCU.
	rcu_read_lock_trace_held() for RCU Tasks Trace.

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_raw_check(p):
		Don't do lockdep at all.  (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 coalescing.  This is useful 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.  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 even 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 an 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))

---

### Documentation RCU Rcu (`Documentation/RCU/rcu.rst`)

.. _rcu_doc:

RCU Concepts
============

The basic idea behind RCU (read-copy update) is to split destructive
operations into two parts, one that prevents anyone from seeing the data
item being destroyed, and one that actually carries out the destruction.
A "grace period" must elapse between the two parts, and this grace period
must be long enough that any readers accessing the item being deleted have
since dropped their references.  For example, an RCU-protected deletion
from a linked list would first remove the item from the list, wait for
a grace period to elapse, then free the element.  See listRCU.rst for more
information on using RCU with linked lists.

Frequently Asked Questions
--------------------------

- Why would anyone want to use RCU?

  The advantage of RCU's two-part approach is that RCU readers need
  not acquire any locks, perform any atomic instructions, write to
  shared memory, or (on CPUs other than Alpha) execute any memory
  barriers.  The fact that these operations are quite expensive
  on modern CPUs is what gives RCU its performance advantages
  in read-mostly situations.  The fact that RCU readers need not
  acquire locks can also greatly simplify deadlock-avoidance code.

- How can the updater tell when a grace period has completed
  if the RCU readers give no indication when they are done?

  Just as with spinlocks, RCU readers are not permitted to
  block, switch to user-mode execution, or enter the idle loop.
  Therefore, as soon as a CPU is seen passing through any of these
  three states, we know that that CPU has exited any previous RCU
  read-side critical sections.  So, if we remove an item from a
  linked list, and then wait until all CPUs have switched context,
  executed in user mode, or executed in the idle loop, we can
  safely free up that item.

  Preemptible variants of RCU (CONFIG_PREEMPT_RCU) get the
  same effect, but require that the readers manipulate CPU-local
  counters.  These counters allow limited types of blocking within
  RCU read-side critical sections.  SRCU also uses CPU-local
  counters, and permits general blocking within RCU read-side
  critical sections.  These variants of RCU detect grace periods
  by sampling these counters.

- If I am running on a uniprocessor kernel, which can only do one
  thing at a time, why should I wait for a grace period?

  See UP.rst for more information.

- How can I see where RCU is currently used in the Linux kernel?

  Search for "rcu_read_lock", "rcu_read_unlock", "call_rcu",
  "rcu_read_lock_bh", "rcu_read_unlock_bh", "srcu_read_lock",
  "srcu_read_unlock", "synchronize_rcu", "synchronize_net",
  "synchronize_srcu", and the other RCU primitives.  Or grab one
  of the cscope databases from:

  (http://www.rdrop.com/users/paulmck/RCU/linuxusage/rculocktab.html).

- What guidelines should I follow when writing code that uses RCU?

  See checklist.rst.

- Why the name "RCU"?

  "RCU" stands for "read-copy update".
  listRCU.rst has more information on where this name came from, search
  for "read-copy update" to find it.

- I hear that RCU is patented?  What is with that?

  Yes, it is.  There are several known patents related to RCU,
  search for the string "Patent" in Documentation/RCU/RTFP.txt to find them.
  Of these, one was allowed to lapse by the assignee, and the
  others have been contributed to the Linux kernel under GPL.
  Many (but not all) have long since expired.
  There are now also LGPL implementations of user-level RCU
  available (https://liburcu.org/).

- I hear that RCU needs work in order to support realtime kernels?

  Realtime-friendly RCU are enabled via the CONFIG_PREEMPTION
  kernel configuration parameter.

- Where can I find more information on RCU?

  See the Documentation/RCU/RTFP.txt file.
  Or point your browser at (https://docs.google.com/document/d/1X0lThx8OK0ZgLMqVoXiR4ZrGURHrXK6NyLRbeXe3Xac/edit)
  or (https://docs.google.com/document/d/1GCdQC8SDbb54W1shjEXqGZ0Rq8a6kIeYutdSIajfpLA/edit?usp=sharing).

---

### Documentation RCU Rcu Dereference (`Documentation/RCU/rcu_dereference.rst`)

.. _rcu_dereference_doc:

PROPER CARE AND FEEDING OF RETURN VALUES FROM rcu_dereference()
===============================================================

Proper care and feeding of address and data dependencies is critically
important to correct use of things like RCU.  To this end, the pointers
returned from the rcu_dereference() family of primitives carry address and
data dependencies.  These dependencies extend from the rcu_dereference()
macro's load of the pointer to the later use of that pointer to compute
either the address of a later memory access (representing an address
dependency) or the value written by a later memory access (representing
a data dependency).

Most of the time, these dependencies are preserved, permitting you to
freely use values from rcu_dereference().  For example, dereferencing
(prefix "*"), field selection ("->"), assignment ("="), address-of
("&"), casts, and addition or subtraction of constants all work quite
naturally and safely.  However, because current compilers do not take
either address or data dependencies into account it is still possible
to get into trouble.

Follow these rules to preserve the address and data dependencies emanating
from your calls to rcu_dereference() and friends, thus keeping your RCU
readers working properly:

-	You must use one of the rcu_dereference() family of primitives
	to load an RCU-protected pointer, otherwise CONFIG_PROVE_RCU
	will complain.  Worse yet, your code can see random memory-corruption
	bugs due to games that compilers and DEC Alpha can play.
	Without one of the rcu_dereference() primitives, compilers
	can reload the value, and won't your code have fun with two
	different values for a single pointer!  Without rcu_dereference(),
	DEC Alpha can load a pointer, dereference that pointer, and
	return data preceding initialization that preceded the store
	of the pointer.  (As noted later, in recent kernels READ_ONCE()
	also prevents DEC Alpha from playing these tricks.)

	In addition, the volatile cast in rcu_dereference() prevents the
	compiler from deducing the resulting pointer value.  Please see
	the section entitled "EXAMPLE WHERE THE COMPILER KNOWS TOO MUCH"
	for an example where the compiler can in fact deduce the exact
	value of the pointer, and thus cause misordering.

-	In the special case where data is added but is never removed
	while readers are accessing the structure, READ_ONCE() may be used
	instead of rcu_dereference().  In this case, use of READ_ONCE()
	takes on the role of the lockless_dereference() primitive that
	was removed in v4.15.

-	You are only permitted to use rcu_dereference() on pointer values.
	The compiler simply knows too much about integral values to
	trust it to carry dependencies through integer operations.
	There are a very few exceptions, namely that you can temporarily
	cast the pointer to uintptr_t in order to:

	-	Set bits and clear bits down in the must-be-zero low-order
		bits of that pointer.  This clearly means that the pointer
		must have alignment constraints, for example, this does
		*not* work in general for char* pointers.

	-	XOR bits to translate pointers, as is done in some
		classic buddy-allocator algorithms.

	It is important to cast the value back to pointer before
	doing much of anything else with it.

-	Avoid cancellation when using the "+" and "-" infix arithmetic
	operators.  For example, for a given variable "x", avoid
	"(x-(uintptr_t)x)" for char* pointers.	The compiler is within its
	rights to substitute zero for this sort of expression, so that
	subsequent accesses no longer depend on the rcu_dereference(),
	again possibly resulting in bugs due to misordering.

	Of course, if "p" is a pointer from rcu_dereference(), and "a"
	and "b" are integers that happen to be equal, the expression
	"p+a-b" is safe because its value still necessarily depends on
	the rcu_dereference(), thus maintaining proper ordering.

-	If you are using RCU to protect JITed functions, so that the
	"()" function-invocation operator is applied to a value obtained
	(directly or indirectly) from rcu_dereference(), you may need to
	interact directly with the hardware to flush instruction caches.
	This issue arises on some systems when a newly JITed function is
	using the same memory that was used by an earlier JITed function.

-	Do not use the results from relational operators ("==", "!=",
	">", ">=", "<", or "<=") when dereferencing.  For example,
	the following (quite strange) code is buggy::

		int *p;
		int *q;

		...

		p = rcu_dereference(gp)
		q = &global_q;
		q += p > &oom_p;
		r1 = *q;  /* BUGGY!!! */

	As before, the reason this is buggy is that relational operators
	are often compiled using branches.  And as before, although
	weak-memory machines such as ARM or PowerPC do order stores
	after such branches, but can speculate loads, which can again
	result in misordering bugs.

-	Be very careful about comparing pointers obtained from
	rcu_dereference() against non-NULL values.  As Linus Torvalds
	explained, if the two pointers are equal, the compiler could
	substitute the pointer you are comparing against for the pointer
	obtained from rcu_dereference().  For example::

		p = rcu_dereference(gp);
		if (p == &default_struct)
			do_default(p->a);

	Because the compiler now knows that the value of "p" is exactly
	the address of the variable "default_struct", it is free to
	transform this code into the following::

		p = rcu_dereference(gp);
		if (p == &default_struct)
			do_default(default_struct.a);

	On ARM and Power hardware, the load from "default_struct.a"
	can now be speculated, such that it might happen before the
	rcu_dereference().  This could result in bugs due to misordering.

	However, comparisons are OK in the following cases:

	-	The comparison was against the NULL pointer.  If the
		compiler knows that the pointer is NULL, you had better
		not be dereferencing it anyway.  If the comparison is
		non-equal, the compiler is none the wiser.  Therefore,
		it is safe to compare pointers from rcu_dereference()
		against NULL pointers.

	-	The pointer is never dereferenced after being compared.
		Since there are no subsequent dereferences, the compiler
		cannot use anything it learned from the comparison
		to reorder the non-existent subsequent dereferences.
		This sort of comparison occurs frequently when scanning
		RCU-protected circular linked lists.

		Note that if the pointer comparison is done outside
		of an RCU read-side critical section, and the pointer
		is never dereferenced, rcu_access_pointer() should be
		used in place of rcu_dereference().  In most cases,
		it is best to avoid accidental dereferences by testing
		the rcu_access_pointer() return value directly, without
		assigning it to a variable.

		Within an RCU read-side critical section, there is little
		reason to use rcu_access_pointer().

	-	The comparison is against a pointer that references memory
		that was initialized "a long time ago."  The reason
		this is safe is that even if misordering occurs, the
		misordering will not affect the accesses that follow
		the comparison.  So exactly how long ago is "a long
		time ago"?  Here are some possibilities:

		-	Compile time.

		-	Boot time.

		-	Module-init time for module code.

		-	Prior to kthread creation for kthread code.

		-	During some prior acquisition of the lock that
			we now hold.

		-	Before mod_timer() time for a timer handler.

		There are many other possibilities involving the Linux
		kernel's wide array of primitives that cause code to
		be invoked at a later time.

	-	The pointer being compared against also came from
		rcu_dereference().  In this case, both pointers depend
		on one rcu_dereference() or another, so you get proper
		ordering either way.

		That said, this situation can make certain RCU usage
		bugs more likely to happen.  Which can be a good thing,
		at least if they happen during testing.  An example
		of such an RCU usage bug is shown in the section titled
		"EXAMPLE OF AMPLIFIED RCU-USAGE BUG".

	-	All of the accesses following the comparison are stores,
		so that a control dependency preserves the needed ordering.
		That said, it is easy to get control dependencies wrong.
		Please see the "CONTROL DEPENDENCIES" section of
		Documentation/memory-barriers.txt for more details.

	-	The pointers are not equal *and* the compiler does
		not have enough information to deduce the value of the
		pointer.  Note that the volatile cast in rcu_dereference()
		will normally prevent the compiler from knowing too much.

		However, please note that if the compiler knows that the
		pointer takes on only one of two values, a not-equal
		comparison will provide exactly the information that the
		compiler needs to deduce the value of the pointer.

-	Disable any value-speculation optimizations that your compiler
	might provide, especially if you are making use of feedback-based
	optimizations that take data collected from prior runs.  Such
	value-speculation optimizations reorder operations by design.

	There is one exception to this rule:  Value-speculation
	optimizations that leverage the branch-prediction hardware are
	safe on strongly ordered systems (such as x86), but not on weakly
	ordered systems (such as ARM or Power).  Choose your compiler
	command-line options wisely!


EXAMPLE OF AMPLIFIED RCU-USAGE BUG
----------------------------------

Because updaters can run concurrently with RCU readers, RCU readers can
see stale and/or inconsistent values.  If RCU readers need fresh or
consistent values, which they sometimes do, they need to take proper
precautions.  To see this, consider the following code fragment::

	struct foo {
		int a;
		int b;
		int c;
	};
	struct foo *gp1;
	struct foo *gp2;

	void updater(void)
	{
		struct foo *p;

		p = kmalloc_obj(*p);
		if (p == NULL)
			deal_with_it();
		p->a = 42;  /* Each field in its own cache line. */
		p->b = 43;
		p->c = 44;
		rcu_assign_pointer(gp1, p);
		p->b = 143;
		p->c = 144;
		rcu_assign_pointer(gp2, p);
	}

	void reader(void)
	{
		struct foo *p;
		struct foo *q;
		int r1, r2;

		rcu_read_lock();
		p = rcu_dereference(gp2);
		if (p == NULL)
			return;
		r1 = p->b;  /* Guaranteed to get 143. */
		q = rcu_dereference(gp1);  /* Guaranteed non-NULL. */
		if (p == q) {
			/* The compiler decides that q->c is same as p->c. */
			r2 = p->c; /* Could get 44 on weakly order system. */
		} else {
			r2 = p->c - r1; /* Unconditional access to p->c. */
		}
		rcu_read_unlock();
		do_something_with(r1, r2);
	}

You might be surprised that the outcome (r1 == 143 && r2 == 44) is possible,
but you should not be.  After all, the updater might have been invoked
a second time between the time reader() loaded into "r1" and the time
that it loaded into "r2".  The fact that this same result can occur due
to some reordering from the compiler and CPUs is beside the point.

But suppose that the reader needs a consistent view?

Then one approach is to use locking, for example, as follows::

	struct foo {
		int a;
		int b;
		int c;
		spinlock_t lock;
	};
	struct foo *gp1;
	struct foo *gp2;

	void updater(void)
	{
		struct foo *p;

		p = kmalloc_obj(*p);
		if (p == NULL)
			deal_with_it();
		spin_lock(&p->lock);
		p->a = 42;  /* Each field in its own cache line. */
		p->b = 43;
		p->c = 44;
		spin_unlock(&p->lock);
		rcu_assign_pointer(gp1, p);
		spin_lock(&p->lock);
		p->b = 143;
		p->c = 144;
		spin_unlock(&p->lock);
		rcu_assign_pointer(gp2, p);
	}

	void reader(void)
	{
		struct foo *p;
		struct foo *q;
		int r1, r2;

		rcu_read_lock();
		p = rcu_dereference(gp2);
		if (p == NULL)
			return;
		spin_lock(&p->lock);
		r1 = p->b;  /* Guaranteed to get 143. */
		q = rcu_dereference(gp1);  /* Guaranteed non-NULL. */
		if (p == q) {
			/* The compiler decides that q->c is same as p->c. */
			r2 = p->c; /* Locking guarantees r2 == 144. */
		} else {
			spin_lock(&q->lock);
			r2 = q->c - r1;
			spin_unlock(&q->lock);
		}
		rcu_read_unlock();
		spin_unlock(&p->lock);
		do_something_with(r1, r2);
	}

As always, use the right tool for the job!


EXAMPLE WHERE THE COMPILER KNOWS TOO MUCH
-----------------------------------------

If a pointer obtained from rcu_dereference() compares not-equal to some
other pointer, the compiler normally has no clue what the value of the
first pointer might be.  This lack of knowledge prevents the compiler
from carrying out optimizations that otherwise might destroy the ordering
guarantees that RCU depends on.  And the volatile cast in rcu_dereference()
should prevent the compiler from guessing the value.

But without rcu_dereference(), the compiler knows more than you might
expect.  Consider the following code fragment::

	struct foo {
		int a;
		int b;
	};
	static struct foo variable1;
	static struct foo variable2;
	static struct foo *gp = &variable1;

	void updater(void)
	{
		initialize_foo(&variable2);
		rcu_assign_pointer(gp, &variable2);
		/*
		 * The above is the only store to gp in this translation unit,
		 * and the address of gp is not exported in any way.
		 */
	}

	int reader(void)
	{
		struct foo *p;

		p = gp;
		barrier();
		if (p == &variable1)
			return p->a; /* Must be variable1.a. */
		else
			return p->b; /* Must be variable2.b. */
	}

Because the compiler can see all stores to "gp", it knows that the only
possible values of "gp" are "variable1" on the one hand and "variable2"
on the other.  The comparison in reader() therefore tells the compiler
the exact value of "p" even in the not-equals case.  This allows the
compiler to make the return values independent of the load from "gp",
in turn destroying the ordering between this load and the loads of the
return values.  This can result in "p->b" returning pre-initialization
garbage values on weakly ordered systems.

In short, rcu_dereference() is *not* optional when you are going to
dereference the resulting pointer.


WHICH MEMBER OF THE rcu_dereference() FAMILY SHOULD YOU USE?
------------------------------------------------------------

First, please avoid using rcu_dereference_raw() and also please avoid
using rcu_dereference_check() and rcu_dereference_protected() with a
second argument with a constant value of 1 (or true, for that matter).
With that caution out of the way, here is some guidance for which
member of the rcu_dereference() to use in various situations:

1.	If the access needs to be within an RCU read-side critical
	section, use rcu_dereference().  With the new consolidated
	RCU flavors, an RCU read-side critical section is entered
	using rcu_read_lock(), anything that disables bottom halves,
	anything that disables interrupts, or anything that disables
	preemption.  Please note that spinlock critical sections
	are also implied RCU read-side critical sections, even when
	they are preemptible, as they are in kernels built with
	CONFIG_PREEMPT_RT=y.

2.	If the access might be within an RCU read-side critical section
	on the one hand, or protected by (say) my_lock on the other,
	use rcu_dereference_check(), for example::

		p1 = rcu_dereference_check(p->rcu_protected_pointer,
					   lockdep_is_held(&my_lock));


3.	If the access might be within an RCU read-side critical section
	on the one hand, or protected by either my_lock or your_lock on
	the other, again use rcu_dereference_check(), for example::

		p1 = rcu_dereference_check(p->rcu_protected_pointer,
					   lockdep_is_held(&my_lock) ||
					   lockdep_is_held(&your_lock));

4.	If the access is on the update side, so that it is always protected
	by my_lock, use rcu_dereference_protected()::

		p1 = rcu_dereference_protected(p->rcu_protected_pointer,
					       lockdep_is_held(&my_lock));

	This can be extended to handle multiple locks as in #3 above,
	and both can be extended to check other conditions as well.

5.	If the protection is supplied by the caller, and is thus unknown
	to this code, that is the rare case when rcu_dereference_raw()
	is appropriate.  In addition, rcu_dereference_raw() might be
	appropriate when the lockdep expression would be excessively
	complex, except that a better approach in that case might be to
	take a long hard look at your synchronization design.  Still,
	there are data-locking cases where any one of a very large number
	of locks or reference counters suffices to protect the pointer,
	so rcu_dereference_raw() does have its place.

	However, its place is probably quite a bit smaller than one
	might expect given the number of uses in the current kernel.
	Ditto for its synonym, rcu_dereference_check( ... , 1), and
	its close relative, rcu_dereference_protected(... , 1).


SPARSE CHECKING OF RCU-PROTECTED POINTERS
-----------------------------------------

The sparse static-analysis tool checks for non-RCU access to RCU-protected
pointers, which can result in "interesting" bugs due to compiler
optimizations involving invented loads and perhaps also load tearing.
For example, suppose someone mistakenly does something like this::

	p = q->rcu_protected_pointer;
	do_something_with(p->a);
	do_something_else_with(p->b);

If register pressure is high, the compiler might optimize "p" out
of existence, transforming the code to something like this::

	do_something_with(q->rcu_protected_pointer->a);
	do_something_else_with(q->rcu_protected_pointer->b);

This could fatally disappoint your code if q->rcu_protected_pointer
changed in the meantime.  Nor is this a theoretical problem:  Exactly
this sort of bug cost Paul E. McKenney (and several of his innocent
colleagues) a three-day weekend back in the early 1990s.

Load tearing could of course result in dereferencing a mashup of a pair
of pointers, which also might fatally disappoint your code.

These problems could have been avoided simply by making the code instead
read as follows::

	p = rcu_dereference(q->rcu_protected_pointer);
	do_something_with(p->a);
	do_something_else_with(p->b);

Unfortunately, these sorts of bugs can be extremely hard to spot during
review.  This is where the sparse tool comes into play, along with the
"__rcu" marker.  If you mark a pointer declaration, whether in a structure
or as a formal parameter, with "__rcu", which tells sparse to complain if
this pointer is accessed directly.  It will also cause sparse to complain
if a pointer not marked with "__rcu" is accessed using rcu_dereference()
and friends.  For example, ->rcu_protected_pointer might be declared as
follows::

	struct foo __rcu *rcu_protected_pointer;

Use of "__rcu" is opt-in.  If you choose not to use it, then you should
ignore the sparse warnings.

---

### Documentation RCU Rcubarrier (`Documentation/RCU/rcubarrier.rst`)

.. _rcu_barrier:

RCU and Unloadable Modules
==========================

[Originally published in LWN Jan. 14, 2007: http://lwn.net/Articles/217484/]

RCU updaters sometimes use call_rcu() to initiate an asynchronous wait for
a grace period to elapse.  This primitive takes a pointer to an rcu_head
struct placed within the RCU-protected data structure and another pointer
to a function that may be invoked later to free that structure. Code to
delete an element p from the linked list from IRQ context might then be
as follows::

	list_del_rcu(p);
	call_rcu(&p->rcu, p_callback);

Since call_rcu() never blocks, this code can safely be used from within
IRQ context. The function p_callback() might be defined as follows::

	static void p_callback(struct rcu_head *rp)
	{
		struct pstruct *p = container_of(rp, struct pstruct, rcu);

		kfree(p);
	}


Unloading Modules That Use call_rcu()
-------------------------------------

But what if the p_callback() function is defined in an unloadable module?

If we unload the module while some RCU callbacks are pending,
the CPUs executing these callbacks are going to be severely
disappointed when they are later invoked, as fancifully depicted at
http://lwn.net/images/ns/kernel/rcu-drop.jpg.

We could try placing a synchronize_rcu() in the module-exit code path,
but this is not sufficient. Although synchronize_rcu() does wait for a
grace period to elapse, it does not wait for the callbacks to complete.

One might be tempted to try several back-to-back synchronize_rcu()
calls, but this is still not guaranteed to work. If there is a very
heavy RCU-callback load, then some of the callbacks might be deferred in
order to allow other processing to proceed. For but one example, such
deferral is required in realtime kernels in order to avoid excessive
scheduling latencies.


rcu_barrier()
-------------

This situation can be handled by the rcu_barrier() primitive.  Rather
than waiting for a grace period to elapse, rcu_barrier() waits for all
outstanding RCU callbacks to complete.  Please note that rcu_barrier()
does **not** imply synchronize_rcu(), in particular, if there are no RCU
callbacks queued anywhere, rcu_barrier() is within its rights to return
immediately, without waiting for anything, let alone a grace period.

Pseudo-code using rcu_barrier() is as follows:

   1. Prevent any new RCU callbacks from being posted.
   2. Execute rcu_barrier().
   3. Allow the module to be unloaded.

There is also an srcu_barrier() function for SRCU, and you of course
must match the flavor of srcu_barrier() with that of call_srcu().
If your module uses multiple srcu_struct structures, then it must also
use multiple invocations of srcu_barrier() when unloading that module.
For example, if it uses call_rcu(), call_srcu() on srcu_struct_1, and
call_srcu() on srcu_struct_2, then the following three lines of code
will be required when unloading::

  1  rcu_barrier();
  2  srcu_barrier(&srcu_struct_1);
  3  srcu_barrier(&srcu_struct_2);

If latency is of the essence, workqueues could be used to run these
three functions concurrently.

An ancient version of the rcutorture module makes use of rcu_barrier()
in its exit function as follows::

  1  static void
  2  rcu_torture_cleanup(void)
  3  {
  4    int i;
  5
  6    fullstop = 1;
  7    if (shuffler_task != NULL) {
  8      VERBOSE_PRINTK_STRING("Stopping rcu_torture_shuffle task");
  9      kthread_stop(shuffler_task);
 10    }
 11    shuffler_task = NULL;
 12
 13    if (writer_task != NULL) {
 14      VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task");
 15      kthread_stop(writer_task);
 16    }
 17    writer_task = NULL;
 18
 19    if (reader_tasks != NULL) {
 20      for (i = 0; i < nrealreaders; i++) {
 21        if (reader_tasks[i] != NULL) {
 22          VERBOSE_PRINTK_STRING(
 23            "Stopping rcu_torture_reader task");
 24          kthread_stop(reader_tasks[i]);
 25        }
 26        reader_tasks[i] = NULL;
 27      }
 28      kfree(reader_tasks);
 29      reader_tasks = NULL;
 30    }
 31    rcu_torture_current = NULL;
 32
 33    if (fakewriter_tasks != NULL) {
 34      for (i = 0; i < nfakewriters; i++) {
 35        if (fakewriter_tasks[i] != NULL) {
 36          VERBOSE_PRINTK_STRING(
 37            "Stopping rcu_torture_fakewriter task");
 38          kthread_stop(fakewriter_tasks[i]);
 39        }
 40        fakewriter_tasks[i] = NULL;
 41      }
 42      kfree(fakewriter_tasks);
 43      fakewriter_tasks = NULL;
 44    }
 45
 46    if (stats_task != NULL) {
 47      VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task");
 48      kthread_stop(stats_task);
 49    }
 50    stats_task = NULL;
 51
 52    /* Wait for all RCU callbacks to fire. */
 53    rcu_barrier();
 54
 55    rcu_torture_stats_print(); /* -After- the stats thread is stopped! */
 56
 57    if (cur_ops->cleanup != NULL)
 58      cur_ops->cleanup();
 59    if (atomic_read(&n_rcu_torture_error))
 60      rcu_torture_print_module_parms("End of test: FAILURE");
 61    else
 62      rcu_torture_print_module_parms("End of test: SUCCESS");
 63  }

Line 6 sets a global variable that prevents any RCU callbacks from
re-posting themselves. This will not be necessary in most cases, since
RCU callbacks rarely include calls to call_rcu(). However, the rcutorture
module is an exception to this rule, and therefore needs to set this
global variable.

Lines 7-50 stop all the kernel tasks associated with the rcutorture
module. Therefore, once execution reaches line 53, no more rcutorture
RCU callbacks will be posted. The rcu_barrier() call on line 53 waits
for any pre-existing callbacks to complete.

Then lines 55-62 print status and do operation-specific cleanup, and
then return, permitting the module-unload operation to be completed.

.. _rcubarrier_quiz_1:

Quick Quiz #1:
	Is there any other situation where rcu_barrier() might
	be required?

:ref:`Answer to Quick Quiz #1 <answer_rcubarrier_quiz_1>`

Your module might have additional complications. For example, if your
module invokes call_rcu() from timers, you will need to first refrain
from posting new timers, cancel (or wait for) all the already-posted
timers, and only then invoke rcu_barrier() to wait for any remaining
RCU callbacks to complete.

Of course, if your module uses call_rcu(), you will need to invoke
rcu_barrier() before unloading.  Similarly, if your module uses
call_srcu(), you will need to invoke srcu_barrier() before unloading,
and on the same srcu_struct structure.  If your module uses call_rcu()
**and** call_srcu(), then (as noted above) you will need to invoke
rcu_barrier() **and** srcu_barrier().


Implementing rcu_barrier()
--------------------------

Dipankar Sarma's implementation of rcu_barrier() makes use of the fact
that RCU callbacks are never reordered once queued on one of the per-CPU
queues. His implementation queues an RCU callback on each of the per-CPU
callback queues, and then waits until they have all started executing, at
which point, all earlier RCU callbacks are guaranteed to have completed.

The original code for rcu_barrier() was roughly as follows::

  1  void rcu_barrier(void)
  2  {
  3    BUG_ON(in_interrupt());
  4    /* Take cpucontrol mutex to protect against CPU hotplug */
  5    mutex_lock(&rcu_barrier_mutex);
  6    init_completion(&rcu_barrier_completion);
  7    atomic_set(&rcu_barrier_cpu_count, 1);
  8    on_each_cpu(rcu_barrier_func, NULL, 0, 1);
  9    if (atomic_dec_and_test(&rcu_barrier_cpu_count))
 10      complete(&rcu_barrier_completion);
 11    wait_for_completion(&rcu_barrier_completion);
 12    mutex_unlock(&rcu_barrier_mutex);
 13  }

Line 3 verifies that the caller is in process context, and lines 5 and 12
use rcu_barrier_mutex to ensure that only one rcu_barrier() is using the
global completion and counters at a time, which are initialized on lines
6 and 7. Line 8 causes each CPU to invoke rcu_barrier_func(), which is
shown below. Note that the final "1" in on_each_cpu()'s argument list
ensures that all the calls to rcu_barrier_func() will have completed
before on_each_cpu() returns. Line 9 removes the initial count from
rcu_barrier_cpu_count, and if this count is now zero, line 10 finalizes
the completion, which prevents line 11 from blocking.  Either way,
line 11 then waits (if needed) for the completion.

.. _rcubarrier_quiz_2:

Quick Quiz #2:
	Why doesn't line 8 initialize rcu_barrier_cpu_count to zero,
	thereby avoiding the need for lines 9 and 10?

:ref:`Answer to Quick Quiz #2 <answer_rcubarrier_quiz_2>`

This code was rewritten in 2008 and several times thereafter, but this
still gives the general idea.

The rcu_barrier_func() runs on each CPU, where it invokes call_rcu()
to post an RCU callback, as follows::

  1  static void rcu_barrier_func(void *notused)
  2  {
  3    int cpu = smp_processor_id();
  4    struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
  5    struct rcu_head *head;
  6
  7    head = &rdp->barrier;
  8    atomic_inc(&rcu_barrier_cpu_count);
  9    call_rcu(head, rcu_barrier_callback);
 10  }

Lines 3 and 4 locate RCU's internal per-CPU rcu_data structure,
which contains the struct rcu_head that needed for the later call to
call_rcu(). Line 7 picks up a pointer to this struct rcu_head, and line
8 increments the global counter. This counter will later be decremented
by the callback. Line 9 then registers the rcu_barrier_callback() on
the current CPU's queue.

The rcu_barrier_callback() function simply atomically decrements the
rcu_barrier_cpu_count variable and finalizes the completion when it
reaches zero, as follows::

  1  static void rcu_barrier_callback(struct rcu_head *notused)
  2  {
  3    if (atomic_dec_and_test(&rcu_barrier_cpu_count))
  4      complete(&rcu_barrier_completion);
  5  }

.. _rcubarrier_quiz_3:

Quick Quiz #3:
	What happens if CPU 0's rcu_barrier_func() executes
	immediately (thus incrementing rcu_barrier_cpu_count to the
	value one), but the other CPU's rcu_barrier_func() invocations
	are delayed for a full grace period? Couldn't this result in
	rcu_barrier() returning prematurely?

:ref:`Answer to Quick Quiz #3 <answer_rcubarrier_quiz_3>`

The current rcu_barrier() implementation is more complex, due to the need
to avoid disturbing idle CPUs (especially on battery-powered systems)
and the need to minimally disturb non-idle CPUs in real-time systems.
In addition, a great many optimizations have been applied.  However,
the code above illustrates the concepts.


rcu_barrier() Summary
---------------------

The rcu_barrier() primitive is used relatively infrequently, since most
code using RCU is in the core kernel rather than in modules. However, if
you are using RCU from an unloadable module, you need to use rcu_barrier()
so that your module may be safely unloaded.


Answers to Quick Quizzes
------------------------

.. _answer_rcubarrier_quiz_1:

Quick Quiz #1:
	Is there any other situation where rcu_barrier() might
	be required?

Answer:
	Interestingly enough, rcu_barrier() was not originally
	implemented for module unloading. Nikita Danilov was using
	RCU in a filesystem, which resulted in a similar situation at
	filesystem-unmount time. Dipankar Sarma coded up rcu_barrier()
	in response, so that Nikita could invoke it during the
	filesystem-unmount process.

	Much later, yours truly hit the RCU module-unload problem when
	implementing rcutorture, and found that rcu_barrier() solves
	this problem as well.

:ref:`Back to Quick Quiz #1 <rcubarrier_quiz_1>`

.. _answer_rcubarrier_quiz_2:

Quick Quiz #2:
	Why doesn't line 8 initialize rcu_barrier_cpu_count to zero,
	thereby avoiding the need for lines 9 and 10?

Answer:
	Suppose that the on_each_cpu() function shown on line 8 was
	delayed, so that CPU 0's rcu_barrier_func() executed and
	the corresponding grace period elapsed, all before CPU 1's
	rcu_barrier_func() started executing.  This would result in
	rcu_barrier_cpu_count being decremented to zero, so that line
	11's wait_for_completion() would return immediately, failing to
	wait for CPU 1's callbacks to be invoked.

	Note that this was not a problem when the rcu_barrier() code
	was first added back in 2005.  This is because on_each_cpu()
	disables preemption, which acted as an RCU read-side critical
	section, thus preventing CPU 0's grace period from completing
	until on_each_cpu() had dealt with all of the CPUs.

	However, with the RCU flavor consolidation around v4.20, this
	possibility was once again ruled out, because the consolidated
	RCU once again waits on nonpreemptible regions of code.

	Nevertheless, that extra count might still be a good idea.
	Relying on these sort of accidents of implementation can result
	in later surprise bugs when the implementation changes.

:ref:`Back to Quick Quiz #2 <rcubarrier_quiz_2>`

.. _answer_rcubarrier_quiz_3:

Quick Quiz #3:
	What happens if CPU 0's rcu_barrier_func() executes
	immediately (thus incrementing rcu_barrier_cpu_count to the
	value one), but the other CPU's rcu_barrier_func() invocations
	are delayed for a full grace period? Couldn't this result in
	rcu_barrier() returning prematurely?

Answer:
	This cannot happen. The reason is that on_each_cpu() has its last
	argument, the wait flag, set to "1". This flag is passed through
	to smp_call_function() and further to smp_call_function_on_cpu(),
	causing this latter to spin until the cross-CPU invocation of
	rcu_barrier_func() has completed. This by itself would prevent
	a grace period from completing on non-CONFIG_PREEMPTION kernels,
	since each CPU must undergo a context switch (or other quiescent
	state) before the grace period can complete. However, this is
	of no use in CONFIG_PREEMPTION kernels.

	Therefore, on_each_cpu() disables preemption across its call
	to smp_call_function() and also across the local call to
	rcu_barrier_func(). Because recent RCU implementations treat
	preemption-disabled regions of code as RCU read-side critical
	sections, this prevents grace periods from completing. This
	means that all CPUs have executed rcu_barrier_func() before
	the first rcu_barrier_callback() can possibly execute, in turn
	preventing rcu_barrier_cpu_count from prematurely reaching zero.

	But if on_each_cpu() ever decides to forgo disabling preemption,
	as might well happen due to real-time latency considerations,
	initializing rcu_barrier_cpu_count to one will save the day.

:ref:`Back to Quick Quiz #3 <rcubarrier_quiz_3>`

---

### Documentation RCU Rculist Nulls (`Documentation/RCU/rculist_nulls.rst`)

.. 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 listRCU.rst.

Using 'nulls'
=============

Using special makers (called 'nulls') is a convenient way
to solve following problem.

Without 'nulls', a typical RCU linked list managing objects which are
allocated with SLAB_TYPESAFE_BY_RCU kmem_cache can use the following
algorithms.  Following examples assume 'obj' is a pointer to such
objects, which is having below type.

::

  struct object {
    struct hlist_node obj_node;
    atomic_t refcnt;
    unsigned int key;
  };

1) Lookup algorithm
-------------------

::

  begin:
  rcu_read_lock();
  obj = lockless_lookup(key);
  if (obj) {
    if (!try_get_ref(obj)) { // might fail for free objects
      rcu_read_unlock();
      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);
      rcu_read_unlock();
      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(); pr