forked from Minki/linux
floppy: convert to blk-mq
This driver likes to fetch requests from all over the place, so make queue_rq put requests on a list so that the logic stays the same. Tested with QEMU. Signed-off-by: Omar Sandoval <osandov@fb.com> Converted to blk_mq_init_sq_queue() and fixed a few spots where the tag_set leaked on cleanup. Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
6ec3938cff
commit
a9f38e1dec
@ -252,13 +252,13 @@ static int allowed_drive_mask = 0x33;
|
|||||||
|
|
||||||
static int irqdma_allocated;
|
static int irqdma_allocated;
|
||||||
|
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blk-mq.h>
|
||||||
#include <linux/blkpg.h>
|
#include <linux/blkpg.h>
|
||||||
#include <linux/cdrom.h> /* for the compatibility eject ioctl */
|
#include <linux/cdrom.h> /* for the compatibility eject ioctl */
|
||||||
#include <linux/completion.h>
|
#include <linux/completion.h>
|
||||||
|
|
||||||
|
static LIST_HEAD(floppy_reqs);
|
||||||
static struct request *current_req;
|
static struct request *current_req;
|
||||||
static void do_fd_request(struct request_queue *q);
|
|
||||||
static int set_next_request(void);
|
static int set_next_request(void);
|
||||||
|
|
||||||
#ifndef fd_get_dma_residue
|
#ifndef fd_get_dma_residue
|
||||||
@ -414,10 +414,10 @@ static struct floppy_drive_struct drive_state[N_DRIVE];
|
|||||||
static struct floppy_write_errors write_errors[N_DRIVE];
|
static struct floppy_write_errors write_errors[N_DRIVE];
|
||||||
static struct timer_list motor_off_timer[N_DRIVE];
|
static struct timer_list motor_off_timer[N_DRIVE];
|
||||||
static struct gendisk *disks[N_DRIVE];
|
static struct gendisk *disks[N_DRIVE];
|
||||||
|
static struct blk_mq_tag_set tag_sets[N_DRIVE];
|
||||||
static struct block_device *opened_bdev[N_DRIVE];
|
static struct block_device *opened_bdev[N_DRIVE];
|
||||||
static DEFINE_MUTEX(open_lock);
|
static DEFINE_MUTEX(open_lock);
|
||||||
static struct floppy_raw_cmd *raw_cmd, default_raw_cmd;
|
static struct floppy_raw_cmd *raw_cmd, default_raw_cmd;
|
||||||
static int fdc_queue;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This struct defines the different floppy types.
|
* This struct defines the different floppy types.
|
||||||
@ -2216,8 +2216,9 @@ static void floppy_end_request(struct request *req, blk_status_t error)
|
|||||||
/* current_count_sectors can be zero if transfer failed */
|
/* current_count_sectors can be zero if transfer failed */
|
||||||
if (error)
|
if (error)
|
||||||
nr_sectors = blk_rq_cur_sectors(req);
|
nr_sectors = blk_rq_cur_sectors(req);
|
||||||
if (__blk_end_request(req, error, nr_sectors << 9))
|
if (blk_update_request(req, error, nr_sectors << 9))
|
||||||
return;
|
return;
|
||||||
|
__blk_mq_end_request(req, error);
|
||||||
|
|
||||||
/* We're done with the request */
|
/* We're done with the request */
|
||||||
floppy_off(drive);
|
floppy_off(drive);
|
||||||
@ -2797,27 +2798,14 @@ static int make_raw_rw_request(void)
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Round-robin between our available drives, doing one request from each
|
|
||||||
*/
|
|
||||||
static int set_next_request(void)
|
static int set_next_request(void)
|
||||||
{
|
{
|
||||||
struct request_queue *q;
|
current_req = list_first_entry_or_null(&floppy_reqs, struct request,
|
||||||
int old_pos = fdc_queue;
|
queuelist);
|
||||||
|
if (current_req) {
|
||||||
do {
|
current_req->error_count = 0;
|
||||||
q = disks[fdc_queue]->queue;
|
list_del_init(¤t_req->queuelist);
|
||||||
if (++fdc_queue == N_DRIVE)
|
}
|
||||||
fdc_queue = 0;
|
|
||||||
if (q) {
|
|
||||||
current_req = blk_fetch_request(q);
|
|
||||||
if (current_req) {
|
|
||||||
current_req->error_count = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (fdc_queue != old_pos);
|
|
||||||
|
|
||||||
return current_req != NULL;
|
return current_req != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2901,29 +2889,38 @@ static void process_fd_request(void)
|
|||||||
schedule_bh(redo_fd_request);
|
schedule_bh(redo_fd_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_fd_request(struct request_queue *q)
|
static blk_status_t floppy_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||||
|
const struct blk_mq_queue_data *bd)
|
||||||
{
|
{
|
||||||
|
blk_mq_start_request(bd->rq);
|
||||||
|
|
||||||
if (WARN(max_buffer_sectors == 0,
|
if (WARN(max_buffer_sectors == 0,
|
||||||
"VFS: %s called on non-open device\n", __func__))
|
"VFS: %s called on non-open device\n", __func__))
|
||||||
return;
|
return BLK_STS_IOERR;
|
||||||
|
|
||||||
if (WARN(atomic_read(&usage_count) == 0,
|
if (WARN(atomic_read(&usage_count) == 0,
|
||||||
"warning: usage count=0, current_req=%p sect=%ld flags=%llx\n",
|
"warning: usage count=0, current_req=%p sect=%ld flags=%llx\n",
|
||||||
current_req, (long)blk_rq_pos(current_req),
|
current_req, (long)blk_rq_pos(current_req),
|
||||||
(unsigned long long) current_req->cmd_flags))
|
(unsigned long long) current_req->cmd_flags))
|
||||||
return;
|
return BLK_STS_IOERR;
|
||||||
|
|
||||||
|
spin_lock_irq(&floppy_lock);
|
||||||
|
list_add_tail(&bd->rq->queuelist, &floppy_reqs);
|
||||||
|
spin_unlock_irq(&floppy_lock);
|
||||||
|
|
||||||
if (test_and_set_bit(0, &fdc_busy)) {
|
if (test_and_set_bit(0, &fdc_busy)) {
|
||||||
/* fdc busy, this new request will be treated when the
|
/* fdc busy, this new request will be treated when the
|
||||||
current one is done */
|
current one is done */
|
||||||
is_alive(__func__, "old request running");
|
is_alive(__func__, "old request running");
|
||||||
return;
|
return BLK_STS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
command_status = FD_COMMAND_NONE;
|
command_status = FD_COMMAND_NONE;
|
||||||
__reschedule_timeout(MAXTIMEOUT, "fd_request");
|
__reschedule_timeout(MAXTIMEOUT, "fd_request");
|
||||||
set_fdc(0);
|
set_fdc(0);
|
||||||
process_fd_request();
|
process_fd_request();
|
||||||
is_alive(__func__, "");
|
is_alive(__func__, "");
|
||||||
|
return BLK_STS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct cont_t poll_cont = {
|
static const struct cont_t poll_cont = {
|
||||||
@ -4486,6 +4483,10 @@ static struct platform_driver floppy_driver = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct blk_mq_ops floppy_mq_ops = {
|
||||||
|
.queue_rq = floppy_queue_rq,
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_device floppy_device[N_DRIVE];
|
static struct platform_device floppy_device[N_DRIVE];
|
||||||
|
|
||||||
static bool floppy_available(int drive)
|
static bool floppy_available(int drive)
|
||||||
@ -4533,9 +4534,12 @@ static int __init do_floppy_init(void)
|
|||||||
goto out_put_disk;
|
goto out_put_disk;
|
||||||
}
|
}
|
||||||
|
|
||||||
disks[drive]->queue = blk_init_queue(do_fd_request, &floppy_lock);
|
disks[drive]->queue = blk_mq_init_sq_queue(&tag_sets[drive],
|
||||||
if (!disks[drive]->queue) {
|
&floppy_mq_ops, 2,
|
||||||
err = -ENOMEM;
|
BLK_MQ_F_SHOULD_MERGE);
|
||||||
|
if (IS_ERR(disks[drive]->queue)) {
|
||||||
|
err = PTR_ERR(disks[drive]->queue);
|
||||||
|
disks[drive]->queue = NULL;
|
||||||
goto out_put_disk;
|
goto out_put_disk;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4708,6 +4712,7 @@ out_put_disk:
|
|||||||
del_timer_sync(&motor_off_timer[drive]);
|
del_timer_sync(&motor_off_timer[drive]);
|
||||||
blk_cleanup_queue(disks[drive]->queue);
|
blk_cleanup_queue(disks[drive]->queue);
|
||||||
disks[drive]->queue = NULL;
|
disks[drive]->queue = NULL;
|
||||||
|
blk_mq_free_tag_set(&tag_sets[drive]);
|
||||||
}
|
}
|
||||||
put_disk(disks[drive]);
|
put_disk(disks[drive]);
|
||||||
}
|
}
|
||||||
@ -4935,6 +4940,7 @@ static void __exit floppy_module_exit(void)
|
|||||||
platform_device_unregister(&floppy_device[drive]);
|
platform_device_unregister(&floppy_device[drive]);
|
||||||
}
|
}
|
||||||
blk_cleanup_queue(disks[drive]->queue);
|
blk_cleanup_queue(disks[drive]->queue);
|
||||||
|
blk_mq_free_tag_set(&tag_sets[drive]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These disks have not called add_disk(). Don't put down
|
* These disks have not called add_disk(). Don't put down
|
||||||
|
Loading…
Reference in New Issue
Block a user