diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-28 14:47:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-28 14:47:45 -0400 |
commit | ed99d3673e082b78b20208f346d2cd375483a779 (patch) | |
tree | 3efb696603c4b9ae9e33bddc2256739cf23795f4 | |
parent | b92d9648edcc56baf537afe491b228f158b68fcb (diff) | |
parent | 52e73eb2872c9af6f382b2b22954ca8214397a4e (diff) |
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
-rw-r--r-- | drivers/dax/Kconfig | 2 | ||||
-rw-r--r-- | drivers/dax/pmem.c | 2 | ||||
-rw-r--r-- | drivers/nvdimm/Kconfig | 2 | ||||
-rw-r--r-- | drivers/nvdimm/namespace_devs.c | 14 | ||||
-rw-r--r-- | drivers/nvdimm/pmem.c | 8 |
5 files changed, 17 insertions, 11 deletions
diff --git a/drivers/dax/Kconfig b/drivers/dax/Kconfig index daadd20aa936..3e2ab3b14eea 100644 --- a/drivers/dax/Kconfig +++ b/drivers/dax/Kconfig | |||
@@ -14,7 +14,7 @@ if DEV_DAX | |||
14 | 14 | ||
15 | config DEV_DAX_PMEM | 15 | config DEV_DAX_PMEM |
16 | tristate "PMEM DAX: direct access to persistent memory" | 16 | tristate "PMEM DAX: direct access to persistent memory" |
17 | depends on NVDIMM_DAX | 17 | depends on LIBNVDIMM && NVDIMM_DAX |
18 | default DEV_DAX | 18 | default DEV_DAX |
19 | help | 19 | help |
20 | Support raw access to persistent memory. Note that this | 20 | Support raw access to persistent memory. Note that this |
diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c index 9630d8837ba9..4a15fa5df98b 100644 --- a/drivers/dax/pmem.c +++ b/drivers/dax/pmem.c | |||
@@ -44,7 +44,6 @@ static void dax_pmem_percpu_exit(void *data) | |||
44 | 44 | ||
45 | dev_dbg(dax_pmem->dev, "%s\n", __func__); | 45 | dev_dbg(dax_pmem->dev, "%s\n", __func__); |
46 | percpu_ref_exit(ref); | 46 | percpu_ref_exit(ref); |
47 | wait_for_completion(&dax_pmem->cmp); | ||
48 | } | 47 | } |
49 | 48 | ||
50 | static void dax_pmem_percpu_kill(void *data) | 49 | static void dax_pmem_percpu_kill(void *data) |
@@ -54,6 +53,7 @@ static void dax_pmem_percpu_kill(void *data) | |||
54 | 53 | ||
55 | dev_dbg(dax_pmem->dev, "%s\n", __func__); | 54 | dev_dbg(dax_pmem->dev, "%s\n", __func__); |
56 | percpu_ref_kill(ref); | 55 | percpu_ref_kill(ref); |
56 | wait_for_completion(&dax_pmem->cmp); | ||
57 | } | 57 | } |
58 | 58 | ||
59 | static int dax_pmem_probe(struct device *dev) | 59 | static int dax_pmem_probe(struct device *dev) |
diff --git a/drivers/nvdimm/Kconfig b/drivers/nvdimm/Kconfig index 8b2b740d6679..124c2432ac9c 100644 --- a/drivers/nvdimm/Kconfig +++ b/drivers/nvdimm/Kconfig | |||
@@ -89,7 +89,7 @@ config NVDIMM_PFN | |||
89 | Select Y if unsure | 89 | Select Y if unsure |
90 | 90 | ||
91 | config NVDIMM_DAX | 91 | config NVDIMM_DAX |
92 | tristate "NVDIMM DAX: Raw access to persistent memory" | 92 | bool "NVDIMM DAX: Raw access to persistent memory" |
93 | default LIBNVDIMM | 93 | default LIBNVDIMM |
94 | depends on NVDIMM_PFN | 94 | depends on NVDIMM_PFN |
95 | help | 95 | help |
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index 3509cff68ef9..abe5c6bc756c 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c | |||
@@ -2176,12 +2176,14 @@ static struct device **scan_labels(struct nd_region *nd_region) | |||
2176 | return devs; | 2176 | return devs; |
2177 | 2177 | ||
2178 | err: | 2178 | err: |
2179 | for (i = 0; devs[i]; i++) | 2179 | if (devs) { |
2180 | if (is_nd_blk(&nd_region->dev)) | 2180 | for (i = 0; devs[i]; i++) |
2181 | namespace_blk_release(devs[i]); | 2181 | if (is_nd_blk(&nd_region->dev)) |
2182 | else | 2182 | namespace_blk_release(devs[i]); |
2183 | namespace_pmem_release(devs[i]); | 2183 | else |
2184 | kfree(devs); | 2184 | namespace_pmem_release(devs[i]); |
2185 | kfree(devs); | ||
2186 | } | ||
2185 | return NULL; | 2187 | return NULL; |
2186 | } | 2188 | } |
2187 | 2189 | ||
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 42b3a8217073..24618431a14b 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c | |||
@@ -47,7 +47,7 @@ static struct nd_region *to_region(struct pmem_device *pmem) | |||
47 | return to_nd_region(to_dev(pmem)->parent); | 47 | return to_nd_region(to_dev(pmem)->parent); |
48 | } | 48 | } |
49 | 49 | ||
50 | static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset, | 50 | static int pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset, |
51 | unsigned int len) | 51 | unsigned int len) |
52 | { | 52 | { |
53 | struct device *dev = to_dev(pmem); | 53 | struct device *dev = to_dev(pmem); |
@@ -62,8 +62,12 @@ static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset, | |||
62 | __func__, (unsigned long long) sector, | 62 | __func__, (unsigned long long) sector, |
63 | cleared / 512, cleared / 512 > 1 ? "s" : ""); | 63 | cleared / 512, cleared / 512 > 1 ? "s" : ""); |
64 | badblocks_clear(&pmem->bb, sector, cleared / 512); | 64 | badblocks_clear(&pmem->bb, sector, cleared / 512); |
65 | } else { | ||
66 | return -EIO; | ||
65 | } | 67 | } |
68 | |||
66 | invalidate_pmem(pmem->virt_addr + offset, len); | 69 | invalidate_pmem(pmem->virt_addr + offset, len); |
70 | return 0; | ||
67 | } | 71 | } |
68 | 72 | ||
69 | static void write_pmem(void *pmem_addr, struct page *page, | 73 | 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 | flush_dcache_page(page); | 127 | flush_dcache_page(page); |
124 | write_pmem(pmem_addr, page, off, len); | 128 | write_pmem(pmem_addr, page, off, len); |
125 | if (unlikely(bad_pmem)) { | 129 | if (unlikely(bad_pmem)) { |
126 | pmem_clear_poison(pmem, pmem_off, len); | 130 | rc = pmem_clear_poison(pmem, pmem_off, len); |
127 | write_pmem(pmem_addr, page, off, len); | 131 | write_pmem(pmem_addr, page, off, len); |
128 | } | 132 | } |
129 | } | 133 | } |