s390/dasd: use blk_mq_alloc_disk

As far as I can tell there is no need for the staged setup in
dasd, so allocate the tagset and the disk with the queue in
dasd_gendisk_alloc.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Link: https://lore.kernel.org/r/20220928143945.1687114-2-sth@linux.ibm.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Christoph Hellwig 2022-09-28 16:39:45 +02:00 committed by Jens Axboe
parent 5765033cf7
commit c68f4f4e29
7 changed files with 39 additions and 88 deletions

View File

@ -41,15 +41,6 @@
#define DASD_DIAG_MOD "dasd_diag_mod" #define DASD_DIAG_MOD "dasd_diag_mod"
static unsigned int queue_depth = 32;
static unsigned int nr_hw_queues = 4;
module_param(queue_depth, uint, 0444);
MODULE_PARM_DESC(queue_depth, "Default queue depth for new DASD devices");
module_param(nr_hw_queues, uint, 0444);
MODULE_PARM_DESC(nr_hw_queues, "Default number of hardware queues for new DASD devices");
/* /*
* SECTION: exported variables of dasd.c * SECTION: exported variables of dasd.c
*/ */
@ -68,8 +59,6 @@ MODULE_LICENSE("GPL");
/* /*
* SECTION: prototypes for static functions of dasd.c * SECTION: prototypes for static functions of dasd.c
*/ */
static int dasd_alloc_queue(struct dasd_block *);
static void dasd_free_queue(struct dasd_block *);
static int dasd_flush_block_queue(struct dasd_block *); static int dasd_flush_block_queue(struct dasd_block *);
static void dasd_device_tasklet(unsigned long); static void dasd_device_tasklet(unsigned long);
static void dasd_block_tasklet(unsigned long); static void dasd_block_tasklet(unsigned long);
@ -198,21 +187,11 @@ EXPORT_SYMBOL_GPL(dasd_free_block);
*/ */
static int dasd_state_new_to_known(struct dasd_device *device) static int dasd_state_new_to_known(struct dasd_device *device)
{ {
int rc;
/* /*
* As long as the device is not in state DASD_STATE_NEW we want to * As long as the device is not in state DASD_STATE_NEW we want to
* keep the reference count > 0. * keep the reference count > 0.
*/ */
dasd_get_device(device); dasd_get_device(device);
if (device->block) {
rc = dasd_alloc_queue(device->block);
if (rc) {
dasd_put_device(device);
return rc;
}
}
device->state = DASD_STATE_KNOWN; device->state = DASD_STATE_KNOWN;
return 0; return 0;
} }
@ -226,9 +205,6 @@ static int dasd_state_known_to_new(struct dasd_device *device)
dasd_eer_disable(device); dasd_eer_disable(device);
device->state = DASD_STATE_NEW; device->state = DASD_STATE_NEW;
if (device->block)
dasd_free_queue(device->block);
/* Give up reference we took in dasd_state_new_to_known. */ /* Give up reference we took in dasd_state_new_to_known. */
dasd_put_device(device); dasd_put_device(device);
return 0; return 0;
@ -1591,9 +1567,8 @@ void dasd_generic_handle_state_change(struct dasd_device *device)
dasd_schedule_device_bh(device); dasd_schedule_device_bh(device);
if (device->block) { if (device->block) {
dasd_schedule_block_bh(device->block); dasd_schedule_block_bh(device->block);
if (device->block->request_queue) if (device->block->gdp)
blk_mq_run_hw_queues(device->block->request_queue, blk_mq_run_hw_queues(device->block->gdp->queue, true);
true);
} }
} }
EXPORT_SYMBOL_GPL(dasd_generic_handle_state_change); EXPORT_SYMBOL_GPL(dasd_generic_handle_state_change);
@ -2691,7 +2666,7 @@ static void dasd_block_timeout(struct timer_list *t)
dasd_device_remove_stop_bits(block->base, DASD_STOPPED_PENDING); dasd_device_remove_stop_bits(block->base, DASD_STOPPED_PENDING);
spin_unlock_irqrestore(get_ccwdev_lock(block->base->cdev), flags); spin_unlock_irqrestore(get_ccwdev_lock(block->base->cdev), flags);
dasd_schedule_block_bh(block); dasd_schedule_block_bh(block);
blk_mq_run_hw_queues(block->request_queue, true); blk_mq_run_hw_queues(block->gdp->queue, true);
} }
/* /*
@ -3239,7 +3214,7 @@ static void dasd_request_done(struct request *req)
blk_mq_run_hw_queues(req->q, true); blk_mq_run_hw_queues(req->q, true);
} }
static struct blk_mq_ops dasd_mq_ops = { struct blk_mq_ops dasd_mq_ops = {
.queue_rq = do_dasd_request, .queue_rq = do_dasd_request,
.complete = dasd_request_done, .complete = dasd_request_done,
.timeout = dasd_times_out, .timeout = dasd_times_out,
@ -3247,45 +3222,6 @@ static struct blk_mq_ops dasd_mq_ops = {
.exit_hctx = dasd_exit_hctx, .exit_hctx = dasd_exit_hctx,
}; };
/*
* Allocate and initialize request queue and default I/O scheduler.
*/
static int dasd_alloc_queue(struct dasd_block *block)
{
int rc;
block->tag_set.ops = &dasd_mq_ops;
block->tag_set.cmd_size = sizeof(struct dasd_ccw_req);
block->tag_set.nr_hw_queues = nr_hw_queues;
block->tag_set.queue_depth = queue_depth;
block->tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
block->tag_set.numa_node = NUMA_NO_NODE;
rc = blk_mq_alloc_tag_set(&block->tag_set);
if (rc)
return rc;
block->request_queue = blk_mq_init_queue(&block->tag_set);
if (IS_ERR(block->request_queue))
return PTR_ERR(block->request_queue);
block->request_queue->queuedata = block;
return 0;
}
/*
* Deactivate and free request queue.
*/
static void dasd_free_queue(struct dasd_block *block)
{
if (block->request_queue) {
blk_mq_destroy_queue(block->request_queue);
blk_mq_free_tag_set(&block->tag_set);
block->request_queue = NULL;
}
}
static int dasd_open(struct block_device *bdev, fmode_t mode) static int dasd_open(struct block_device *bdev, fmode_t mode)
{ {
struct dasd_device *base; struct dasd_device *base;
@ -3762,10 +3698,9 @@ int dasd_generic_path_operational(struct dasd_device *device)
dasd_schedule_device_bh(device); dasd_schedule_device_bh(device);
if (device->block) { if (device->block) {
dasd_schedule_block_bh(device->block); dasd_schedule_block_bh(device->block);
if (device->block->request_queue) if (device->block->gdp)
blk_mq_run_hw_queues(device->block->request_queue, blk_mq_run_hw_queues(device->block->gdp->queue, true);
true); }
}
if (!device->stopped) if (!device->stopped)
wake_up(&generic_waitq); wake_up(&generic_waitq);
@ -3916,8 +3851,8 @@ void dasd_generic_space_avail(struct dasd_device *device)
if (device->block) { if (device->block) {
dasd_schedule_block_bh(device->block); dasd_schedule_block_bh(device->block);
if (device->block->request_queue) if (device->block->gdp)
blk_mq_run_hw_queues(device->block->request_queue, true); blk_mq_run_hw_queues(device->block->gdp->queue, true);
} }
if (!device->stopped) if (!device->stopped)
wake_up(&generic_waitq); wake_up(&generic_waitq);

View File

@ -1578,7 +1578,6 @@ dasd_timeout_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct dasd_device *device; struct dasd_device *device;
struct request_queue *q;
unsigned long val; unsigned long val;
device = dasd_device_from_cdev(to_ccwdev(dev)); device = dasd_device_from_cdev(to_ccwdev(dev));
@ -1590,15 +1589,13 @@ dasd_timeout_store(struct device *dev, struct device_attribute *attr,
dasd_put_device(device); dasd_put_device(device);
return -EINVAL; return -EINVAL;
} }
q = device->block->request_queue; if (!device->block->gdp) {
if (!q) {
dasd_put_device(device); dasd_put_device(device);
return -ENODEV; return -ENODEV;
} }
device->blk_timeout = val; device->blk_timeout = val;
blk_queue_rq_timeout(device->block->gdp->queue, val * HZ);
blk_queue_rq_timeout(q, device->blk_timeout * HZ);
dasd_put_device(device); dasd_put_device(device);
return count; return count;

View File

@ -627,7 +627,7 @@ dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
static void dasd_diag_setup_blk_queue(struct dasd_block *block) static void dasd_diag_setup_blk_queue(struct dasd_block *block)
{ {
unsigned int logical_block_size = block->bp_block; unsigned int logical_block_size = block->bp_block;
struct request_queue *q = block->request_queue; struct request_queue *q = block->gdp->queue;
int max; int max;
max = DIAG_MAX_BLOCKS << block->s2b_shift; max = DIAG_MAX_BLOCKS << block->s2b_shift;

View File

@ -6844,7 +6844,7 @@ static void dasd_eckd_handle_hpf_error(struct dasd_device *device,
static void dasd_eckd_setup_blk_queue(struct dasd_block *block) static void dasd_eckd_setup_blk_queue(struct dasd_block *block)
{ {
unsigned int logical_block_size = block->bp_block; unsigned int logical_block_size = block->bp_block;
struct request_queue *q = block->request_queue; struct request_queue *q = block->gdp->queue;
struct dasd_device *device = block->base; struct dasd_device *device = block->base;
int max; int max;

View File

@ -767,7 +767,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
static void dasd_fba_setup_blk_queue(struct dasd_block *block) static void dasd_fba_setup_blk_queue(struct dasd_block *block)
{ {
unsigned int logical_block_size = block->bp_block; unsigned int logical_block_size = block->bp_block;
struct request_queue *q = block->request_queue; struct request_queue *q = block->gdp->queue;
unsigned int max_bytes, max_discard_sectors; unsigned int max_bytes, max_discard_sectors;
int max; int max;

View File

@ -25,7 +25,14 @@
#include "dasd_int.h" #include "dasd_int.h"
static struct lock_class_key dasd_bio_compl_lkclass; static unsigned int queue_depth = 32;
static unsigned int nr_hw_queues = 4;
module_param(queue_depth, uint, 0444);
MODULE_PARM_DESC(queue_depth, "Default queue depth for new DASD devices");
module_param(nr_hw_queues, uint, 0444);
MODULE_PARM_DESC(nr_hw_queues, "Default number of hardware queues for new DASD devices");
/* /*
* Allocate and register gendisk structure for device. * Allocate and register gendisk structure for device.
@ -41,10 +48,21 @@ int dasd_gendisk_alloc(struct dasd_block *block)
if (base->devindex >= DASD_PER_MAJOR) if (base->devindex >= DASD_PER_MAJOR)
return -EBUSY; return -EBUSY;
gdp = blk_mq_alloc_disk_for_queue(block->request_queue, block->tag_set.ops = &dasd_mq_ops;
&dasd_bio_compl_lkclass); block->tag_set.cmd_size = sizeof(struct dasd_ccw_req);
if (!gdp) block->tag_set.nr_hw_queues = nr_hw_queues;
return -ENOMEM; block->tag_set.queue_depth = queue_depth;
block->tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
block->tag_set.numa_node = NUMA_NO_NODE;
rc = blk_mq_alloc_tag_set(&block->tag_set);
if (rc)
return rc;
gdp = blk_mq_alloc_disk(&block->tag_set, block);
if (IS_ERR(gdp)) {
blk_mq_free_tag_set(&block->tag_set);
return PTR_ERR(gdp);
}
/* Initialize gendisk structure. */ /* Initialize gendisk structure. */
gdp->major = DASD_MAJOR; gdp->major = DASD_MAJOR;
@ -100,6 +118,7 @@ void dasd_gendisk_free(struct dasd_block *block)
block->gdp->private_data = NULL; block->gdp->private_data = NULL;
put_disk(block->gdp); put_disk(block->gdp);
block->gdp = NULL; block->gdp = NULL;
blk_mq_free_tag_set(&block->tag_set);
} }
} }

View File

@ -642,7 +642,6 @@ struct dasd_device {
struct dasd_block { struct dasd_block {
/* Block device stuff. */ /* Block device stuff. */
struct gendisk *gdp; struct gendisk *gdp;
struct request_queue *request_queue;
spinlock_t request_queue_lock; spinlock_t request_queue_lock;
struct blk_mq_tag_set tag_set; struct blk_mq_tag_set tag_set;
struct block_device *bdev; struct block_device *bdev;
@ -850,6 +849,7 @@ extern debug_info_t *dasd_debug_area;
extern struct dasd_profile dasd_global_profile; extern struct dasd_profile dasd_global_profile;
extern unsigned int dasd_global_profile_level; extern unsigned int dasd_global_profile_level;
extern const struct block_device_operations dasd_device_operations; extern const struct block_device_operations dasd_device_operations;
extern struct blk_mq_ops dasd_mq_ops;
extern struct kmem_cache *dasd_page_cache; extern struct kmem_cache *dasd_page_cache;