mirror of https://gitee.com/openkylin/linux.git
hd: stop sharing request queue across multiple gendisks
Compile-tested only. Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
parent
53696b8d21
commit
a893cd76bb
|
@ -95,7 +95,7 @@
|
|||
#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
|
||||
|
||||
static DEFINE_SPINLOCK(hd_lock);
|
||||
static struct request_queue *hd_queue;
|
||||
static unsigned int hd_queue;
|
||||
static struct request *hd_req;
|
||||
|
||||
#define TIMEOUT_VALUE (6*HZ)
|
||||
|
@ -537,7 +537,7 @@ static void hd_times_out(unsigned long dummy)
|
|||
if (!hd_req)
|
||||
return;
|
||||
|
||||
spin_lock_irq(hd_queue->queue_lock);
|
||||
spin_lock_irq(&hd_lock);
|
||||
reset = 1;
|
||||
name = hd_req->rq_disk->disk_name;
|
||||
printk("%s: timeout\n", name);
|
||||
|
@ -548,7 +548,7 @@ static void hd_times_out(unsigned long dummy)
|
|||
hd_end_request_cur(-EIO);
|
||||
}
|
||||
hd_request();
|
||||
spin_unlock_irq(hd_queue->queue_lock);
|
||||
spin_unlock_irq(&hd_lock);
|
||||
}
|
||||
|
||||
static int do_special_op(struct hd_i_struct *disk, struct request *req)
|
||||
|
@ -566,6 +566,25 @@ static int do_special_op(struct hd_i_struct *disk, struct request *req)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int set_next_request(void)
|
||||
{
|
||||
struct request_queue *q;
|
||||
int old_pos = hd_queue;
|
||||
|
||||
do {
|
||||
q = hd_gendisk[hd_queue]->queue;
|
||||
if (++hd_queue == NR_HD)
|
||||
hd_queue = 0;
|
||||
if (q) {
|
||||
hd_req = blk_fetch_request(q);
|
||||
if (hd_req)
|
||||
break;
|
||||
}
|
||||
} while (hd_queue != old_pos);
|
||||
|
||||
return hd_req != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The driver enables interrupts as much as possible. In order to do this,
|
||||
* (a) the device-interrupt is disabled before entering hd_request(),
|
||||
|
@ -587,12 +606,9 @@ static void hd_request(void)
|
|||
repeat:
|
||||
del_timer(&device_timer);
|
||||
|
||||
if (!hd_req) {
|
||||
hd_req = blk_fetch_request(hd_queue);
|
||||
if (!hd_req) {
|
||||
do_hd = NULL;
|
||||
return;
|
||||
}
|
||||
if (!hd_req && !set_next_request()) {
|
||||
do_hd = NULL;
|
||||
return;
|
||||
}
|
||||
req = hd_req;
|
||||
|
||||
|
@ -676,7 +692,7 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id)
|
|||
{
|
||||
void (*handler)(void) = do_hd;
|
||||
|
||||
spin_lock(hd_queue->queue_lock);
|
||||
spin_lock(&hd_lock);
|
||||
|
||||
do_hd = NULL;
|
||||
del_timer(&device_timer);
|
||||
|
@ -684,7 +700,7 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id)
|
|||
handler = unexpected_hd_interrupt;
|
||||
handler();
|
||||
|
||||
spin_unlock(hd_queue->queue_lock);
|
||||
spin_unlock(&hd_lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -700,16 +716,8 @@ static int __init hd_init(void)
|
|||
if (register_blkdev(HD_MAJOR, "hd"))
|
||||
return -1;
|
||||
|
||||
hd_queue = blk_init_queue(do_hd_request, &hd_lock);
|
||||
if (!hd_queue) {
|
||||
unregister_blkdev(HD_MAJOR, "hd");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
blk_queue_max_hw_sectors(hd_queue, 255);
|
||||
init_timer(&device_timer);
|
||||
device_timer.function = hd_times_out;
|
||||
blk_queue_logical_block_size(hd_queue, 512);
|
||||
|
||||
if (!NR_HD) {
|
||||
/*
|
||||
|
@ -742,7 +750,11 @@ static int __init hd_init(void)
|
|||
sprintf(disk->disk_name, "hd%c", 'a'+drive);
|
||||
disk->private_data = p;
|
||||
set_capacity(disk, p->head * p->sect * p->cyl);
|
||||
disk->queue = hd_queue;
|
||||
disk->queue = blk_init_queue(do_hd_request, &hd_lock);
|
||||
if (!disk->queue)
|
||||
goto Enomem;
|
||||
blk_queue_max_hw_sectors(disk->queue, 255);
|
||||
blk_queue_logical_block_size(disk->queue, 512);
|
||||
p->unit = drive;
|
||||
hd_gendisk[drive] = disk;
|
||||
printk("%s: %luMB, CHS=%d/%d/%d\n",
|
||||
|
@ -781,11 +793,15 @@ static int __init hd_init(void)
|
|||
out:
|
||||
del_timer(&device_timer);
|
||||
unregister_blkdev(HD_MAJOR, "hd");
|
||||
blk_cleanup_queue(hd_queue);
|
||||
return -1;
|
||||
Enomem:
|
||||
while (drive--)
|
||||
put_disk(hd_gendisk[drive]);
|
||||
for (drive = 0; drive < NR_HD; drive++) {
|
||||
if (hd_gendisk[drive]) {
|
||||
if (hd_gendisk[drive]->queue)
|
||||
blk_cleanup_queue(hd_gendisk[drive]->queue);
|
||||
put_disk(hd_gendisk[drive]);
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue