aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLOLi <[email protected]>2018-11-28 20:29:57 +0100
committerBrian Behlendorf <[email protected]>2018-11-28 11:29:57 -0800
commitc71c8c715b7a4f6b842f8f04c18a93086012e2a0 (patch)
treedf43d18dccae29aca4b586bc3a76b37d9be8258b
parentcef48f14da6eec8a9095a0272f1cd7d9d60ca476 (diff)
zfs_dbgmsg() is not safe from every context
This commit reverts to using printk() instead of zfs_dbgmsg() to log messages in vdev_disk_error(): this is necessary because the latter can be called from interrupt context where we are not allowed to sleep. Unfortunately zfs_dbgmsg() performs its allocations calling kmalloc() with the KM_SLEEP flag which may result in the following oops: BUG: scheduling while atomic: swapper/4/0/0x10000100 Call Trace: <IRQ> [<0>] dump_stack+0x19/0x1b ... [<0>] spl_kmem_alloc+0xdf/0x140 [spl] <-- kmem_alloc(size, KM_SLEEP) [<0>] __dprintf+0x69/0x150 [zfs] [<0>] ? kmem_cache_free+0x1e2/0x200 [<0>] vdev_disk_error.part.15+0x5f/0x70 [zfs] [<0>] vdev_disk_io_flush_completion+0x48/0x70 [zfs] [<0>] bio_endio+0x67/0xb0 [<0>] blk_update_request+0x90/0x360 ... [<0>] scsi_finish_command+0xdc/0x140 [<0>] scsi_softirq_done+0x132/0x160 [<0>] blk_done_softirq+0x96/0xc0 [<0>] __do_softirq+0xf5/0x280 [<0>] call_softirq+0x1c/0x30 [<0>] do_softirq+0x65/0xa0 [<0>] irq_exit+0x105/0x110 [<0>] do_IRQ+0x56/0xf0 [<0>] common_interrupt+0x162/0x162 <EOI> [<0>] ? cpuidle_enter_state+0x54/0xd0 [<0>] cpuidle_idle_call+0xde/0x230 [<0>] arch_cpu_idle+0xe/0xb0 [<0>] cpu_startup_entry+0x14a/0x1e0 [<0>] start_secondary+0x1f7/0x270 [<0>] start_cpu+0x5/0x14 Reviewed-by: Olaf Faaland <[email protected]> Reviewed by: Brian Behlendorf <[email protected]> Signed-off-by: loli10K <[email protected]> Closes #8137 Closes #8150
-rw-r--r--module/zfs/vdev_disk.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c
index a4109543d..9c44ba12a 100644
--- a/module/zfs/vdev_disk.c
+++ b/module/zfs/vdev_disk.c
@@ -139,9 +139,16 @@ bdev_max_capacity(struct block_device *bdev, uint64_t wholedisk)
static void
vdev_disk_error(zio_t *zio)
{
- zfs_dbgmsg("zio error=%d type=%d offset=%llu size=%llu flags=%x\n",
- zio->io_error, zio->io_type, (u_longlong_t)zio->io_offset,
- (u_longlong_t)zio->io_size, zio->io_flags);
+ /*
+ * This function can be called in interrupt context, for instance while
+ * handling IRQs coming from a misbehaving disk device; use printk()
+ * which is safe from any context.
+ */
+ printk(KERN_WARNING "zio pool=%s vdev=%s error=%d type=%d "
+ "offset=%llu size=%llu flags=%x\n", spa_name(zio->io_spa),
+ zio->io_vd->vdev_path, zio->io_error, zio->io_type,
+ (u_longlong_t)zio->io_offset, (u_longlong_t)zio->io_size,
+ zio->io_flags);
}
/*