public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
To: linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>,
	Jan Glauber <jang@linux.vnet.ibm.com>,
	Martin Schwidefsky <schwidefsky@de.ibm.com>
Subject: [patch/s390 37/46] qdio: proper kill of qdio tasklets
Date: Wed, 25 Feb 2009 16:06:59 +0100	[thread overview]
Message-ID: <20090225150837.398862645@de.ibm.com> (raw)
In-Reply-To: 20090225150622.529143164@de.ibm.com

[-- Attachment #1: 136-qdio-kill-tasklet.diff --]
[-- Type: text/plain, Size: 7789 bytes --]

From: Jan Glauber <jang@linux.vnet.ibm.com>

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>
---

 drivers/s390/cio/qdio_main.c    |   35 ++++++++++++++++++++++++-----------
 drivers/s390/cio/qdio_thinint.c |    8 ++++----
 2 files changed, 28 insertions(+), 15 deletions(-)

Index: quilt-2.6/drivers/s390/cio/qdio_main.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/qdio_main.c
+++ quilt-2.6/drivers/s390/cio/qdio_main.c
@@ -778,21 +778,17 @@ static void __qdio_outbound_processing(s
 
 	spin_unlock_irqrestore(&q->lock, flags);
 
-	if (queue_type(q) == QDIO_ZFCP_QFMT) {
+	if (queue_type(q) == QDIO_ZFCP_QFMT)
 		if (!pci_out_supported(q) && !qdio_outbound_q_done(q))
-			tasklet_schedule(&q->tasklet);
-		return;
-	}
+			goto sched;
 
 	/* bail out for HiperSockets unicast queues */
 	if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q))
 		return;
 
 	if ((queue_type(q) == QDIO_IQDIO_QFMT) &&
-	    (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL) {
-		tasklet_schedule(&q->tasklet);
-		return;
-	}
+	    (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL)
+		goto sched;
 
 	if (q->u.out.pci_out_enabled)
 		return;
@@ -810,6 +806,12 @@ static void __qdio_outbound_processing(s
 			qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer);
 		}
 	}
+	return;
+
+sched:
+	if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+		return;
+	tasklet_schedule(&q->tasklet);
 }
 
 /* outbound tasklet */
