mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 14:41:39 +00:00
libnvdimm, pmem: fix 'pfn' support for section-misaligned namespaces
The altmap for a section-misaligned namespace needs to arrange for the base_pfn to be section-aligned. As a result the 'reserve' region (pfns from base that do not have a struct page) must be increased. Otherwise we trip the altmap validation check in __add_pages: if (altmap->base_pfn != phys_start_pfn || vmem_altmap_offset(altmap) > nr_pages) { pr_warn_once("memory add fail, invalid altmap\n"); return -EINVAL; } Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
bc94b99636
commit
d9cbe09d39
@ -15,6 +15,7 @@
|
||||
#define __NVDIMM_PFN_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/mmzone.h>
|
||||
|
||||
#define PFN_SIG_LEN 16
|
||||
#define PFN_SIG "NVDIMM_PFN_INFO\0"
|
||||
@ -32,4 +33,16 @@ struct nd_pfn_sb {
|
||||
u8 padding[4012];
|
||||
__le64 checksum;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SPARSEMEM
|
||||
#define PFN_SECTION_ALIGN_DOWN(x) SECTION_ALIGN_DOWN(x)
|
||||
#define PFN_SECTION_ALIGN_UP(x) SECTION_ALIGN_UP(x)
|
||||
#else
|
||||
/*
|
||||
* In this case ZONE_DEVICE=n and we will disable 'pfn' device support,
|
||||
* but we still want pmem to compile.
|
||||
*/
|
||||
#define PFN_SECTION_ALIGN_DOWN(x) (x)
|
||||
#define PFN_SECTION_ALIGN_UP(x) (x)
|
||||
#endif
|
||||
#endif /* __NVDIMM_PFN_H */
|
||||
|
@ -356,6 +356,26 @@ static int nvdimm_namespace_detach_pfn(struct nd_namespace_common *ndns)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We hotplug memory at section granularity, pad the reserved area from
|
||||
* the previous section base to the namespace base address.
|
||||
*/
|
||||
static unsigned long init_altmap_base(resource_size_t base)
|
||||
{
|
||||
unsigned long base_pfn = __phys_to_pfn(base);
|
||||
|
||||
return PFN_SECTION_ALIGN_DOWN(base_pfn);
|
||||
}
|
||||
|
||||
static unsigned long init_altmap_reserve(resource_size_t base)
|
||||
{
|
||||
unsigned long reserve = __phys_to_pfn(SZ_8K);
|
||||
unsigned long base_pfn = __phys_to_pfn(base);
|
||||
|
||||
reserve += base_pfn - PFN_SECTION_ALIGN_DOWN(base_pfn);
|
||||
return reserve;
|
||||
}
|
||||
|
||||
static int nvdimm_namespace_attach_pfn(struct nd_namespace_common *ndns)
|
||||
{
|
||||
struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
|
||||
@ -369,8 +389,8 @@ static int nvdimm_namespace_attach_pfn(struct nd_namespace_common *ndns)
|
||||
phys_addr_t offset;
|
||||
int rc;
|
||||
struct vmem_altmap __altmap = {
|
||||
.base_pfn = __phys_to_pfn(nsio->res.start),
|
||||
.reserve = __phys_to_pfn(SZ_8K),
|
||||
.base_pfn = init_altmap_base(nsio->res.start),
|
||||
.reserve = init_altmap_reserve(nsio->res.start),
|
||||
};
|
||||
|
||||
if (!nd_pfn->uuid || !nd_pfn->ndns)
|
||||
|
Loading…
Reference in New Issue
Block a user