summaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd.c
diff options
context:
space:
mode:
authorJan Höppner <hoeppner@linux.vnet.ibm.com>2016-06-30 13:28:57 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-08-29 16:31:26 +0200
commit28b841b3a7cb07a4bfd436a15b31bc88509dcf9a (patch)
treeb73ad19e32e2be733c51419b7b859f7e900b4ced /drivers/s390/block/dasd.c
parents390/zcrypt: make CPRBX const (diff)
downloadlinux-28b841b3a7cb07a4bfd436a15b31bc88509dcf9a.tar.xz
linux-28b841b3a7cb07a4bfd436a15b31bc88509dcf9a.zip
s390/dasd: Add discard support for FBA devices
The z/VM hypervisor provides virtual disks (VDISK) which are backed by main memory of the hypervisor. Those devices are seen as DASD FBA disks within the Linux guest. Whenever data is written to such a device, memory is allocated on-the-fly by z/VM accordingly. This memory, however, is not being freed if data on the device is deleted by the guest OS. In order to make memory usable after deletion again, add discard support to the FBA discipline. While at it, update comments regarding the DASD_FEATURE_* flags. Reviewed-by: Stefan Haberland <sth@linux.vnet.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd.c')
-rw-r--r--drivers/s390/block/dasd.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 83f80710d555..9c97ad1ee121 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -3178,7 +3178,9 @@ static int dasd_alloc_queue(struct dasd_block *block)
*/
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) {
@@ -3195,7 +3197,7 @@ static void dasd_setup_queue(struct dasd_block *block)
}
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
q->limits.max_dev_sectors = max;
- blk_queue_logical_block_size(q, block->bp_block);
+ 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
@@ -3203,6 +3205,21 @@ static void dasd_setup_queue(struct dasd_block *block)
*/
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);
+ queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
+ }
}
/*