Skip to contentSkip to conversation

2.5.66-bk5 spinlock warnings/errors - Specifically ide-io:109 spinlock notice

DISCUSSION Manfred Spraul 2 participants 4 messages Apr 3, 2003 – Apr 16, 2003

lore
Share & tools
lore
#0 lore raw
Quoted 5 lines · Shawn
Quoted 2 lines
List:     linux-kernel
Subject:  2.5.66-bk5 spinlock warnings/errors

From: Narayan Desai <desai () mcs ! anl ! gov>

Quoted 1 line

Date: 2003-04-02 4:01:02

Quoted 9 lines
Quoted 5 lines

hda: dma_timer_expiry: dma status == 0x24
drivers/ide/ide-io.c:109: spin_lock(drivers/ide/ide.c:c037abe8) already locked by drivers/ide/ide-io.c/948 drivers/ide/ide-io.c:990: spin_unlock(drivers/ide/ide.c:c037abe8) not locked
hda: lost interrupt
hda: dma_intr: bad DMA status (dma_stat=30)
hda: dma_intr: status=0x50 { DriveReady SeekComplete }

I had this problem last night while making a huge debian package (tar.bz2 stage). It occured once.

The attached patch should fix the problem:
the dma_timer_expiry handler calls HWGROUP(drive)->handler in the wrong context. Instead of calling ->handler directly, the ->expiry handler must inform the caller that ->handler must be called, and then the caller must do some setup before calling ->handler.

--
Manfred

// $Header$
// Kernel Version:

//  VERSION = 2
//  PATCHLEVEL = 5
//  SUBLEVEL = 66
//  EXTRAVERSION =
include/linux/ide.h +2 -0
@@ -1043,6 +1043,8 @@
 typedef ide_startstop_t (ide_handler_t)(ide_drive_t *);
 typedef ide_startstop_t (ide_post_handler_t)(ide_drive_t *);
 typedef int (ide_expiry_t)(ide_drive_t *);
