linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH #upstream-fixes 1/2] libata: invert ATA_PFLAG_INITIALIZING to RUNNING
@ 2007-08-20 11:50 Tejun Heo
  2007-08-20 11:53 ` [PATCH #upstream-fixes 2/2] libata: prevent EH from being scheduled after port is detached Tejun Heo
  0 siblings, 1 reply; 3+ messages in thread
From: Tejun Heo @ 2007-08-20 11:50 UTC (permalink / raw)
  To: Jeff Garzik, linux-ide

Invert the meaning of ATA_PFLAG_INITIALIZING and rename it to
ATA_PFLAG_RUNNING.  This will be used to prevent EH from being
scheduled during host removal.

Signed-off-by: Tejun Heo <htejun@gmail.com>
---
 drivers/ata/libata-core.c |    4 +---
 drivers/ata/libata-eh.c   |    2 +-
 include/linux/libata.h    |    2 +-
 3 files changed, 3 insertions(+), 5 deletions(-)

Index: work/drivers/ata/libata-core.c
===================================================================
--- work.orig/drivers/ata/libata-core.c
+++ work/drivers/ata/libata-core.c
@@ -6052,7 +6052,6 @@ struct ata_port *ata_port_alloc(struct a
 	if (!ap)
 		return NULL;
 
-	ap->pflags |= ATA_PFLAG_INITIALIZING;
 	ap->lock = &host->lock;
 	ap->flags = ATA_FLAG_DISABLED;
 	ap->print_id = -1;
@@ -6428,8 +6427,7 @@ int ata_host_register(struct ata_host *h
 			ehi->action |= ATA_EH_SOFTRESET;
 			ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
 
-			ap->pflags &= ~ATA_PFLAG_INITIALIZING;
-			ap->pflags |= ATA_PFLAG_LOADING;
+			ap->pflags |= ATA_PFLAG_LOADING | ATA_PFLAG_RUNNING;
 			ata_port_schedule_eh(ap);
 
 			spin_unlock_irqrestore(ap->lock, flags);
Index: work/drivers/ata/libata-eh.c
===================================================================
--- work.orig/drivers/ata/libata-eh.c
+++ work/drivers/ata/libata-eh.c
@@ -709,7 +709,7 @@ void ata_port_schedule_eh(struct ata_por
 {
 	WARN_ON(!ap->ops->error_handler);
 
-	if (ap->pflags & ATA_PFLAG_INITIALIZING)
+	if (!(ap->pflags & ATA_PFLAG_RUNNING))
 		return;
 
 	ata_eh_set_pending(ap, 1);
Index: work/include/linux/libata.h
===================================================================
--- work.orig/include/linux/libata.h
+++ work/include/linux/libata.h
@@ -194,7 +194,7 @@ enum {
 	ATA_PFLAG_LOADING	= (1 << 4), /* boot/loading probe */
 	ATA_PFLAG_UNLOADING	= (1 << 5), /* module is unloading */
 	ATA_PFLAG_SCSI_HOTPLUG	= (1 << 6), /* SCSI hotplug scheduled */
-	ATA_PFLAG_INITIALIZING	= (1 << 7), /* being initialized, don't touch */
+	ATA_PFLAG_RUNNING	= (1 << 7), /* port up & running */
 
 	ATA_PFLAG_SUSPENDED	= (1 << 17), /* port is suspended (power) */
 	ATA_PFLAG_PM_PENDING	= (1 << 18), /* PM operation pending */

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH #upstream-fixes 2/2] libata: prevent EH from being scheduled after port is detached
  2007-08-20 11:50 [PATCH #upstream-fixes 1/2] libata: invert ATA_PFLAG_INITIALIZING to RUNNING Tejun Heo
@ 2007-08-20 11:53 ` Tejun Heo
  2007-08-20 12:27   ` Tejun Heo
  0 siblings, 1 reply; 3+ messages in thread
From: Tejun Heo @ 2007-08-20 11:53 UTC (permalink / raw)
  To: Jeff Garzik, linux-ide

SCSI EH thread is stopped during SCSI host release which can happen
after ATA host detach and free.  This leads to the following oops.

  general protection fault: 0000 [1] PREEMPT SMP 
  CPU 0 
  Modules linked in: ahci libata
  Pid: 98, comm: kblockd/0 Not tainted 2.6.23-rc2-work #19
  RIP: 0010:[<ffffffff80242aa7>]  [<ffffffff80242aa7>] run_workqueue+0xb7/0x190
  RSP: 0018:ffff81001fd2be80  EFLAGS: 00010087
  RAX: 6b6b6b6b6b6b6b6b RBX: ffff81001fae4a18 RCX: 1240000000000000
  RDX: 6b6b6b6b6b6b6b6b RSI: 9200000000000000 RDI: ffff81001fc1b930
  RBP: ffff81001fd2beb0 R08: fffffffffedc0049 R09: 0000000000000000
  R10: ffffffff80242a09 R11: 0000000000000000 R12: ffff81001fae4a10
  R13: ffff81001fc1b930 R14: 6b6b6b6b6b6b6b6b R15: ffff81001fc1b960
  FS:  0000000000000000(0000) GS:ffffffff808cb000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
  CR2: 00002b531964d890 CR3: 0000000000201000 CR4: 00000000000006e0
  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
  DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
  Process kblockd/0 (pid: 98, threadinfo ffff81001fd2a000, task ffff81001fe78140)
  Stack:  ffff81001fd2beb0 ffff81001fc1b970 ffff81001fc1b930 ffff81001fd2bec0
   ffff81001fc1b960 0000000000000000 ffff81001fd2bf10 ffffffff8024385a
   0000000000000000 ffff81001fe78140 ffffffff80247450 ffff81001fd2bed8
  Call Trace:
   [<ffffffff8024385a>] worker_thread+0xca/0x130
   [<ffffffff80247450>] autoremove_wake_function+0x0/0x40
   [<ffffffff80243790>] worker_thread+0x0/0x130
   [<ffffffff8024706d>] kthread+0x4d/0x80
   [<ffffffff8020cbf8>] child_rip+0xa/0x12
   [<ffffffff8020c2e0>] restore_args+0x0/0x30
   [<ffffffff80247178>] kthreadd+0xd8/0x160
   [<ffffffff80247020>] kthread+0x0/0x80
   [<ffffffff8020cbee>] child_rip+0x0/0x12

This patch clears ATA_PFLAG_RUNNING after final freeze and moves
ATA_PFLAG_RUNNING check into ata_eh_set_pending() to cover all EH
schedule functions.

Signed-off-by: Tejun Heo <htejun@gmail.com>
---
 drivers/ata/libata-core.c |    3 ++-
 drivers/ata/libata-eh.c   |    8 +++-----
 2 files changed, 5 insertions(+), 6 deletions(-)

Index: work/drivers/ata/libata-core.c
===================================================================
--- work.orig/drivers/ata/libata-core.c
+++ work/drivers/ata/libata-core.c
@@ -6547,7 +6547,8 @@ void ata_port_detach(struct ata_port *ap
 	 * target.
 	 */
 	spin_lock_irqsave(ap->lock, flags);
-	ata_port_freeze(ap);	/* won't be thawed */
+	ata_port_freeze(ap);			/* won't be thawed */
+	ap->pflags &= ~ATA_PFLAG_RUNNING;	/* port is dead now */
 	spin_unlock_irqrestore(ap->lock, flags);
 
 	ata_port_wait_eh(ap);
Index: work/drivers/ata/libata-eh.c
===================================================================
--- work.orig/drivers/ata/libata-eh.c
+++ work/drivers/ata/libata-eh.c
@@ -648,8 +648,9 @@ static void ata_eh_set_pending(struct at
 {
 	int cnt;
 
-	/* already scheduled? */
-	if (ap->pflags & ATA_PFLAG_EH_PENDING)
+	/* nothing to do if port isn't running or EH is already scheduled */
+	if (!(ap->pflags & ATA_PFLAG_RUNNING) ||
+	    (ap->pflags & ATA_PFLAG_EH_PENDING))
 		return;
 
 	ap->pflags |= ATA_PFLAG_EH_PENDING;
@@ -709,9 +710,6 @@ void ata_port_schedule_eh(struct ata_por
 {
 	WARN_ON(!ap->ops->error_handler);
 
-	if (!(ap->pflags & ATA_PFLAG_RUNNING))
-		return;
-
 	ata_eh_set_pending(ap, 1);
 	scsi_schedule_eh(ap->scsi_host);
 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH #upstream-fixes 2/2] libata: prevent EH from being scheduled after port is detached
  2007-08-20 11:53 ` [PATCH #upstream-fixes 2/2] libata: prevent EH from being scheduled after port is detached Tejun Heo
@ 2007-08-20 12:27   ` Tejun Heo
  0 siblings, 0 replies; 3+ messages in thread
From: Tejun Heo @ 2007-08-20 12:27 UTC (permalink / raw)
  To: Tejun Heo; +Cc: Jeff Garzik, linux-ide

Tejun Heo wrote:
> SCSI EH thread is stopped during SCSI host release which can happen
> after ATA host detach and free.  This leads to the following oops.
> 
>   general protection fault: 0000 [1] PREEMPT SMP 
>   CPU 0 
>   Modules linked in: ahci libata
>   Pid: 98, comm: kblockd/0 Not tainted 2.6.23-rc2-work #19
>   RIP: 0010:[<ffffffff80242aa7>]  [<ffffffff80242aa7>] run_workqueue+0xb7/0x190
>   RSP: 0018:ffff81001fd2be80  EFLAGS: 00010087
>   RAX: 6b6b6b6b6b6b6b6b RBX: ffff81001fae4a18 RCX: 1240000000000000
>   RDX: 6b6b6b6b6b6b6b6b RSI: 9200000000000000 RDI: ffff81001fc1b930
>   RBP: ffff81001fd2beb0 R08: fffffffffedc0049 R09: 0000000000000000
>   R10: ffffffff80242a09 R11: 0000000000000000 R12: ffff81001fae4a10
>   R13: ffff81001fc1b930 R14: 6b6b6b6b6b6b6b6b R15: ffff81001fc1b960
>   FS:  0000000000000000(0000) GS:ffffffff808cb000(0000) knlGS:0000000000000000
>   CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
>   CR2: 00002b531964d890 CR3: 0000000000201000 CR4: 00000000000006e0
>   DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>   DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
>   Process kblockd/0 (pid: 98, threadinfo ffff81001fd2a000, task ffff81001fe78140)
>   Stack:  ffff81001fd2beb0 ffff81001fc1b970 ffff81001fc1b930 ffff81001fd2bec0
>    ffff81001fc1b960 0000000000000000 ffff81001fd2bf10 ffffffff8024385a
>    0000000000000000 ffff81001fe78140 ffffffff80247450 ffff81001fd2bed8
>   Call Trace:
>    [<ffffffff8024385a>] worker_thread+0xca/0x130
>    [<ffffffff80247450>] autoremove_wake_function+0x0/0x40
>    [<ffffffff80243790>] worker_thread+0x0/0x130
>    [<ffffffff8024706d>] kthread+0x4d/0x80
>    [<ffffffff8020cbf8>] child_rip+0xa/0x12
>    [<ffffffff8020c2e0>] restore_args+0x0/0x30
>    [<ffffffff80247178>] kthreadd+0xd8/0x160
>    [<ffffffff80247020>] kthread+0x0/0x80
>    [<ffffffff8020cbee>] child_rip+0x0/0x12
> 
> This patch clears ATA_PFLAG_RUNNING after final freeze and moves
> ATA_PFLAG_RUNNING check into ata_eh_set_pending() to cover all EH
> schedule functions.

Oops, please hold a bit.  After 30min of testing, it happened again.  It
seems it needs more fixing.  I'll write when I know more.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-08-20 12:27 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-20 11:50 [PATCH #upstream-fixes 1/2] libata: invert ATA_PFLAG_INITIALIZING to RUNNING Tejun Heo
2007-08-20 11:53 ` [PATCH #upstream-fixes 2/2] libata: prevent EH from being scheduled after port is detached Tejun Heo
2007-08-20 12:27   ` Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).