Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0610a8a authored by Jan Höppner's avatar Jan Höppner Committed by Vasily Gorbik
Browse files

s390/dasd: Make dasd_setup_queue() a discipline function



ECKD, FBA, and the DIAG discipline use slightly different block layer
settings. In preparation of even more diverse queue settings, make
dasd_setup_queue() a discipline function.

Signed-off-by: default avatarJan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: default avatarStefan Haberland <sth@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 91dc4a19
Loading
Loading
Loading
Loading
+2 −51
Original line number Diff line number Diff line
@@ -70,7 +70,6 @@ MODULE_LICENSE("GPL");
 * SECTION: prototypes for static functions of dasd.c
 */
static int  dasd_alloc_queue(struct dasd_block *);
static void dasd_setup_queue(struct dasd_block *);
static void dasd_free_queue(struct dasd_block *);
static int dasd_flush_block_queue(struct dasd_block *);
static void dasd_device_tasklet(unsigned long);
@@ -358,7 +357,8 @@ static int dasd_state_basic_to_ready(struct dasd_device *device)
			}
			return rc;
		}
		dasd_setup_queue(block);
		if (device->discipline->setup_blk_queue)
			device->discipline->setup_blk_queue(block);
		set_capacity(block->gdp,
			     block->blocks << block->s2b_shift);
		device->state = DASD_STATE_READY;
@@ -3249,55 +3249,6 @@ static int dasd_alloc_queue(struct dasd_block *block)
	return 0;
}

/*
 * Allocate and initialize request queue.
 */
static void dasd_setup_queue(struct dasd_block *block)
{
	unsigned int logical_block_size = block->bp_block;
	struct request_queue *q = block->request_queue;
	unsigned int max_bytes, max_discard_sectors;
	int max;

	if (block->base->features & DASD_FEATURE_USERAW) {
		/*
		 * the max_blocks value for raw_track access is 256
		 * it is higher than the native ECKD value because we
		 * only need one ccw per track
		 * so the max_hw_sectors are
		 * 2048 x 512B = 1024kB = 16 tracks
		 */
		max = 2048;
	} else {
		max = block->base->discipline->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 we can translate each segement into
	 * one idaw/tidaw
	 */
	blk_queue_max_segment_size(q, PAGE_SIZE);
	blk_queue_segment_boundary(q, PAGE_SIZE - 1);

	/* Only activate blocklayer discard support for devices that support it */
	if (block->base->features & DASD_FEATURE_DISCARD) {
		q->limits.discard_granularity = logical_block_size;
		q->limits.discard_alignment = PAGE_SIZE;

		/* Calculate max_discard_sectors and make it PAGE aligned */
		max_bytes = USHRT_MAX * logical_block_size;
		max_bytes = ALIGN(max_bytes, PAGE_SIZE) - 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);
		blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
	}
}

/*
 * Deactivate and free request queue.
 */
+21 −1
Original line number Diff line number Diff line
@@ -615,14 +615,34 @@ dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
		    "dump sense not available for DIAG data");
}

/*
 * Initialize block layer request queue.
 */
static void dasd_diag_setup_blk_queue(struct dasd_block *block)
{
	unsigned int logical_block_size = block->bp_block;
	struct request_queue *q = block->request_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);
}

static struct dasd_discipline dasd_diag_discipline = {
	.owner = THIS_MODULE,
	.name = "DIAG",
	.ebcname = "DIAG",
	.max_blocks = DIAG_MAX_BLOCKS,
	.check_device = dasd_diag_check_device,
	.verify_path = dasd_generic_verify_path,
	.fill_geometry = dasd_diag_fill_geometry,
	.setup_blk_queue = dasd_diag_setup_blk_queue,
	.start_IO = dasd_start_diag,
	.term_IO = dasd_diag_term_IO,
	.handle_terminated_request = dasd_diag_handle_terminated_request,
+33 −14
Original line number Diff line number Diff line
@@ -6349,6 +6349,38 @@ static void dasd_eckd_handle_hpf_error(struct dasd_device *device,
	dasd_schedule_requeue(device);
}

/*
 * Initialize block layer request queue.
 */
static void dasd_eckd_setup_blk_queue(struct dasd_block *block)
{
	unsigned int logical_block_size = block->bp_block;
	struct request_queue *q = block->request_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
		 * it is higher than the native ECKD value because we
		 * only need one ccw per track
		 * so the max_hw_sectors are
		 * 2048 x 512B = 1024kB = 16 tracks
		 */
		max = 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;
	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);
}

