kernel_optimize_test/include/linux
Srivatsa S. Bhat e30e2fdfe5 VFS: Fix race between CPU hotplug and lglocks
Currently, the *_global_[un]lock_online() routines are not at all synchronized
with CPU hotplug. Soft-lockups detected as a consequence of this race was
reported earlier at https://lkml.org/lkml/2011/8/24/185. (Thanks to Cong Meng
for finding out that the root-cause of this issue is the race condition
between br_write_[un]lock() and CPU hotplug, which results in the lock states
getting messed up).

Fixing this race by just adding {get,put}_online_cpus() at appropriate places
in *_global_[un]lock_online() is not a good option, because, then suddenly
br_write_[un]lock() would become blocking, whereas they have been kept as
non-blocking all this time, and we would want to keep them that way.

So, overall, we want to ensure 3 things:
1. br_write_lock() and br_write_unlock() must remain as non-blocking.
2. The corresponding lock and unlock of the per-cpu spinlocks must not happen
   for different sets of CPUs.
3. Either prevent any new CPU online operation in between this lock-unlock, or
   ensure that the newly onlined CPU does not proceed with its corresponding
   per-cpu spinlock unlocked.

To achieve all this:
(a) We introduce a new spinlock that is taken by the *_global_lock_online()
    routine and released by the *_global_unlock_online() routine.
(b) We register a callback for CPU hotplug notifications, and this callback
    takes the same spinlock as above.
(c) We maintain a bitmap which is close to the cpu_online_mask, and once it is
    initialized in the lock_init() code, all future updates to it are done in
    the callback, under the above spinlock.
(d) The above bitmap is used (instead of cpu_online_mask) while locking and
    unlocking the per-cpu locks.

The callback takes the spinlock upon the CPU_UP_PREPARE event. So, if the
br_write_lock-unlock sequence is in progress, the callback keeps spinning,
thus preventing the CPU online operation till the lock-unlock sequence is
complete. This takes care of requirement (3).

The bitmap that we maintain remains unmodified throughout the lock-unlock
sequence, since all updates to it are managed by the callback, which takes
the same spinlock as the one taken by the lock code and released only by the
unlock routine. Combining this with (d) above, satisfies requirement (2).

Overall, since we use a spinlock (mentioned in (a)) to prevent CPU hotplug
operations from racing with br_write_lock-unlock, requirement (1) is also
taken care of.

By the way, it is to be noted that a CPU offline operation can actually run
in parallel with our lock-unlock sequence, because our callback doesn't react
to notifications earlier than CPU_DEAD (in order to maintain our bitmap
properly). And this means, since we use our own bitmap (which is stale, on
purpose) during the lock-unlock sequence, we could end up unlocking the
per-cpu lock of an offline CPU (because we had locked it earlier, when the
CPU was online), in order to satisfy requirement (2). But this is harmless,
though it looks a bit awkward.

Debugged-by: Cong Meng <mc@linux.vnet.ibm.com>
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Cc: stable@vger.kernel.org
2011-12-22 02:02:20 -05:00
..
amba
bcma
byteorder
caif
can
ceph
crush
decompress
dvb
hdlc
i2c
input
isdn
lockd
mfd
mlx4
mmc
mtd
netfilter
netfilter_arp
netfilter_bridge
netfilter_ipv4
netfilter_ipv6
nfc
nfsd
pinctrl
platform_data
power
raid
regulator
rtc
spi
ssb
sunrpc
tc_act
tc_ematch
unaligned
usb
uwb
wimax
8250_pci.h
a.out.h
ac97_codec.h
acct.h
acpi_io.h
acpi_pmtmr.h
acpi.h
adb.h
adfs_fs.h
aer.h
affs_hardblocks.h
agp_backend.h
agpgart.h
ahci_platform.h
aio_abi.h
aio.h
alarmtimer.h
altera_jtaguart.h
altera_uart.h
amd-iommu.h
amifd.h
amifdreg.h
amigaffs.h
anon_inodes.h
apm_bios.h
apm-emulation.h
arcdevice.h
arcfb.h
async_tx.h
async.h
ata_platform.h
ata.h
atalk.h
ath9k_platform.h
atm_eni.h
atm_he.h
atm_idt77105.h
atm_nicstar.h
atm_suni.h
atm_tcp.h
atm_zatm.h
atm.h
atmapi.h
atmarp.h
atmbr2684.h
atmclip.h
atmdev.h
atmel_pdc.h
atmel_pwm.h
atmel_serial.h
atmel_tc.h
atmel-mci.h
atmel-pwm-bl.h
atmel-ssc.h
atmioc.h
atmlec.h
atmmpc.h
atmppp.h
atmsap.h
atmsvc.h
atomic.h
attribute_container.h
audit.h
auto_dev-ioctl.h
auto_fs4.h
auto_fs.h
auxvec.h
average.h
ax25.h
b1lli.h
b1pcmcia.h
backing-dev.h
backlight.h
basic_mmio_gpio.h
baycom.h
bcd.h
bch.h
bfin_mac.h
bfs_fs.h
binfmts.h
bio.h
bit_spinlock.h
bitmap.h
bitops.h
bitrev.h
blk_types.h
blk-iopoll.h
blkdev.h
blkpg.h
blktrace_api.h
blockgroup_lock.h
bma150.h
bootmem.h
bottom_half.h
bpqether.h
brcmphy.h
bsearch.h
bsg-lib.h
bsg.h
btree-128.h
btree-type.h
btree.h
buffer_head.h
bug.h
c2port.h
cache.h
can.h
capability.h
capi.h
cb710.h
cciss_defs.h
cciss_ioctl.h
cd1400.h
cdev.h
cdk.h
cdrom.h
cfag12864b.h
cgroup_subsys.h
cgroup.h
cgroupstats.h
chio.h
circ_buf.h
cleancache.h
clk.h
clkdev.h
clksrc-dbx500-prcmu.h
clockchips.h
clocksource.h time/clocksource: Fix kernel-doc warnings 2011-12-19 11:41:40 +01:00
cm4000_cs.h
cn_proc.h
cnt32_to_63.h
coda_psdev.h
coda.h
coff.h
com20020.h
compaction.h
compat.h
compiler-gcc3.h
compiler-gcc4.h
compiler-gcc.h
compiler-intel.h
compiler.h
completion.h
comstats.h
concap.h
configfs.h
connector.h
console_struct.h
console.h
consolemap.h
const.h
cordic.h
coredump.h
cper.h
cpu_pm.h
cpu_rmap.h
cpu.h
cpufreq.h
cpuidle.h
cpumask.h
cpuset.h
cramfs_fs_sb.h
cramfs_fs.h
crash_dump.h
crc7.h
crc8.h
crc16.h
crc32.h
crc32c.h
crc-ccitt.h
crc-itu-t.h
crc-t10dif.h
cred.h
crypto.h
cryptohash.h
cryptouser.h
cs5535.h
ctype.h
cuda.h
cyclades.h
cyclomx.h
cycx_cfm.h
cycx_drv.h
cycx_x25.h
davinci_emac.h
dca.h
dcache.h
dcbnl.h
dccp.h
dcookies.h
debug_locks.h
debugfs.h
debugobjects.h
delay.h
delayacct.h
devfreq.h
device_cgroup.h
device-mapper.h
device.h
devpts_fs.h
dio.h
dirent.h
display.h
dlm_device.h
dlm_netlink.h
dlm_plock.h
dlm.h
dlmconstants.h
dm9000.h
dm-dirty-log.h
dm-io.h
dm-ioctl.h
dm-kcopyd.h
dm-log-userspace.h
dm-region-hash.h
dma_remapping.h iommu: Export intel_iommu_enabled to signal when iommu is in use 2011-12-16 08:49:57 -08:00
dma-attrs.h
dma-debug.h
dma-direction.h
dma-mapping.h
dmaengine.h
dmapool.h
dmar.h
dmi.h
dn.h
dnotify.h
dns_resolver.h
dqblk_qtree.h
dqblk_v1.h
dqblk_v2.h
dqblk_xfs.h
drbd_limits.h
drbd_nl.h
drbd_tag_magic.h
drbd.h
ds1286.h
ds2782_battery.h
ds17287rtc.h
dtlk.h
dw_apb_timer.h
dw_dmac.h
dynamic_debug.h
ecryptfs.h
edac.h
edd.h
eeprom_93cx6.h
eeprom_93xx46.h
efi.h
efs_fs_sb.h
efs_vh.h
eisa.h
elevator.h
elf-em.h
elf-fdpic.h
elf.h
elfcore-compat.h
elfcore.h
elfnote.h
enclosure.h
err.h
errno.h
errqueue.h
etherdevice.h
ethtool.h
eventfd.h
eventpoll.h
evm.h
export.h
exportfs.h
ext2_fs_sb.h
ext2_fs.h
ext3_fs_i.h
ext3_fs_sb.h
ext3_fs.h
ext3_jbd.h
f75375s.h
fadvise.h
falloc.h
fanotify.h
fault-inject.h
fb.h
fcdevice.h
fcntl.h
fd.h
fddidevice.h
fdreg.h
fdtable.h
fec.h
fib_rules.h
fiemap.h
file.h
filter.h
fips.h
firewire-cdev.h
firewire-constants.h
firewire.h
firmware-map.h
firmware.h
flat.h
flex_array.h
font.h
freezer.h
fs_enet_pd.h
fs_stack.h
fs_struct.h
fs_uart_pd.h
fs.h
fscache-cache.h
fscache.h
fsl_devices.h
fsl_hypervisor.h
fsl-diu-fb.h
fsnotify_backend.h
fsnotify.h
ftrace_event.h
ftrace_irq.h
ftrace.h
fuse.h
futex.h
gameport.h
gcd.h
gen_stats.h
genalloc.h
generic_acl.h
generic_serial.h
genetlink.h
genhd.h
getcpu.h
gfp.h
gfs2_ondisk.h
gigaset_dev.h
gpio_keys.h
gpio_mouse.h
gpio-fan.h
gpio-i2cmux.h
gpio.h
gsmmux.h
hardirq.h
hash.h
hdlc.h
hdlcdrv.h
hdreg.h
hid-debug.h
hid-roccat.h
hid.h
hiddev.h
hidraw.h
highmem.h
highuid.h
hil_mlc.h
hil.h
hippidevice.h
hp_sdc.h
hpet.h
hrtimer.h
htcpld.h
htirq.h
huge_mm.h
hugetlb_inline.h
hugetlb.h
hw_breakpoint.h
hw_random.h
hwmon-sysfs.h
hwmon-vid.h
hwmon.h
hwspinlock.h
hyperv.h
hysdn_if.h
i2c-algo-bit.h
i2c-algo-pca.h
i2c-algo-pcf.h
i2c-dev.h
i2c-gpio.h
i2c-mux.h
i2c-ocores.h
i2c-omap.h
i2c-pca-platform.h
i2c-pnx.h
i2c-pxa.h
i2c-smbus.h
i2c-tegra.h
i2c-xiic.h
i2c.h
i2o-dev.h
i2o.h
i8k.h
i7300_idle.h
i8042.h
i8253.h
i82593.h
ibmtr.h
icmp.h
icmpv6.h
ide.h
idr.h
ieee80211.h
if_addr.h
if_addrlabel.h
if_alg.h
if_arcnet.h
if_arp.h
if_bonding.h
if_bridge.h
if_cablemodem.h
if_ec.h
if_eql.h
if_ether.h
if_fc.h
if_fddi.h
if_frad.h
if_hippi.h
if_infiniband.h
if_link.h
if_ltalk.h
if_macvlan.h
if_packet.h
if_phonet.h
if_plip.h
if_ppp.h
if_pppol2tp.h
if_pppox.h
if_slip.h
if_strip.h
if_tr.h
if_tun.h
if_tunnel.h
if_vlan.h
if_x25.h
if.h
igmp.h
ihex.h
ima.h
in6.h
in_route.h
in.h
inet_diag.h
inet_lro.h
inet.h
inetdevice.h
init_ohci1394_dma.h
init_task.h
init.h
initrd.h
inotify.h
input-polldev.h
input.h
integrity.h
intel_mid_dma.h
intel_pmic_gpio.h
intel-iommu.h
interrupt.h
io-mapping.h
io.h
ioc3.h
ioc4.h
iocontext.h
ioctl.h
iommu-helper.h
iommu.h
ioport.h
ioprio.h
iova.h
ip6_tunnel.h
ip_vs.h
ip.h
ipc_namespace.h
ipc.h
ipmi_msgdefs.h
ipmi_smi.h
ipmi.h
ipsec.h
ipv6_route.h
ipv6.h
ipx.h
irda.h
irq_cpustat.h
irq_work.h
irq.h
irqdesc.h
irqdomain.h
irqflags.h
irqnr.h
irqreturn.h
isa.h
isapnp.h
iscsi_boot_sysfs.h
iscsi_ibft.h
isdn_divertif.h
isdn_ppp.h
isdn.h
isdnif.h
isicom.h
iso_fs.h
istallion.h
ivtv.h
ivtvfb.h
ixjuser.h
jbd2.h
jbd_common.h
jbd.h
jffs2.h
jhash.h
jiffies.h
journal-head.h
joystick.h
jump_label.h
jz4740-adc.h
kallsyms.h
kbd_diacr.h
kbd_kern.h
Kbuild
kbuild.h
kconfig.h
kd.h
kdb.h
kdebug.h
kdev_t.h
kernel_stat.h
kernel-page-flags.h
kernel.h
kernelcapi.h
kexec.h
key-type.h
key.h
keyboard.h
keyctl.h
kfifo.h
kgdb.h
khugepaged.h
klist.h
kmalloc_sizes.h
kmemcheck.h
kmemleak.h
kmod.h
kmsg_dump.h
kobj_map.h
kobject_ns.h
kobject.h
kprobes.h
kref.h
ks0108.h
ks8842.h
ksm.h
kthread.h
ktime.h
kvm_host.h
kvm_para.h
kvm_types.h
kvm.h
l2tp.h
lapb.h
latencytop.h
lcd.h
lcm.h
led-lm3530.h
leds_pwm.h
leds-bd2802.h
leds-lp3944.h
leds-lp5521.h
leds-lp5523.h
leds-pca9532.h
leds-regulator.h
leds.h
lglock.h VFS: Fix race between CPU hotplug and lglocks 2011-12-22 02:02:20 -05:00
lguest_launcher.h
lguest.h
libata.h
libps2.h
license.h
limits.h
linkage.h
linux_logo.h
lis3lv02d.h
list_bl.h
list_nulls.h
list_sort.h
list.h
llc.h
llist.h
lockdep.h
log2.h
loop.h
lp.h
lru_cache.h
lsm_audit.h
lzo.h
m48t86.h
magic.h
major.h
map_to_7segment.h
maple.h
marvell_phy.h
math64.h
matroxfb.h
max17040_battery.h
mbcache.h
mbus.h
mc6821.h
mc146818rtc.h
mca-legacy.h
mca.h
mdio-bitbang.h
mdio-gpio.h
mdio.h
media.h
memblock.h
memcontrol.h
memory_hotplug.h
memory.h
mempolicy.h
mempool.h
memstick.h
meye.h
mg_disk.h
micrel_phy.h
migrate.h
mii.h
minix_fs.h
miscdevice.h
mISDNdsp.h
mISDNhw.h
mISDNif.h
mm_inline.h
mm_types.h
mm.h
mman.h
mmdebug.h
mmiotrace.h
mmtimer.h
mmu_context.h
mmu_notifier.h
mmzone.h
mnt_namespace.h
mod_devicetable.h
module.h
moduleloader.h
moduleparam.h
mount.h
mpage.h
mqueue.h
mroute6.h
mroute.h
msdos_fs.h
msg.h
msi.h
msm_mdp.h
mtio.h
mutex-debug.h
mutex.h
mv643xx_eth.h
mv643xx_i2c.h
mv643xx.h
mxm-wmi.h
n_r3964.h
namei.h
nbd.h
ncp_fs.h
ncp_mount.h
ncp_no.h
ncp.h
neighbour.h
net_dropmon.h
net_tstamp.h
net.h
netdevice.h
netfilter_arp.h
netfilter_bridge.h
netfilter_decnet.h
netfilter_ipv4.h
netfilter_ipv6.h
netfilter.h
netlink.h
netpoll.h
netrom.h
nfc.h
nfs2.h
nfs3.h
nfs4_mount.h
nfs4.h
nfs_fs_i.h
nfs_fs_sb.h
nfs_fs.h
nfs_idmap.h
nfs_iostat.h
nfs_mount.h
nfs_page.h
nfs_xdr.h
nfs.h
nfsacl.h
nilfs2_fs.h
nl80211.h
nl802154.h
nls.h
nmi.h
node.h
nodemask.h
notifier.h
nsc_gpio.h
nsproxy.h
nubus.h
numa.h
nvram.h
nwpserial.h
of_address.h
of_device.h
of_fdt.h
of_gpio.h
of_i2c.h
of_irq.h
of_mdio.h
of_net.h
of_pci.h
of_pdt.h
of_platform.h
of_spi.h
of.h
omap3isp.h
omapfb.h
oom.h
opp.h
oprofile.h
oxu210hp.h
padata.h
page_cgroup.h
page-debug-flags.h
page-flags.h
page-isolation.h
pageblock-flags.h
pagemap.h
pagevec.h
param.h
parport_pc.h
parport.h
parser.h
pata_arasan_cf_data.h
patchkey.h
path.h
pch_dma.h
pci_hotplug.h
pci_ids.h
pci_regs.h
pci-acpi.h
pci-aspm.h
pci-ats.h
pci-dma.h
pci.h
pcieport_if.h
pda_power.h
percpu_counter.h
percpu-defs.h
percpu.h
perf_event.h
personality.h
pfkeyv2.h
pfn.h
pg.h
phantom.h
phonedev.h
phonet.h
phy_fixed.h
phy.h
pid_namespace.h
pid.h
pim.h
pipe_fs_i.h
pkt_cls.h
pkt_sched.h
pktcdvd.h
platform_device.h
plist.h
pm_clock.h
pm_domain.h
pm_qos.h
pm_runtime.h
pm_wakeup.h
pm.h
pmu.h
pnfs_osd_xdr.h
pnp.h
poison.h
poll.h
posix_acl_xattr.h
posix_acl.h
posix_types.h
posix-clock.h
posix-timers.h
power_supply.h
ppdev.h
ppp_channel.h
ppp_defs.h
ppp-comp.h
pps_kernel.h
pps-gpio.h
pps.h
prctl.h
preempt.h
prefetch.h
printk.h
prio_heap.h
prio_tree.h
proc_fs.h
profile.h
proportions.h
pstore.h
pti.h
ptp_classify.h
ptp_clock_kernel.h
ptp_clock.h
ptrace.h
pwm_backlight.h
pwm.h
pxa2xx_ssp.h
pxa168_eth.h
qnx4_fs.h
qnxtypes.h
quicklist.h
quota.h
quotaops.h
radeonfb.h
radix-tree.h
raid_class.h
ramfs.h
ramoops.h
random.h
range.h
rar_register.h
ratelimit.h
rational.h
raw.h
rbtree.h
rculist_bl.h
rculist_nulls.h
rculist.h
rcupdate.h
rcutiny.h
rcutree.h
rds.h
reboot.h
reciprocal_div.h
regmap.h
regset.h
reiserfs_acl.h
reiserfs_fs_i.h
reiserfs_fs_sb.h
reiserfs_fs.h
reiserfs_xattr.h
relay.h
res_counter.h
resource.h
resume-trace.h
rfkill-gpio.h
rfkill-regulator.h
rfkill.h
ring_buffer.h
rio_drv.h
rio_ids.h
rio_regs.h
rio.h
rmap.h
romfs_fs.h
root_dev.h
rose.h
rotary_encoder.h
route.h
rslib.h
rtc-v3020.h
rtc.h
rtmutex.h
rtnetlink.h
rwlock_api_smp.h
rwlock_types.h
rwlock.h
rwsem-spinlock.h
rwsem.h
rxrpc.h
s3c_adc_battery.h
sc26198.h
scatterlist.h
scc.h
sched.h
screen_info.h
sctp.h
scx200_gpio.h
scx200.h
sdla.h
seccomp.h
securebits.h
security.h
selection.h
selinux_netlink.h
selinux.h
sem.h
semaphore.h
seq_file_net.h
seq_file.h
seqlock.h
serial167.h
serial_8250.h
serial_core.h
serial_max3100.h
serial_mfd.h
serial_pnx8xxx.h
serial_reg.h
serial_sci.h
serial.h
serialP.h
serio.h
sfi_acpi.h
sfi.h
sh_clk.h
sh_dma.h
sh_eth.h
sh_intc.h
sh_pfc.h
sh_timer.h
shm.h
shmem_fs.h
shrinker.h
sht15.h
sigma.h
signal.h
signalfd.h
skbuff.h
slab_def.h
slab.h
slob_def.h
slub_def.h
sm501-regs.h
sm501.h
smc91x.h
smc911x.h
smp.h
smsc911x.h
snmp.h
socket.h
sockios.h
som.h
sonet.h
sony-laptop.h
sonypi.h
sort.h
sound.h
soundcard.h
spinlock_api_smp.h
spinlock_api_up.h
spinlock_types_up.h
spinlock_types.h
spinlock_up.h
spinlock.h
splice.h
srcu.h
stackprotector.h
stacktrace.h
stallion.h
start_kernel.h
stat.h
statfs.h
stddef.h
stmmac.h
stop_machine.h
string_helpers.h
string.h
stringify.h
sungem_phy.h
superhyway.h
suspend_ioctls.h
suspend.h
svga.h
swab.h
swap.h
swapops.h
swiotlb.h
synclink.h
sys.h
syscalls.h
syscore_ops.h
sysctl.h
sysdev.h
sysfs.h
syslog.h
sysrq.h
sysv_fs.h
task_io_accounting_ops.h
task_io_accounting.h
taskstats_kern.h
taskstats.h
tboot.h
tc.h
tca6416_keypad.h
tcp.h
telephony.h
termios.h
textsearch_fsm.h
textsearch.h
tfrc.h
thermal.h
thread_info.h
threads.h
ti_wilink_st.h
tick.h
tifm.h
timb_dma.h
timb_gpio.h
time.h
timecompare.h
timer.h
timerfd.h
timeriomem-rng.h
timerqueue.h
times.h
timex.h
tiocl.h
tipc_config.h
tipc.h
topology.h
toshiba.h
tpm_command.h
tpm.h
trace_clock.h
trace_seq.h
tracehook.h
tracepoint.h
transport_class.h
trdevice.h
tsacct_kern.h
tty_driver.h
tty_flip.h
tty_ldisc.h
tty.h
typecheck.h
types.h
u64_stats_sync.h
uaccess.h
ucb1400.h
udf_fs_i.h
udp.h
uinput.h
uio_driver.h
uio.h
ultrasound.h
un.h
unistd.h
usb_usual.h
usb.h
usbdevice_fs.h
user_namespace.h
user-return-notifier.h
user.h
utime.h
uts.h
utsname.h
uuid.h
uvcvideo.h
uwb.h
v4l2-mediabus.h
v4l2-subdev.h
vermagic.h
veth.h
vfs.h
vga_switcheroo.h
vgaarb.h
vhost.h
via_i2c.h
via-core.h
via-gpio.h
via.h
video_output.h
videodev2.h
virtio_9p.h
virtio_balloon.h
virtio_blk.h
virtio_config.h
virtio_console.h
virtio_ids.h
virtio_mmio.h
virtio_net.h
virtio_pci.h
virtio_ring.h
virtio_rng.h
virtio.h
vlynq.h
vm_event_item.h
vmalloc.h
vmstat.h
vt_buffer.h
vt_kern.h
vt.h
w1-gpio.h
wait.h
wanrouter.h
watchdog.h
wimax.h
wireless.h
wl12xx.h
wm97xx.h
workqueue.h
writeback.h
x25.h
xattr.h
xfrm.h
xilinxfb.h
xz.h
yam.h
z2_battery.h
zconf.h
zlib.h
zorro_ids.h
zorro.h
zutil.h