[S390] qdio: proper kill of qdio tasklets
The queue tasklets were stopped with tasklet_disable. Although tasklet_disable
prevents the tasklet from beeing executed it is still possible that a tasklet
is scheduled on a CPU at that point. A following qdio_establish calls
tasklet_init which clears the tasklet count and the tasklet state leading to
the following Oops:
<2>kernel BUG at kernel/softirq.c:392!
<4>illegal operation: 0001 [#1] SMP
<4>Modules linked in: iptable_filter ip_tables x_tables dm_round_robin dm_multipath scsi_dh sg sd_mod crc_t10dif nfs lockd nfs
_acl sunrpc fuse loop dm_mod qeth_l3 ipv6 zfcp qeth scsi_transport_fc qdio scsi_tgt scsi_mod chsc_sch ccwgroup dasd_eckd_mod dasdm
od ext3 mbcache jbd
<4>Supported: Yes
<4>CPU: 0 Not tainted 2.6.27.13-1.1.mz13-default #1
<4>Process blast.LzS_64 (pid: 16445, task:
000000006cc02538, ksp:
000000006cb67998)
<4>Krnl PSW :
0704c00180000000 00000000001399f4 (tasklet_action+0xc8/0x1d4)
<4> R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 EA:3
<4>Krnl GPRS:
ffffffff00000030 0000000000000002 0000000000000002 fffffffffffffffe
<4>
000000000013aabe 00000000003b6a18 fffffffffffffffd 0000000000000000
<4>
00000000006705a8 000000007d0914a8 000000007d0914b0 000000007fecfd30
<4>
0000000000000000 00000000003b63e8 000000007fecfd90 000000007fecfd30
<4>Krnl Code:
00000000001399e8:
b9200021 cgr %r2,%r1
<4>
00000000001399ec:
a7740004 brc 7,1399f4
<4>
00000000001399f0:
a7f40001 brc 15,1399f2
<4> >
00000000001399f4:
c0100027e8ee larl %r1,636bd0
<4>
00000000001399fa:
bf1f1008 icm %r1,15,8(%r1)
<4>
00000000001399fe:
a7840019 brc 8,139a30
<4>
0000000000139a02:
c0300027e8ef larl %r3,636be0
<4>
0000000000139a08:
e3c030000004 lg %r12,0(%r3)
<4>Call Trace:
<4>([<
0000000000139c12>] tasklet_hi_action+0x112/0x1d4)
<4> [<
000000000013aabe>] __do_softirq+0xde/0x1c4
<4> [<
000000000010fa2e>] do_softirq+0x96/0xb0
<4> [<
000000000013a8d8>] irq_exit+0x70/0xcc
<4> [<
000000000010d1d8>] do_extint+0xf0/0x110
<4> [<
0000000000113b10>] ext_no_vtime+0x16/0x1a
<4> [<
000003e0000a3662>] ext3_dirty_inode+0xe6/0xe8 [ext3]
<4>([<
00000000001f6cf2>] __mark_inode_dirty+0x52/0x1d4)
<4> [<
000003e0000a44f0>] ext3_ordered_write_end+0x138/0x190 [ext3]
<4> [<
000000000018d5ec>] generic_perform_write+0x174/0x230
<4> [<
0000000000190144>] generic_file_buffered_write+0xb4/0x194
<4> [<
0000000000190864>] __generic_file_aio_write_nolock+0x418/0x454
<4> [<
0000000000190ee2>] generic_file_aio_write+0x76/0xe4
<4> [<
000003e0000a05c2>] ext3_file_write+0x3e/0xc8 [ext3]
<4> [<
00000000001cc2fe>] do_sync_write+0xd6/0x120
<4> [<
00000000001ccfc8>] vfs_write+0xac/0x184
<4> [<
00000000001cd218>] SyS_write+0x68/0xe0
<4> [<
0000000000113402>] sysc_noemu+0x10/0x16
<4> [<
0000020000043188>] 0x20000043188
<4>Last Breaking-Event-Address:
<4> [<
00000000001399f0>] tasklet_action+0xc4/0x1d4
<6>qdio: 0.0.c61b ZFCP on SC f67 using AI:1 QEBSM:0 PCI:1 TDD:1 SIGA: W AOP
<4> <0>Kernel panic - not syncing: Fatal exception in interrupt
Use tasklet_kill instead of tasklet_disbale. Since tasklet_schedule must not be
called after tasklet_kill use the QDIO_IRQ_STATE_STOPPED to inidicate that a
queue is going down and prevent further tasklet schedules in that case.
Remove superflous tasklet_schedule from input queue setup, at that time
the queues are not ready so the schedule results in a NOP.
Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>