dasd: move queue setup to common code
Most of the code in setup_blk_queue is shared between all disciplines. Move it to common code and leave a method to query the maximum number of transferable blocks, and a flag to indicate discard support. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Stefan Haberland <sth@linux.ibm.com> Link: https://lore.kernel.org/r/20240228133742.806274-3-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
41463f2dfd
commit
0127a47f58
@ -308,6 +308,7 @@ static int dasd_state_basic_to_known(struct dasd_device *device)
|
|||||||
static int dasd_state_basic_to_ready(struct dasd_device *device)
|
static int dasd_state_basic_to_ready(struct dasd_device *device)
|
||||||
{
|
{
|
||||||
struct dasd_block *block = device->block;
|
struct dasd_block *block = device->block;
|
||||||
|
struct request_queue *q;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/* make disk known with correct capacity */
|
/* make disk known with correct capacity */
|
||||||
@ -327,8 +328,32 @@ static int dasd_state_basic_to_ready(struct dasd_device *device)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->discipline->setup_blk_queue)
|
q = block->gdp->queue;
|
||||||
device->discipline->setup_blk_queue(block);
|
blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
|
||||||
|
q->limits.max_dev_sectors = device->discipline->max_sectors(block);
|
||||||
|
blk_queue_max_hw_sectors(q, q->limits.max_dev_sectors);
|
||||||
|
blk_queue_logical_block_size(q, block->bp_block);
|
||||||
|
blk_queue_max_segments(q, USHRT_MAX);
|
||||||
|
|
||||||
|
/* With page sized segments each segment can be translated into one idaw/tidaw */
|
||||||
|
blk_queue_max_segment_size(q, PAGE_SIZE);
|
||||||
|
blk_queue_segment_boundary(q, PAGE_SIZE - 1);
|
||||||
|
blk_queue_dma_alignment(q, PAGE_SIZE - 1);
|
||||||
|
|
||||||
|
if (device->discipline->has_discard) {
|
||||||
|
unsigned int max_bytes, max_discard_sectors;
|
||||||
|
|
||||||
|
q->limits.discard_granularity = block->bp_block;
|
||||||
|
|
||||||
|
/* Calculate max_discard_sectors and make it PAGE aligned */
|
||||||
|
max_bytes = USHRT_MAX * block->bp_block;
|
||||||
|
max_bytes = ALIGN_DOWN(max_bytes, PAGE_SIZE);
|
||||||
|
max_discard_sectors = max_bytes / block->bp_block;
|
||||||
|
|
||||||
|
blk_queue_max_discard_sectors(q, max_discard_sectors);
|
||||||
|
blk_queue_max_write_zeroes_sectors(q, max_discard_sectors);
|
||||||
|
}
|
||||||
|
|
||||||
set_capacity(block->gdp, block->blocks << block->s2b_shift);
|
set_capacity(block->gdp, block->blocks << block->s2b_shift);
|
||||||
device->state = DASD_STATE_READY;
|
device->state = DASD_STATE_READY;
|
||||||
|
|
||||||
|
@ -617,25 +617,9 @@ dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
|
|||||||
"dump sense not available for DIAG data");
|
"dump sense not available for DIAG data");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static unsigned int dasd_diag_max_sectors(struct dasd_block *block)
|
||||||
* Initialize block layer request queue.
|
|
||||||
*/
|
|
||||||
static void dasd_diag_setup_blk_queue(struct dasd_block *block)
|
|
||||||
{
|
{
|
||||||
unsigned int logical_block_size = block->bp_block;
|
return DIAG_MAX_BLOCKS << block->s2b_shift;
|
||||||
struct request_queue *q = block->gdp->queue;
|
|
||||||
int max;
|
|
||||||
|
|
||||||
max = DIAG_MAX_BLOCKS << block->s2b_shift;
|
|
||||||
blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
|
|
||||||
q->limits.max_dev_sectors = max;
|
|
||||||
blk_queue_logical_block_size(q, logical_block_size);
|
|
||||||
blk_queue_max_hw_sectors(q, max);
|
|
||||||
blk_queue_max_segments(q, USHRT_MAX);
|
|
||||||
/* With page sized segments each segment can be translated into one idaw/tidaw */
|
|
||||||
blk_queue_max_segment_size(q, PAGE_SIZE);
|
|
||||||
blk_queue_segment_boundary(q, PAGE_SIZE - 1);
|
|
||||||
blk_queue_dma_alignment(q, PAGE_SIZE - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dasd_diag_pe_handler(struct dasd_device *device,
|
static int dasd_diag_pe_handler(struct dasd_device *device,
|
||||||
@ -648,10 +632,10 @@ static struct dasd_discipline dasd_diag_discipline = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "DIAG",
|
.name = "DIAG",
|
||||||
.ebcname = "DIAG",
|
.ebcname = "DIAG",
|
||||||
|
.max_sectors = dasd_diag_max_sectors,
|
||||||
.check_device = dasd_diag_check_device,
|
.check_device = dasd_diag_check_device,
|
||||||
.pe_handler = dasd_diag_pe_handler,
|
.pe_handler = dasd_diag_pe_handler,
|
||||||
.fill_geometry = dasd_diag_fill_geometry,
|
.fill_geometry = dasd_diag_fill_geometry,
|
||||||
.setup_blk_queue = dasd_diag_setup_blk_queue,
|
|
||||||
.start_IO = dasd_start_diag,
|
.start_IO = dasd_start_diag,
|
||||||
.term_IO = dasd_diag_term_IO,
|
.term_IO = dasd_diag_term_IO,
|
||||||
.handle_terminated_request = dasd_diag_handle_terminated_request,
|
.handle_terminated_request = dasd_diag_handle_terminated_request,
|
||||||
|
@ -6826,17 +6826,9 @@ static void dasd_eckd_handle_hpf_error(struct dasd_device *device,
|
|||||||
dasd_schedule_requeue(device);
|
dasd_schedule_requeue(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static unsigned int dasd_eckd_max_sectors(struct dasd_block *block)
|
||||||
* Initialize block layer request queue.
|
|
||||||
*/
|
|
||||||
static void dasd_eckd_setup_blk_queue(struct dasd_block *block)
|
|
||||||
{
|
{
|
||||||
unsigned int logical_block_size = block->bp_block;
|
if (block->base->features & DASD_FEATURE_USERAW) {
|
||||||
struct request_queue *q = block->gdp->queue;
|
|
||||||
struct dasd_device *device = block->base;
|
|
||||||
int max;
|
|
||||||
|
|
||||||
if (device->features & DASD_FEATURE_USERAW) {
|
|
||||||
/*
|
/*
|
||||||
* the max_blocks value for raw_track access is 256
|
* the max_blocks value for raw_track access is 256
|
||||||
* it is higher than the native ECKD value because we
|
* it is higher than the native ECKD value because we
|
||||||
@ -6844,19 +6836,10 @@ static void dasd_eckd_setup_blk_queue(struct dasd_block *block)
|
|||||||
* so the max_hw_sectors are
|
* so the max_hw_sectors are
|
||||||
* 2048 x 512B = 1024kB = 16 tracks
|
* 2048 x 512B = 1024kB = 16 tracks
|
||||||
*/
|
*/
|
||||||
max = DASD_ECKD_MAX_BLOCKS_RAW << block->s2b_shift;
|
return DASD_ECKD_MAX_BLOCKS_RAW << block->s2b_shift;
|
||||||
} else {
|
|
||||||
max = DASD_ECKD_MAX_BLOCKS << block->s2b_shift;
|
|
||||||
}
|
}
|
||||||
blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
|
|
||||||
q->limits.max_dev_sectors = max;
|
return DASD_ECKD_MAX_BLOCKS << block->s2b_shift;
|
||||||
blk_queue_logical_block_size(q, logical_block_size);
|
|
||||||
blk_queue_max_hw_sectors(q, max);
|
|
||||||
blk_queue_max_segments(q, USHRT_MAX);
|
|
||||||
/* With page sized segments each segment can be translated into one idaw/tidaw */
|
|
||||||
blk_queue_max_segment_size(q, PAGE_SIZE);
|
|
||||||
blk_queue_segment_boundary(q, PAGE_SIZE - 1);
|
|
||||||
blk_queue_dma_alignment(q, PAGE_SIZE - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ccw_driver dasd_eckd_driver = {
|
static struct ccw_driver dasd_eckd_driver = {
|
||||||
@ -6888,7 +6871,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
|
|||||||
.basic_to_ready = dasd_eckd_basic_to_ready,
|
.basic_to_ready = dasd_eckd_basic_to_ready,
|
||||||
.online_to_ready = dasd_eckd_online_to_ready,
|
.online_to_ready = dasd_eckd_online_to_ready,
|
||||||
.basic_to_known = dasd_eckd_basic_to_known,
|
.basic_to_known = dasd_eckd_basic_to_known,
|
||||||
.setup_blk_queue = dasd_eckd_setup_blk_queue,
|
.max_sectors = dasd_eckd_max_sectors,
|
||||||
.fill_geometry = dasd_eckd_fill_geometry,
|
.fill_geometry = dasd_eckd_fill_geometry,
|
||||||
.start_IO = dasd_start_IO,
|
.start_IO = dasd_start_IO,
|
||||||
.term_IO = dasd_term_IO,
|
.term_IO = dasd_term_IO,
|
||||||
|
@ -748,35 +748,9 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
|
|||||||
free_page((unsigned long) page);
|
free_page((unsigned long) page);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static unsigned int dasd_fba_max_sectors(struct dasd_block *block)
|
||||||
* Initialize block layer request queue.
|
|
||||||
*/
|
|
||||||
static void dasd_fba_setup_blk_queue(struct dasd_block *block)
|
|
||||||
{
|
{
|
||||||
unsigned int logical_block_size = block->bp_block;
|
return DASD_FBA_MAX_BLOCKS << block->s2b_shift;
|
||||||
struct request_queue *q = block->gdp->queue;
|
|
||||||
unsigned int max_bytes, max_discard_sectors;
|
|
||||||
int max;
|
|
||||||
|
|
||||||
max = DASD_FBA_MAX_BLOCKS << block->s2b_shift;
|
|
||||||
blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
|
|
||||||
q->limits.max_dev_sectors = max;
|
|
||||||
blk_queue_logical_block_size(q, logical_block_size);
|
|
||||||
blk_queue_max_hw_sectors(q, max);
|
|
||||||
blk_queue_max_segments(q, USHRT_MAX);
|
|
||||||
/* With page sized segments each segment can be translated into one idaw/tidaw */
|
|
||||||
blk_queue_max_segment_size(q, PAGE_SIZE);
|
|
||||||
blk_queue_segment_boundary(q, PAGE_SIZE - 1);
|
|
||||||
|
|
||||||
q->limits.discard_granularity = logical_block_size;
|
|
||||||
|
|
||||||
/* Calculate max_discard_sectors and make it PAGE aligned */
|
|
||||||
max_bytes = USHRT_MAX * logical_block_size;
|
|
||||||
max_bytes = ALIGN_DOWN(max_bytes, PAGE_SIZE);
|
|
||||||
max_discard_sectors = max_bytes / logical_block_size;
|
|
||||||
|
|
||||||
blk_queue_max_discard_sectors(q, max_discard_sectors);
|
|
||||||
blk_queue_max_write_zeroes_sectors(q, max_discard_sectors);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dasd_fba_pe_handler(struct dasd_device *device,
|
static int dasd_fba_pe_handler(struct dasd_device *device,
|
||||||
@ -789,10 +763,11 @@ static struct dasd_discipline dasd_fba_discipline = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "FBA ",
|
.name = "FBA ",
|
||||||
.ebcname = "FBA ",
|
.ebcname = "FBA ",
|
||||||
|
.has_discard = true,
|
||||||
.check_device = dasd_fba_check_characteristics,
|
.check_device = dasd_fba_check_characteristics,
|
||||||
.do_analysis = dasd_fba_do_analysis,
|
.do_analysis = dasd_fba_do_analysis,
|
||||||
.pe_handler = dasd_fba_pe_handler,
|
.pe_handler = dasd_fba_pe_handler,
|
||||||
.setup_blk_queue = dasd_fba_setup_blk_queue,
|
.max_sectors = dasd_fba_max_sectors,
|
||||||
.fill_geometry = dasd_fba_fill_geometry,
|
.fill_geometry = dasd_fba_fill_geometry,
|
||||||
.start_IO = dasd_start_IO,
|
.start_IO = dasd_start_IO,
|
||||||
.term_IO = dasd_term_IO,
|
.term_IO = dasd_term_IO,
|
||||||
|
@ -293,6 +293,7 @@ struct dasd_discipline {
|
|||||||
struct module *owner;
|
struct module *owner;
|
||||||
char ebcname[8]; /* a name used for tagging and printks */
|
char ebcname[8]; /* a name used for tagging and printks */
|
||||||
char name[8]; /* a name used for tagging and printks */
|
char name[8]; /* a name used for tagging and printks */
|
||||||
|
bool has_discard;
|
||||||
|
|
||||||
struct list_head list; /* used for list of disciplines */
|
struct list_head list; /* used for list of disciplines */
|
||||||
|
|
||||||
@ -331,10 +332,7 @@ struct dasd_discipline {
|
|||||||
int (*online_to_ready) (struct dasd_device *);
|
int (*online_to_ready) (struct dasd_device *);
|
||||||
int (*basic_to_known)(struct dasd_device *);
|
int (*basic_to_known)(struct dasd_device *);
|
||||||
|
|
||||||
/*
|
unsigned int (*max_sectors)(struct dasd_block *);
|
||||||
* Initialize block layer request queue.
|
|
||||||
*/
|
|
||||||
void (*setup_blk_queue)(struct dasd_block *);
|
|
||||||
/* (struct dasd_device *);
|
/* (struct dasd_device *);
|
||||||
* Device operation functions. build_cp creates a ccw chain for
|
* Device operation functions. build_cp creates a ccw chain for
|
||||||
* a block device request, start_io starts the request and
|
* a block device request, start_io starts the request and
|
||||||
|
Loading…
x
Reference in New Issue
Block a user