Commit a893cd76 authored by Omar Sandoval's avatar Omar Sandoval Committed by Jens Axboe

hd: stop sharing request queue across multiple gendisks

Compile-tested only.
Signed-off-by: default avatarOmar Sandoval <osandov@fb.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 53696b8d
...@@ -95,7 +95,7 @@ ...@@ -95,7 +95,7 @@
#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ #define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
static DEFINE_SPINLOCK(hd_lock); static DEFINE_SPINLOCK(hd_lock);
static struct request_queue *hd_queue; static unsigned int hd_queue;
static struct request *hd_req; static struct request *hd_req;
#define TIMEOUT_VALUE (6*HZ) #define TIMEOUT_VALUE (6*HZ)
...@@ -537,7 +537,7 @@ static void hd_times_out(unsigned long dummy) ...@@ -537,7 +537,7 @@ static void hd_times_out(unsigned long dummy)
if (!hd_req) if (!hd_req)
return; return;
spin_lock_irq(hd_queue->queue_lock); spin_lock_irq(&hd_lock);
reset = 1; reset = 1;
name = hd_req->rq_disk->disk_name; name = hd_req->rq_disk->disk_name;
printk("%s: timeout\n", name); printk("%s: timeout\n", name);
...@@ -548,7 +548,7 @@ static void hd_times_out(unsigned long dummy) ...@@ -548,7 +548,7 @@ static void hd_times_out(unsigned long dummy)
hd_end_request_cur(-EIO); hd_end_request_cur(-EIO);
} }
hd_request(); 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) 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) ...@@ -566,6 +566,25 @@ static int do_special_op(struct hd_i_struct *disk, struct request *req)
return 1; 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, * The driver enables interrupts as much as possible. In order to do this,
* (a) the device-interrupt is disabled before entering hd_request(), * (a) the device-interrupt is disabled before entering hd_request(),
...@@ -587,12 +606,9 @@ static void hd_request(void) ...@@ -587,12 +606,9 @@ static void hd_request(void)
repeat: repeat:
del_timer(&device_timer); del_timer(&device_timer);
if (!hd_req) { if (!hd_req && !set_next_request()) {
hd_req = blk_fetch_request(hd_queue); do_hd = NULL;
if (!hd_req) { return;
do_hd = NULL;
return;
}
} }
req = hd_req; req = hd_req;
...@@ -676,7 +692,7 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id) ...@@ -676,7 +692,7 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id)
{ {
void (*handler)(void) = do_hd; void (*handler)(void) = do_hd;
spin_lock(hd_queue->queue_lock); spin_lock(&hd_lock);
do_hd = NULL; do_hd = NULL;
del_timer(&device_timer); del_timer(&device_timer);
...@@ -684,7 +700,7 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id) ...@@ -684,7 +700,7 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id)
handler = unexpected_hd_interrupt; handler = unexpected_hd_interrupt;
handler(); handler();
spin_unlock(hd_queue->queue_lock); spin_unlock(&hd_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -700,16 +716,8 @@ static int __init hd_init(void) ...@@ -700,16 +716,8 @@ static int __init hd_init(void)
if (register_blkdev(HD_MAJOR, "hd")) if (register_blkdev(HD_MAJOR, "hd"))
return -1; 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); init_timer(&device_timer);
device_timer.function = hd_times_out; device_timer.function = hd_times_out;
blk_queue_logical_block_size(hd_queue, 512);
if (!NR_HD) { if (!NR_HD) {
/* /*
...@@ -742,7 +750,11 @@ static int __init hd_init(void) ...@@ -742,7 +750,11 @@ static int __init hd_init(void)
sprintf(disk->disk_name, "hd%c", 'a'+drive); sprintf(disk->disk_name, "hd%c", 'a'+drive);
disk->private_data = p; disk->private_data = p;
set_capacity(disk, p->head * p->sect * p->cyl); 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; p->unit = drive;
hd_gendisk[drive] = disk; hd_gendisk[drive] = disk;
printk("%s: %luMB, CHS=%d/%d/%d\n", printk("%s: %luMB, CHS=%d/%d/%d\n",
...@@ -781,11 +793,15 @@ static int __init hd_init(void) ...@@ -781,11 +793,15 @@ static int __init hd_init(void)
out: out:
del_timer(&device_timer); del_timer(&device_timer);
unregister_blkdev(HD_MAJOR, "hd"); unregister_blkdev(HD_MAJOR, "hd");
blk_cleanup_queue(hd_queue);
return -1; return -1;
Enomem: Enomem:
while (drive--) for (drive = 0; drive < NR_HD; drive++) {
put_disk(hd_gendisk[drive]); if (hd_gendisk[drive]) {
if (hd_gendisk[drive]->queue)
blk_cleanup_queue(hd_gendisk[drive]->queue);
put_disk(hd_gendisk[drive]);
}
}
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment