Skip to content

Commit 8401c72

Browse files
committed
Merge branch 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm fixes from Dan Williams: "Two regression fixes, two bug fixes for older issues, two fixes for new functionality added this cycle that have userspace ABI concerns, and a small cleanup. These have appeared in a linux-next release and have a build success report from the 0day robot. * The 4.16 rework of altmap handling led to some configurations leaking page table allocations due to freeing from the altmap reservation rather than the page allocator. The impact without the fix is leaked memory and a WARN() message when tearing down libnvdimm namespaces. The rework also missed a place where error handling code needed to be removed that can lead to a crash if devm_memremap_pages() fails. * acpi_map_pxm_to_node() had a latent bug whereby it could misidentify the closest online node to a given proximity domain. * Block integrity handling was reworked several kernels back to allow calling add_disk() after setting up the integrity profile. The nd_btt and nd_blk drivers are just now catching up to fix automatic partition detection at driver load time. * The new peristence_domain attribute, a platform indicator of whether cpu caches are powerfail protected for example, is meant to be a single value enum and not a set of flags. This oversight was caught while reviewing new userspace code in libndctl to communicate the attribute. Fix this new enabling up so that we are not stuck with an unwanted userspace ABI" * 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: libnvdimm, nfit: fix persistence domain reporting libnvdimm, region: hide persistence_domain when unknown acpi, numa: fix pxm to online numa node associations x86, memremap: fix altmap accounting at free libnvdimm: remove redundant assignment to pointer 'dev' libnvdimm, {btt, blk}: do integrity setup before add_disk() kernel/memremap: Remove stale devres_free() call
2 parents 9ec7ccc + fe9a552 commit 8401c72

File tree

8 files changed

+57
-49
lines changed

8 files changed

+57
-49
lines changed

arch/x86/mm/init_64.c

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -800,17 +800,11 @@ int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
800800

801801
#define PAGE_INUSE 0xFD
802802

803-
static void __meminit free_pagetable(struct page *page, int order,
804-
struct vmem_altmap *altmap)
803+
static void __meminit free_pagetable(struct page *page, int order)
805804
{
806805
unsigned long magic;
807806
unsigned int nr_pages = 1 << order;
808807

809-
if (altmap) {
810-
vmem_altmap_free(altmap, nr_pages);
811-
return;
812-
}
813-
814808
/* bootmem page has reserved flag */
815809
if (PageReserved(page)) {
816810
__ClearPageReserved(page);
@@ -826,8 +820,16 @@ static void __meminit free_pagetable(struct page *page, int order,
826820
free_pages((unsigned long)page_address(page), order);
827821
}
828822

829-
static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd,
823+
static void __meminit free_hugepage_table(struct page *page,
830824
struct vmem_altmap *altmap)
825+
{
826+
if (altmap)
827+
vmem_altmap_free(altmap, PMD_SIZE / PAGE_SIZE);
828+
else
829+
free_pagetable(page, get_order(PMD_SIZE));
830+
}
831+
832+
static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
831833
{
832834
pte_t *pte;
833835
int i;
@@ -839,14 +841,13 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd,
839841
}
840842

841843
/* free a pte talbe */
842-
free_pagetable(pmd_page(*pmd), 0, altmap);
844+
free_pagetable(pmd_page(*pmd), 0);
843845
spin_lock(&init_mm.page_table_lock);
844846
pmd_clear(pmd);
845847
spin_unlock(&init_mm.page_table_lock);
846848
}
847849

848-
static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud,
849-
struct vmem_altmap *altmap)
850+
static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
850851
{
851852
pmd_t *pmd;
852853
int i;
@@ -858,14 +859,13 @@ static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud,
858859
}
859860

860861
/* free a pmd talbe */
861-
free_pagetable(pud_page(*pud), 0, altmap);
862+
free_pagetable(pud_page(*pud), 0);
862863
spin_lock(&init_mm.page_table_lock);
863864
pud_clear(pud);
864865
spin_unlock(&init_mm.page_table_lock);
865866
}
866867

867-
static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d,
868-
struct vmem_altmap *altmap)
868+
static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d)
869869
{
870870
pud_t *pud;
871871
int i;
@@ -877,15 +877,15 @@ static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d,
877877
}
878878

879879
/* free a pud talbe */
880-
free_pagetable(p4d_page(*p4d), 0, altmap);
880+
free_pagetable(p4d_page(*p4d), 0);
881881
spin_lock(&init_mm.page_table_lock);
882882
p4d_clear(p4d);
883883
spin_unlock(&init_mm.page_table_lock);
884884
}
885885

886886
static void __meminit
887887
remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
888-
struct vmem_altmap *altmap, bool direct)
888+
bool direct)
889889
{
890890
unsigned long next, pages = 0;
891891
pte_t *pte;
@@ -916,7 +916,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
916916
* freed when offlining, or simplely not in use.
917917
*/
918918
if (!direct)
919-
free_pagetable(pte_page(*pte), 0, altmap);
919+
free_pagetable(pte_page(*pte), 0);
920920

921921
spin_lock(&init_mm.page_table_lock);
922922
pte_clear(&init_mm, addr, pte);
@@ -939,7 +939,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
939939

940940
page_addr = page_address(pte_page(*pte));
941941
if (!memchr_inv(page_addr, PAGE_INUSE, PAGE_SIZE)) {
942-
free_pagetable(pte_page(*pte), 0, altmap);
942+
free_pagetable(pte_page(*pte), 0);
943943

944944
spin_lock(&init_mm.page_table_lock);
945945
pte_clear(&init_mm, addr, pte);
@@ -974,9 +974,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
974974
if (IS_ALIGNED(addr, PMD_SIZE) &&
975975
IS_ALIGNED(next, PMD_SIZE)) {
976976
if (!direct)
977-
free_pagetable(pmd_page(*pmd),
978-
get_order(PMD_SIZE),
979-
altmap);
977+
free_hugepage_table(pmd_page(*pmd),
978+
altmap);
980979

981980
spin_lock(&init_mm.page_table_lock);
982981
pmd_clear(pmd);
@@ -989,9 +988,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
989988
page_addr = page_address(pmd_page(*pmd));
990989
if (!memchr_inv(page_addr, PAGE_INUSE,
991990
PMD_SIZE)) {
992-
free_pagetable(pmd_page(*pmd),
993-
get_order(PMD_SIZE),
994-
altmap);
991+
free_hugepage_table(pmd_page(*pmd),
992+
altmap);
995993

996994
spin_lock(&init_mm.page_table_lock);
997995
pmd_clear(pmd);
@@ -1003,8 +1001,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
10031001
}
10041002

10051003
pte_base = (pte_t *)pmd_page_vaddr(*pmd);
1006-
remove_pte_table(pte_base, addr, next, altmap, direct);
1007-
free_pte_table(pte_base, pmd, altmap);
1004+
remove_pte_table(pte_base, addr, next, direct);
1005+
free_pte_table(pte_base, pmd);
10081006
}
10091007

10101008
/* Call free_pmd_table() in remove_pud_table(). */
@@ -1033,8 +1031,7 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
10331031
IS_ALIGNED(next, PUD_SIZE)) {
10341032
if (!direct)
10351033
free_pagetable(pud_page(*pud),
1036-
get_order(PUD_SIZE),
1037-
altmap);
1034+
get_order(PUD_SIZE));
10381035

10391036
spin_lock(&init_mm.page_table_lock);
10401037
pud_clear(pud);
@@ -1048,8 +1045,7 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
10481045
if (!memchr_inv(page_addr, PAGE_INUSE,
10491046
PUD_SIZE)) {
10501047
free_pagetable(pud_page(*pud),
1051-
get_order(PUD_SIZE),
1052-
altmap);
1048+
get_order(PUD_SIZE));
10531049

10541050
spin_lock(&init_mm.page_table_lock);
10551051
pud_clear(pud);
@@ -1062,7 +1058,7 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
10621058

10631059
pmd_base = pmd_offset(pud, 0);
10641060
remove_pmd_table(pmd_base, addr, next, direct, altmap);
1065-
free_pmd_table(pmd_base, pud, altmap);
1061+
free_pmd_table(pmd_base, pud);
10661062
}
10671063

10681064
if (direct)
@@ -1094,7 +1090,7 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end,
10941090
* to adapt for boot-time switching between 4 and 5 level page tables.
10951091
*/
10961092
if (CONFIG_PGTABLE_LEVELS == 5)
1097-
free_pud_table(pud_base, p4d, altmap);
1093+
free_pud_table(pud_base, p4d);
10981094
}
10991095

11001096
if (direct)

drivers/acpi/nfit/core.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2675,10 +2675,14 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
26752675
else
26762676
ndr_desc->numa_node = NUMA_NO_NODE;
26772677

2678-
if(acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_CACHE_FLUSH)
2678+
/*
2679+
* Persistence domain bits are hierarchical, if
2680+
* ACPI_NFIT_CAPABILITY_CACHE_FLUSH is set then
2681+
* ACPI_NFIT_CAPABILITY_MEM_FLUSH is implied.
2682+
*/
2683+
if (acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_CACHE_FLUSH)
26792684
set_bit(ND_REGION_PERSIST_CACHE, &ndr_desc->flags);
2680-
2681-
if (acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_MEM_FLUSH)
2685+
else if (acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_MEM_FLUSH)
26822686
set_bit(ND_REGION_PERSIST_MEMCTRL, &ndr_desc->flags);
26832687