+#define EXPIRY_ABORT		(0)
+#define EXPIRY_CALLHANDLER	(-1)
 
 typedef struct hwgroup_s {
 		/* irq handler, if active */
drivers/ide/ide-io.c +2 -2
@@ -973,7 +973,7 @@
 			}
 			if ((expiry = hwgroup->expiry) != NULL) {
 				/* continue */
-				if ((wait = expiry(drive)) != 0) {
+				if ((wait = expiry(drive)) > 0) {
 					/* reset timer */
 					hwgroup->timer.expires  = jiffies + wait;
 					add_timer(&hwgroup->timer);
@@ -998,7 +998,7 @@
 			/* local CPU only,
 			 * as if we were handling an interrupt */
 			local_irq_disable();
-			if (hwgroup->poll_timeout != 0) {
+			if (hwgroup->poll_timeout != 0 || wait == EXPIRY_CALLHANDLER) {
 				startstop = handler(drive);
 			} else if (drive_is_ready(drive)) {
 				if (drive->waiting_for_dma)
drivers/ide/ide-dma.c +2 -2
@@ -483,9 +483,9 @@
 		return WAIT_CMD;
 
 	if (dma_stat & 4)	/* Got an Interrupt */
-		HWGROUP(drive)->handler(drive);
+		return EXPIRY_CALLHANDLER;
 
-	return 0;
+	return EXPIRY_ABORT;
 }
 
 /**
#1 lore raw

I will test this tonight when I get home :-)

Quoted 28 lines · Manfred Spraul
Quoted 13 lines · Shawn
Quoted 2 lines
List:     linux-kernel
Subject:  2.5.66-bk5 spinlock warnings/errors

From: Narayan Desai <desai () mcs ! anl ! gov>

Quoted 9 lines

Date: 2003-04-02 4:01:02

hda: dma_timer_expiry: dma status == 0x24 drivers/ide/ide-io.c:109: spin_lock(drivers/ide/ide.c:c037abe8) already locked by drivers/ide/ide-io.c/948 drivers/ide/ide-io.c:990:
spin_unlock(drivers/ide/ide.c:c037abe8) not locked
hda: lost interrupt
hda: dma_intr: bad DMA status (dma_stat=30)
hda: dma_intr: status=0x50 { DriveReady SeekComplete }

Quoted 4 lines

I had this problem last night while making a huge debian package (tar.bz2 stage). It occured once.

The attached patch should fix the problem:
the dma_timer_expiry handler calls HWGROUP(drive)->handler in the wrong context. Instead of calling ->handler directly, the ->expiry handler must inform the caller that ->handler must be called, and then the caller must do some setup before calling ->handler.

--
Manfred

#2 lore raw
In reply to Manfred Spraul

I'm going to apply this and see what happens, unless it was already added to .67-bk latest?

Shawn.

----- Original Message -----
From: "Manfred Spraul" <[email protected]>
To: "Shawn Starr" <[email protected]>
Cc: "Narayan Desai" <[email protected]>; <[email protected]>
Sent: Thursday, April 03, 2003 1:48 AM
Subject: Re: 2.5.66-bk5 spinlock warnings/errors - Specifically ide-io:109 spinlock notice

Quoted 19 lines
Quoted 13 lines · Shawn
Quoted 2 lines
List:     linux-kernel
Subject:  2.5.66-bk5 spinlock warnings/errors

From: Narayan Desai <desai () mcs ! anl ! gov>

Quoted 9 lines

Date: 2003-04-02 4:01:02

hda: dma_timer_expiry: dma status == 0x24 drivers/ide/ide-io.c:109: spin_lock(drivers/ide/ide.c:c037abe8) already locked by drivers/ide/ide-io.c/948 drivers/ide/ide-io.c:990:
spin_unlock(drivers/ide/ide.c:c037abe8) not locked
hda: lost interrupt
hda: dma_intr: bad DMA status (dma_stat=30)
hda: dma_intr: status=0x50 { DriveReady SeekComplete }

Quoted 4 lines

I had this problem last night while making a huge debian package (tar.bz2 stage). It occured once.

Quoted 9 lines

The attached patch should fix the problem:
the dma_timer_expiry handler calls HWGROUP(drive)->handler in the wrong context. Instead of calling ->handler directly, the ->expiry handler must inform the caller that ->handler must be called, and then the caller must do some setup before calling ->handler.

--
Manfred

----------------------------------------------------------------------------
----

Quoted 52 lines

// $Header$
// Kernel Version:

//  VERSION = 2
//  PATCHLEVEL = 5
//  SUBLEVEL = 66
//  EXTRAVERSION =
include/linux/ide.h 2003-03-30 10:04:08.000000000 +0200 renamed from include/linux/ide.h 2003-03-25 17:49:52.000000000 +0100 +2 -0
@@ -1043,6 +1043,8 @@
 typedef ide_startstop_t (ide_handler_t)(ide_drive_t *);
 typedef ide_startstop_t (ide_post_handler_t)(ide_drive_t *);
 typedef int (ide_expiry_t)(ide_drive_t *);
+#define EXPIRY_ABORT (0)
+#define EXPIRY_CALLHANDLER (-1)
 
 typedef struct hwgroup_s {
  /* irq handler, if active */
drivers/ide/ide-io.c 2003-03-30 10:05:28.000000000 +0200 renamed from drivers/ide/ide-io.c 2003-03-25 17:49:40.000000000 +0100 +2 -2
@@ -973,7 +973,7 @@
  }
  if ((expiry = hwgroup->expiry) != NULL) {
  /* continue */
- if ((wait = expiry(drive)) != 0) {
+ if ((wait = expiry(drive)) > 0) {
  /* reset timer */
  hwgroup->timer.expires  = jiffies + wait;
  add_timer(&hwgroup->timer);
@@ -998,7 +998,7 @@
  /* local CPU only,
  * as if we were handling an interrupt */
  local_irq_disable();
- if (hwgroup->poll_timeout != 0) {
+ if (hwgroup->poll_timeout != 0 || wait == EXPIRY_CALLHANDLER) {
  startstop = handler(drive);
  } else if (drive_is_ready(drive)) {
  if (drive->waiting_for_dma)
drivers/ide/ide-dma.c 2003-03-30 10:05:54.000000000 +0200 renamed from drivers/ide/ide-dma.c 2003-03-25 17:49:40.000000000 +0100 +2 -2
@@ -483,9 +483,9 @@
  return WAIT_CMD;
 
  if (dma_stat & 4) /* Got an Interrupt */
- HWGROUP(drive)->handler(drive);
+ return EXPIRY_CALLHANDLER;
 
- return 0;
+ return EXPIRY_ABORT;
 }
 
 /**
#3 lore raw
Quoted 4 lines · Shawn Starr

I'm going to apply this and see what happens, unless it was already added to .67-bk latest?

Alan included it into the -ac kernels, I guess he will forward it to Linus.

Quoted 7 lines

drivers/ide/ide-io.c 2003-03-30 10:05:28.000000000 +0200 line 976

Quoted 7 lines
drivers/ide/ide-io.c 2003-03-30 10:05:28.000000000 +0200 renamed from drivers/ide/ide-io.c 2003-03-25 17:49:40.000000000 +0100 +0 -0
@@ -973,7 +973,7 @@
 
 
 }
 

+ wait = 0;

Quoted 8 lines
Quoted 8 lines
drivers/ide/ide-io.c 2003-03-30 10:05:28.000000000 +0200 renamed from drivers/ide/ide-io.c 2003-03-25 17:49:40.000000000 +0100 +1 -1
 if ((expiry = hwgroup->expiry) != NULL) {
 /* continue */
- if ((wait = expiry(drive)) != 0) {
+ if ((wait = expiry(drive)) > 0) {

/* reset timer */
hwgroup->timer.expires = jiffies + wait;
add_timer(&hwgroup->timer);

This change was missing in my patch: wait was used without initialization.

--
Manfred