All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch] cciss: Fix race between disk-adding code and interrupt handler
@ 2008-04-14 14:20 scameron
  2008-04-14 17:05 ` Jens Axboe
  0 siblings, 1 reply; 12+ messages in thread
From: scameron @ 2008-04-14 14:20 UTC (permalink / raw)
  To: linux-kernel, axboe, mike.miller, mikem



Fix race condition between cciss_init_one(), cciss_update_drive_info(),
and cciss_check_queues().  cciss_softirq_done would try to start
queues which were not quite ready to be started, as its checks for
readiness were not sufficiently synchronized with the queue initializing
code in cciss_init_one and cciss_update_drive_info.  Slow cpu and
large numbers of logical drives seem to make the race more likely 
to cause a problem.


Signed-off-by: Stephen M. Cameron <scameron@beardog.cca.cpqcorp.net>

---

 linux-2.6.25-rc9/drivers/block/cciss.c |   25 ++++++++++++++++++++++++-
 linux-2.6.25-rc9/drivers/block/cciss.h |    3 +++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff -puN linux-2.6.25-rc9/drivers/block/cciss.c~cciss_init_one_race linux-2.6.25-rc9/drivers/block/cciss.c
--- linux-2.6.25-rc9/linux-2.6.25-rc9/drivers/block/cciss.c~cciss_init_one_race	2008-04-14 08:21:03.000000000 -0500
+++ linux-2.6.25-rc9-scameron/linux-2.6.25-rc9/drivers/block/cciss.c	2008-04-14 08:22:04.000000000 -0500
@@ -1270,7 +1270,9 @@ static void cciss_check_queues(ctlr_info
 		/* make sure the disk has been added and the drive is real
 		 * because this can be called from the middle of init_one.
 		 */
-		if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads))
+		if (!(h->drv[curr_queue].queue) ||
+			!(h->drv[curr_queue].heads) ||
+			!h->drv[curr_queue].queue_ready)
 			continue;
 		blk_start_queue(h->gendisk[curr_queue]->queue);
 
@@ -1394,6 +1396,11 @@ geo_inq:
 
 	/* if it's the controller it's already added */
 	if (drv_index) {
+
+		/* Prevent race with interrupt handler's queue starting code. */
+		h->drv[drv_index].queue_ready = 0;
+		wmb();
+
 		disk->queue = blk_init_queue(do_cciss_request, &h->lock);
 		sprintf(disk->disk_name, "cciss/c%dd%d", ctlr, drv_index);
 		disk->major = h->major;
@@ -1420,6 +1427,11 @@ geo_inq:
 					hba[ctlr]->drv[drv_index].block_size);
 
 		h->drv[drv_index].queue = disk->queue;
+
+		/* Prevent race with interrupt handler's queue starting code. */
+		wmb();
+		h->drv[drv_index].queue_ready = 1;
+
 		add_disk(disk);
 	}
 
@@ -3473,6 +3485,11 @@ static int __devinit cciss_init_one(stru
 		struct gendisk *disk = hba[i]->gendisk[j];
 		struct request_queue *q;
 
+		/* prevent race with interrupt handler's */
+		/* queue starting code. */
+		drv->queue_ready = 0;
+		wmb();
+
 		/* Check if the disk was allocated already */
 		if (!disk){
 			hba[i]->gendisk[j] = alloc_disk(1 << NWD_SHIFT);
@@ -3520,6 +3537,12 @@ static int __devinit cciss_init_one(stru
 			continue;
 		blk_queue_hardsect_size(q, drv->block_size);
 		set_capacity(disk, drv->nr_blocks);
+
+		/* prevent race with interrupt handler's */
+		/* queue starting code. */
+		wmb();
+		drv->queue_ready = 1;
+
 		add_disk(disk);
 		j++;
 	} while (j <= hba[i]->highest_lun);
diff -puN linux-2.6.25-rc9/drivers/block/cciss.h~cciss_init_one_race linux-2.6.25-rc9/drivers/block/cciss.h
--- linux-2.6.25-rc9/linux-2.6.25-rc9/drivers/block/cciss.h~cciss_init_one_race	2008-04-14 08:21:06.000000000 -0500
+++ linux-2.6.25-rc9-scameron/linux-2.6.25-rc9/drivers/block/cciss.h	2008-04-14 08:21:58.000000000 -0500
@@ -39,6 +39,9 @@ typedef struct _drive_info_struct
 				   *to prevent it from being opened or it's queue
 				   *from being started.
 				  */
+	int queue_ready; /* This is used to prevent the interrupt handler */
+			 /* from racing (while starting up queues) with */
+			 /* cciss_init_one() (while setting up new queues) */
 } drive_info_struct;
 
 #ifdef CONFIG_CISS_SCSI_TAPE
_

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

end of thread, other threads:[~2008-04-17 11:16 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-14 14:20 [patch] cciss: Fix race between disk-adding code and interrupt handler scameron
2008-04-14 17:05 ` Jens Axboe
2008-04-14 17:27   ` scameron
2008-04-14 17:37     ` Jens Axboe
2008-04-14 17:45       ` scameron
2008-04-14 17:52         ` Jens Axboe
2008-04-16 18:59           ` scameron
2008-04-16 19:03             ` Miller, Mike (OS Dev)
2008-04-17 11:16             ` Jens Axboe
2008-04-16 19:00           ` [patch] cciss: fix warning oops on rmmod of driver scameron
2008-04-16 19:18             ` Miller, Mike (OS Dev)
2008-04-17 11:15             ` Jens Axboe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.