static struct ccw_driver dasd_eckd_driver = {
	.driver = {
		.name	= "dasd-eckd",
@@ -6369,24 +6401,10 @@ static struct ccw_driver dasd_eckd_driver = {
	.int_class   = IRQIO_DAS,
};

/*
 * max_blocks is dependent on the amount of storage that is available
 * in the static io buffer for each device. Currently each device has
 * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has
 * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use
 * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In
 * addition we have one define extent ccw + 16 bytes of data and one
 * locate record ccw + 16 bytes of data. That makes:
 * (8192 - 24 - 136 - 8 - 16 - 8 - 16) / 16 = 499 blocks at maximum.
 * We want to fit two into the available memory so that we can immediately
 * start the next request if one finishes off. That makes 249.5 blocks
 * for one request. Give a little safety and the result is 240.
 */
static struct dasd_discipline dasd_eckd_discipline = {
	.owner = THIS_MODULE,
	.name = "ECKD",
	.ebcname = "ECKD",
	.max_blocks = 190,
	.check_device = dasd_eckd_check_characteristics,
	.uncheck_device = dasd_eckd_uncheck_device,
	.do_analysis = dasd_eckd_do_analysis,
@@ -6394,6 +6412,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
	.basic_to_ready = dasd_eckd_basic_to_ready,
	.online_to_ready = dasd_eckd_online_to_ready,
	.basic_to_known = dasd_eckd_basic_to_known,
	.setup_blk_queue = dasd_eckd_setup_blk_queue,
	.fill_geometry = dasd_eckd_fill_geometry,
	.start_IO = dasd_start_IO,
	.term_IO = dasd_term_IO,
+6 −0
Original line number Diff line number Diff line
@@ -109,6 +109,12 @@
#define DASD_ECKD_PATH_THRHLD		 256
#define DASD_ECKD_PATH_INTERVAL		 300

/*
 * Maximum number of blocks to be chained
 */
#define DASD_ECKD_MAX_BLOCKS		 190
#define DASD_ECKD_MAX_BLOCKS_RAW	 256

/*****************************************************************************
 * SECTION: Type Definitions
 ****************************************************************************/
+32 −13
Original line number Diff line number Diff line
@@ -770,27 +770,46 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
}

/*
 * max_blocks is dependent on the amount of storage that is available
 * in the static io buffer for each device. Currently each device has
 * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has
 * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use
 * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In
 * addition we have one define extent ccw + 16 bytes of data and a
 * locate record ccw for each block (stupid devices!) + 16 bytes of data.
 * That makes:
 * (8192 - 24 - 136 - 8 - 16) / 40 = 200.2 blocks at maximum.
 * We want to fit two into the available memory so that we can immediately
 * start the next request if one finishes off. That makes 100.1 blocks
 * for one request. Give a little safety and the result is 96.
 * Initialize block layer request queue.
 */
static void dasd_fba_setup_blk_queue(struct dasd_block *block)
{
	unsigned int logical_block_size = block->bp_block;
	struct request_queue *q = block->request_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;
	q->limits.discard_alignment = PAGE_SIZE;

	/* Calculate max_discard_sectors and make it PAGE aligned */
	max_bytes = USHRT_MAX * logical_block_size;
	max_bytes = ALIGN(max_bytes, PAGE_SIZE) - 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);
	blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
}

static struct dasd_discipline dasd_fba_discipline = {
	.owner = THIS_MODULE,
	.name = "FBA ",
	.ebcname = "FBA ",
	.max_blocks = 96,
	.check_device = dasd_fba_check_characteristics,
	.do_analysis = dasd_fba_do_analysis,
	.verify_path = dasd_generic_verify_path,
	.setup_blk_queue = dasd_fba_setup_blk_queue,
	.fill_geometry = dasd_fba_fill_geometry,
	.start_IO = dasd_start_IO,
	.term_IO = dasd_term_IO,
Loading