Commit ed99d367 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm

Pull libnvdimm fixes from Dan Williams:
 "A build fix, a NULL de-reference found by static analysis, a misuse of
  the percpu_ref_exit() (tagged for -stable), and notification of failed
  attempts to clear media errors.

  These patches have received a build success notification from the
  0day- kbuild-robot and appeared in next-20161028"

* 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
  device-dax: fix percpu_ref_exit ordering
  nvdimm: make CONFIG_NVDIMM_DAX 'bool'
  pmem: report error on clear poison failure
  libnvdimm, namespace: potential NULL deref on allocation error
parents b92d9648 52e73eb2
...@@ -14,7 +14,7 @@ if DEV_DAX ...@@ -14,7 +14,7 @@ if DEV_DAX
config DEV_DAX_PMEM config DEV_DAX_PMEM
tristate "PMEM DAX: direct access to persistent memory" tristate "PMEM DAX: direct access to persistent memory"
depends on NVDIMM_DAX depends on LIBNVDIMM && NVDIMM_DAX
default DEV_DAX default DEV_DAX
help help
Support raw access to persistent memory. Note that this Support raw access to persistent memory. Note that this
......
...@@ -44,7 +44,6 @@ static void dax_pmem_percpu_exit(void *data) ...@@ -44,7 +44,6 @@ static void dax_pmem_percpu_exit(void *data)
dev_dbg(dax_pmem->dev, "%s\n", __func__); dev_dbg(dax_pmem->dev, "%s\n", __func__);
percpu_ref_exit(ref); percpu_ref_exit(ref);
wait_for_completion(&dax_pmem->cmp);
} }
static void dax_pmem_percpu_kill(void *data) static void dax_pmem_percpu_kill(void *data)
...@@ -54,6 +53,7 @@ static void dax_pmem_percpu_kill(void *data) ...@@ -54,6 +53,7 @@ static void dax_pmem_percpu_kill(void *data)
dev_dbg(dax_pmem->dev, "%s\n", __func__); dev_dbg(dax_pmem->dev, "%s\n", __func__);
percpu_ref_kill(ref); percpu_ref_kill(ref);
wait_for_completion(&dax_pmem->cmp);
} }
static int dax_pmem_probe(struct device *dev) static int dax_pmem_probe(struct device *dev)
......
...@@ -89,7 +89,7 @@ config NVDIMM_PFN ...@@ -89,7 +89,7 @@ config NVDIMM_PFN
Select Y if unsure Select Y if unsure
config NVDIMM_DAX config NVDIMM_DAX
tristate "NVDIMM DAX: Raw access to persistent memory" bool "NVDIMM DAX: Raw access to persistent memory"
default LIBNVDIMM default LIBNVDIMM
depends on NVDIMM_PFN depends on NVDIMM_PFN
help help
......
...@@ -2176,12 +2176,14 @@ static struct device **scan_labels(struct nd_region *nd_region) ...@@ -2176,12 +2176,14 @@ static struct device **scan_labels(struct nd_region *nd_region)
return devs; return devs;
err: err:
if (devs) {
for (i = 0; devs[i]; i++) for (i = 0; devs[i]; i++)
if (is_nd_blk(&nd_region->dev)) if (is_nd_blk(&nd_region->dev))
namespace_blk_release(devs[i]); namespace_blk_release(devs[i]);
else else
namespace_pmem_release(devs[i]); namespace_pmem_release(devs[i]);
kfree(devs); kfree(devs);
}
return NULL; return NULL;
} }
......
...@@ -47,7 +47,7 @@ static struct nd_region *to_region(struct pmem_device *pmem) ...@@ -47,7 +47,7 @@ static struct nd_region *to_region(struct pmem_device *pmem)
return to_nd_region(to_dev(pmem)->parent); return to_nd_region(to_dev(pmem)->parent);
} }
static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset, static int pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset,
unsigned int len) unsigned int len)
{ {
struct device *dev = to_dev(pmem); struct device *dev = to_dev(pmem);
...@@ -62,8 +62,12 @@ static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset, ...@@ -62,8 +62,12 @@ static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset,
__func__, (unsigned long long) sector, __func__, (unsigned long long) sector,
cleared / 512, cleared / 512 > 1 ? "s" : ""); cleared / 512, cleared / 512 > 1 ? "s" : "");
badblocks_clear(&pmem->bb, sector, cleared / 512); badblocks_clear(&pmem->bb, sector, cleared / 512);
} else {
return -EIO;
} }
invalidate_pmem(pmem->virt_addr + offset, len); invalidate_pmem(pmem->virt_addr + offset, len);
return 0;
} }
static void write_pmem(void *pmem_addr, struct page *page, static void write_pmem(void *pmem_addr, struct page *page,
...@@ -123,7 +127,7 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page, ...@@ -123,7 +127,7 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page,
flush_dcache_page(page); flush_dcache_page(page);
write_pmem(pmem_addr, page, off, len); write_pmem(pmem_addr, page, off, len);
if (unlikely(bad_pmem)) { if (unlikely(bad_pmem)) {
pmem_clear_poison(pmem, pmem_off, len); rc = pmem_clear_poison(pmem, pmem_off, len);
write_pmem(pmem_addr, page, off, len); write_pmem(pmem_addr, page, off, len);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment