]> git.ipfire.org Git - people/ms/linux.git/commitdiff
s390/dasd: Make dasd_setup_queue() a discipline function
authorJan Höppner <hoeppner@linux.ibm.com>
Fri, 27 Apr 2018 14:55:27 +0000 (16:55 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Thu, 11 Jul 2019 18:39:54 +0000 (20:39 +0200)
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: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
drivers/s390/block/dasd.c
drivers/s390/block/dasd_diag.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_eckd.h
drivers/s390/block/dasd_fba.c
drivers/s390/block/dasd_fba.h
drivers/s390/block/dasd_int.h

index 065f7b0ff0dc8a391c6d2729155a7b1e80141c3c..ae460543f59dbf1843429b9c72f31f2647121a8a 100644 (file)
@@ -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.
  */
index e1fe02477ea8fca951232dabe7f89754c8f287ff..8d4971645cf1ad72a4f2fde8cb21b023b3dbdced 100644 (file)
@@ -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,
index 21164a48317d3c08c4a13524d3c238ebed56827a..3edb35359843e36e2f0a5fc2d299543f7c6d0178 100644 (file)
@@ -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,
index 4226936427ec5a7feb6770e37ca1d6fa698de48a..13112ba9f93f6ef4adc386fa6447f780366650c7 100644 (file)
 #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
  ****************************************************************************/
index 56007a3e7f110358e27ad74563f24e428cbae473..79fbe0d68a8d9a074788b1e9a62d9c614c8d456a 100644 (file)
@@ -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,
index b14bf1b2c69114fd7e9ac1e5159b74303bd03e6a..8f75df06e893cd1b09ceb31e44cbb5442401547b 100644 (file)
@@ -9,6 +9,11 @@
 #ifndef DASD_FBA_H
 #define DASD_FBA_H
 
+/*
+ * Maximum number of blocks to be chained
+ */
+#define DASD_FBA_MAX_BLOCKS            96
+
 struct DE_fba_data {
        struct {
                unsigned char perm:2;   /* Permissions on this extent */
index 7fe0c6b9d9ef41a2f05192a518cfdb3562e18743..aa4fd0d206bbe8e4837a8d1b08cc74a44a850429 100644 (file)
@@ -268,7 +268,6 @@ struct dasd_discipline {
        struct module *owner;
        char ebcname[8];        /* a name used for tagging and printks */
        char name[8];           /* a name used for tagging and printks */
-       int max_blocks;         /* maximum number of blocks to be chained */
 
        struct list_head list;  /* used for list of disciplines */
 
@@ -307,6 +306,10 @@ struct dasd_discipline {
        int (*online_to_ready) (struct dasd_device *);
        int (*basic_to_known)(struct dasd_device *);
 
+       /*
+        * Initialize block layer request queue.
+        */
+       void (*setup_blk_queue)(struct dasd_block *);
        /* (struct dasd_device *);
         * Device operation functions. build_cp creates a ccw chain for
         * a block device request, start_io starts the request and