summaryrefslogtreecommitdiffstats
path: root/drivers/nvdimm/region_devs.c
diff options
context:
space:
mode:
authorDave Jiang2016-09-26 20:06:50 +0200
committerDan Williams2016-10-01 04:12:52 +0200
commitdb58028ee4e360430de8e3b48f657dc798ee6591 (patch)
tree1f59b23cb217117e18c557b3705e7a66976cbe1e /drivers/nvdimm/region_devs.c
parentlibnvdimm, region: fix flush hint table thinko (diff)
downloadkernel-qcow2-linux-db58028ee4e360430de8e3b48f657dc798ee6591.tar.gz
kernel-qcow2-linux-db58028ee4e360430de8e3b48f657dc798ee6591.tar.xz
kernel-qcow2-linux-db58028ee4e360430de8e3b48f657dc798ee6591.zip
nvdimm: reduce duplicated wpq flushes
Existing implemenetation writes to all the flush hint addresses for a given ND region. This is not necessary as the flushes are per imc and not per DIMM. Search the mappings and clear out the duplicates at init to avoid multiple flush to the same imc. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/nvdimm/region_devs.c')
-rw-r--r--drivers/nvdimm/region_devs.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index 4c0ac4abb629..f9d58c2b5341 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -70,7 +70,7 @@ static int nvdimm_map_flush(struct device *dev, struct nvdimm *nvdimm, int dimm,
int nd_region_activate(struct nd_region *nd_region)
{
- int i, num_flush = 0;
+ int i, j, num_flush = 0;
struct nd_region_data *ndrd;
struct device *dev = &nd_region->dev;
size_t flush_data_size = sizeof(void *);
@@ -107,6 +107,21 @@ int nd_region_activate(struct nd_region *nd_region)
return rc;
}
+ /*
+ * Clear out entries that are duplicates. This should prevent the
+ * extra flushings.
+ */
+ for (i = 0; i < nd_region->ndr_mappings - 1; i++) {
+ /* ignore if NULL already */
+ if (!ndrd_get_flush_wpq(ndrd, i, 0))
+ continue;
+
+ for (j = i + 1; j < nd_region->ndr_mappings; j++)
+ if (ndrd_get_flush_wpq(ndrd, i, 0) ==
+ ndrd_get_flush_wpq(ndrd, j, 0))
+ ndrd_set_flush_wpq(ndrd, j, 0, NULL);
+ }
+
return 0;
}