diff options
author | Dan Williams | 2022-03-09 19:49:26 -0800 |
---|---|---|
committer | Dan Williams | 2022-03-11 15:53:12 -0800 |
commit | f8669f1d6a86a6b17104ceca9340ded280307ac1 (patch) | |
tree | 75e6e5f318afe7ccad3f8faa9c11f54422a36b83 /drivers/nvdimm | |
parent | d9d290d7e659e9db3e4518040cc18b97f5535f4a (diff) |
nvdimm/blk: Delete the block-aperture window driver
Block Aperture Window support was an attempt to layer an error model
over PMEM for platforms that did not support machine-check-recovery.
However, it was abandoned before it ever shipped, and only ever existed
in the ACPI specification. Meanwhile Linux has carried a large pile of
dead code for non-shipping infrastructure. For years it has been off to
the side out of the way, but now CXL and recent directions with DAX
support have the potential to collide with this code.
In preparation for adding discontiguous namespace support, a
pre-requisite for the nvdimm subsystem to replace device-mapper for
striping + concatenation use cases, delete BLK aperture support.
On the obscure chance that some hardware vendor shipped support for this
mode, note that the driver will still keep BLK space reserved in the
label area. So an end user in this case would still have the opportunity
to report the regression to get BLK-mode support restored without
risking the data they have on that device.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/164688416668.2879318.16903178375774275120.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/nvdimm')
-rw-r--r-- | drivers/nvdimm/Kconfig | 25 | ||||
-rw-r--r-- | drivers/nvdimm/Makefile | 3 | ||||
-rw-r--r-- | drivers/nvdimm/blk.c | 335 |
3 files changed, 4 insertions, 359 deletions
diff --git a/drivers/nvdimm/Kconfig b/drivers/nvdimm/Kconfig index 347fe7afa583..5a29046e3319 100644 --- a/drivers/nvdimm/Kconfig +++ b/drivers/nvdimm/Kconfig @@ -10,12 +10,9 @@ menuconfig LIBNVDIMM ACPI-6-NFIT defined resources. On platforms that define an NFIT, or otherwise can discover NVDIMM resources, a libnvdimm bus is registered to advertise PMEM (persistent memory) - namespaces (/dev/pmemX) and BLK (sliding mmio window(s)) - namespaces (/dev/ndblkX.Y). A PMEM namespace refers to a + namespaces (/dev/pmemX). A PMEM namespace refers to a memory resource that may span multiple DIMMs and support DAX - (see CONFIG_DAX). A BLK namespace refers to an NVDIMM control - region which exposes an mmio register set for windowed access - mode to non-volatile memory. + (see CONFIG_DAX). if LIBNVDIMM @@ -38,19 +35,6 @@ config BLK_DEV_PMEM Say Y if you want to use an NVDIMM -config ND_BLK - tristate "BLK: Block data window (aperture) device support" - default LIBNVDIMM - select ND_BTT if BTT - help - Support NVDIMMs, or other devices, that implement a BLK-mode - access capability. BLK-mode access uses memory-mapped-i/o - apertures to access persistent media. - - Say Y if your platform firmware emits an ACPI.NFIT table - (CONFIG_ACPI_NFIT), or otherwise exposes BLK-mode - capabilities. - config ND_CLAIM bool @@ -67,9 +51,8 @@ config BTT applications that rely on sector writes not being torn (a guarantee that typical disks provide) can continue to do so. The BTT manifests itself as an alternate personality for an - NVDIMM namespace, i.e. a namespace can be in raw mode (pmemX, - ndblkX.Y, etc...), or 'sectored' mode, (pmemXs, ndblkX.Ys, - etc...). + NVDIMM namespace, i.e. a namespace can be in raw mode pmemX, + or 'sectored' mode. Select Y if unsure diff --git a/drivers/nvdimm/Makefile b/drivers/nvdimm/Makefile index 25dba6095612..3fb806748716 100644 --- a/drivers/nvdimm/Makefile +++ b/drivers/nvdimm/Makefile @@ -2,7 +2,6 @@ obj-$(CONFIG_LIBNVDIMM) += libnvdimm.o obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o obj-$(CONFIG_ND_BTT) += nd_btt.o -obj-$(CONFIG_ND_BLK) += nd_blk.o obj-$(CONFIG_X86_PMEM_LEGACY) += nd_e820.o obj-$(CONFIG_OF_PMEM) += of_pmem.o obj-$(CONFIG_VIRTIO_PMEM) += virtio_pmem.o nd_virtio.o @@ -11,8 +10,6 @@ nd_pmem-y := pmem.o nd_btt-y := btt.o -nd_blk-y := blk.o - nd_e820-y := e820.o libnvdimm-y := core.o diff --git a/drivers/nvdimm/blk.c b/drivers/nvdimm/blk.c deleted file mode 100644 index 228c33b8d1d6..000000000000 --- a/drivers/nvdimm/blk.c +++ /dev/null @@ -1,335 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * NVDIMM Block Window Driver - * Copyright (c) 2014, Intel Corporation. - */ - -#include <linux/blkdev.h> -#include <linux/fs.h> -#include <linux/genhd.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/nd.h> -#include <linux/sizes.h> -#include "nd.h" - -static u32 nsblk_meta_size(struct nd_namespace_blk *nsblk) -{ - return nsblk->lbasize - ((nsblk->lbasize >= 4096) ? 4096 : 512); -} - -static u32 nsblk_internal_lbasize(struct nd_namespace_blk *nsblk) -{ - return roundup(nsblk->lbasize, INT_LBASIZE_ALIGNMENT); -} - -static u32 nsblk_sector_size(struct nd_namespace_blk *nsblk) -{ - return nsblk->lbasize - nsblk_meta_size(nsblk); -} - -static resource_size_t to_dev_offset(struct nd_namespace_blk *nsblk, - resource_size_t ns_offset, unsigned int len) -{ - int i; - - for (i = 0; i < nsblk->num_resources; i++) { - if (ns_offset < resource_size(nsblk->res[i])) { - if (ns_offset + len > resource_size(nsblk->res[i])) { - dev_WARN_ONCE(&nsblk->common.dev, 1, - "illegal request\n"); - return SIZE_MAX; - } - return nsblk->res[i]->start + ns_offset; - } - ns_offset -= resource_size(nsblk->res[i]); - } - - dev_WARN_ONCE(&nsblk->common.dev, 1, "request out of range\n"); - return SIZE_MAX; -} - -static struct nd_blk_region *to_ndbr(struct nd_namespace_blk *nsblk) -{ - struct nd_region *nd_region; - struct device *parent; - - parent = nsblk->common.dev.parent; - nd_region = container_of(parent, struct nd_region, dev); - return container_of(nd_region, struct nd_blk_region, nd_region); -} - -#ifdef CONFIG_BLK_DEV_INTEGRITY -static int nd_blk_rw_integrity(struct nd_namespace_blk *nsblk, - struct bio_integrity_payload *bip, u64 lba, int rw) -{ - struct nd_blk_region *ndbr = to_ndbr(nsblk); - unsigned int len = nsblk_meta_size(nsblk); - resource_size_t dev_offset, ns_offset; - u32 internal_lbasize, sector_size; - int err = 0; - - internal_lbasize = nsblk_internal_lbasize(nsblk); - sector_size = nsblk_sector_size(nsblk); - ns_offset = lba * internal_lbasize + sector_size; - dev_offset = to_dev_offset(nsblk, ns_offset, len); - if (dev_offset == SIZE_MAX) - return -EIO; - - while (len) { - unsigned int cur_len; - struct bio_vec bv; - void *iobuf; - - bv = bvec_iter_bvec(bip->bip_vec, bip->bip_iter); - /* - * The 'bv' obtained from bvec_iter_bvec has its .bv_len and - * .bv_offset already adjusted for iter->bi_bvec_done, and we - * can use those directly - */ - - cur_len = min(len, bv.bv_len); - iobuf = kmap_atomic(bv.bv_page); - err = ndbr->do_io(ndbr, dev_offset, iobuf + bv.bv_offset, - cur_len, rw); - kunmap_atomic(iobuf); - if (err) - return err; - - len -= cur_len; - dev_offset += cur_len; - if (!bvec_iter_advance(bip->bip_vec, &bip->bip_iter, cur_len)) - return -EIO; - } - - return err; -} - -#else /* CONFIG_BLK_DEV_INTEGRITY */ -static int nd_blk_rw_integrity(struct nd_namespace_blk *nsblk, - struct bio_integrity_payload *bip, u64 lba, int rw) -{ - return 0; -} -#endif - -static int nsblk_do_bvec(struct nd_namespace_blk *nsblk, - struct bio_integrity_payload *bip, struct page *page, - unsigned int len, unsigned int off, int rw, sector_t sector) -{ - struct nd_blk_region *ndbr = to_ndbr(nsblk); - resource_size_t dev_offset, ns_offset; - u32 internal_lbasize, sector_size; - int err = 0; - void *iobuf; - u64 lba; - - internal_lbasize = nsblk_internal_lbasize(nsblk); - sector_size = nsblk_sector_size(nsblk); - while (len) { - unsigned int cur_len; - - /* - * If we don't have an integrity payload, we don't have to - * split the bvec into sectors, as this would cause unnecessary - * Block Window setup/move steps. the do_io routine is capable - * of handling len <= PAGE_SIZE. - */ - cur_len = bip ? min(len, sector_size) : len; - - lba = div_u64(sector << SECTOR_SHIFT, sector_size); - ns_offset = lba * internal_lbasize; - dev_offset = to_dev_offset(nsblk, ns_offset, cur_len); - if (dev_offset == SIZE_MAX) - return -EIO; - - iobuf = kmap_atomic(page); - err = ndbr->do_io(ndbr, dev_offset, iobuf + off, cur_len, rw); - kunmap_atomic(iobuf); - if (err) - return err; - - if (bip) { - err = nd_blk_rw_integrity(nsblk, bip, lba, rw); - if (err) - return err; - } - len -= cur_len; - off += cur_len; - sector += sector_size >> SECTOR_SHIFT; - } - - return err; -} - -static void nd_blk_submit_bio(struct bio *bio) -{ - struct bio_integrity_payload *bip; - struct nd_namespace_blk *nsblk = bio->bi_bdev->bd_disk->private_data; - struct bvec_iter iter; - unsigned long start; - struct bio_vec bvec; - int err = 0, rw; - bool do_acct; - - if (!bio_integrity_prep(bio)) - return; - - bip = bio_integrity(bio); - rw = bio_data_dir(bio); - do_acct = blk_queue_io_stat(bio->bi_bdev->bd_disk->queue); - if (do_acct) - start = bio_start_io_acct(bio); - bio_for_each_segment(bvec, bio, iter) { - unsigned int len = bvec.bv_len; - - BUG_ON(len > PAGE_SIZE); - err = nsblk_do_bvec(nsblk, bip, bvec.bv_page, len, - bvec.bv_offset, rw, iter.bi_sector); - if (err) { - dev_dbg(&nsblk->common.dev, - "io error in %s sector %lld, len %d,\n", - (rw == READ) ? "READ" : "WRITE", - (unsigned long long) iter.bi_sector, len); - bio->bi_status = errno_to_blk_status(err); - break; - } - } - if (do_acct) - bio_end_io_acct(bio, start); - - bio_endio(bio); -} - -static int nsblk_rw_bytes(struct nd_namespace_common *ndns, - resource_size_t offset, void *iobuf, size_t n, int rw, - unsigned long flags) -{ - struct nd_namespace_blk *nsblk = to_nd_namespace_blk(&ndns->dev); - struct nd_blk_region *ndbr = to_ndbr(nsblk); - resource_size_t dev_offset; - - dev_offset = to_dev_offset(nsblk, offset, n); - - if (unlikely(offset + n > nsblk->size)) { - dev_WARN_ONCE(&ndns->dev, 1, "request out of range\n"); - return -EFAULT; - } - - if (dev_offset == SIZE_MAX) - return -EIO; - - return ndbr->do_io(ndbr, dev_offset, iobuf, n, rw); -} - -static const struct block_device_operations nd_blk_fops = { - .owner = THIS_MODULE, - .submit_bio = nd_blk_submit_bio, -}; - -static void nd_blk_release_disk(void *disk) -{ - del_gendisk(disk); - blk_cleanup_disk(disk); -} - -static int nsblk_attach_disk(struct nd_namespace_blk *nsblk) -{ - struct device *dev = &nsblk->common.dev; - resource_size_t available_disk_size; - struct gendisk *disk; - u64 internal_nlba; - int rc; - - internal_nlba = div_u64(nsblk->size, nsblk_internal_lbasize(nsblk)); - available_disk_size = internal_nlba * nsblk_sector_size(nsblk); - - disk = blk_alloc_disk(NUMA_NO_NODE); - if (!disk) - return -ENOMEM; - - disk->fops = &nd_blk_fops; - disk->private_data = nsblk; - nvdimm_namespace_disk_name(&nsblk->common, disk->disk_name); - - blk_queue_max_hw_sectors(disk->queue, UINT_MAX); - blk_queue_logical_block_size(disk->queue, nsblk_sector_size(nsblk)); - blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue); - - if (nsblk_meta_size(nsblk)) { - rc = nd_integrity_init(disk, nsblk_meta_size(nsblk)); - - if (rc) - goto out_before_devm_err; - } - - set_capacity(disk, available_disk_size >> SECTOR_SHIFT); - rc = device_add_disk(dev, disk, NULL); - if (rc) - goto out_before_devm_err; - - /* nd_blk_release_disk() is called if this fails */ - if (devm_add_action_or_reset(dev, nd_blk_release_disk, disk)) - return -ENOMEM; - - nvdimm_check_and_set_ro(disk); - return 0; - -out_before_devm_err: - blk_cleanup_disk(disk); - return rc; -} - -static int nd_blk_probe(struct device *dev) -{ - struct nd_namespace_common *ndns; - struct nd_namespace_blk *nsblk; - - ndns = nvdimm_namespace_common_probe(dev); - if (IS_ERR(ndns)) - return PTR_ERR(ndns); - - nsblk = to_nd_namespace_blk(&ndns->dev); - nsblk->size = nvdimm_namespace_capacity(ndns); - dev_set_drvdata(dev, nsblk); - - ndns->rw_bytes = nsblk_rw_bytes; - if (is_nd_btt(dev)) - return nvdimm_namespace_attach_btt(ndns); - else if (nd_btt_probe(dev, ndns) == 0) { - /* we'll come back as btt-blk */ - return -ENXIO; - } else - return nsblk_attach_disk(nsblk); -} - -static void nd_blk_remove(struct device *dev) -{ - if (is_nd_btt(dev)) - nvdimm_namespace_detach_btt(to_nd_btt(dev)); -} - -static struct nd_device_driver nd_blk_driver = { - .probe = nd_blk_probe, - .remove = nd_blk_remove, - .drv = { - .name = "nd_blk", - }, - .type = ND_DRIVER_NAMESPACE_BLK, -}; - -static int __init nd_blk_init(void) -{ - return nd_driver_register(&nd_blk_driver); -} - -static void __exit nd_blk_exit(void) -{ - driver_unregister(&nd_blk_driver.drv); -} - -MODULE_AUTHOR("Ross Zwisler <ross.zwisler@linux.intel.com>"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS_ND_DEVICE(ND_DEVICE_NAMESPACE_BLK); -module_init(nd_blk_init); -module_exit(nd_blk_exit); |