lkml.org 
[lkml]   [2008]   [Apr]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
Date
SubjectRE: [patch] cciss: Fix race between disk-adding code and interrupt handler


> -----Original Message-----
> From: scameron@beardog.cca.cpqcorp.net
> [mailto:scameron@beardog.cca.cpqcorp.net]
> Sent: Wednesday, April 16, 2008 1:59 PM
> To: Jens Axboe
> Cc: linux-kernel@vger.kernel.org; Miller, Mike (OS Dev);
> mikem@beardog.cca.cpqcorp.net
> Subject: Re: [patch] cciss: Fix race between disk-adding code
> and interrupt handler
>
>
> Fix race condition between cciss_init_one(),
> cciss_update_drive_info(), and cciss_check_queues().
>
> Signed-off-by: Stephen M. Cameron <scameron@beardog.cca.cpqcorp.net>

Acked-by: Mike Miller <mike.miller@hp.com>

>
> ---
>
> linux-2.6.25-rc9/drivers/block/cciss.c | 17 ++++++++++++++++-
> drivers/block/cciss.h | 0
> 2 files changed, 16 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-16 08:15:38.000000000 -0500
> @@ -1349,6 +1349,10 @@ static void cciss_update_drive_info(int
> spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
> h->drv[drv_index].busy_configuring = 1;
> spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
> +
> + /* deregister_disk sets
> h->drv[drv_index].queue = NULL */
> + /* which keeps the interrupt handler from starting */
> + /* the queue. */
> ret = deregister_disk(h->gendisk[drv_index],
> &h->drv[drv_index], 0);
> h->drv[drv_index].busy_configuring = 0; @@
> -1419,6 +1423,10 @@ geo_inq:
> blk_queue_hardsect_size(disk->queue,
>
> hba[ctlr]->drv[drv_index].block_size);
>
> + /* Make sure all queue data is written out before */
> + /* setting h->drv[drv_index].queue, as setting this */
> + /* allows the interrupt handler to start the queue */
> + wmb();
> h->drv[drv_index].queue = disk->queue;
> add_disk(disk);
> }
> @@ -3520,10 +3528,17 @@ static int __devinit cciss_init_one(stru
> continue;
> blk_queue_hardsect_size(q, drv->block_size);
> set_capacity(disk, drv->nr_blocks);
> - add_disk(disk);
> j++;
> } while (j <= hba[i]->highest_lun);
>
> + /* Make sure all queue data is written out before */
> + /* interrupt handler, triggered by add_disk, */
> + /* is allowed to start them. */
> + wmb();
> +
> + for (j = 0; j <= hba[i]->highest_lun; j++)
> + add_disk(hba[i]->gendisk[j]);
> +
> return 1;
>
> clean4:
> diff -puN
> linux-2.6.25-rc9/drivers/block/cciss.h~cciss_init_one_race
> linux-2.6.25-rc9/drivers/block/cciss.h
> _
>
>


\
 
 \ /
  Last update: 2008-04-16 21:07    [W:0.116 / U:0.840 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site