| From bfb34527a32a1a576d9bfb7026d3ab0369a6cd60 Mon Sep 17 00:00:00 2001 |
| From: Dan Williams <dan.j.williams@intel.com> |
| Date: Sat, 4 Feb 2017 14:47:31 -0800 |
| Subject: [PATCH] libnvdimm, pfn: fix memmap reservation size versus 4K |
| alignment |
| |
| commit bfb34527a32a1a576d9bfb7026d3ab0369a6cd60 upstream. |
| |
| When vmemmap_populate() allocates space for the memmap it does so in 2MB |
| sized chunks. The libnvdimm-pfn driver incorrectly accounts for this |
| when the alignment of the device is set to 4K. When this happens we |
| trigger memory allocation failures in altmap_alloc_block_buf() and |
| trigger warnings of the form: |
| |
| WARNING: CPU: 0 PID: 3376 at arch/x86/mm/init_64.c:656 arch_add_memory+0xe4/0xf0 |
| [..] |
| Call Trace: |
| dump_stack+0x86/0xc3 |
| __warn+0xcb/0xf0 |
| warn_slowpath_null+0x1d/0x20 |
| arch_add_memory+0xe4/0xf0 |
| devm_memremap_pages+0x29b/0x4e0 |
| |
| Fixes: 315c562536c4 ("libnvdimm, pfn: add 'align' attribute, default to HPAGE_SIZE") |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Dan Williams <dan.j.williams@intel.com> |
| |
| diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c |
| index a2ac9e641aa9..6c033c9a2f06 100644 |
| --- a/drivers/nvdimm/pfn_devs.c |
| +++ b/drivers/nvdimm/pfn_devs.c |
| @@ -627,15 +627,12 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) |
| size = resource_size(&nsio->res); |
| npfns = (size - start_pad - end_trunc - SZ_8K) / SZ_4K; |
| if (nd_pfn->mode == PFN_MODE_PMEM) { |
| - unsigned long memmap_size; |
| - |
| /* |
| * vmemmap_populate_hugepages() allocates the memmap array in |
| * HPAGE_SIZE chunks. |
| */ |
| - memmap_size = ALIGN(64 * npfns, HPAGE_SIZE); |
| - offset = ALIGN(start + SZ_8K + memmap_size + dax_label_reserve, |
| - nd_pfn->align) - start; |
| + offset = ALIGN(start + SZ_8K + 64 * npfns + dax_label_reserve, |
| + max(nd_pfn->align, HPAGE_SIZE)) - start; |
| } else if (nd_pfn->mode == PFN_MODE_RAM) |
| offset = ALIGN(start + SZ_8K + dax_label_reserve, |
| nd_pfn->align) - start; |
| -- |
| 2.12.0 |
| |