diff options
author | Dan Williams <dan.j.williams@intel.com> | 2017-04-30 01:24:03 +0300 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2017-04-30 01:24:03 +0300 |
commit | 23f4984483623cf8621246004228f08fcabf51e4 (patch) | |
tree | 4545eac73213e6c22a2c43af64818db1e7023aa0 /drivers/nvdimm/region.c | |
parent | 7699a6a36b82f22cb0b355c6411531abedf12964 (diff) | |
download | linux-23f4984483623cf8621246004228f08fcabf51e4.tar.xz |
libnvdimm: rework region badblocks clearing
Toshi noticed that the new support for a region-level badblocks missed
the case where errors are cleared due to BTT I/O.
An initial attempt to fix this ran into a "sleeping while atomic"
warning due to taking the nvdimm_bus_lock() in the BTT I/O path to
satisfy the locking requirements of __nvdimm_bus_badblocks_clear().
However, that lock is not needed since we are not acting on any data that
is subject to change under that lock. The badblocks instance has its own
internal lock to handle mutations of the error list.
So, in order to make it clear that we are just acting on region devices,
rename __nvdimm_bus_badblocks_clear() to nvdimm_clear_badblocks_regions().
Eliminate the lock and consolidate all support routines for the new
nvdimm_account_cleared_poison() in drivers/nvdimm/bus.c. Finally, to the
opportunity to cleanup to some unnecessary casts, make the calling
convention of nvdimm_clear_badblocks_regions() clearer by replacing struct
resource with the minimal struct clear_badblocks_context, and use the
DEVICE_ATTR macro.
Cc: Dave Jiang <dave.jiang@intel.com>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Reported-by: Toshi Kani <toshi.kani@hpe.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/nvdimm/region.c')
-rw-r--r-- | drivers/nvdimm/region.c | 25 |
1 files changed, 0 insertions, 25 deletions
diff --git a/drivers/nvdimm/region.c b/drivers/nvdimm/region.c index 23c4307d254c..869a886c292e 100644 --- a/drivers/nvdimm/region.c +++ b/drivers/nvdimm/region.c @@ -131,31 +131,6 @@ static void nd_region_notify(struct device *dev, enum nvdimm_event event) device_for_each_child(dev, &event, child_notify); } -int nvdimm_region_badblocks_clear(struct device *dev, void *data) -{ - struct resource *res = (struct resource *)data; - struct nd_region *nd_region; - resource_size_t ndr_end; - sector_t sector; - - /* make sure device is a region */ - if (!is_nd_pmem(dev)) - return 0; - - nd_region = to_nd_region(dev); - ndr_end = nd_region->ndr_start + nd_region->ndr_size - 1; - - /* make sure we are in the region */ - if (res->start < nd_region->ndr_start || res->end > ndr_end) - return 0; - - sector = (res->start - nd_region->ndr_start) >> 9; - badblocks_clear(&nd_region->bb, sector, resource_size(res) >> 9); - - return 0; -} -EXPORT_SYMBOL_GPL(nvdimm_region_badblocks_clear); - static struct nd_device_driver nd_region_driver = { .probe = nd_region_probe, .remove = nd_region_remove, |