Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98ac9a60 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull libnvdimm fixes from Dan Williams:
 "nvdimm fixes for v4.8, two of them are tagged for -stable:

   - Fix devm_memremap_pages() to use track_pfn_insert().  Otherwise,
     DAX pmd mappings end up with an uncached pgprot, and unusable
     performance for the device-dax interface.  The device-dax interface
     appeared in 4.7 so this is tagged for -stable.

   - Fix a couple VM_BUG_ON() checks in the show_smaps() path to
     understand DAX pmd entries.  This fix is tagged for -stable.

   - Fix a mis-merge of the nfit machine-check handler to flip the
     polarity of an if() to match the final version of the patch that
     Vishal sent for 4.8-rc1.  Without this the nfit machine check
     handler never detects / inserts new 'badblocks' entries which
     applications use to identify lost portions of files.

   - For test purposes, fix the nvdimm_clear_poison() path to operate on
     legacy / simulated nvdimm memory ranges.  Without this fix a test
     can set badblocks, but never clear them on these ranges.

   - Fix the range checking done by dax_dev_pmd_fault().  This is not
     tagged for -stable since this problem is mitigated by specifying
     aligned resources at device-dax setup time.

  These patches have appeared in a next release over the past week.  The
  recent rebase you can see in the timestamps was to drop an invalid fix
  as identified by the updated device-dax unit tests [1].  The -mm
  touches have an ack from Andrew"

[1]: "[ndctl PATCH 0/3] device-dax test for recent kernel bugs"
   https://lists.01.org/pipermail/linux-nvdimm/2016-September/006855.html

* 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
  libnvdimm: allow legacy (e820) pmem region to clear bad blocks
  nfit, mce: Fix SPA matching logic in MCE handler
  mm: fix cache mode of dax pmd mappings
  mm: fix show_smap() for zone_device-pmd ranges
  dax: fix mapping size check
parents b8db3714 1e8b8d96
Loading
Loading
Loading
Loading
+10 −7
Original line number Original line Diff line number Diff line
@@ -927,9 +927,10 @@ int track_pfn_copy(struct vm_area_struct *vma)
}
}


/*
/*
 * prot is passed in as a parameter for the new mapping. If the vma has a
 * prot is passed in as a parameter for the new mapping. If the vma has
 * linear pfn mapping for the entire range reserve the entire vma range with
 * a linear pfn mapping for the entire range, or no vma is provided,
 * single reserve_pfn_range call.
 * reserve the entire pfn + size range with single reserve_pfn_range
 * call.
 */
 */
int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot,
int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot,
		    unsigned long pfn, unsigned long addr, unsigned long size)
		    unsigned long pfn, unsigned long addr, unsigned long size)
@@ -938,11 +939,12 @@ int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot,
	enum page_cache_mode pcm;
	enum page_cache_mode pcm;


	/* reserve the whole chunk starting from paddr */
	/* reserve the whole chunk starting from paddr */
	if (addr == vma->vm_start && size == (vma->vm_end - vma->vm_start)) {
	if (!vma || (addr == vma->vm_start
				&& size == (vma->vm_end - vma->vm_start))) {
		int ret;
		int ret;


		ret = reserve_pfn_range(paddr, size, prot, 0);
		ret = reserve_pfn_range(paddr, size, prot, 0);
		if (!ret)
		if (ret == 0 && vma)
			vma->vm_flags |= VM_PAT;
			vma->vm_flags |= VM_PAT;
		return ret;
		return ret;
	}
	}
@@ -997,7 +999,7 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
	resource_size_t paddr;
	resource_size_t paddr;
	unsigned long prot;
	unsigned long prot;


	if (!(vma->vm_flags & VM_PAT))
	if (vma && !(vma->vm_flags & VM_PAT))
		return;
		return;


	/* free the chunk starting from pfn or the whole chunk */
	/* free the chunk starting from pfn or the whole chunk */
@@ -1011,6 +1013,7 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
		size = vma->vm_end - vma->vm_start;
		size = vma->vm_end - vma->vm_start;
	}
	}
	free_pfn_range(paddr, size);
	free_pfn_range(paddr, size);
	if (vma)
		vma->vm_flags &= ~VM_PAT;
		vma->vm_flags &= ~VM_PAT;
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -42,7 +42,7 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val,
		list_for_each_entry(nfit_spa, &acpi_desc->spas, list) {
		list_for_each_entry(nfit_spa, &acpi_desc->spas, list) {
			struct acpi_nfit_system_address *spa = nfit_spa->spa;
			struct acpi_nfit_system_address *spa = nfit_spa->spa;


			if (nfit_spa_type(spa) == NFIT_SPA_PM)
			if (nfit_spa_type(spa) != NFIT_SPA_PM)
				continue;
				continue;
			/* find the spa that covers the mce addr */
			/* find the spa that covers the mce addr */
			if (spa->address > mce->addr)
			if (spa->address > mce->addr)
+1 −1
Original line number Original line Diff line number Diff line
@@ -459,7 +459,7 @@ static int __dax_dev_pmd_fault(struct dax_dev *dax_dev,
	}
	}


	pgoff = linear_page_index(vma, pmd_addr);
	pgoff = linear_page_index(vma, pmd_addr);
	phys = pgoff_to_phys(dax_dev, pgoff, PAGE_SIZE);
	phys = pgoff_to_phys(dax_dev, pgoff, PMD_SIZE);
	if (phys == -1) {
	if (phys == -1) {
		dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__,
		dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__,
				pgoff);
				pgoff);
+5 −1
Original line number Original line Diff line number Diff line
@@ -185,8 +185,12 @@ long nvdimm_clear_poison(struct device *dev, phys_addr_t phys,
		return -ENXIO;
		return -ENXIO;


	nd_desc = nvdimm_bus->nd_desc;
	nd_desc = nvdimm_bus->nd_desc;
	/*
	 * if ndctl does not exist, it's PMEM_LEGACY and
	 * we want to just pretend everything is handled.
	 */
	if (!nd_desc->ndctl)
	if (!nd_desc->ndctl)
		return -ENXIO;
		return len;


	memset(&ars_cap, 0, sizeof(ars_cap));
	memset(&ars_cap, 0, sizeof(ars_cap));
	ars_cap.address = phys;
	ars_cap.address = phys;
+2 −0
Original line number Original line Diff line number Diff line
@@ -581,6 +581,8 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
		mss->anonymous_thp += HPAGE_PMD_SIZE;
		mss->anonymous_thp += HPAGE_PMD_SIZE;
	else if (PageSwapBacked(page))
	else if (PageSwapBacked(page))
		mss->shmem_thp += HPAGE_PMD_SIZE;
		mss->shmem_thp += HPAGE_PMD_SIZE;
	else if (is_zone_device_page(page))
		/* pass */;
	else
	else
		VM_BUG_ON_PAGE(1, page);
		VM_BUG_ON_PAGE(1, page);
	smaps_account(mss, page, true, pmd_young(*pmd), pmd_dirty(*pmd));
	smaps_account(mss, page, true, pmd_young(*pmd), pmd_dirty(*pmd));
Loading