In cio_tpi only disable bottom halves when not in interrupt context.
Otherwise a WARN_ON gets triggered. Besides that, when we are in
interrupt context bottom halves are disabled anyway.
Fixes this one:
Badness at kernel/softirq.c:77
Modules linked in:
CPU: 2 Not tainted 2.6.26 #4
Process swapper (pid: 0, task:
000000003fe83db0, ksp:
000000003fea7d28)
Krnl PSW :
0404c00180000000 0000000000053f4e (__local_bh_disable+0xbe/0xcc)
R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 EA:3
Krnl GPRS:
0000000000008ee0 00000000005f95e0 0000000000000000 0000000000000001
000000000020be92 0000000000000000 0000000000000210 00000000005d36c0
000000003fb5f4d8 0000000000000000 000000000020bed0 000000003fb5f3c8
00000000009be920 0000000000364898 000000003fb5f408 000000003fb5f3c8
Krnl Code:
0000000000053f42:
bf2f1000 icm %r2,15,0(%r1)
0000000000053f46:
a774ffc5 brc 7,53ed0
0000000000053f4a:
a7f40001 brc 15,53f4c
>
0000000000053f4e:
a7280001 lhi %r2,1
0000000000053f52:
50201000 st %r2,0(%r1)
0000000000053f56:
a7f4ffbd brc 15,53ed0
0000000000053f5a: 0707 bcr 0,%r7
0000000000053f5c:
a7f13fc0 tmll %r15,16320
Call Trace:
([<
0000000000000210>] 0x210)
[<
0000000000053f86>] local_bh_disable+0x2a/0x38
[<
000000000020bed0>] wait_cons_dev+0xd4/0x154
[<
0000000000247cb2>] raw3215_make_room+0x6a/0x1a8
[<
000000000024861a>] raw3215_write+0x86/0x28c
[<
00000000002488a0>] con3215_write+0x80/0x110
[<
000000000004c3e0>] __call_console_drivers+0xc8/0xe4
[<
000000000004c47e>] _call_console_drivers+0x82/0xc4
[<
000000000004c744>] release_console_sem+0x218/0x2c0
[<
000000000004cf64>] vprintk+0x3c0/0x504
[<
0000000000354a4a>] printk+0x52/0x64
[<
0000000000088004>] __print_symbol+0x40/0x50
[<
0000000000071dbc>] print_stack_trace+0x78/0xac
[<
0000000000079e78>] print_lock_dependencies+0x148/0x208
[<
000000000007a050>] print_irq_inversion_bug+0x118/0x15c
[<
000000000007a106>] check_usage_forwards+0x72/0x84
[<
000000000007a36e>] mark_lock+0x1d2/0x594
[<
000000000007baca>] __lock_acquire+0x886/0xf48
[<
000000000007c234>] lock_acquire+0xa8/0xe0
[<
0000000000350316>] _write_lock+0x56/0x98
[<
000000000026cd92>] zfcp_erp_adapter_reopen+0x4e/0x8c
[<
000000000026f1e8>] zfcp_qdio_int_resp+0x2e4/0x2f4
[<
00000000002210f4>] qdio_int_handler+0x274/0x888
[<
00000000002177b6>] ccw_device_call_handler+0x6e/0xd8
[<
0000000000215336>] ccw_device_irq+0xd6/0x160
[<
0000000000212f88>] io_subchannel_irq+0x8c/0x118
[<
000000000020c120>] do_IRQ+0x1d0/0x1fc
[<
00000000000270b2>] io_return+0x0/0x8
[<
000000000001c8a4>] cpu_idle+0x178/0x21c
([<
000000000001c884>] cpu_idle+0x158/0x21c)
[<
00000000003483a2>] start_secondary+0xb6/0xc8
INFO: lockdep is turned off.
Last Breaking-Event-Address:
[<
0000000000053f4a>] __local_bh_disable+0xba/0xcc
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
struct tpi_info *tpi_info;
struct subchannel *sch;
struct irb *irb;
+ int irq_context;
tpi_info = (struct tpi_info *) __LC_SUBCHANNEL_ID;
if (tpi (NULL) != 1)
sch = (struct subchannel *)(unsigned long)tpi_info->intparm;
if (!sch)
return 1;
- local_bh_disable();
+ irq_context = in_interrupt();
+ if (!irq_context)
+ local_bh_disable();
irq_enter ();
spin_lock(sch->lock);
memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw));
sch->driver->irq(sch);
spin_unlock(sch->lock);
irq_exit ();
- _local_bh_enable();
+ if (!irq_context)
+ _local_bh_enable();
return 1;
}