@@ -822,6 +824,9 @@ void qdio_outbound_processing(unsigned l
 void qdio_outbound_timer(unsigned long data)
 {
 	struct qdio_q *q = (struct qdio_q *)data;
+
+	if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+		return;
 	tasklet_schedule(&q->tasklet);
 }
 
@@ -863,6 +868,9 @@ static void qdio_int_handler_pci(struct 
 	int i;
 	struct qdio_q *q;
 
+	if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+		return;
+
 	qdio_perf_stat_inc(&perf_stats.pci_int);
 
 	for_each_input_queue(irq_ptr, q, i)
@@ -1090,11 +1098,11 @@ static void qdio_shutdown_queues(struct 
 	int i;
 
 	for_each_input_queue(irq_ptr, q, i)
-		tasklet_disable(&q->tasklet);
+		tasklet_kill(&q->tasklet);
 
 	for_each_output_queue(irq_ptr, q, i) {
-		tasklet_disable(&q->tasklet);
 		del_timer(&q->u.out.timer);
+		tasklet_kill(&q->tasklet);
 	}
 }
 
@@ -1125,6 +1133,12 @@ int qdio_shutdown(struct ccw_device *cde
 		return 0;
 	}
 
+	/*
+	 * Indicate that the device is going down. Scheduling the queue
+	 * tasklets is forbidden from here on.
+	 */
+	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
+
 	tiqdio_remove_input_queues(irq_ptr);
 	qdio_shutdown_queues(cdev);
 	qdio_shutdown_debug_entries(irq_ptr, cdev);
@@ -1556,7 +1570,6 @@ static void handle_outbound(struct qdio_
 		qdio_perf_stat_inc(&perf_stats.fast_requeue);
 	}
 out:
-	/* Fixme: could wait forever if called from process context */
 	tasklet_schedule(&q->tasklet);
 }
 
Index: quilt-2.6/drivers/s390/cio/qdio_thinint.c
===================================================================
--- quilt-2.6.orig/drivers/s390/cio/qdio_thinint.c
+++ quilt-2.6/drivers/s390/cio/qdio_thinint.c
@@ -101,7 +101,6 @@ void tiqdio_add_input_queues(struct qdio
 		list_add_rcu(&q->entry, &tiq_list);
 	mutex_unlock(&tiq_list_lock);
 	xchg(irq_ptr->dsci, 1);
-	tasklet_schedule(&tiqdio_tasklet);
 }
 
 /*
@@ -159,7 +158,6 @@ static void __tiqdio_inbound_processing(
 	 */
 	qdio_check_outbound_after_thinint(q);
 
-again:
 	if (!qdio_inbound_q_moved(q))
 		return;
 
@@ -167,7 +165,8 @@ again:
 
 	if (!tiqdio_inbound_q_done(q)) {
 		qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
-		goto again;
+		if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+			tasklet_schedule(&q->tasklet);
 	}
 
 	qdio_stop_polling(q);
@@ -177,7 +176,8 @@ again:
 	 */
 	if (!tiqdio_inbound_q_done(q)) {
 		qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
-		goto again;
+		if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+			tasklet_schedule(&q->tasklet);
 	}
 }
 

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


  parent reply	other threads:[~2009-02-25 15:16 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-25 15:06 [patch/s390 00/46] s390 features patches for 2.6.30 Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 01/46] fix dump_stack vs. %p and (null) Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 02/46] Automatic IPL after dump Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 03/46] page fault: invoke oom-killer Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 04/46] dasd: enable compat ioctls Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 05/46] dasd_eckd / Write format R0 is now allowed BB Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 06/46] dasd: add large volume support Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 07/46] dasd: message cleanup Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 08/46] dasd: add High Performance FICON support Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 09/46] move sysinfo.c from drivers/s390 to arch/s390/kernel Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 10/46] delete drivers/s390/ebcdic.c Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 11/46] arch/s390/kernel/process.c: fix whitespace damage Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 12/46] cputime: initialize per thread timer values on fork Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 13/46] hvc_iucv: Update and add missing kernel messages Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 14/46] hvc_iucv: Provide IUCV z/VM user ID filtering Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 15/46] lockdep: trace hardirq off in smp_send_stop Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 16/46] check addressing mode in s390_enable_sie Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 17/46] Fix hypervisor detection for KVM Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 18/46] ftrace: dont trace machine check handler Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 19/46] Fix appldata build break with !NET Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 20/46] split/move machine check handler code Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 21/46] Remove CONFIG_MACHCHK_WARNING Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 22/46] convert bitmap definitions to C Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 23/46] move EXPORT_SYMBOLs to definitions Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 24/46] cio: Use unbind/bind instead of unregister/register Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 25/46] cio: Try harder to disable subchannel Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 26/46] cio: Use ccw_device_set_notoper() Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 27/46] cio: ccw device online store - report rc from ccw driver Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 28/46] cio/crw: add/fix locking Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 29/46] cio: ensure single load of irq handler pointer Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 30/46] cio: device scan oom fallback Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 31/46] clock sync mode flags Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 32/46] kernel: Disable switch_amode by default Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 33/46] Add zcrypt section in MAINTAINERS Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 34/46] topology: define SD_MC_INIT to fix performance regression Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 35/46] qdio: add missing tiq_list locking Martin Schwidefsky
2009-02-25 15:06 ` [patch/s390 36/46] qdio: Dont call qdio_shutdown in case qdio_activate fails Martin Schwidefsky
2009-02-25 15:06 ` Martin Schwidefsky [this message]
2009-02-25 15:07 ` [patch/s390 38/46] qdio: call qdio_free also if qdio_shutdown fails Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 39/46] qdio: move ACK to newest buffer for devices without QEBSM Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 40/46] allow usage of string functions in linux/string.h Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 41/46] s390: remove duplicate nul-termination of string Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 42/46] bitops: remove likely annotations Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 43/46] module function call optimization Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 44/46] use compiler builtin versions of strlen/strcpy/strcat Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 45/46] ftrace/mcount: fix kernel stack backchain Martin Schwidefsky
2009-02-25 15:07 ` [patch/s390 46/46] tape message cleanup Martin Schwidefsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090225150837.398862645@de.ibm.com \
    --to=schwidefsky@de.ibm.com \
    --cc=heiko.carstens@de.ibm.com \
    --cc=jang@linux.vnet.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox