* Re: [PATCH] powerpc/mm/nvdimm: Add an informative message if we fail to allocate altmap block
From: Oliver O'Halloran @ 2019-06-30 23:15 UTC (permalink / raw)
To: Aneesh Kumar K.V; +Cc: Paul Mackerras, linuxppc-dev, Nicholas Piggin
In-Reply-To: <20190629073813.12973-1-aneesh.kumar@linux.ibm.com>
On Sat, Jun 29, 2019 at 5:39 PM Aneesh Kumar K.V
<aneesh.kumar@linux.ibm.com> wrote:
>
> Allocation from altmap area can fail based on vmemmap page size used. Add kernel
> info message to indicate the failure. That allows the user to identify whether they
> are really using persistent memory reserved space for per-page metadata.
>
> The message looks like:
> [ 136.587212] altmap block allocation failed, falling back to system memory
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> ---
> arch/powerpc/mm/init_64.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index a4e17a979e45..57c0573650dc 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -194,8 +194,12 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
> * fail due to alignment issues when using 16MB hugepages, so
> * fall back to system memory if the altmap allocation fail.
> */
> - if (altmap)
> + if (altmap) {
> p = altmap_alloc_block_buf(page_size, altmap);
> + if (!p)
> + pr_info("altmap block allocation failed, " \
> + "falling back to system memory");
I think this is kind of misleading. If you're mapping a large amount
of memory you can have most of the vmemmap backing allocated from the
altmap and one extra block allocated from normal memory. E.g. If you
have 32MB of altmap space, one 16MB block will be allocated from the
altmap, but the 2nd 16MB block is probably unusable due to the
reserved pages at the start of the altmap. Maybe this should be a
pr_debug() so it's only printed along with the "vmemmap_populate ..."
message above?
Also, isn't kernel style to keep printf()s, even long ones, on one line?
Oliver
^ permalink raw reply
* Re: [PATCH 22/39] docs: ocxl.rst: add it to the uAPI book
From: Andrew Donnellan @ 2019-07-01 1:21 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Linux Doc Mailing List
Cc: Frederic Barrat, Jonathan Corbet, linuxppc-dev, linux-kernel,
Mauro Carvalho Chehab
In-Reply-To: <ee63ec4412f2f8c87da877f67f693f2cd85c1a37.1561724493.git.mchehab+samsung@kernel.org>
On 28/6/19 10:30 pm, Mauro Carvalho Chehab wrote:
> The content of this file is user-faced.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Acked-by: Andrew Donnellan <ajd@linux.ibm.com>
> ---
> Documentation/{ => userspace-api}/accelerators/ocxl.rst | 2 --
> Documentation/userspace-api/index.rst | 1 +
> MAINTAINERS | 2 +-
> 3 files changed, 2 insertions(+), 3 deletions(-)
> rename Documentation/{ => userspace-api}/accelerators/ocxl.rst (99%)
>
> diff --git a/Documentation/accelerators/ocxl.rst b/Documentation/userspace-api/accelerators/ocxl.rst
> similarity index 99%
> rename from Documentation/accelerators/ocxl.rst
> rename to Documentation/userspace-api/accelerators/ocxl.rst
> index b1cea19a90f5..14cefc020e2d 100644
> --- a/Documentation/accelerators/ocxl.rst
> +++ b/Documentation/userspace-api/accelerators/ocxl.rst
> @@ -1,5 +1,3 @@
> -:orphan:
> -
> ========================================================
> OpenCAPI (Open Coherent Accelerator Processor Interface)
> ========================================================
> diff --git a/Documentation/userspace-api/index.rst b/Documentation/userspace-api/index.rst
> index a3233da7fa88..ad494da40009 100644
> --- a/Documentation/userspace-api/index.rst
> +++ b/Documentation/userspace-api/index.rst
> @@ -20,6 +20,7 @@ place where this information is gathered.
> seccomp_filter
> unshare
> spec_ctrl
> + accelerators/ocxl
>
> .. only:: subproject and html
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 29d1498ad39d..f723371dccd0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11483,7 +11483,7 @@ F: arch/powerpc/include/asm/pnv-ocxl.h
> F: drivers/misc/ocxl/
> F: include/misc/ocxl*
> F: include/uapi/misc/ocxl.h
> -F: Documentation/accelerators/ocxl.rst
> +F: Documentation/userspace-api/accelerators/ocxl.rst
>
> OMAP AUDIO SUPPORT
> M: Peter Ujfalusi <peter.ujfalusi@ti.com>
>
--
Andrew Donnellan OzLabs, ADL Canberra
ajd@linux.ibm.com IBM Australia Limited
^ permalink raw reply
* Re: [PATCH] powerpc/mm/radix: Use the right page size for vmemmap mapping
From: Nicholas Piggin @ 2019-07-01 2:17 UTC (permalink / raw)
To: Aneesh Kumar K.V, mpe, paulus; +Cc: linuxppc-dev
In-Reply-To: <20190629073829.13095-1-aneesh.kumar@linux.ibm.com>
Aneesh Kumar K.V's on June 29, 2019 5:38 pm:
> Also on hash with 4K PAGE_SIZE make sure we use 4K page size for
> vmemmap.
Can you add a line in the changelog to describe the radix problem
you fixed?
Also I would say the also could be a separate patch?
Thanks,
Nick
>
> Fixes: 2bfd65e45e87 ("powerpc/mm/radix: Add radix callbacks for early init routines")
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> ---
> arch/powerpc/mm/book3s64/hash_utils.c | 4 +---
> arch/powerpc/mm/book3s64/radix_pgtable.c | 16 +++++++---------
> 2 files changed, 8 insertions(+), 12 deletions(-)
>
> diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c
> index 49f8c8940bd9..54013bbc60aa 100644
> --- a/arch/powerpc/mm/book3s64/hash_utils.c
> +++ b/arch/powerpc/mm/book3s64/hash_utils.c
> @@ -686,10 +686,8 @@ static void __init htab_init_page_sizes(void)
> if (mmu_psize_defs[MMU_PAGE_16M].shift &&
> memblock_phys_mem_size() >= 0x40000000)
> mmu_vmemmap_psize = MMU_PAGE_16M;
> - else if (mmu_psize_defs[MMU_PAGE_64K].shift)
> - mmu_vmemmap_psize = MMU_PAGE_64K;
> else
> - mmu_vmemmap_psize = MMU_PAGE_4K;
> + mmu_vmemmap_psize = mmu_virtual_psize;
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>
> printk(KERN_DEBUG "Page orders: linear mapping = %d, "
> diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
> index 60d97fab4de2..03d804a0dc8c 100644
> --- a/arch/powerpc/mm/book3s64/radix_pgtable.c
> +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
> @@ -529,14 +529,6 @@ void __init radix__early_init_devtree(void)
> mmu_psize_defs[MMU_PAGE_64K].shift = 16;
> mmu_psize_defs[MMU_PAGE_64K].ap = 0x5;
> found:
> -#ifdef CONFIG_SPARSEMEM_VMEMMAP
> - if (mmu_psize_defs[MMU_PAGE_2M].shift) {
> - /*
> - * map vmemmap using 2M if available
> - */
> - mmu_vmemmap_psize = MMU_PAGE_2M;
> - }
> -#endif /* CONFIG_SPARSEMEM_VMEMMAP */
> return;
> }
>
> @@ -601,7 +593,13 @@ void __init radix__early_init_mmu(void)
>
> #ifdef CONFIG_SPARSEMEM_VMEMMAP
> /* vmemmap mapping */
> - mmu_vmemmap_psize = mmu_virtual_psize;
> + if (mmu_psize_defs[MMU_PAGE_2M].shift) {
> + /*
> + * map vmemmap using 2M if available
> + */
> + mmu_vmemmap_psize = MMU_PAGE_2M;
> + } else
> + mmu_vmemmap_psize = mmu_virtual_psize;
> #endif
> /*
> * initialize page table size
> --
> 2.21.0
>
>
^ permalink raw reply
* Re: [PATCH] powerpc: remove device_to_mask
From: Alexey Kardashevskiy @ 2019-07-01 3:06 UTC (permalink / raw)
To: Christoph Hellwig, paulus, mpe; +Cc: linuxppc-dev
In-Reply-To: <20190629080359.23182-1-hch@lst.de>
On 29/06/2019 18:03, Christoph Hellwig wrote:
> Use the dma_get_mask helper from dma-mapping.h instead.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
> arch/powerpc/include/asm/iommu.h | 8 --------
> arch/powerpc/kernel/dma-iommu.c | 4 ++--
> arch/powerpc/platforms/pseries/vio.c | 4 ++--
> 3 files changed, 4 insertions(+), 12 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
> index 0ac52392ed99..f98f2864b66a 100644
> --- a/arch/powerpc/include/asm/iommu.h
> +++ b/arch/powerpc/include/asm/iommu.h
> @@ -327,13 +327,5 @@ extern bool iommu_fixed_is_weak;
>
> extern const struct dma_map_ops dma_iommu_ops;
>
> -static inline unsigned long device_to_mask(struct device *dev)
> -{
> - if (dev->dma_mask && *dev->dma_mask)
> - return *dev->dma_mask;
> - /* Assume devices without mask can take 32 bit addresses */
> - return 0xfffffffful;
> -}
> -
> #endif /* __KERNEL__ */
> #endif /* _ASM_IOMMU_H */
> diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
> index 09231ef06d01..168af3a5b4b1 100644
> --- a/arch/powerpc/kernel/dma-iommu.c
> +++ b/arch/powerpc/kernel/dma-iommu.c
> @@ -71,7 +71,7 @@ static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page,
> return dma_direct_map_page(dev, page, offset, size, direction,
> attrs);
> return iommu_map_page(dev, get_iommu_table_base(dev), page, offset,
> - size, device_to_mask(dev), direction, attrs);
> + size, dma_get_mask(dev), direction, attrs);
> }
>
>
> @@ -92,7 +92,7 @@ static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
> if (dma_iommu_map_bypass(dev, attrs))
> return dma_direct_map_sg(dev, sglist, nelems, direction, attrs);
> return ppc_iommu_map_sg(dev, get_iommu_table_base(dev), sglist, nelems,
> - device_to_mask(dev), direction, attrs);
> + dma_get_mask(dev), direction, attrs);
> }
>
> static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,
> diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
> index 141795275ccb..97c0e3e5eae5 100644
> --- a/arch/powerpc/platforms/pseries/vio.c
> +++ b/arch/powerpc/platforms/pseries/vio.c
> @@ -524,7 +524,7 @@ static dma_addr_t vio_dma_iommu_map_page(struct device *dev, struct page *page,
>
> if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl))))
> goto out_fail;
> - ret = iommu_map_page(dev, tbl, page, offset, size, device_to_mask(dev),
> + ret = iommu_map_page(dev, tbl, page, offset, size, dma_get_mask(dev),
> direction, attrs);
> if (unlikely(ret == DMA_MAPPING_ERROR))
> goto out_deallocate;
> @@ -564,7 +564,7 @@ static int vio_dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
>
> if (vio_cmo_alloc(viodev, alloc_size))
> goto out_fail;
> - ret = ppc_iommu_map_sg(dev, tbl, sglist, nelems, device_to_mask(dev),
> + ret = ppc_iommu_map_sg(dev, tbl, sglist, nelems, dma_get_mask(dev),
> direction, attrs);
> if (unlikely(!ret))
> goto out_deallocate;
>
--
Alexey
^ permalink raw reply
* Re: [RFC PATCH 03/12] powerpc/prom_init: Add the ESM call to prom_init
From: Alexey Kardashevskiy @ 2019-07-01 3:13 UTC (permalink / raw)
To: Thiago Jung Bauermann
Cc: Anshuman Khandual, Mike Anderson, Ram Pai, linux-kernel,
Claudio Carvalho, Paul Mackerras, linuxppc-dev, Christoph Hellwig
In-Reply-To: <87mui1732j.fsf@morokweng.localdomain>
On 29/06/2019 08:33, Thiago Jung Bauermann wrote:
>
> Hello Alexey,
>
> Thanks for reviewing this patch!
>
> Alexey Kardashevskiy <aik@ozlabs.ru> writes:
>
>> On 21/05/2019 14:49, Thiago Jung Bauermann wrote:
>>> @@ -1707,6 +1723,43 @@ static void __init prom_close_stdin(void)
>>> }
>>> }
>>>
>>> +#ifdef CONFIG_PPC_SVM
>>> +static int prom_rtas_os_term_hcall(uint64_t args)
>>
>>
>> This is just an rtas hcall, nothing special about "os-term".
>
> Sorry, unfortunately I don't understand how we're treating os-term
> especially. Do you mean that we should inline this function directly
> into prom_rtas_os_term()?
I meant the function name - prom_rtas_os_term_hcall - should rather be
prom_rtas_hcall.
>
>>> +{
>>> + register uint64_t arg1 asm("r3") = 0xf000;
>>> + register uint64_t arg2 asm("r4") = args;
>>> +
>>> + asm volatile("sc 1\n" : "=r" (arg1) :
>>> + "r" (arg1),
>>> + "r" (arg2) :);
>>> + return arg1;
>>> +}
>>> +
>>> +static struct rtas_args __prombss os_term_args;
>>> +
>>> +static void __init prom_rtas_os_term(char *str)
>>> +{
>>> + phandle rtas_node;
>>> + __be32 val;
>>> + u32 token;
>>> +
>>> + prom_printf("%s: start...\n", __func__);
>>> + rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
>>> + prom_printf("rtas_node: %x\n", rtas_node);
>>> + if (!PHANDLE_VALID(rtas_node))
>>> + return;
>>> +
>>> + val = 0;
>>> + prom_getprop(rtas_node, "ibm,os-term", &val, sizeof(val));
>>> + token = be32_to_cpu(val);
>>> + prom_printf("ibm,os-term: %x\n", token);
>>> + if (token == 0)
>>> + prom_panic("Could not get token for ibm,os-term\n");
>>> + os_term_args.token = cpu_to_be32(token);
>>> + prom_rtas_os_term_hcall((uint64_t)&os_term_args);
>>> +}
>>> +#endif /* CONFIG_PPC_SVM */
>>> +
>>> /*
>>> * Allocate room for and instantiate RTAS
>>> */
>
--
Alexey
^ permalink raw reply
* Re: [PATCH v2] powerpc/pseries: Fix maximum memory value
From: Aravinda Prasad @ 2019-07-01 4:03 UTC (permalink / raw)
To: Nathan Lynch; +Cc: naveen.n.rao, linuxppc-dev
In-Reply-To: <87tvc9sjrb.fsf@linux.ibm.com>
On Friday 28 June 2019 10:57 PM, Nathan Lynch wrote:
> Aravinda Prasad <aravinda@linux.vnet.ibm.com> writes:
>> Calculating the maximum memory based on the number of lmbs
>> and lmb size does not account for the RMA region. Hence
>> use memory_hotplug_max(), which already accounts for the
>> RMA region, to fetch the maximum memory value. Thanks to
>> Nathan Lynch for suggesting the memory_hotplug_max()
>> function.
>
> Well, I hope I haven't led you astray... will it give you the desired
> result on a kernel configured without memory hotplug support, booted in
> an LPAR with some huge pages configured?
Yes. I have tested the patch both with CONFIG_MEMORY_HOTPLUG set and not
set. It is working as expected.
Regards,
Aravinda
>
> If so, then
> Acked-by: Nathan Lynch <nathanl@linux.ibm.com>
>
> It would likely help with review and future maintenance if the semantics
> and intended use of the MaxMem field are made a little more
> explicit. For example, is it supposed to include persistent memory?
> Perhaps a follow-up patch could address this. Or maybe I'm overthinking
> it.
>
--
Regards,
Aravinda
^ permalink raw reply
* Re: [PATCH v4 6/8] KVM: PPC: Ultravisor: Restrict LDBAR access
From: Alexey Kardashevskiy @ 2019-07-01 5:54 UTC (permalink / raw)
To: Claudio Carvalho, linuxppc-dev
Cc: Madhavan Srinivasan, Michael Anderson, Ram Pai, kvm-ppc,
Bharata B Rao, Ryan Grimm, Sukadev Bhattiprolu, Thiago Bauermann,
Anshuman Khandual
In-Reply-To: <20190628200825.31049-7-cclaudio@linux.ibm.com>
On 29/06/2019 06:08, Claudio Carvalho wrote:
> When the ultravisor firmware is available, it takes control over the
> LDBAR register. In this case, thread-imc updates and save/restore
> operations on the LDBAR register are handled by ultravisor.
What does LDBAR do? "Power ISA™ Version 3.0 B" or "User’s Manual POWER9
Processor" do not tell.
>
> Signed-off-by: Claudio Carvalho <cclaudio@linux.ibm.com>
> Reviewed-by: Ram Pai <linuxram@us.ibm.com>
> Reviewed-by: Ryan Grimm <grimm@linux.ibm.com>
> Acked-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
> Acked-by: Paul Mackerras <paulus@ozlabs.org>
> ---
> arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 ++
> arch/powerpc/platforms/powernv/idle.c | 6 ++++--
> arch/powerpc/platforms/powernv/opal-imc.c | 4 ++++
> 3 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> index f9b2620fbecd..cffb365d9d02 100644
> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> @@ -375,8 +375,10 @@ BEGIN_FTR_SECTION
> mtspr SPRN_RPR, r0
> ld r0, KVM_SPLIT_PMMAR(r6)
> mtspr SPRN_PMMAR, r0
> +BEGIN_FW_FTR_SECTION_NESTED(70)
> ld r0, KVM_SPLIT_LDBAR(r6)
> mtspr SPRN_LDBAR, r0
> +END_FW_FTR_SECTION_NESTED(FW_FEATURE_ULTRAVISOR, 0, 70)
> isync
> FTR_SECTION_ELSE
> /* On P9 we use the split_info for coordinating LPCR changes */
> diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
> index 77f2e0a4ee37..5593a2d55959 100644
> --- a/arch/powerpc/platforms/powernv/idle.c
> +++ b/arch/powerpc/platforms/powernv/idle.c
> @@ -679,7 +679,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
> sprs.ptcr = mfspr(SPRN_PTCR);
> sprs.rpr = mfspr(SPRN_RPR);
> sprs.tscr = mfspr(SPRN_TSCR);
> - sprs.ldbar = mfspr(SPRN_LDBAR);
> + if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
> + sprs.ldbar = mfspr(SPRN_LDBAR);
>
> sprs_saved = true;
>
> @@ -762,7 +763,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
> mtspr(SPRN_PTCR, sprs.ptcr);
> mtspr(SPRN_RPR, sprs.rpr);
> mtspr(SPRN_TSCR, sprs.tscr);
> - mtspr(SPRN_LDBAR, sprs.ldbar);
> + if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
> + mtspr(SPRN_LDBAR, sprs.ldbar);
>
> if (pls >= pnv_first_tb_loss_level) {
> /* TB loss */
> diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c
> index 1b6932890a73..5fe2d4526cbc 100644
> --- a/arch/powerpc/platforms/powernv/opal-imc.c
> +++ b/arch/powerpc/platforms/powernv/opal-imc.c
> @@ -254,6 +254,10 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
> bool core_imc_reg = false, thread_imc_reg = false;
> u32 type;
>
> + /* Disable IMC devices, when Ultravisor is enabled. */
> + if (firmware_has_feature(FW_FEATURE_ULTRAVISOR))
> + return -EACCES;
> +
> /*
> * Check whether this is kdump kernel. If yes, force the engines to
> * stop and return.
>
--
Alexey
^ permalink raw reply
* Re: [PATCH v4 5/8] KVM: PPC: Ultravisor: Restrict flush of the partition tlb cache
From: Alexey Kardashevskiy @ 2019-07-01 5:54 UTC (permalink / raw)
To: Claudio Carvalho, linuxppc-dev
Cc: Madhavan Srinivasan, Michael Anderson, Ram Pai, kvm-ppc,
Bharata B Rao, Ryan Grimm, Sukadev Bhattiprolu, Thiago Bauermann,
Anshuman Khandual
In-Reply-To: <20190628200825.31049-6-cclaudio@linux.ibm.com>
On 29/06/2019 06:08, Claudio Carvalho wrote:
> From: Ram Pai <linuxram@us.ibm.com>
>
> Ultravisor is responsible for flushing the tlb cache, since it manages
> the PATE entries. Hence skip tlb flush, if the ultravisor firmware is
> available.
>
> Signed-off-by: Ram Pai <linuxram@us.ibm.com>
> Signed-off-by: Claudio Carvalho <cclaudio@linux.ibm.com>
> ---
> arch/powerpc/mm/book3s64/pgtable.c | 33 +++++++++++++++++-------------
> 1 file changed, 19 insertions(+), 14 deletions(-)
>
> diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c
> index 224c5c7c2e3d..bc8eb2bf9810 100644
> --- a/arch/powerpc/mm/book3s64/pgtable.c
> +++ b/arch/powerpc/mm/book3s64/pgtable.c
> @@ -224,6 +224,23 @@ void __init mmu_partition_table_init(void)
> powernv_set_nmmu_ptcr(ptcr);
> }
>
> +static void flush_partition(unsigned int lpid, unsigned long dw0)
> +{
> + if (dw0 & PATB_HR) {
> + asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 1) : :
> + "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
> + asm volatile(PPC_TLBIE_5(%0, %1, 2, 1, 1) : :
> + "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
> + trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
> + } else {
> + asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 0) : :
> + "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
> + trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
> + }
> + /* do we need fixup here ?*/
> + asm volatile("eieio; tlbsync; ptesync" : : : "memory");
> +}
> +
> static void __mmu_partition_table_set_entry(unsigned int lpid,
> unsigned long dw0,
> unsigned long dw1)
> @@ -238,20 +255,8 @@ static void __mmu_partition_table_set_entry(unsigned int lpid,
> * The type of flush (hash or radix) depends on what the previous
> * use of this partition ID was, not the new use.
> */
> - asm volatile("ptesync" : : : "memory");
> - if (old & PATB_HR) {
> - asm volatile(PPC_TLBIE_5(%0,%1,2,0,1) : :
> - "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
> - asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
> - "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
> - trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
> - } else {
> - asm volatile(PPC_TLBIE_5(%0,%1,2,0,0) : :
> - "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
> - trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
> - }
> - /* do we need fixup here ?*/
> - asm volatile("eieio; tlbsync; ptesync" : : : "memory");
> + if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
__mmu_partition_table_set_entry() checks for UV and
mmu_partition_table_set_entry() (the caller) checks for UV and the whole
point of having separate flush_partition() and
__mmu_partition_table_set_entry() is not really clear.
4/8 and 5/8 make more sense as one patch imho.
> + flush_partition(lpid, old);
> }
>
> void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
>
--
Alexey
^ permalink raw reply
* Re: [PATCH v4 6/8] KVM: PPC: Ultravisor: Restrict LDBAR access
From: maddy @ 2019-07-01 6:17 UTC (permalink / raw)
To: Alexey Kardashevskiy, Claudio Carvalho, linuxppc-dev
Cc: Michael Anderson, Ram Pai, kvm-ppc, Bharata B Rao, Ryan Grimm,
Sukadev Bhattiprolu, Thiago Bauermann, Anshuman Khandual
In-Reply-To: <f153b6bf-4661-9dc0-c28f-076fc8fe598e@ozlabs.ru>
On 01/07/19 11:24 AM, Alexey Kardashevskiy wrote:
>
> On 29/06/2019 06:08, Claudio Carvalho wrote:
>> When the ultravisor firmware is available, it takes control over the
>> LDBAR register. In this case, thread-imc updates and save/restore
>> operations on the LDBAR register are handled by ultravisor.
> What does LDBAR do? "Power ISA™ Version 3.0 B" or "User’s Manual POWER9
> Processor" do not tell.
LDBAR is a per-thread SPR used by thread-imc pmu to dump the counter
data into memory.
LDBAR contains memory address along with few other configuration bits
(it is populated
by the thread-imc pmu driver). It is populated and enabled only when any
of the thread
imc pmu events are monitored.
Maddy
>
>
>> Signed-off-by: Claudio Carvalho <cclaudio@linux.ibm.com>
>> Reviewed-by: Ram Pai <linuxram@us.ibm.com>
>> Reviewed-by: Ryan Grimm <grimm@linux.ibm.com>
>> Acked-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
>> Acked-by: Paul Mackerras <paulus@ozlabs.org>
>> ---
>> arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 ++
>> arch/powerpc/platforms/powernv/idle.c | 6 ++++--
>> arch/powerpc/platforms/powernv/opal-imc.c | 4 ++++
>> 3 files changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> index f9b2620fbecd..cffb365d9d02 100644
>> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> @@ -375,8 +375,10 @@ BEGIN_FTR_SECTION
>> mtspr SPRN_RPR, r0
>> ld r0, KVM_SPLIT_PMMAR(r6)
>> mtspr SPRN_PMMAR, r0
>> +BEGIN_FW_FTR_SECTION_NESTED(70)
>> ld r0, KVM_SPLIT_LDBAR(r6)
>> mtspr SPRN_LDBAR, r0
>> +END_FW_FTR_SECTION_NESTED(FW_FEATURE_ULTRAVISOR, 0, 70)
>> isync
>> FTR_SECTION_ELSE
>> /* On P9 we use the split_info for coordinating LPCR changes */
>> diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
>> index 77f2e0a4ee37..5593a2d55959 100644
>> --- a/arch/powerpc/platforms/powernv/idle.c
>> +++ b/arch/powerpc/platforms/powernv/idle.c
>> @@ -679,7 +679,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
>> sprs.ptcr = mfspr(SPRN_PTCR);
>> sprs.rpr = mfspr(SPRN_RPR);
>> sprs.tscr = mfspr(SPRN_TSCR);
>> - sprs.ldbar = mfspr(SPRN_LDBAR);
>> + if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>> + sprs.ldbar = mfspr(SPRN_LDBAR);
>>
>> sprs_saved = true;
>>
>> @@ -762,7 +763,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
>> mtspr(SPRN_PTCR, sprs.ptcr);
>> mtspr(SPRN_RPR, sprs.rpr);
>> mtspr(SPRN_TSCR, sprs.tscr);
>> - mtspr(SPRN_LDBAR, sprs.ldbar);
>> + if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>> + mtspr(SPRN_LDBAR, sprs.ldbar);
>>
>> if (pls >= pnv_first_tb_loss_level) {
>> /* TB loss */
>> diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c
>> index 1b6932890a73..5fe2d4526cbc 100644
>> --- a/arch/powerpc/platforms/powernv/opal-imc.c
>> +++ b/arch/powerpc/platforms/powernv/opal-imc.c
>> @@ -254,6 +254,10 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
>> bool core_imc_reg = false, thread_imc_reg = false;
>> u32 type;
>>
>> + /* Disable IMC devices, when Ultravisor is enabled. */
>> + if (firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>> + return -EACCES;
>> +
>> /*
>> * Check whether this is kdump kernel. If yes, force the engines to
>> * stop and return.
>>
^ permalink raw reply
* Re: [PATCH v4 6/8] KVM: PPC: Ultravisor: Restrict LDBAR access
From: Alexey Kardashevskiy @ 2019-07-01 6:30 UTC (permalink / raw)
To: maddy, Claudio Carvalho, linuxppc-dev
Cc: Michael Anderson, Ram Pai, kvm-ppc, Bharata B Rao, Ryan Grimm,
Sukadev Bhattiprolu, Thiago Bauermann, Anshuman Khandual
In-Reply-To: <1e7f702a-c0cd-393d-934e-9e1a1234fe28@linux.vnet.ibm.com>
On 01/07/2019 16:17, maddy wrote:
>
> On 01/07/19 11:24 AM, Alexey Kardashevskiy wrote:
>>
>> On 29/06/2019 06:08, Claudio Carvalho wrote:
>>> When the ultravisor firmware is available, it takes control over the
>>> LDBAR register. In this case, thread-imc updates and save/restore
>>> operations on the LDBAR register are handled by ultravisor.
>> What does LDBAR do? "Power ISA™ Version 3.0 B" or "User’s Manual POWER9
>> Processor" do not tell.
> LDBAR is a per-thread SPR used by thread-imc pmu to dump the counter
> data into memory.
> LDBAR contains memory address along with few other configuration bits
> (it is populated
> by the thread-imc pmu driver). It is populated and enabled only when any
> of the thread
> imc pmu events are monitored.
I was actually looking for a spec for this register, what is the
document name?
>
> Maddy
>>
>>
>>> Signed-off-by: Claudio Carvalho <cclaudio@linux.ibm.com>
>>> Reviewed-by: Ram Pai <linuxram@us.ibm.com>
>>> Reviewed-by: Ryan Grimm <grimm@linux.ibm.com>
>>> Acked-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
>>> Acked-by: Paul Mackerras <paulus@ozlabs.org>
>>> ---
>>> arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 ++
>>> arch/powerpc/platforms/powernv/idle.c | 6 ++++--
>>> arch/powerpc/platforms/powernv/opal-imc.c | 4 ++++
>>> 3 files changed, 10 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>>> b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>>> index f9b2620fbecd..cffb365d9d02 100644
>>> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>>> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>>> @@ -375,8 +375,10 @@ BEGIN_FTR_SECTION
>>> mtspr SPRN_RPR, r0
>>> ld r0, KVM_SPLIT_PMMAR(r6)
>>> mtspr SPRN_PMMAR, r0
>>> +BEGIN_FW_FTR_SECTION_NESTED(70)
>>> ld r0, KVM_SPLIT_LDBAR(r6)
>>> mtspr SPRN_LDBAR, r0
>>> +END_FW_FTR_SECTION_NESTED(FW_FEATURE_ULTRAVISOR, 0, 70)
>>> isync
>>> FTR_SECTION_ELSE
>>> /* On P9 we use the split_info for coordinating LPCR changes */
>>> diff --git a/arch/powerpc/platforms/powernv/idle.c
>>> b/arch/powerpc/platforms/powernv/idle.c
>>> index 77f2e0a4ee37..5593a2d55959 100644
>>> --- a/arch/powerpc/platforms/powernv/idle.c
>>> +++ b/arch/powerpc/platforms/powernv/idle.c
>>> @@ -679,7 +679,8 @@ static unsigned long power9_idle_stop(unsigned
>>> long psscr, bool mmu_on)
>>> sprs.ptcr = mfspr(SPRN_PTCR);
>>> sprs.rpr = mfspr(SPRN_RPR);
>>> sprs.tscr = mfspr(SPRN_TSCR);
>>> - sprs.ldbar = mfspr(SPRN_LDBAR);
>>> + if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>>> + sprs.ldbar = mfspr(SPRN_LDBAR);
>>> sprs_saved = true;
>>> @@ -762,7 +763,8 @@ static unsigned long power9_idle_stop(unsigned
>>> long psscr, bool mmu_on)
>>> mtspr(SPRN_PTCR, sprs.ptcr);
>>> mtspr(SPRN_RPR, sprs.rpr);
>>> mtspr(SPRN_TSCR, sprs.tscr);
>>> - mtspr(SPRN_LDBAR, sprs.ldbar);
>>> + if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>>> + mtspr(SPRN_LDBAR, sprs.ldbar);
>>> if (pls >= pnv_first_tb_loss_level) {
>>> /* TB loss */
>>> diff --git a/arch/powerpc/platforms/powernv/opal-imc.c
>>> b/arch/powerpc/platforms/powernv/opal-imc.c
>>> index 1b6932890a73..5fe2d4526cbc 100644
>>> --- a/arch/powerpc/platforms/powernv/opal-imc.c
>>> +++ b/arch/powerpc/platforms/powernv/opal-imc.c
>>> @@ -254,6 +254,10 @@ static int opal_imc_counters_probe(struct
>>> platform_device *pdev)
>>> bool core_imc_reg = false, thread_imc_reg = false;
>>> u32 type;
>>> + /* Disable IMC devices, when Ultravisor is enabled. */
>>> + if (firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>>> + return -EACCES;
>>> +
>>> /*
>>> * Check whether this is kdump kernel. If yes, force the
>>> engines to
>>> * stop and return.
>>>
>
--
Alexey
^ permalink raw reply
* [PATCH v2 0/3] fix vmalloc_to_page for huge vmap mappings
From: Nicholas Piggin @ 2019-07-01 6:40 UTC (permalink / raw)
To: linux-mm @ kvack . org
Cc: Mark Rutland, Anshuman Khandual, Ard Biesheuvel, Nicholas Piggin,
Andrew Morton, linuxppc-dev @ lists . ozlabs . org,
linux-arm-kernel @ lists . infradead . org
This is a change broken out from the huge vmap vmalloc series as
requested. There is a little bit of dependency juggling across
trees, but patches are pretty trivial. Ideally if Andrew accepts
this patch and queues it up for next, then the arch patches would
be merged through those trees then patch 3 gets sent by Andrew.
I've tested this with other powerpc and vmalloc patches, with code
that explicitly tests vmalloc_to_page on vmalloced memory and
results look fine.
v2: change the order of testing pxx_large and pxx_bad, to avoid issues
with arm64
Thanks,
Nick
Nicholas Piggin (3):
arm64: mm: Add p?d_large() definitions
powerpc/64s: Add p?d_large definitions
mm/vmalloc: fix vmalloc_to_page for huge vmap mappings
arch/arm64/include/asm/pgtable.h | 2 ++
arch/powerpc/include/asm/book3s/64/pgtable.h | 24 ++++++++-----
include/asm-generic/4level-fixup.h | 1 +
include/asm-generic/5level-fixup.h | 1 +
mm/vmalloc.c | 37 +++++++++++++-------
5 files changed, 43 insertions(+), 22 deletions(-)
--
2.20.1
^ permalink raw reply
* [PATCH v2 1/3] arm64: mm: Add p?d_large() definitions
From: Nicholas Piggin @ 2019-07-01 6:40 UTC (permalink / raw)
To: linux-mm @ kvack . org
Cc: Mark Rutland, Anshuman Khandual, Catalin Marinas, Ard Biesheuvel,
Will Deacon, Nicholas Piggin, Steven Price, Andrew Morton,
linuxppc-dev @ lists . ozlabs . org,
linux-arm-kernel @ lists . infradead . org
In-Reply-To: <20190701064026.970-1-npiggin@gmail.com>
walk_page_range() is going to be allowed to walk page tables other than
those of user space. For this it needs to know when it has reached a
'leaf' entry in the page tables. This information will be provided by the
p?d_large() functions/macros.
For arm64, we already have p?d_sect() macros which we can reuse for
p?d_large().
pud_sect() is defined as a dummy function when CONFIG_PGTABLE_LEVELS < 3
or CONFIG_ARM64_64K_PAGES is defined. However when the kernel is
configured this way then architecturally it isn't allowed to have a
large page that this level, and any code using these page walking macros
is implicitly relying on the page size/number of levels being the same as
the kernel. So it is safe to reuse this for p?d_large() as it is an
architectural restriction.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm64/include/asm/pgtable.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index fca26759081a..0e973201bc16 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -417,6 +417,7 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
PMD_TYPE_TABLE)
#define pmd_sect(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == \
PMD_TYPE_SECT)
+#define pmd_large(pmd) pmd_sect(pmd)
#if defined(CONFIG_ARM64_64K_PAGES) || CONFIG_PGTABLE_LEVELS < 3
#define pud_sect(pud) (0)
@@ -499,6 +500,7 @@ static inline void pte_unmap(pte_t *pte) { }
#define pud_none(pud) (!pud_val(pud))
#define pud_bad(pud) (!(pud_val(pud) & PUD_TABLE_BIT))
#define pud_present(pud) pte_present(pud_pte(pud))
+#define pud_large(pud) pud_sect(pud)
#define pud_valid(pud) pte_valid(pud_pte(pud))
static inline void set_pud(pud_t *pudp, pud_t pud)
--
2.20.1
^ permalink raw reply related
* [PATCH v2 2/3] powerpc/64s: Add p?d_large definitions
From: Nicholas Piggin @ 2019-07-01 6:40 UTC (permalink / raw)
To: linux-mm @ kvack . org
Cc: Mark Rutland, Anshuman Khandual, Ard Biesheuvel, Nicholas Piggin,
Andrew Morton, linuxppc-dev @ lists . ozlabs . org,
linux-arm-kernel @ lists . infradead . org
In-Reply-To: <20190701064026.970-1-npiggin@gmail.com>
The subsequent patch to fix vmalloc_to_page with huge vmap requires
HUGE_VMAP archs to provide p?d_large definitions for the non-pgd page
table levels they support.
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/book3s/64/pgtable.h | 24 ++++++++++++--------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index ccf00a8b98c6..c19c8396a1bd 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -915,6 +915,11 @@ static inline int pud_present(pud_t pud)
return !!(pud_raw(pud) & cpu_to_be64(_PAGE_PRESENT));
}
+static inline int pud_large(pud_t pud)
+{
+ return !!(pud_raw(pud) & cpu_to_be64(_PAGE_PTE));
+}
+
extern struct page *pud_page(pud_t pud);
extern struct page *pmd_page(pmd_t pmd);
static inline pte_t pud_pte(pud_t pud)
@@ -958,6 +963,11 @@ static inline int pgd_present(pgd_t pgd)
return !!(pgd_raw(pgd) & cpu_to_be64(_PAGE_PRESENT));
}
+static inline int pgd_large(pgd_t pgd)
+{
+ return !!(pgd_raw(pgd) & cpu_to_be64(_PAGE_PTE));
+}
+
static inline pte_t pgd_pte(pgd_t pgd)
{
return __pte_raw(pgd_raw(pgd));
@@ -1083,6 +1093,11 @@ static inline pte_t *pmdp_ptep(pmd_t *pmd)
#define pmd_mk_savedwrite(pmd) pte_pmd(pte_mk_savedwrite(pmd_pte(pmd)))
#define pmd_clear_savedwrite(pmd) pte_pmd(pte_clear_savedwrite(pmd_pte(pmd)))
+static inline int pmd_large(pmd_t pmd)
+{
+ return !!(pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE));
+}
+
#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
#define pmd_soft_dirty(pmd) pte_soft_dirty(pmd_pte(pmd))
#define pmd_mksoft_dirty(pmd) pte_pmd(pte_mksoft_dirty(pmd_pte(pmd)))
@@ -1151,15 +1166,6 @@ pmd_hugepage_update(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp,
return hash__pmd_hugepage_update(mm, addr, pmdp, clr, set);
}
-/*
- * returns true for pmd migration entries, THP, devmap, hugetlb
- * But compile time dependent on THP config
- */
-static inline int pmd_large(pmd_t pmd)
-{
- return !!(pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE));
-}
-
static inline pmd_t pmd_mknotpresent(pmd_t pmd)
{
return __pmd(pmd_val(pmd) & ~_PAGE_PRESENT);
--
2.20.1
^ permalink raw reply related
* [PATCH v2 3/3] mm/vmalloc: fix vmalloc_to_page for huge vmap mappings
From: Nicholas Piggin @ 2019-07-01 6:40 UTC (permalink / raw)
To: linux-mm @ kvack . org
Cc: Mark Rutland, Anshuman Khandual, Ard Biesheuvel, Nicholas Piggin,
Andrew Morton, linuxppc-dev @ lists . ozlabs . org,
linux-arm-kernel @ lists . infradead . org
In-Reply-To: <20190701064026.970-1-npiggin@gmail.com>
vmalloc_to_page returns NULL for addresses mapped by larger pages[*].
Whether or not a vmap is huge depends on the architecture details,
alignments, boot options, etc., which the caller can not be expected
to know. Therefore HUGE_VMAP is a regression for vmalloc_to_page.
This change teaches vmalloc_to_page about larger pages, and returns
the struct page that corresponds to the offset within the large page.
This makes the API agnostic to mapping implementation details.
[*] As explained by commit 029c54b095995 ("mm/vmalloc.c: huge-vmap:
fail gracefully on unexpected huge vmap mappings")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
include/asm-generic/4level-fixup.h | 1 +
include/asm-generic/5level-fixup.h | 1 +
mm/vmalloc.c | 37 +++++++++++++++++++-----------
3 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/include/asm-generic/4level-fixup.h b/include/asm-generic/4level-fixup.h
index e3667c9a33a5..3cc65a4dd093 100644
--- a/include/asm-generic/4level-fixup.h
+++ b/include/asm-generic/4level-fixup.h
@@ -20,6 +20,7 @@
#define pud_none(pud) 0
#define pud_bad(pud) 0
#define pud_present(pud) 1
+#define pud_large(pud) 0
#define pud_ERROR(pud) do { } while (0)
#define pud_clear(pud) pgd_clear(pud)
#define pud_val(pud) pgd_val(pud)
diff --git a/include/asm-generic/5level-fixup.h b/include/asm-generic/5level-fixup.h
index bb6cb347018c..c4377db09a4f 100644
--- a/include/asm-generic/5level-fixup.h
+++ b/include/asm-generic/5level-fixup.h
@@ -22,6 +22,7 @@
#define p4d_none(p4d) 0
#define p4d_bad(p4d) 0
#define p4d_present(p4d) 1
+#define p4d_large(p4d) 0
#define p4d_ERROR(p4d) do { } while (0)
#define p4d_clear(p4d) pgd_clear(p4d)
#define p4d_val(p4d) pgd_val(p4d)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 0f76cca32a1c..09a283866368 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -36,6 +36,7 @@
#include <linux/rbtree_augmented.h>
#include <linux/uaccess.h>
+#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/shmparam.h>
@@ -284,25 +285,35 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
if (pgd_none(*pgd))
return NULL;
+
p4d = p4d_offset(pgd, addr);
if (p4d_none(*p4d))
return NULL;
- pud = pud_offset(p4d, addr);
+#ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
+ if (p4d_large(*p4d))
+ return p4d_page(*p4d) + ((addr & ~P4D_MASK) >> PAGE_SHIFT);
+#endif
+ if (WARN_ON_ONCE(p4d_bad(*p4d)))
+ return NULL;
- /*
- * Don't dereference bad PUD or PMD (below) entries. This will also
- * identify huge mappings, which we may encounter on architectures
- * that define CONFIG_HAVE_ARCH_HUGE_VMAP=y. Such regions will be
- * identified as vmalloc addresses by is_vmalloc_addr(), but are
- * not [unambiguously] associated with a struct page, so there is
- * no correct value to return for them.
- */
- WARN_ON_ONCE(pud_bad(*pud));
- if (pud_none(*pud) || pud_bad(*pud))
+ pud = pud_offset(p4d, addr);
+ if (pud_none(*pud))
+ return NULL;
+#ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
+ if (pud_large(*pud))
+ return pud_page(*pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
+#endif
+ if (WARN_ON_ONCE(pud_bad(*pud)))
return NULL;
+
pmd = pmd_offset(pud, addr);
- WARN_ON_ONCE(pmd_bad(*pmd));
- if (pmd_none(*pmd) || pmd_bad(*pmd))
+ if (pmd_none(*pmd))
+ return NULL;
+#ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
+ if (pmd_large(*pmd))
+ return pmd_page(*pmd) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
+#endif
+ if (WARN_ON_ONCE(pmd_bad(*pmd)))
return NULL;
ptep = pte_offset_map(pmd, addr);
--
2.20.1
^ permalink raw reply related
* Re: Re: [PATCH v4 6/8] KVM: PPC: Ultravisor: Restrict LDBAR access
From: Ram Pai @ 2019-07-01 6:46 UTC (permalink / raw)
To: Alexey Kardashevskiy
Cc: maddy, Michael Anderson, Claudio Carvalho, kvm-ppc, Bharata B Rao,
linuxppc-dev, Ryan Grimm, Sukadev Bhattiprolu, Thiago Bauermann,
Anshuman Khandual
In-Reply-To: <abe23edf-e593-ca98-8047-39ecb6cf16b5@ozlabs.ru>
On Mon, Jul 01, 2019 at 04:30:55PM +1000, Alexey Kardashevskiy wrote:
>
>
> On 01/07/2019 16:17, maddy wrote:
> >
> > On 01/07/19 11:24 AM, Alexey Kardashevskiy wrote:
> >>
> >> On 29/06/2019 06:08, Claudio Carvalho wrote:
> >>> When the ultravisor firmware is available, it takes control over the
> >>> LDBAR register. In this case, thread-imc updates and save/restore
> >>> operations on the LDBAR register are handled by ultravisor.
> >> What does LDBAR do? "Power ISA™ Version 3.0 B" or "User’s Manual POWER9
> >> Processor" do not tell.
> > LDBAR is a per-thread SPR used by thread-imc pmu to dump the counter
> > data into memory.
> > LDBAR contains memory address along with few other configuration bits
> > (it is populated
> > by the thread-imc pmu driver). It is populated and enabled only when any
> > of the thread
> > imc pmu events are monitored.
>
>
> I was actually looking for a spec for this register, what is the
> document name?
Its not a architected register. Its documented in the Power9
workbook.
RP
^ permalink raw reply
* Re: [PATCH v3 01/11] mm/memory_hotplug: Simplify and fix check_hotplug_memory_range()
From: Michal Hocko @ 2019-07-01 7:42 UTC (permalink / raw)
To: David Hildenbrand
Cc: linux-s390, linux-ia64, Pavel Tatashin, linux-sh,
Mathieu Malaterre, linux-kernel, Wei Yang, linux-mm, Arun KS,
Qian Cai, Wei Yang, Igor Mammedov, akpm, linuxppc-dev,
Dan Williams, linux-arm-kernel, Oscar Salvador
In-Reply-To: <20190527111152.16324-2-david@redhat.com>
[Sorry for a really late response]
On Mon 27-05-19 13:11:42, David Hildenbrand wrote:
> By converting start and size to page granularity, we actually ignore
> unaligned parts within a page instead of properly bailing out with an
> error.
I do not expect any code path would ever provide an unaligned address
and even if it did then rounding that to a pfn doesn't sound like a
terrible thing to do. Anyway this removes few lines so why not.
>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Oscar Salvador <osalvador@suse.de>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
> Cc: Qian Cai <cai@lca.pw>
> Cc: Wei Yang <richard.weiyang@gmail.com>
> Cc: Arun KS <arunks@codeaurora.org>
> Cc: Mathieu Malaterre <malat@debian.org>
> Reviewed-by: Dan Williams <dan.j.williams@intel.com>
> Reviewed-by: Wei Yang <richardw.yang@linux.intel.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>
Acked-by: Michal Hocko <mhocko@suse.com>
> ---
> mm/memory_hotplug.c | 11 +++--------
> 1 file changed, 3 insertions(+), 8 deletions(-)
>
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index e096c987d261..762887b2358b 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -1051,16 +1051,11 @@ int try_online_node(int nid)
>
> static int check_hotplug_memory_range(u64 start, u64 size)
> {
> - unsigned long block_sz = memory_block_size_bytes();
> - u64 block_nr_pages = block_sz >> PAGE_SHIFT;
> - u64 nr_pages = size >> PAGE_SHIFT;
> - u64 start_pfn = PFN_DOWN(start);
> -
> /* memory range must be block size aligned */
> - if (!nr_pages || !IS_ALIGNED(start_pfn, block_nr_pages) ||
> - !IS_ALIGNED(nr_pages, block_nr_pages)) {
> + if (!size || !IS_ALIGNED(start, memory_block_size_bytes()) ||
> + !IS_ALIGNED(size, memory_block_size_bytes())) {
> pr_err("Block size [%#lx] unaligned hotplug range: start %#llx, size %#llx",
> - block_sz, start, size);
> + memory_block_size_bytes(), start, size);
> return -EINVAL;
> }
>
> --
> 2.20.1
>
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [PATCH v3 02/11] s390x/mm: Fail when an altmap is used for arch_add_memory()
From: Michal Hocko @ 2019-07-01 7:43 UTC (permalink / raw)
To: David Hildenbrand
Cc: Oscar Salvador, linux-s390, linux-ia64, Vasily Gorbik, linux-sh,
Heiko Carstens, linux-kernel, Wei Yang, linux-mm, Mike Rapoport,
Martin Schwidefsky, Igor Mammedov, akpm, linuxppc-dev,
Dan Williams, linux-arm-kernel
In-Reply-To: <20190527111152.16324-3-david@redhat.com>
On Mon 27-05-19 13:11:43, David Hildenbrand wrote:
> ZONE_DEVICE is not yet supported, fail if an altmap is passed, so we
> don't forget arch_add_memory()/arch_remove_memory() when unlocking
> support.
Why do we need this? Sure ZONE_DEVICE is not supported for s390 and so
might be the case for other arches which support hotplug. I do not see
much point in adding warning to each of them.
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Vasily Gorbik <gor@linux.ibm.com>
> Cc: Oscar Salvador <osalvador@suse.com>
> Suggested-by: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
> arch/s390/mm/init.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
> index 14d1eae9fe43..d552e330fbcc 100644
> --- a/arch/s390/mm/init.c
> +++ b/arch/s390/mm/init.c
> @@ -226,6 +226,9 @@ int arch_add_memory(int nid, u64 start, u64 size,
> unsigned long size_pages = PFN_DOWN(size);
> int rc;
>
> + if (WARN_ON_ONCE(restrictions->altmap))
> + return -EINVAL;
> +
> rc = vmem_add_mapping(start, size);
> if (rc)
> return rc;
> --
> 2.20.1
>
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [PATCH v3 03/11] s390x/mm: Implement arch_remove_memory()
From: Michal Hocko @ 2019-07-01 7:45 UTC (permalink / raw)
To: David Hildenbrand
Cc: Oscar Salvador, linux-s390, linux-ia64, Vasily Gorbik, linux-sh,
Heiko Carstens, linux-kernel, Wei Yang, linux-mm, Mike Rapoport,
Martin Schwidefsky, Igor Mammedov, akpm, linuxppc-dev,
Dan Williams, linux-arm-kernel
In-Reply-To: <20190527111152.16324-4-david@redhat.com>
On Mon 27-05-19 13:11:44, David Hildenbrand wrote:
> Will come in handy when wanting to handle errors after
> arch_add_memory().
I do not understand this. Why do you add a code for something that is
not possible on this HW (based on the comment - is it still valid btw?)
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Vasily Gorbik <gor@linux.ibm.com>
> Cc: Oscar Salvador <osalvador@suse.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
> arch/s390/mm/init.c | 13 +++++++------
> 1 file changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
> index d552e330fbcc..14955e0a9fcf 100644
> --- a/arch/s390/mm/init.c
> +++ b/arch/s390/mm/init.c
> @@ -243,12 +243,13 @@ int arch_add_memory(int nid, u64 start, u64 size,
> void arch_remove_memory(int nid, u64 start, u64 size,
> struct vmem_altmap *altmap)
> {
> - /*
> - * There is no hardware or firmware interface which could trigger a
> - * hot memory remove on s390. So there is nothing that needs to be
> - * implemented.
> - */
> - BUG();
> + unsigned long start_pfn = start >> PAGE_SHIFT;
> + unsigned long nr_pages = size >> PAGE_SHIFT;
> + struct zone *zone;
> +
> + zone = page_zone(pfn_to_page(start_pfn));
> + __remove_pages(zone, start_pfn, nr_pages, altmap);
> + vmem_remove_mapping(start, size);
> }
> #endif
> #endif /* CONFIG_MEMORY_HOTPLUG */
> --
> 2.20.1
>
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [PATCH v3 05/11] drivers/base/memory: Pass a block_id to init_memory_block()
From: Michal Hocko @ 2019-07-01 7:56 UTC (permalink / raw)
To: David Hildenbrand
Cc: linux-s390, linux-ia64, linux-sh, Greg Kroah-Hartman,
Rafael J. Wysocki, linux-kernel, Wei Yang, linux-mm,
Igor Mammedov, akpm, linuxppc-dev, Dan Williams, linux-arm-kernel
In-Reply-To: <20190527111152.16324-6-david@redhat.com>
On Mon 27-05-19 13:11:46, David Hildenbrand wrote:
> We'll rework hotplug_memory_register() shortly, so it no longer consumes
> pass a section.
>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: David Hildenbrand <david@redhat.com>
Acked-by: Michal Hocko <mhocko@suse.com>
> ---
> drivers/base/memory.c | 15 +++++++--------
> 1 file changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/base/memory.c b/drivers/base/memory.c
> index f180427e48f4..f914fa6fe350 100644
> --- a/drivers/base/memory.c
> +++ b/drivers/base/memory.c
> @@ -651,21 +651,18 @@ int register_memory(struct memory_block *memory)
> return ret;
> }
>
> -static int init_memory_block(struct memory_block **memory,
> - struct mem_section *section, unsigned long state)
> +static int init_memory_block(struct memory_block **memory, int block_id,
> + unsigned long state)
> {
> struct memory_block *mem;
> unsigned long start_pfn;
> - int scn_nr;
> int ret = 0;
>
> mem = kzalloc(sizeof(*mem), GFP_KERNEL);
> if (!mem)
> return -ENOMEM;
>
> - scn_nr = __section_nr(section);
> - mem->start_section_nr =
> - base_memory_block_id(scn_nr) * sections_per_block;
> + mem->start_section_nr = block_id * sections_per_block;
> mem->end_section_nr = mem->start_section_nr + sections_per_block - 1;
> mem->state = state;
> start_pfn = section_nr_to_pfn(mem->start_section_nr);
> @@ -694,7 +691,8 @@ static int add_memory_block(int base_section_nr)
>
> if (section_count == 0)
> return 0;
> - ret = init_memory_block(&mem, __nr_to_section(section_nr), MEM_ONLINE);
> + ret = init_memory_block(&mem, base_memory_block_id(base_section_nr),
> + MEM_ONLINE);
> if (ret)
> return ret;
> mem->section_count = section_count;
> @@ -707,6 +705,7 @@ static int add_memory_block(int base_section_nr)
> */
> int hotplug_memory_register(int nid, struct mem_section *section)
> {
> + int block_id = base_memory_block_id(__section_nr(section));
> int ret = 0;
> struct memory_block *mem;
>
> @@ -717,7 +716,7 @@ int hotplug_memory_register(int nid, struct mem_section *section)
> mem->section_count++;
> put_device(&mem->dev);
> } else {
> - ret = init_memory_block(&mem, section, MEM_OFFLINE);
> + ret = init_memory_block(&mem, block_id, MEM_OFFLINE);
> if (ret)
> goto out;
> mem->section_count++;
> --
> 2.20.1
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [PATCH v3 06/11] mm/memory_hotplug: Allow arch_remove_pages() without CONFIG_MEMORY_HOTREMOVE
From: Michal Hocko @ 2019-07-01 8:01 UTC (permalink / raw)
To: David Hildenbrand
Cc: Oscar Salvador, Rich Felker, linux-ia64, Anshuman Khandual,
linux-sh, Peter Zijlstra, Dave Hansen, Heiko Carstens, Wei Yang,
linux-mm, Arun KS, Paul Mackerras, H. Peter Anvin,
Thomas Gleixner, Qian Cai, linux-s390, Yoshinori Sato,
Rafael J. Wysocki, Mike Rapoport, Ingo Molnar, Fenghua Yu,
Pavel Tatashin, Vasily Gorbik, Rob Herring, mike.travis@hpe.com,
Nicholas Piggin, Alex Deucher, Mark Brown, Borislav Petkov,
Andy Lutomirski, Dan Williams, Chris Wilson, linux-arm-kernel,
Tony Luck, Baoquan He, Masahiro Yamada, Mathieu Malaterre,
Greg Kroah-Hartman, Andrew Banman, linux-kernel, Logan Gunthorpe,
Wei Yang, Martin Schwidefsky, Igor Mammedov, akpm, linuxppc-dev,
David S. Miller, Kirill A. Shutemov
In-Reply-To: <20190527111152.16324-7-david@redhat.com>
On Mon 27-05-19 13:11:47, David Hildenbrand wrote:
> We want to improve error handling while adding memory by allowing
> to use arch_remove_memory() and __remove_pages() even if
> CONFIG_MEMORY_HOTREMOVE is not set to e.g., implement something like:
>
> arch_add_memory()
> rc = do_something();
> if (rc) {
> arch_remove_memory();
> }
>
> We won't get rid of CONFIG_MEMORY_HOTREMOVE for now, as it will require
> quite some dependencies for memory offlining.
If we cannot really remove CONFIG_MEMORY_HOTREMOVE altogether then why
not simply add an empty placeholder for arch_remove_memory when the
config is disabled?
> Cc: Tony Luck <tony.luck@intel.com>
> Cc: Fenghua Yu <fenghua.yu@intel.com>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Cc: Rich Felker <dalias@libc.org>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Mike Rapoport <rppt@linux.ibm.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Oscar Salvador <osalvador@suse.com>
> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Christophe Leroy <christophe.leroy@c-s.fr>
> Cc: Nicholas Piggin <npiggin@gmail.com>
> Cc: Vasily Gorbik <gor@linux.ibm.com>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
> Cc: "mike.travis@hpe.com" <mike.travis@hpe.com>
> Cc: Andrew Banman <andrew.banman@hpe.com>
> Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
> Cc: Wei Yang <richardw.yang@linux.intel.com>
> Cc: Arun KS <arunks@codeaurora.org>
> Cc: Qian Cai <cai@lca.pw>
> Cc: Mathieu Malaterre <malat@debian.org>
> Cc: Baoquan He <bhe@redhat.com>
> Cc: Logan Gunthorpe <logang@deltatee.com>
> Cc: Anshuman Khandual <anshuman.khandual@arm.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
> arch/arm64/mm/mmu.c | 2 --
> arch/ia64/mm/init.c | 2 --
> arch/powerpc/mm/mem.c | 2 --
> arch/s390/mm/init.c | 2 --
> arch/sh/mm/init.c | 2 --
> arch/x86/mm/init_32.c | 2 --
> arch/x86/mm/init_64.c | 2 --
> drivers/base/memory.c | 2 --
> include/linux/memory.h | 2 --
> include/linux/memory_hotplug.h | 2 --
> mm/memory_hotplug.c | 2 --
> mm/sparse.c | 6 ------
> 12 files changed, 28 deletions(-)
>
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index e569a543c384..9ccd7539f2d4 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -1084,7 +1084,6 @@ int arch_add_memory(int nid, u64 start, u64 size,
> return __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT,
> restrictions);
> }
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> void arch_remove_memory(int nid, u64 start, u64 size,
> struct vmem_altmap *altmap)
> {
> @@ -1103,4 +1102,3 @@ void arch_remove_memory(int nid, u64 start, u64 size,
> __remove_pages(zone, start_pfn, nr_pages, altmap);
> }
> #endif
> -#endif
> diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
> index d28e29103bdb..aae75fd7b810 100644
> --- a/arch/ia64/mm/init.c
> +++ b/arch/ia64/mm/init.c
> @@ -681,7 +681,6 @@ int arch_add_memory(int nid, u64 start, u64 size,
> return ret;
> }
>
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> void arch_remove_memory(int nid, u64 start, u64 size,
> struct vmem_altmap *altmap)
> {
> @@ -693,4 +692,3 @@ void arch_remove_memory(int nid, u64 start, u64 size,
> __remove_pages(zone, start_pfn, nr_pages, altmap);
> }
> #endif
> -#endif
> diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
> index e885fe2aafcc..e4bc2dc3f593 100644
> --- a/arch/powerpc/mm/mem.c
> +++ b/arch/powerpc/mm/mem.c
> @@ -130,7 +130,6 @@ int __ref arch_add_memory(int nid, u64 start, u64 size,
> return __add_pages(nid, start_pfn, nr_pages, restrictions);
> }
>
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> void __ref arch_remove_memory(int nid, u64 start, u64 size,
> struct vmem_altmap *altmap)
> {
> @@ -164,7 +163,6 @@ void __ref arch_remove_memory(int nid, u64 start, u64 size,
> pr_warn("Hash collision while resizing HPT\n");
> }
> #endif
> -#endif /* CONFIG_MEMORY_HOTPLUG */
>
> #ifndef CONFIG_NEED_MULTIPLE_NODES
> void __init mem_topology_setup(void)
> diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
> index 14955e0a9fcf..ffb81fe95c77 100644
> --- a/arch/s390/mm/init.c
> +++ b/arch/s390/mm/init.c
> @@ -239,7 +239,6 @@ int arch_add_memory(int nid, u64 start, u64 size,
> return rc;
> }
>
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> void arch_remove_memory(int nid, u64 start, u64 size,
> struct vmem_altmap *altmap)
> {
> @@ -251,5 +250,4 @@ void arch_remove_memory(int nid, u64 start, u64 size,
> __remove_pages(zone, start_pfn, nr_pages, altmap);
> vmem_remove_mapping(start, size);
> }
> -#endif
> #endif /* CONFIG_MEMORY_HOTPLUG */
> diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
> index 13c6a6bb5fd9..dfdbaa50946e 100644
> --- a/arch/sh/mm/init.c
> +++ b/arch/sh/mm/init.c
> @@ -429,7 +429,6 @@ int memory_add_physaddr_to_nid(u64 addr)
> EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
> #endif
>
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> void arch_remove_memory(int nid, u64 start, u64 size,
> struct vmem_altmap *altmap)
> {
> @@ -440,5 +439,4 @@ void arch_remove_memory(int nid, u64 start, u64 size,
> zone = page_zone(pfn_to_page(start_pfn));
> __remove_pages(zone, start_pfn, nr_pages, altmap);
> }
> -#endif
> #endif /* CONFIG_MEMORY_HOTPLUG */
> diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
> index f265a4316179..4068abb9427f 100644
> --- a/arch/x86/mm/init_32.c
> +++ b/arch/x86/mm/init_32.c
> @@ -860,7 +860,6 @@ int arch_add_memory(int nid, u64 start, u64 size,
> return __add_pages(nid, start_pfn, nr_pages, restrictions);
> }
>
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> void arch_remove_memory(int nid, u64 start, u64 size,
> struct vmem_altmap *altmap)
> {
> @@ -872,7 +871,6 @@ void arch_remove_memory(int nid, u64 start, u64 size,
> __remove_pages(zone, start_pfn, nr_pages, altmap);
> }
> #endif
> -#endif
>
> int kernel_set_to_readonly __read_mostly;
>
> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
> index 693aaf28d5fe..8335ac6e1112 100644
> --- a/arch/x86/mm/init_64.c
> +++ b/arch/x86/mm/init_64.c
> @@ -1196,7 +1196,6 @@ void __ref vmemmap_free(unsigned long start, unsigned long end,
> remove_pagetable(start, end, false, altmap);
> }
>
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> static void __meminit
> kernel_physical_mapping_remove(unsigned long start, unsigned long end)
> {
> @@ -1221,7 +1220,6 @@ void __ref arch_remove_memory(int nid, u64 start, u64 size,
> __remove_pages(zone, start_pfn, nr_pages, altmap);
> kernel_physical_mapping_remove(start, start + size);
> }
> -#endif
> #endif /* CONFIG_MEMORY_HOTPLUG */
>
> static struct kcore_list kcore_vsyscall;
> diff --git a/drivers/base/memory.c b/drivers/base/memory.c
> index f914fa6fe350..ac17c95a5f28 100644
> --- a/drivers/base/memory.c
> +++ b/drivers/base/memory.c
> @@ -727,7 +727,6 @@ int hotplug_memory_register(int nid, struct mem_section *section)
> return ret;
> }
>
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> static void
> unregister_memory(struct memory_block *memory)
> {
> @@ -766,7 +765,6 @@ void unregister_memory_section(struct mem_section *section)
> out_unlock:
> mutex_unlock(&mem_sysfs_mutex);
> }
> -#endif /* CONFIG_MEMORY_HOTREMOVE */
>
> /* return true if the memory block is offlined, otherwise, return false */
> bool is_memblock_offlined(struct memory_block *mem)
> diff --git a/include/linux/memory.h b/include/linux/memory.h
> index e1dc1bb2b787..474c7c60c8f2 100644
> --- a/include/linux/memory.h
> +++ b/include/linux/memory.h
> @@ -112,9 +112,7 @@ extern void unregister_memory_notifier(struct notifier_block *nb);
> extern int register_memory_isolate_notifier(struct notifier_block *nb);
> extern void unregister_memory_isolate_notifier(struct notifier_block *nb);
> int hotplug_memory_register(int nid, struct mem_section *section);
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> extern void unregister_memory_section(struct mem_section *);
> -#endif
> extern int memory_dev_init(void);
> extern int memory_notify(unsigned long val, void *v);
> extern int memory_isolate_notify(unsigned long val, void *v);
> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
> index ae892eef8b82..2d4de313926d 100644
> --- a/include/linux/memory_hotplug.h
> +++ b/include/linux/memory_hotplug.h
> @@ -123,12 +123,10 @@ static inline bool movable_node_is_enabled(void)
> return movable_node_enabled;
> }
>
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> extern void arch_remove_memory(int nid, u64 start, u64 size,
> struct vmem_altmap *altmap);
> extern void __remove_pages(struct zone *zone, unsigned long start_pfn,
> unsigned long nr_pages, struct vmem_altmap *altmap);
> -#endif /* CONFIG_MEMORY_HOTREMOVE */
>
> /*
> * Do we want sysfs memblock files created. This will allow userspace to online
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 762887b2358b..4b9d2974f86c 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -318,7 +318,6 @@ int __ref __add_pages(int nid, unsigned long phys_start_pfn,
> return err;
> }
>
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> /* find the smallest valid pfn in the range [start_pfn, end_pfn) */
> static unsigned long find_smallest_section_pfn(int nid, struct zone *zone,
> unsigned long start_pfn,
> @@ -582,7 +581,6 @@ void __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
>
> set_zone_contiguous(zone);
> }
> -#endif /* CONFIG_MEMORY_HOTREMOVE */
>
> int set_online_page_callback(online_page_callback_t callback)
> {
> diff --git a/mm/sparse.c b/mm/sparse.c
> index fd13166949b5..d1d5e05f5b8d 100644
> --- a/mm/sparse.c
> +++ b/mm/sparse.c
> @@ -604,7 +604,6 @@ static void __kfree_section_memmap(struct page *memmap,
>
> vmemmap_free(start, end, altmap);
> }
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> static void free_map_bootmem(struct page *memmap)
> {
> unsigned long start = (unsigned long)memmap;
> @@ -612,7 +611,6 @@ static void free_map_bootmem(struct page *memmap)
>
> vmemmap_free(start, end, NULL);
> }
> -#endif /* CONFIG_MEMORY_HOTREMOVE */
> #else
> static struct page *__kmalloc_section_memmap(void)
> {
> @@ -651,7 +649,6 @@ static void __kfree_section_memmap(struct page *memmap,
> get_order(sizeof(struct page) * PAGES_PER_SECTION));
> }
>
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> static void free_map_bootmem(struct page *memmap)
> {
> unsigned long maps_section_nr, removing_section_nr, i;
> @@ -681,7 +678,6 @@ static void free_map_bootmem(struct page *memmap)
> put_page_bootmem(page);
> }
> }
> -#endif /* CONFIG_MEMORY_HOTREMOVE */
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>
> /**
> @@ -746,7 +742,6 @@ int __meminit sparse_add_one_section(int nid, unsigned long start_pfn,
> return ret;
> }
>
> -#ifdef CONFIG_MEMORY_HOTREMOVE
> #ifdef CONFIG_MEMORY_FAILURE
> static void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
> {
> @@ -823,5 +818,4 @@ void sparse_remove_one_section(struct zone *zone, struct mem_section *ms,
> PAGES_PER_SECTION - map_offset);
> free_section_usemap(memmap, usemap, altmap);
> }
> -#endif /* CONFIG_MEMORY_HOTREMOVE */
> #endif /* CONFIG_MEMORY_HOTPLUG */
> --
> 2.20.1
>
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [PATCH v3 07/11] mm/memory_hotplug: Create memory block devices after arch_add_memory()
From: Michal Hocko @ 2019-07-01 8:14 UTC (permalink / raw)
To: David Hildenbrand
Cc: Ingo Molnar, linux-s390, linux-ia64, Pavel Tatashin, linux-sh,
mike.travis@hpe.com, Greg Kroah-Hartman, Rafael J. Wysocki,
Mathieu Malaterre, linux-kernel, Arun KS, Wei Yang, linux-mm,
Andrew Banman, Qian Cai, Igor Mammedov, akpm, linuxppc-dev,
Dan Williams, linux-arm-kernel, Oscar Salvador
In-Reply-To: <20190527111152.16324-8-david@redhat.com>
On Mon 27-05-19 13:11:48, David Hildenbrand wrote:
> Only memory to be added to the buddy and to be onlined/offlined by
> user space using /sys/devices/system/memory/... needs (and should have!)
> memory block devices.
>
> Factor out creation of memory block devices. Create all devices after
> arch_add_memory() succeeded. We can later drop the want_memblock parameter,
> because it is now effectively stale.
>
> Only after memory block devices have been added, memory can be onlined
> by user space. This implies, that memory is not visible to user space at
> all before arch_add_memory() succeeded.
I like the memblock API to go away from the low level hotplug handling.
The current implementation is just too convoluted and I remember I was
fighting with subtle expectations wired deep in call chains when
touching that code in the past (some memblocks didn't get created etc.).
Maybe those have been addressed in the meantime.
> While at it
> - use WARN_ON_ONCE instead of BUG_ON in moved unregister_memory()
This would better be a separate patch with an explanation
> - introduce find_memory_block_by_id() to search via block id
> - Use find_memory_block_by_id() in init_memory_block() to catch
> duplicates
>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: "mike.travis@hpe.com" <mike.travis@hpe.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Andrew Banman <andrew.banman@hpe.com>
> Cc: Oscar Salvador <osalvador@suse.de>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
> Cc: Qian Cai <cai@lca.pw>
> Cc: Wei Yang <richard.weiyang@gmail.com>
> Cc: Arun KS <arunks@codeaurora.org>
> Cc: Mathieu Malaterre <malat@debian.org>
> Signed-off-by: David Hildenbrand <david@redhat.com>
Other than that looks good to me.
Acked-by: Michal Hocko <mhocko@suse.com>
> ---
> drivers/base/memory.c | 82 +++++++++++++++++++++++++++---------------
> include/linux/memory.h | 2 +-
> mm/memory_hotplug.c | 15 ++++----
> 3 files changed, 63 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/base/memory.c b/drivers/base/memory.c
> index ac17c95a5f28..5a0370f0c506 100644
> --- a/drivers/base/memory.c
> +++ b/drivers/base/memory.c
> @@ -39,6 +39,11 @@ static inline int base_memory_block_id(int section_nr)
> return section_nr / sections_per_block;
> }
>
> +static inline int pfn_to_block_id(unsigned long pfn)
> +{
> + return base_memory_block_id(pfn_to_section_nr(pfn));
> +}
> +
> static int memory_subsys_online(struct device *dev);
> static int memory_subsys_offline(struct device *dev);
>
> @@ -582,10 +587,9 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn)
> * A reference for the returned object is held and the reference for the
> * hinted object is released.
> */
> -struct memory_block *find_memory_block_hinted(struct mem_section *section,
> - struct memory_block *hint)
> +static struct memory_block *find_memory_block_by_id(int block_id,
> + struct memory_block *hint)
> {
> - int block_id = base_memory_block_id(__section_nr(section));
> struct device *hintdev = hint ? &hint->dev : NULL;
> struct device *dev;
>
> @@ -597,6 +601,14 @@ struct memory_block *find_memory_block_hinted(struct mem_section *section,
> return to_memory_block(dev);
> }
>
> +struct memory_block *find_memory_block_hinted(struct mem_section *section,
> + struct memory_block *hint)
> +{
> + int block_id = base_memory_block_id(__section_nr(section));
> +
> + return find_memory_block_by_id(block_id, hint);
> +}
> +
> /*
> * For now, we have a linear search to go find the appropriate
> * memory_block corresponding to a particular phys_index. If
> @@ -658,6 +670,11 @@ static int init_memory_block(struct memory_block **memory, int block_id,
> unsigned long start_pfn;
> int ret = 0;
>
> + mem = find_memory_block_by_id(block_id, NULL);
> + if (mem) {
> + put_device(&mem->dev);
> + return -EEXIST;
> + }
> mem = kzalloc(sizeof(*mem), GFP_KERNEL);
> if (!mem)
> return -ENOMEM;
> @@ -699,44 +716,53 @@ static int add_memory_block(int base_section_nr)
> return 0;
> }
>
> +static void unregister_memory(struct memory_block *memory)
> +{
> + if (WARN_ON_ONCE(memory->dev.bus != &memory_subsys))
> + return;
> +
> + /* drop the ref. we got via find_memory_block() */
> + put_device(&memory->dev);
> + device_unregister(&memory->dev);
> +}
> +
> /*
> - * need an interface for the VM to add new memory regions,
> - * but without onlining it.
> + * Create memory block devices for the given memory area. Start and size
> + * have to be aligned to memory block granularity. Memory block devices
> + * will be initialized as offline.
> */
> -int hotplug_memory_register(int nid, struct mem_section *section)
> +int create_memory_block_devices(unsigned long start, unsigned long size)
> {
> - int block_id = base_memory_block_id(__section_nr(section));
> - int ret = 0;
> + const int start_block_id = pfn_to_block_id(PFN_DOWN(start));
> + int end_block_id = pfn_to_block_id(PFN_DOWN(start + size));
> struct memory_block *mem;
> + unsigned long block_id;
> + int ret = 0;
>
> - mutex_lock(&mem_sysfs_mutex);
> + if (WARN_ON_ONCE(!IS_ALIGNED(start, memory_block_size_bytes()) ||
> + !IS_ALIGNED(size, memory_block_size_bytes())))
> + return -EINVAL;
>
> - mem = find_memory_block(section);
> - if (mem) {
> - mem->section_count++;
> - put_device(&mem->dev);
> - } else {
> + mutex_lock(&mem_sysfs_mutex);
> + for (block_id = start_block_id; block_id != end_block_id; block_id++) {
> ret = init_memory_block(&mem, block_id, MEM_OFFLINE);
> if (ret)
> - goto out;
> - mem->section_count++;
> + break;
> + mem->section_count = sections_per_block;
> + }
> + if (ret) {
> + end_block_id = block_id;
> + for (block_id = start_block_id; block_id != end_block_id;
> + block_id++) {
> + mem = find_memory_block_by_id(block_id, NULL);
> + mem->section_count = 0;
> + unregister_memory(mem);
> + }
> }
> -
> -out:
> mutex_unlock(&mem_sysfs_mutex);
> return ret;
> }
>
> -static void
> -unregister_memory(struct memory_block *memory)
> -{
> - BUG_ON(memory->dev.bus != &memory_subsys);
> -
> - /* drop the ref. we got via find_memory_block() */
> - put_device(&memory->dev);
> - device_unregister(&memory->dev);
> -}
> -
> void unregister_memory_section(struct mem_section *section)
> {
> struct memory_block *mem;
> diff --git a/include/linux/memory.h b/include/linux/memory.h
> index 474c7c60c8f2..db3e8567f900 100644
> --- a/include/linux/memory.h
> +++ b/include/linux/memory.h
> @@ -111,7 +111,7 @@ extern int register_memory_notifier(struct notifier_block *nb);
> extern void unregister_memory_notifier(struct notifier_block *nb);
> extern int register_memory_isolate_notifier(struct notifier_block *nb);
> extern void unregister_memory_isolate_notifier(struct notifier_block *nb);
> -int hotplug_memory_register(int nid, struct mem_section *section);
> +int create_memory_block_devices(unsigned long start, unsigned long size);
> extern void unregister_memory_section(struct mem_section *);
> extern int memory_dev_init(void);
> extern int memory_notify(unsigned long val, void *v);
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 4b9d2974f86c..b1fde90bbf19 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -259,13 +259,7 @@ static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
> return -EEXIST;
>
> ret = sparse_add_one_section(nid, phys_start_pfn, altmap);
> - if (ret < 0)
> - return ret;
> -
> - if (!want_memblock)
> - return 0;
> -
> - return hotplug_memory_register(nid, __pfn_to_section(phys_start_pfn));
> + return ret < 0 ? ret : 0;
> }
>
> /*
> @@ -1107,6 +1101,13 @@ int __ref add_memory_resource(int nid, struct resource *res)
> if (ret < 0)
> goto error;
>
> + /* create memory block devices after memory was added */
> + ret = create_memory_block_devices(start, size);
> + if (ret) {
> + arch_remove_memory(nid, start, size, NULL);
> + goto error;
> + }
> +
> if (new_node) {
> /* If sysfs file of new node can't be created, cpu on the node
> * can't be hot-added. There is no rollback way now.
> --
> 2.20.1
>
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [PATCH v3 08/11] mm/memory_hotplug: Drop MHP_MEMBLOCK_API
From: Michal Hocko @ 2019-07-01 8:15 UTC (permalink / raw)
To: David Hildenbrand
Cc: Oscar Salvador, linux-s390, linux-ia64, Pavel Tatashin, linux-sh,
Mathieu Malaterre, Joonsoo Kim, linux-kernel, Wei Yang, linux-mm,
Arun KS, Qian Cai, Igor Mammedov, akpm, linuxppc-dev,
Dan Williams, linux-arm-kernel
In-Reply-To: <20190527111152.16324-9-david@redhat.com>
On Mon 27-05-19 13:11:49, David Hildenbrand wrote:
> No longer needed, the callers of arch_add_memory() can handle this
> manually.
>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Oscar Salvador <osalvador@suse.com>
> Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
> Cc: Wei Yang <richard.weiyang@gmail.com>
> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
> Cc: Qian Cai <cai@lca.pw>
> Cc: Arun KS <arunks@codeaurora.org>
> Cc: Mathieu Malaterre <malat@debian.org>
> Signed-off-by: David Hildenbrand <david@redhat.com>
Acked-by: Michal Hocko <mhocko@suse.com>
> ---
> include/linux/memory_hotplug.h | 8 --------
> mm/memory_hotplug.c | 9 +++------
> 2 files changed, 3 insertions(+), 14 deletions(-)
>
> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
> index 2d4de313926d..2f1f87e13baa 100644
> --- a/include/linux/memory_hotplug.h
> +++ b/include/linux/memory_hotplug.h
> @@ -128,14 +128,6 @@ extern void arch_remove_memory(int nid, u64 start, u64 size,
> extern void __remove_pages(struct zone *zone, unsigned long start_pfn,
> unsigned long nr_pages, struct vmem_altmap *altmap);
>
> -/*
> - * Do we want sysfs memblock files created. This will allow userspace to online
> - * and offline memory explicitly. Lack of this bit means that the caller has to
> - * call move_pfn_range_to_zone to finish the initialization.
> - */
> -
> -#define MHP_MEMBLOCK_API (1<<0)
> -
> /* reasonably generic interface to expand the physical pages */
> extern int __add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
> struct mhp_restrictions *restrictions);
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index b1fde90bbf19..9a92549ef23b 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -251,7 +251,7 @@ void __init register_page_bootmem_info_node(struct pglist_data *pgdat)
> #endif /* CONFIG_HAVE_BOOTMEM_INFO_NODE */
>
> static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
> - struct vmem_altmap *altmap, bool want_memblock)
> + struct vmem_altmap *altmap)
> {
> int ret;
>
> @@ -294,8 +294,7 @@ int __ref __add_pages(int nid, unsigned long phys_start_pfn,
> }
>
> for (i = start_sec; i <= end_sec; i++) {
> - err = __add_section(nid, section_nr_to_pfn(i), altmap,
> - restrictions->flags & MHP_MEMBLOCK_API);
> + err = __add_section(nid, section_nr_to_pfn(i), altmap);
>
> /*
> * EEXIST is finally dealt with by ioresource collision
> @@ -1067,9 +1066,7 @@ static int online_memory_block(struct memory_block *mem, void *arg)
> */
> int __ref add_memory_resource(int nid, struct resource *res)
> {
> - struct mhp_restrictions restrictions = {
> - .flags = MHP_MEMBLOCK_API,
> - };
> + struct mhp_restrictions restrictions = {};
> u64 start, size;
> bool new_node = false;
> int ret;
> --
> 2.20.1
>
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [PATCH v3 09/11] mm/memory_hotplug: Remove memory block devices before arch_remove_memory()
From: Michal Hocko @ 2019-07-01 8:41 UTC (permalink / raw)
To: David Hildenbrand
Cc: linux-ia64, linux-sh, Wei Yang, linux-mm, Arun KS, Ingo Molnar,
linux-s390, Rafael J. Wysocki, Pavel Tatashin,
mike.travis@hpe.com, Mark Brown, Jonathan Cameron, Dan Williams,
Chris Wilson, linux-arm-kernel, Oscar Salvador, Andrew Banman,
Mathieu Malaterre, Greg Kroah-Hartman, linux-kernel, Alex Deucher,
Igor Mammedov, akpm, linuxppc-dev, David S. Miller
In-Reply-To: <20190527111152.16324-10-david@redhat.com>
On Mon 27-05-19 13:11:50, David Hildenbrand wrote:
> Let's factor out removing of memory block devices, which is only
> necessary for memory added via add_memory() and friends that created
> memory block devices. Remove the devices before calling
> arch_remove_memory().
>
> This finishes factoring out memory block device handling from
> arch_add_memory() and arch_remove_memory().
OK, this makes sense again. Just a nit. Calling find_memory_block_by_id
for each memory block looks a bit suboptimal, especially when we are
removing consequent physical memblocks. I have to confess that I do not
know how expensive is the search and I also expect that there won't be
that many memblocks in the removed range anyway as large setups have
large memblocks.
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: "mike.travis@hpe.com" <mike.travis@hpe.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Andrew Banman <andrew.banman@hpe.com>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Oscar Salvador <osalvador@suse.de>
> Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Pavel Tatashin <pavel.tatashin@microsoft.com>
> Cc: Arun KS <arunks@codeaurora.org>
> Cc: Mathieu Malaterre <malat@debian.org>
> Reviewed-by: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>
Other than that looks good to me.
Acked-by: Michal Hocko <mhocko@suse.com>
> ---
> drivers/base/memory.c | 37 ++++++++++++++++++-------------------
> drivers/base/node.c | 11 ++++++-----
> include/linux/memory.h | 2 +-
> include/linux/node.h | 6 ++----
> mm/memory_hotplug.c | 5 +++--
> 5 files changed, 30 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/base/memory.c b/drivers/base/memory.c
> index 5a0370f0c506..f28efb0bf5c7 100644
> --- a/drivers/base/memory.c
> +++ b/drivers/base/memory.c
> @@ -763,32 +763,31 @@ int create_memory_block_devices(unsigned long start, unsigned long size)
> return ret;
> }
>
> -void unregister_memory_section(struct mem_section *section)
> +/*
> + * Remove memory block devices for the given memory area. Start and size
> + * have to be aligned to memory block granularity. Memory block devices
> + * have to be offline.
> + */
> +void remove_memory_block_devices(unsigned long start, unsigned long size)
> {
> + const int start_block_id = pfn_to_block_id(PFN_DOWN(start));
> + const int end_block_id = pfn_to_block_id(PFN_DOWN(start + size));
> struct memory_block *mem;
> + int block_id;
>
> - if (WARN_ON_ONCE(!present_section(section)))
> + if (WARN_ON_ONCE(!IS_ALIGNED(start, memory_block_size_bytes()) ||
> + !IS_ALIGNED(size, memory_block_size_bytes())))
> return;
>
> mutex_lock(&mem_sysfs_mutex);
> -
> - /*
> - * Some users of the memory hotplug do not want/need memblock to
> - * track all sections. Skip over those.
> - */
> - mem = find_memory_block(section);
> - if (!mem)
> - goto out_unlock;
> -
> - unregister_mem_sect_under_nodes(mem, __section_nr(section));
> -
> - mem->section_count--;
> - if (mem->section_count == 0)
> + for (block_id = start_block_id; block_id != end_block_id; block_id++) {
> + mem = find_memory_block_by_id(block_id, NULL);
> + if (WARN_ON_ONCE(!mem))
> + continue;
> + mem->section_count = 0;
> + unregister_memory_block_under_nodes(mem);
> unregister_memory(mem);
> - else
> - put_device(&mem->dev);
> -
> -out_unlock:
> + }
> mutex_unlock(&mem_sysfs_mutex);
> }
>
> diff --git a/drivers/base/node.c b/drivers/base/node.c
> index 8598fcbd2a17..04fdfa99b8bc 100644
> --- a/drivers/base/node.c
> +++ b/drivers/base/node.c
> @@ -801,9 +801,10 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, void *arg)
> return 0;
> }
>
> -/* unregister memory section under all nodes that it spans */
> -int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
> - unsigned long phys_index)
> +/*
> + * Unregister memory block device under all nodes that it spans.
> + */
> +int unregister_memory_block_under_nodes(struct memory_block *mem_blk)
> {
> NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL);
> unsigned long pfn, sect_start_pfn, sect_end_pfn;
> @@ -816,8 +817,8 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
> return -ENOMEM;
> nodes_clear(*unlinked_nodes);
>
> - sect_start_pfn = section_nr_to_pfn(phys_index);
> - sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1;
> + sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
> + sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr);
> for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {
> int nid;
>
> diff --git a/include/linux/memory.h b/include/linux/memory.h
> index db3e8567f900..f26a5417ec5d 100644
> --- a/include/linux/memory.h
> +++ b/include/linux/memory.h
> @@ -112,7 +112,7 @@ extern void unregister_memory_notifier(struct notifier_block *nb);
> extern int register_memory_isolate_notifier(struct notifier_block *nb);
> extern void unregister_memory_isolate_notifier(struct notifier_block *nb);
> int create_memory_block_devices(unsigned long start, unsigned long size);
> -extern void unregister_memory_section(struct mem_section *);
> +void remove_memory_block_devices(unsigned long start, unsigned long size);
> extern int memory_dev_init(void);
> extern int memory_notify(unsigned long val, void *v);
> extern int memory_isolate_notify(unsigned long val, void *v);
> diff --git a/include/linux/node.h b/include/linux/node.h
> index 1a557c589ecb..02a29e71b175 100644
> --- a/include/linux/node.h
> +++ b/include/linux/node.h
> @@ -139,8 +139,7 @@ extern int register_cpu_under_node(unsigned int cpu, unsigned int nid);
> extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
> extern int register_mem_sect_under_node(struct memory_block *mem_blk,
> void *arg);
> -extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
> - unsigned long phys_index);
> +extern int unregister_memory_block_under_nodes(struct memory_block *mem_blk);
>
> extern int register_memory_node_under_compute_node(unsigned int mem_nid,
> unsigned int cpu_nid,
> @@ -176,8 +175,7 @@ static inline int register_mem_sect_under_node(struct memory_block *mem_blk,
> {
> return 0;
> }
> -static inline int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
> - unsigned long phys_index)
> +static inline int unregister_memory_block_under_nodes(struct memory_block *mem_blk)
> {
> return 0;
> }
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 9a92549ef23b..82136c5b4c5f 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -520,8 +520,6 @@ static void __remove_section(struct zone *zone, struct mem_section *ms,
> if (WARN_ON_ONCE(!valid_section(ms)))
> return;
>
> - unregister_memory_section(ms);
> -
> scn_nr = __section_nr(ms);
> start_pfn = section_nr_to_pfn((unsigned long)scn_nr);
> __remove_zone(zone, start_pfn);
> @@ -1845,6 +1843,9 @@ void __ref __remove_memory(int nid, u64 start, u64 size)
> memblock_free(start, size);
> memblock_remove(start, size);
>
> + /* remove memory block devices before removing memory */
> + remove_memory_block_devices(start, size);
> +
> arch_remove_memory(nid, start, size, NULL);
> __release_memory_resource(start, size);
>
> --
> 2.20.1
>
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [PATCH v2 4/7] powerpc/ftrace: Additionally nop out the preceding mflr with -mprofile-kernel
From: Naveen N. Rao @ 2019-07-01 8:51 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, Nicholas Piggin, Masami Hiramatsu, linuxppc-dev,
Ingo Molnar
In-Reply-To: <20190627121344.25b5449a@gandalf.local.home>
Steven Rostedt wrote:
> On Thu, 27 Jun 2019 20:58:20 +0530
> "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com> wrote:
>
>>
>> > But interesting, I don't see a synchronize_rcu_tasks() call
>> > there.
>>
>> We felt we don't need it in this case. We patch the branch to ftrace
>> with a nop first. Other cpus should see that first. But, now that I
>> think about it, should we add a memory barrier to ensure the writes get
>> ordered properly?
>
> Do you send an ipi to the other CPUs. I would just to be safe.
>
<snip>
>>
>> We are handling this through ftrace_replace_code() and
>> __ftrace_make_call_prep() below. For FTRACE_UPDATE_MAKE_CALL, we patch
>> in the mflr, followed by smp_call_function(isync) and
>> synchronize_rcu_tasks() before we proceed to patch the branch to ftrace.
>>
>> I don't see any other scenario where we end up in
>> __ftrace_make_nop_kernel() without going through ftrace_replace_code().
>> For kernel modules, this can happen during module load/init and so, I
>> patch out both instructions in __ftrace_make_call() above without any
>> synchronization.
>>
>> Am I missing anything?
>>
>
> No, I think I got confused ;-), it's the patch out that I was worried
> about, but when I was going through the scenario, I somehow turned it
> into the patching in (which I already audited :-p). I was going to
> reply with just the top part of this email, but then the confusion
> started :-/
>
> OK, yes, patching out should be fine, and you already covered the
> patching in. Sorry for the noise.
>
> Just to confirm and totally remove the confusion, the patch does:
>
> <func>:
> mflr r0 <-- preempt here
> bl _mcount
>
> <func>:
> mflr r0
> nop
>
> And this is fine regardless.
>
> OK, Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Thanks for confirming! We do need an IPI to be sure, as you pointed out
above. I will have the patching out take the same path to simplify
things.
- Naveen
^ permalink raw reply
* Re: [PATCH v3 10/11] mm/memory_hotplug: Make unregister_memory_block_under_nodes() never fail
From: Michal Hocko @ 2019-07-01 8:51 UTC (permalink / raw)
To: David Hildenbrand
Cc: linux-s390, linux-ia64, linux-sh, Greg Kroah-Hartman, Mark Brown,
Rafael J. Wysocki, linux-kernel, Wei Yang, linux-mm,
David S. Miller, Jonathan Cameron, Alex Deucher, Igor Mammedov,
akpm, Chris Wilson, linuxppc-dev, Dan Williams, linux-arm-kernel,
Oscar Salvador
In-Reply-To: <20190527111152.16324-11-david@redhat.com>
On Mon 27-05-19 13:11:51, David Hildenbrand wrote:
> We really don't want anything during memory hotunplug to fail.
> We always pass a valid memory block device, that check can go. Avoid
> allocating memory and eventually failing. As we are always called under
> lock, we can use a static piece of memory. This avoids having to put
> the structure onto the stack, having to guess about the stack size
> of callers.
>
> Patch inspired by a patch from Oscar Salvador.
>
> In the future, there might be no need to iterate over nodes at all.
> mem->nid should tell us exactly what to remove. Memory block devices
> with mixed nodes (added during boot) should properly fenced off and never
> removed.
Yeah, we do not allow to offline multi zone (node) ranges so the current
code seems to be over engineered.
Anyway, I am wondering why do we have to strictly check for already
removed nodes links. Is the sysfs code going to complain we we try to
remove again?
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Oscar Salvador <osalvador@suse.de>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>
Anyway
Acked-by: Michal Hocko <mhocko@suse.com>
> ---
> drivers/base/node.c | 18 +++++-------------
> include/linux/node.h | 5 ++---
> 2 files changed, 7 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/base/node.c b/drivers/base/node.c
> index 04fdfa99b8bc..9be88fd05147 100644
> --- a/drivers/base/node.c
> +++ b/drivers/base/node.c
> @@ -803,20 +803,14 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, void *arg)
>
> /*
> * Unregister memory block device under all nodes that it spans.
> + * Has to be called with mem_sysfs_mutex held (due to unlinked_nodes).
> */
> -int unregister_memory_block_under_nodes(struct memory_block *mem_blk)
> +void unregister_memory_block_under_nodes(struct memory_block *mem_blk)
> {
> - NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL);
> unsigned long pfn, sect_start_pfn, sect_end_pfn;
> + static nodemask_t unlinked_nodes;
>
> - if (!mem_blk) {
> - NODEMASK_FREE(unlinked_nodes);
> - return -EFAULT;
> - }
> - if (!unlinked_nodes)
> - return -ENOMEM;
> - nodes_clear(*unlinked_nodes);
> -
> + nodes_clear(unlinked_nodes);
> sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
> sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr);
> for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {
> @@ -827,15 +821,13 @@ int unregister_memory_block_under_nodes(struct memory_block *mem_blk)
> continue;
> if (!node_online(nid))
> continue;
> - if (node_test_and_set(nid, *unlinked_nodes))
> + if (node_test_and_set(nid, unlinked_nodes))
> continue;
> sysfs_remove_link(&node_devices[nid]->dev.kobj,
> kobject_name(&mem_blk->dev.kobj));
> sysfs_remove_link(&mem_blk->dev.kobj,
> kobject_name(&node_devices[nid]->dev.kobj));
> }
> - NODEMASK_FREE(unlinked_nodes);
> - return 0;
> }
>
> int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn)
> diff --git a/include/linux/node.h b/include/linux/node.h
> index 02a29e71b175..548c226966a2 100644
> --- a/include/linux/node.h
> +++ b/include/linux/node.h
> @@ -139,7 +139,7 @@ extern int register_cpu_under_node(unsigned int cpu, unsigned int nid);
> extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
> extern int register_mem_sect_under_node(struct memory_block *mem_blk,
> void *arg);
> -extern int unregister_memory_block_under_nodes(struct memory_block *mem_blk);
> +extern void unregister_memory_block_under_nodes(struct memory_block *mem_blk);
>
> extern int register_memory_node_under_compute_node(unsigned int mem_nid,
> unsigned int cpu_nid,
> @@ -175,9 +175,8 @@ static inline int register_mem_sect_under_node(struct memory_block *mem_blk,
> {
> return 0;
> }
> -static inline int unregister_memory_block_under_nodes(struct memory_block *mem_blk)
> +static inline void unregister_memory_block_under_nodes(struct memory_block *mem_blk)
> {
> - return 0;
> }
>
> static inline void register_hugetlbfs_with_node(node_registration_func_t reg,
> --
> 2.20.1
--
Michal Hocko
SUSE Labs
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox