]> git.hungrycats.org Git - linux/commitdiff
[PATCH] IDE: Fix Power Management request race on resume
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 9 Sep 2003 05:09:41 +0000 (22:09 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Tue, 9 Sep 2003 05:09:41 +0000 (22:09 -0700)
The current IDE Power Management code I wrote has a race on wakeup when
the master device got resumed, it may take a request.  At this point, a
PM resume request to a slave device of the same hwgroup would clear
hwgroup->rq and cause an Oops when the master device request completes.

This patch fixes it.  Due to the context in which PM resume requests are
sent, just not clearing hwgroup->rq for these is enough.

I also removed a useless debug message in the PM code that was
actually misleading (people though it indicated a problem while it
didn't, it's really useless) and fix a typo in a comment.

drivers/ide/ide-io.c

index 0d9fff1f883db5b2aa1edd88cd0f6c5c9f62dd17..5295420010db71f245826d727529771f5ff03142 100644 (file)
@@ -928,13 +928,10 @@ queue_next:
                 * 
                 * We let requests forced at head of queue with ide-preempt
                 * though. I hope that doesn't happen too much, hopefully not
-                * unless the subdriver triggers such a thing in it's own PM
+                * unless the subdriver triggers such a thing in its own PM
                 * state machine.
                 */
                if (drive->blocked && !blk_pm_request(rq) && !(rq->flags & REQ_PREEMPT)) {
-#ifdef DEBUG_PM
-                       printk("%s: a request made it's way while we are power managing...\n", drive->name);
-#endif
                        /* We clear busy, there should be no pending ATA command at this point. */
                        hwgroup->busy = 0;
                        break;
@@ -1417,8 +1414,9 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
        }
 
        spin_lock_irqsave(&ide_lock, flags);
-       if (action == ide_preempt || action == ide_head_wait) {
+       if (action == ide_preempt)
                hwgroup->rq = NULL;
+       if (action == ide_preempt || action == ide_head_wait) {
                where = ELEVATOR_INSERT_FRONT;
                rq->flags |= REQ_PREEMPT;
        }