26842688
list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {

drivers/acpi/numa.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,25 +103,27 @@ int acpi_map_pxm_to_node(int pxm)
103103
*/
104104
int acpi_map_pxm_to_online_node(int pxm)
105105
{
106-
int node, n, dist, min_dist;
106+
int node, min_node;
107107

108108
node = acpi_map_pxm_to_node(pxm);
109109

110110
if (node == NUMA_NO_NODE)
111111
node = 0;
112112

113+
min_node = node;
113114
if (!node_online(node)) {
114-
min_dist = INT_MAX;
115+
int min_dist = INT_MAX, dist, n;
116+
115117
for_each_online_node(n) {
116118
dist = node_distance(node, n);
117119
if (dist < min_dist) {
118120
min_dist = dist;
119-
node = n;
121+
min_node = n;
120122
}
121123
}
122124
}
123125

124-
return node;
126+
return min_node;
125127
}
126128
EXPORT_SYMBOL(acpi_map_pxm_to_online_node);
127129

drivers/nvdimm/blk.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,6 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk)
278278
disk->queue = q;
279279
disk->flags = GENHD_FL_EXT_DEVT;
280280
nvdimm_namespace_disk_name(&nsblk->common, disk->disk_name);
281-
set_capacity(disk, 0);
282-
device_add_disk(dev, disk);
283281

284282
if (devm_add_action_or_reset(dev, nd_blk_release_disk, disk))
285283
return -ENOMEM;
@@ -292,6 +290,7 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk)
292290
}
293291

294292
set_capacity(disk, available_disk_size >> SECTOR_SHIFT);
293+
device_add_disk(dev, disk);
295294
revalidate_disk(disk);
296295
return 0;
297296
}

drivers/nvdimm/btt.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,8 +1545,6 @@ static int btt_blk_init(struct btt *btt)
15451545
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, btt->btt_queue);
15461546
btt->btt_queue->queuedata = btt;
15471547

1548-
set_capacity(btt->btt_disk, 0);
1549-
device_add_disk(&btt->nd_btt->dev, btt->btt_disk);
15501548
if (btt_meta_size(btt)) {
15511549
int rc = nd_integrity_init(btt->btt_disk, btt_meta_size(btt));
15521550

@@ -1558,6 +1556,7 @@ static int btt_blk_init(struct btt *btt)
15581556
}
15591557
}
15601558
set_capacity(btt->btt_disk, btt->nlba * btt->sector_size >> 9);
1559+
device_add_disk(&btt->nd_btt->dev, btt->btt_disk);
15611560
btt->nd_btt->size = btt->nlba * (u64)btt->sector_size;
15621561
revalidate_disk(btt->btt_disk);
15631562

drivers/nvdimm/pfn_devs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ static const struct attribute_group *nd_pfn_attribute_groups[] = {
304304
struct device *nd_pfn_devinit(struct nd_pfn *nd_pfn,
305305
struct nd_namespace_common *ndns)
306306
{
307-
struct device *dev = &nd_pfn->dev;
307+
struct device *dev;
308308

309309
if (!nd_pfn)
310310
return NULL;

drivers/nvdimm/region_devs.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -532,11 +532,13 @@ static ssize_t persistence_domain_show(struct device *dev,
532532
struct device_attribute *attr, char *buf)
533533
{
534534
struct nd_region *nd_region = to_nd_region(dev);
535-
unsigned long flags = nd_region->flags;
536535

537-
return sprintf(buf, "%s%s\n",
538-
flags & BIT(ND_REGION_PERSIST_CACHE) ? "cpu_cache " : "",
539-
flags & BIT(ND_REGION_PERSIST_MEMCTRL) ? "memory_controller " : "");
536+
if (test_bit(ND_REGION_PERSIST_CACHE, &nd_region->flags))
537+
return sprintf(buf, "cpu_cache\n");
538+
else if (test_bit(ND_REGION_PERSIST_MEMCTRL, &nd_region->flags))
539+
return sprintf(buf, "memory_controller\n");
540+
else
541+
return sprintf(buf, "\n");
540542
}
541543
static DEVICE_ATTR_RO(persistence_domain);
542544

@@ -593,6 +595,13 @@ static umode_t region_visible(struct kobject *kobj, struct attribute *a, int n)
593595
return 0;
594596
}
595597

598+
if (a == &dev_attr_persistence_domain.attr) {
599+
if ((nd_region->flags & (BIT(ND_REGION_PERSIST_CACHE)
600+
| BIT(ND_REGION_PERSIST_MEMCTRL))) == 0)
601+
return 0;
602+
return a->mode;
603+
}
604+
596605
if (a != &dev_attr_set_cookie.attr
597606
&& a != &dev_attr_available_size.attr)
598607
return a->mode;

kernel/memremap.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,6 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
427427
err_pfn_remap:
428428
err_radix:
429429
pgmap_radix_release(res, pgoff);
430-
devres_free(pgmap);
431430
return ERR_PTR(error);
432431
}
433432
EXPORT_SYMBOL(devm_memremap_pages);

0 commit comments

Comments
 (0)