public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH linux-2.6-block:master] block: fix try_module_get race in elevator_find
@ 2005-07-26 13:19 Tejun Heo
  2005-08-01 13:17 ` Jens Axboe
  0 siblings, 1 reply; 2+ messages in thread
From: Tejun Heo @ 2005-07-26 13:19 UTC (permalink / raw)
  To: axboe, linux-kernel

 Hello, Jens.

 This patch removes try_module_get race in elevator_find.
try_module_get should always be called with the spinlock protecting
what the module init/cleanup routines register/unregister to held.  In
the case of elevators, we should be holding elv_list to avoid it going
away between spin_unlock_irq and try_module_get.

 This currently doesn't cause any problem as elevators are never
unloaded, but the fix is simple and it's always nice to be correct.

Signed-off-by: Tejun Heo <htejun@gmail.com>

Index: blk-fixes/drivers/block/elevator.c
===================================================================
--- blk-fixes.orig/drivers/block/elevator.c	2005-07-25 23:16:11.000000000 +0900
+++ blk-fixes/drivers/block/elevator.c	2005-07-25 23:20:30.000000000 +0900
@@ -97,7 +97,6 @@ static struct elevator_type *elevator_fi
 	struct elevator_type *e = NULL;
 	struct list_head *entry;
 
-	spin_lock_irq(&elv_list_lock);
 	list_for_each(entry, &elv_list) {
 		struct elevator_type *__e;
 
@@ -108,7 +107,6 @@ static struct elevator_type *elevator_fi
 			break;
 		}
 	}
-	spin_unlock_irq(&elv_list_lock);
 
 	return e;
 }
@@ -120,12 +118,15 @@ static void elevator_put(struct elevator
 
 static struct elevator_type *elevator_get(const char *name)
 {
-	struct elevator_type *e = elevator_find(name);
+	struct elevator_type *e;
 
-	if (!e)
-		return NULL;
-	if (!try_module_get(e->elevator_owner))
-		return NULL;
+	spin_lock_irq(&elv_list_lock);
+
+	e = elevator_find(name);
+	if (e && !try_module_get(e->elevator_owner))
+		e = NULL;
+
+	spin_unlock_irq(&elv_list_lock);
 
 	return e;
 }
@@ -153,11 +154,15 @@ static char chosen_elevator[16];
 
 static void elevator_setup_default(void)
 {
+	struct elevator_type *e;
+
 	/*
 	 * check if default is set and exists
 	 */
-	if (chosen_elevator[0] && elevator_find(chosen_elevator))
+	if (chosen_elevator[0] && (e = elevator_get(chosen_elevator))) {
+		elevator_put(e);
 		return;
+	}
 
 #if defined(CONFIG_IOSCHED_AS)
 	strcpy(chosen_elevator, "anticipatory");
@@ -554,10 +559,9 @@ void elv_unregister_queue(struct request
 
 int elv_register(struct elevator_type *e)
 {
+	spin_lock_irq(&elv_list_lock);
 	if (elevator_find(e->elevator_name))
 		BUG();
-
-	spin_lock_irq(&elv_list_lock);
 	list_add_tail(&e->list, &elv_list);
 	spin_unlock_irq(&elv_list_lock);
 

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

* Re: [PATCH linux-2.6-block:master] block: fix try_module_get race in elevator_find
  2005-07-26 13:19 [PATCH linux-2.6-block:master] block: fix try_module_get race in elevator_find Tejun Heo
@ 2005-08-01 13:17 ` Jens Axboe
  0 siblings, 0 replies; 2+ messages in thread
From: Jens Axboe @ 2005-08-01 13:17 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-kernel

On Tue, Jul 26 2005, Tejun Heo wrote:
>  Hello, Jens.
> 
>  This patch removes try_module_get race in elevator_find.
> try_module_get should always be called with the spinlock protecting
> what the module init/cleanup routines register/unregister to held.  In
> the case of elevators, we should be holding elv_list to avoid it going
> away between spin_unlock_irq and try_module_get.
> 
>  This currently doesn't cause any problem as elevators are never
> unloaded, but the fix is simple and it's always nice to be correct.

Looks good. Elevators _are_ unloaded, right now you just can't unload as
and cfq because they use io contexts. But that will happen in the future
as well.

-- 
Jens Axboe


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

end of thread, other threads:[~2005-08-01 13:15 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-26 13:19 [PATCH linux-2.6-block:master] block: fix try_module_get race in elevator_find Tejun Heo
2005-08-01 13:17 ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox