linux_dsm_epyc7002/drivers
Kiyoshi Ueda 3f77316de0 dm: separate device deletion from dm_put
This patch separates the device deletion code from dm_put()
to make sure the deletion happens in the process context.

By this patch, device deletion always occurs in an ioctl (process)
context and dm_put() can be called in interrupt context.
As a result, the request-based dm's bad dm_put() usage pointed out
by Mikulas below disappears.
    http://marc.info/?l=dm-devel&m=126699981019735&w=2

Without this patch, I confirmed there is a case to crash the system:
    dm_put() => dm_table_destroy() => vfree() => BUG_ON(in_interrupt())

Some more backgrounds and details:
In request-based dm, a device opener can remove a mapped_device
while the last request is still completing, because bios in the last
request complete first and then the device opener can close and remove
the mapped_device before the last request completes:
  CPU0                                          CPU1
  =================================================================
  <<INTERRUPT>>
  blk_end_request_all(clone_rq)
    blk_update_request(clone_rq)
      bio_endio(clone_bio) == end_clone_bio
        blk_update_request(orig_rq)
          bio_endio(orig_bio)
                                                <<I/O completed>>
                                                dm_blk_close()
                                                dev_remove()
                                                  dm_put(md)
                                                    <<Free md>>
   blk_finish_request(clone_rq)
     ....
     dm_end_request(clone_rq)
       free_rq_clone(clone_rq)
       blk_end_request_all(orig_rq)
       rq_completed(md)

So request-based dm used dm_get()/dm_put() to hold md for each I/O
until its request completion handling is fully done.
However, the final dm_put() can call the device deletion code which
must not be run in interrupt context and may cause kernel panic.

To solve the problem, this patch moves the device deletion code,
dm_destroy(), to predetermined places that is actually deleting
the mapped_device in ioctl (process) context, and changes dm_put()
just to decrement the reference count of the mapped_device.
By this change, dm_put() can be used in any context and the symmetric
model below is introduced:
    dm_create():  create a mapped_device
    dm_destroy(): destroy a mapped_device
    dm_get():     increment the reference count of a mapped_device
    dm_put():     decrement the reference count of a mapped_device

dm_destroy() waits for all references of the mapped_device to disappear,
then deletes the mapped_device.

dm_destroy() uses active waiting with msleep(1), since deleting
the mapped_device isn't performance-critical task.
And since at this point, nobody opens the mapped_device and no new
reference will be taken, the pending counts are just for racing
completing activity and will eventually decrease to zero.

For the unlikely case of the forced module unload, dm_destroy_immediate(),
which doesn't wait and forcibly deletes the mapped_device, is also
introduced and used in dm_hash_remove_all().  Otherwise, "rmmod -f"
may be stuck and never return.
And now, because the mapped_device is deleted at this point, subsequent
accesses to the mapped_device may cause NULL pointer references.

Cc: stable@kernel.org
Signed-off-by: Kiyoshi Ueda <k-ueda@ct.jp.nec.com>
Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
2010-08-12 04:13:56 +01:00
..
accessibility
acpi Merge branch 'acpica' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6 2010-08-07 17:08:30 -07:00
amba
ata Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm 2010-08-11 09:13:19 -07:00
atm Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6 2010-08-09 21:05:52 -07:00
auxdisplay
base drivers/base/node.c: reduce stack usage of node_read_meminfo() 2010-08-09 20:45:02 -07:00
block Merge branch 'for-2.6.36' of git://git.kernel.dk/linux-2.6-block 2010-08-10 15:22:42 -07:00
bluetooth Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6 2010-08-06 12:25:06 -07:00
cdrom block: push down BKL into .open and .release 2010-08-07 18:25:34 +02:00
char kfifo: fix kfifo miss use of nozami.c 2010-08-11 08:59:23 -07:00
clocksource
connector
cpufreq [CPUFREQ] fix brace coding style issue. 2010-08-03 13:47:05 -04:00
cpuidle cpuidle: extend cpuidle and menu governor to handle dynamic states 2010-08-09 20:45:04 -07:00
crypto Merge branch 'ixp4xx' of git://git.kernel.org/pub/scm/linux/kernel/git/chris/linux-2.6 2010-08-11 09:17:27 -07:00
dca
dio
dma Merge branches 'master' and 'devel' into for-linus 2010-08-10 23:17:52 +01:00
edac edac: mpc85xx: add support for new MPCxxx/Pxxxx EDAC controllers 2010-08-11 08:59:21 -07:00
eisa
firewire Merge firewire branches to be released post v2.6.35 2010-08-02 10:09:04 +02:00
firmware edd: fix possible memory leak in edd_init() error path 2010-08-09 20:45:09 -07:00
gpio gpio: sx150x: add Semtech I2C sx150x gpio expander driver 2010-08-11 08:59:09 -07:00
gpu vt/console: try harder to print output when panicing 2010-08-10 13:47:40 -07:00
hid Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input 2010-08-10 15:08:02 -07:00
hwmon fix "hwmon: coretemp: update hotplug condition check" 2010-08-11 08:58:59 -07:00
i2c Merge branch 'for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into devel-stable 2010-08-09 14:07:19 +01:00
ide Merge branch 'for-2.6.36' of git://git.kernel.dk/linux-2.6-block 2010-08-10 15:22:42 -07:00
idle Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq 2010-08-04 11:13:36 -07:00
ieee1394 Merge firewire branches to be released post v2.6.35 2010-08-02 10:09:04 +02:00
ieee802154
infiniband RDMA/cxgb4: Obtain RDMA QID ranges from LLD/FW 2010-08-07 23:08:47 -07:00
input panic: keep blinking in spite of long spin timer mode 2010-08-11 08:59:22 -07:00
isdn Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6 2010-08-09 21:05:52 -07:00
leds leds: Remove owner field from attribute initialization in bd2802 driver 2010-08-05 13:53:35 -07:00
lguest
macintosh Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2010-08-06 13:25:43 -07:00
mca
md dm: separate device deletion from dm_put 2010-08-12 04:13:56 +01:00
media Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6 2010-08-10 15:09:54 -07:00
memstick block: push down BKL into .open and .release 2010-08-07 18:25:34 +02:00
message fusion: fix kernel-doc warnings 2010-08-11 08:59:12 -07:00
mfd
misc cs5535-mfgpt: reuse timers that have never been set up 2010-08-11 08:59:20 -07:00
mmc mmc: add ricoh e822 pci id 2010-08-11 08:59:05 -07:00
mtd mtd/nand_base: fix kernel-doc warnings & typos 2010-08-11 08:59:18 -07:00
net Merge branch 'ixp4xx' of git://git.kernel.org/pub/scm/linux/kernel/git/chris/linux-2.6 2010-08-11 09:17:27 -07:00
nubus
of of/platform: Register of_platform_drivers with an "of:" prefix 2010-08-01 01:44:18 -06:00
oprofile
parisc Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2010-08-04 15:31:02 -07:00
parport parport_serial: use the PCI IRQ if offered 2010-08-11 08:59:22 -07:00
pci Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx 2010-08-09 21:00:07 -07:00
pcmcia Merge branches 'master' and 'devel' into for-linus 2010-08-10 23:17:52 +01:00
platform ips driver: make it less chatty 2010-08-03 11:55:15 -04:00
pnp
power Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm 2010-08-11 09:13:19 -07:00
pps
ps3
rapidio
regulator regulator: Remove owner field from attribute initialization in regulator core driver 2010-08-05 13:53:35 -07:00
rtc Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm 2010-08-11 09:13:19 -07:00
s390 Merge branch 'for-2.6.36' of git://git.kernel.dk/linux-2.6-block 2010-08-10 15:22:42 -07:00
sbus Merge branch 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6 2010-08-05 15:57:35 -07:00
scsi scsi: 53c700: remove dma_is_consistent usage 2010-08-11 08:59:21 -07:00
serial Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm 2010-08-11 09:13:19 -07:00
sfi
sh sh: add a reparent function to DIV6 clocks 2010-08-04 16:12:01 +09:00
sn
spi of/address: Clean up function declarations 2010-08-01 01:42:42 -06:00
ssb Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6 2010-08-06 12:25:06 -07:00
staging Merge branch 'for-2.6.36' of git://git.kernel.dk/linux-2.6-block 2010-08-10 15:22:42 -07:00
tc
telephony pcmcia: do not use io_req_t when calling pcmcia_request_io() 2010-08-03 09:04:11 +02:00
thermal
uio uio: Remove IRQF_DISABLED flag from uio_cif.c 2010-08-05 13:53:33 -07:00
usb Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6 2010-08-10 15:05:02 -07:00
uwb
vhost Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6 2010-08-04 11:47:58 -07:00
video Merge branch 'msm-video' of git://codeaurora.org/quic/kernel/dwalker/linux-msm 2010-08-11 09:18:06 -07:00
virtio
vlynq
w1
watchdog watchdog: hpwdt: formatting of pointers in printk() 2010-08-08 18:22:44 +00:00
xen Merge branch 'for-2.6.36' of git://git.kernel.dk/linux-2.6-block 2010-08-10 15:22:42 -07:00
zorro zorro: Fix reading of proc/bus/zorro/* in small chunks 2010-08-09 21:14:08 +02:00
Kconfig
Makefile