s390/dcssblk: Add DAX support
With ZONE_DEVICE now available for s390, struct pages can be allocated for proper DAX support in dcssblk driver via devm_memremap_pages(). Adding struct pages for a range requires that the range is aligned to SUBSECTION_SIZE, which is defined as 2 MB in common code. Therefore, only enable DAX support and allocate struct pages for DCSS ranges that are aligned to 2 MB. Signed-off-by: Gerald Schaefer <gerald.schaefer@linux.ibm.com> Acked-by: Heiko Carstens <hca@linux.ibm.com> Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
This commit is contained in:
committed by
Alexander Gordeev
parent
5450abb0de
commit
5b27dfb1d7
@@ -5,19 +5,11 @@ comment "S/390 block device drivers"
|
||||
config DCSSBLK
|
||||
def_tristate m
|
||||
prompt "DCSSBLK support"
|
||||
depends on S390 && BLOCK && (DAX || DAX=n)
|
||||
depends on S390 && BLOCK && ZONE_DEVICE
|
||||
select FS_DAX
|
||||
help
|
||||
Support for dcss block device
|
||||
|
||||
config DCSSBLK_DAX
|
||||
def_bool y
|
||||
depends on DCSSBLK
|
||||
# requires S390 ZONE_DEVICE support
|
||||
depends on BROKEN
|
||||
prompt "DCSSBLK DAX support"
|
||||
help
|
||||
Enable DAX operation for the dcss block device
|
||||
|
||||
config DASD
|
||||
def_tristate y
|
||||
prompt "Support for DASD devices"
|
||||
|
||||
@@ -79,6 +79,8 @@ struct dcssblk_dev_info {
|
||||
int num_of_segments;
|
||||
struct list_head seg_list;
|
||||
struct dax_device *dax_dev;
|
||||
struct dev_pagemap pgmap;
|
||||
void *pgmap_addr;
|
||||
};
|
||||
|
||||
struct segment_info {
|
||||
@@ -415,6 +417,8 @@ removeseg:
|
||||
dax_remove_host(dev_info->gd);
|
||||
kill_dax(dev_info->dax_dev);
|
||||
put_dax(dev_info->dax_dev);
|
||||
if (dev_info->pgmap_addr)
|
||||
devm_memunmap_pages(&dev_info->dev, &dev_info->pgmap);
|
||||
del_gendisk(dev_info->gd);
|
||||
put_disk(dev_info->gd);
|
||||
|
||||
@@ -537,9 +541,6 @@ static int dcssblk_setup_dax(struct dcssblk_dev_info *dev_info)
|
||||
{
|
||||
struct dax_device *dax_dev;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_DCSSBLK_DAX))
|
||||
return 0;
|
||||
|
||||
dax_dev = alloc_dax(dev_info, &dcssblk_dax_ops);
|
||||
if (IS_ERR(dax_dev))
|
||||
return PTR_ERR(dax_dev);
|
||||
@@ -562,6 +563,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
|
||||
struct dcssblk_dev_info *dev_info;
|
||||
struct segment_info *seg_info, *temp;
|
||||
char *local_buf;
|
||||
void *addr;
|
||||
unsigned long seg_byte_size;
|
||||
|
||||
dev_info = NULL;
|
||||
@@ -687,9 +689,26 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
|
||||
if (rc)
|
||||
goto put_dev;
|
||||
|
||||
rc = dcssblk_setup_dax(dev_info);
|
||||
if (rc)
|
||||
goto out_dax;
|
||||
if (!IS_ALIGNED(dev_info->start, SUBSECTION_SIZE) ||
|
||||
!IS_ALIGNED(dev_info->end + 1, SUBSECTION_SIZE)) {
|
||||
pr_info("DCSS %s is not aligned to %lu bytes, DAX support disabled\n",
|
||||
local_buf, SUBSECTION_SIZE);
|
||||
} else {
|
||||
dev_info->pgmap.type = MEMORY_DEVICE_FS_DAX;
|
||||
dev_info->pgmap.range.start = dev_info->start;
|
||||
dev_info->pgmap.range.end = dev_info->end;
|
||||
dev_info->pgmap.nr_range = 1;
|
||||
addr = devm_memremap_pages(&dev_info->dev, &dev_info->pgmap);
|
||||
if (IS_ERR(addr)) {
|
||||
rc = PTR_ERR(addr);
|
||||
goto put_dev;
|
||||
}
|
||||
dev_info->pgmap_addr = addr;
|
||||
rc = dcssblk_setup_dax(dev_info);
|
||||
if (rc)
|
||||
goto out_dax;
|
||||
pr_info("DAX support enabled for DCSS %s\n", local_buf);
|
||||
}
|
||||
|
||||
get_device(&dev_info->dev);
|
||||
rc = device_add_disk(&dev_info->dev, dev_info->gd, NULL);
|
||||
@@ -716,6 +735,8 @@ out_dax_host:
|
||||
out_dax:
|
||||
kill_dax(dev_info->dax_dev);
|
||||
put_dax(dev_info->dax_dev);
|
||||
if (dev_info->pgmap_addr)
|
||||
devm_memunmap_pages(&dev_info->dev, &dev_info->pgmap);
|
||||
put_dev:
|
||||
list_del(&dev_info->lh);
|
||||
put_disk(dev_info->gd);
|
||||
@@ -801,6 +822,8 @@ dcssblk_remove_store(struct device *dev, struct device_attribute *attr, const ch
|
||||
dax_remove_host(dev_info->gd);
|
||||
kill_dax(dev_info->dax_dev);
|
||||
put_dax(dev_info->dax_dev);
|
||||
if (dev_info->pgmap_addr)
|
||||
devm_memunmap_pages(&dev_info->dev, &dev_info->pgmap);
|
||||
del_gendisk(dev_info->gd);
|
||||
put_disk(dev_info->gd);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user