summary refs log tree commit diff
path: root/block/as-iosched.c
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2008-02-01 09:44:28 +0100
committerJens Axboe <jens.axboe@oracle.com>2008-02-01 09:44:28 +0100
commit8bdd3f8a6993fef2f364aca6e1a59559405773a2 (patch)
treecbf07985c3396417932002be5cd5e4f2c47433e9 /block/as-iosched.c
parent4f4f6c2502474f51654a699d7127d86c2f87075a (diff)
downloadlinux-8bdd3f8a6993fef2f364aca6e1a59559405773a2.tar.gz
as-iosched: fix inconsistent ioc->lock context
Since it's acquired from irq context, all locking must be of the
irq safe variant. Most are already inside the queue lock (which
already disables interrupts), but the io scheduler rmmod path
always has irqs enabled and the put_io_context() path may legally
be called with irqs enabled (even if it isn't usually). So fixup
those two.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/as-iosched.c')
-rw-r--r--block/as-iosched.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/block/as-iosched.c b/block/as-iosched.c
index 96036846a001..612d64096300 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -170,11 +170,11 @@ static void free_as_io_context(struct as_io_context *aic)
 
 static void as_trim(struct io_context *ioc)
 {
-	spin_lock(&ioc->lock);
+	spin_lock_irq(&ioc->lock);
 	if (ioc->aic)
 		free_as_io_context(ioc->aic);
 	ioc->aic = NULL;
-	spin_unlock(&ioc->lock);
+	spin_unlock_irq(&ioc->lock);
 }
 
 /* Called when the task exits */
@@ -235,10 +235,12 @@ static void as_put_io_context(struct request *rq)
 	aic = RQ_IOC(rq)->aic;
 
 	if (rq_is_sync(rq) && aic) {
-		spin_lock(&aic->lock);
+		unsigned long flags;
+
+		spin_lock_irqsave(&aic->lock, flags);
 		set_bit(AS_TASK_IORUNNING, &aic->state);
 		aic->last_end_request = jiffies;
-		spin_unlock(&aic->lock);
+		spin_unlock_irqrestore(&aic->lock, flags);
 	}
 
 	put_io_context(RQ_IOC(rq));