lkml.org 
[lkml]   [2008]   [Apr]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [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>

    ---

    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:03    [W:0.057 / U:30.488 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site