diff options
author | Jan Höppner <hoeppner@linux.ibm.com> | 2020-09-14 13:56:47 +0200 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2020-09-14 19:40:21 -0600 |
commit | 709192d531e5b0a91f20aa14abfe2fc27ddd47af (patch) | |
tree | 3ef738f7fb01ff7d1a9630bcb748710733bfb2c5 /drivers/s390 | |
parent | fd04358e0196fe3b7b44c69b755c7fc329360829 (diff) | |
download | linux-709192d531e5b0a91f20aa14abfe2fc27ddd47af.tar.gz linux-709192d531e5b0a91f20aa14abfe2fc27ddd47af.tar.bz2 linux-709192d531e5b0a91f20aa14abfe2fc27ddd47af.zip |
s390/dasd: Fix zero write for FBA devices
A discard request that writes zeros using the global kernel internal
ZERO_PAGE will fail for machines with more than 2GB of memory due to the
location of the ZERO_PAGE.
Fix this by using a driver owned global zero page allocated with GFP_DMA
flag set.
Fixes: 28b841b3a7cb ("s390/dasd: Add discard support for FBA devices")
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Cc: <stable@vger.kernel.org> # 4.14+
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dasd_fba.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index cbb770824226..1a44e321b54e 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c @@ -40,6 +40,7 @@ MODULE_LICENSE("GPL"); static struct dasd_discipline dasd_fba_discipline; +static void *dasd_fba_zero_page; struct dasd_fba_private { struct dasd_fba_characteristics rdc_data; @@ -270,7 +271,7 @@ static void ccw_write_zero(struct ccw1 *ccw, int count) ccw->cmd_code = DASD_FBA_CCW_WRITE; ccw->flags |= CCW_FLAG_SLI; ccw->count = count; - ccw->cda = (__u32) (addr_t) page_to_phys(ZERO_PAGE(0)); + ccw->cda = (__u32) (addr_t) dasd_fba_zero_page; } /* @@ -830,6 +831,11 @@ dasd_fba_init(void) int ret; ASCEBC(dasd_fba_discipline.ebcname, 4); + + dasd_fba_zero_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!dasd_fba_zero_page) + return -ENOMEM; + ret = ccw_driver_register(&dasd_fba_driver); if (!ret) wait_for_device_probe(); @@ -841,6 +847,7 @@ static void __exit dasd_fba_cleanup(void) { ccw_driver_unregister(&dasd_fba_driver); + free_page((unsigned long)dasd_fba_zero_page); } module_init(dasd_fba_init); |