Commit 6f4d1d80 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Linus Torvalds

[PATCH] IDE: Fix Power Management request race on resume

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.
parent fe30003b
...@@ -928,13 +928,10 @@ void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) ...@@ -928,13 +928,10 @@ void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
* *
* We let requests forced at head of queue with ide-preempt * We let requests forced at head of queue with ide-preempt
* though. I hope that doesn't happen too much, hopefully not * 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. * state machine.
*/ */
if (drive->blocked && !blk_pm_request(rq) && !(rq->flags & REQ_PREEMPT)) { 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. */ /* We clear busy, there should be no pending ATA command at this point. */
hwgroup->busy = 0; hwgroup->busy = 0;
break; break;
...@@ -1417,8 +1414,9 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio ...@@ -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); spin_lock_irqsave(&ide_lock, flags);
if (action == ide_preempt || action == ide_head_wait) { if (action == ide_preempt)
hwgroup->rq = NULL; hwgroup->rq = NULL;
if (action == ide_preempt || action == ide_head_wait) {
where = ELEVATOR_INSERT_FRONT; where = ELEVATOR_INSERT_FRONT;
rq->flags |= REQ_PREEMPT; rq->flags |= REQ_PREEMPT;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment