* Re: [PATCH v3 4/7] powerpc/fadump: exclude memory holes while reserving memory in second kernel.
From: Hari Bathini @ 2018-04-03 9:51 UTC (permalink / raw)
To: Mahesh J Salgaonkar, linuxppc-dev
Cc: Srikar Dronamraju, kernelfans, Aneesh Kumar K.V, Ananth Narayan,
Nathan Fontenot, Anshuman Khandual
In-Reply-To: <152265062142.23251.2863873644423472277.stgit@jupiter.in.ibm.com>
On Monday 02 April 2018 12:00 PM, Mahesh J Salgaonkar wrote:
> From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
>
> The second kernel, during early boot after the crash, reserves rest of
> the memory above boot memory size to make sure it does not touch any of the
> dump memory area. It uses memblock_reserve() that reserves the specified
> memory region irrespective of memory holes present within that region.
> There are chances where previous kernel would have hot removed some of
> its memory leaving memory holes behind. In such cases fadump kernel reports
> incorrect number of reserved pages through arch_reserved_kernel_pages()
> hook causing kernel to hang or panic.
>
> Fix this by excluding memory holes while reserving rest of the memory
> above boot memory size during second kernel boot after crash.
>
> Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> ---
> arch/powerpc/kernel/fadump.c | 17 ++++++++++++++++-
> 1 file changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
> index 011f1aa7abab..a497e9fb93fe 100644
> --- a/arch/powerpc/kernel/fadump.c
> +++ b/arch/powerpc/kernel/fadump.c
> @@ -433,6 +433,21 @@ static inline unsigned long get_fadump_metadata_base(
> return be64_to_cpu(fdm->metadata_region.source_address);
> }
>
> +static void fadump_memblock_reserve(unsigned long base, unsigned long size)
> +{
> + struct memblock_region *reg;
> + unsigned long start, end;
> +
> + for_each_memblock(memory, reg) {
> + start = max(base, (unsigned long)reg->base);
> + end = reg->base + reg->size;
> + end = min(base + size, end);
> +
> + if (start < end)
> + memblock_reserve(start, end - start);
> + }
> +}
> +
> int __init fadump_reserve_mem(void)
> {
> unsigned long base, size, memory_boundary;
> @@ -487,7 +502,7 @@ int __init fadump_reserve_mem(void)
> */
> base = fw_dump.boot_memory_size;
> size = memory_boundary - base;
> - memblock_reserve(base, size);
> + fadump_memblock_reserve(base, size);
> printk(KERN_INFO "Reserved %ldMB of memory at %ldMB "
Mahesh, you may want to change this print as well as it would be
misleading in case of
holes in the memory.
Thanks
Hari
> "for saving crash dump\n",
> (unsigned long)(size >> 20),
>
^ permalink raw reply
* [PATCH] cxl: Fix possible deadlock when processing page faults from cxllib
From: Frederic Barrat @ 2018-04-03 9:43 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: ldufour, clombard, andrew.donnellan, vaibhav
cxllib_handle_fault() is called by an external driver when it needs to
have the host process page faults for a buffer which may cover several
pages. Currently the function holds the mm->mmap_sem semaphore with
read access while iterating over the buffer, since it could spawn
several VMAs. When calling a lower-level function to handle the page
fault for a single page, the semaphore is accessed again in read
mode. That is wrong and can lead to deadlocks if a writer tries to
sneak in while a buffer of several pages is being processed.
The fix is to release the semaphore once cxllib_handle_fault() got the
information it needs from the current vma. The address space/VMAs
could evolve while we iterate over the full buffer, but in the
unlikely case where we miss a page, the driver will raise a new page
fault when retrying.
Fixes: 3ced8d730063 ("cxl: Export library to support IBM XSL")
Cc: stable@vger.kernel.org # 4.13+
Signed-off-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
---
drivers/misc/cxl/cxllib.c | 85 ++++++++++++++++++++++++++++++-----------------
1 file changed, 55 insertions(+), 30 deletions(-)
diff --git a/drivers/misc/cxl/cxllib.c b/drivers/misc/cxl/cxllib.c
index 30ccba436b3b..55cd35d1a9cc 100644
--- a/drivers/misc/cxl/cxllib.c
+++ b/drivers/misc/cxl/cxllib.c
@@ -208,49 +208,74 @@ int cxllib_get_PE_attributes(struct task_struct *task,
}
EXPORT_SYMBOL_GPL(cxllib_get_PE_attributes);
-int cxllib_handle_fault(struct mm_struct *mm, u64 addr, u64 size, u64 flags)
+static int get_vma_info(struct mm_struct *mm, u64 addr,
+ u64 *vma_start, u64 *vma_end,
+ unsigned long *page_size)
{
- int rc;
- u64 dar;
struct vm_area_struct *vma = NULL;
- unsigned long page_size;
-
- if (mm == NULL)
- return -EFAULT;
+ int rc = 0;
down_read(&mm->mmap_sem);
vma = find_vma(mm, addr);
if (!vma) {
- pr_err("Can't find vma for addr %016llx\n", addr);
rc = -EFAULT;
goto out;
}
- /* get the size of the pages allocated */
- page_size = vma_kernel_pagesize(vma);
-
- for (dar = (addr & ~(page_size - 1)); dar < (addr + size); dar += page_size) {
- if (dar < vma->vm_start || dar >= vma->vm_end) {
- vma = find_vma(mm, addr);
- if (!vma) {
- pr_err("Can't find vma for addr %016llx\n", addr);
- rc = -EFAULT;
- goto out;
- }
- /* get the size of the pages allocated */
- page_size = vma_kernel_pagesize(vma);
+ *page_size = vma_kernel_pagesize(vma);
+ *vma_start = vma->vm_start;
+ *vma_end = vma->vm_end;
+out:
+ up_read(&mm->mmap_sem);
+ return rc;
+}
+
+int cxllib_handle_fault(struct mm_struct *mm, u64 addr, u64 size, u64 flags)
+{
+ int rc;
+ u64 dar, vma_start, vma_end;
+ unsigned long page_size;
+
+ if (mm == NULL)
+ return -EFAULT;
+
+ /*
+ * The buffer we have to process can extend over several pages
+ * and may also cover several VMAs.
+ * We iterate over all the pages. The page size could vary
+ * between VMAs.
+ */
+ rc = get_vma_info(mm, addr, &vma_start, &vma_end, &page_size);
+ if (rc)
+ return rc;
+
+ for (dar = (addr & ~(page_size - 1)); dar < (addr + size);
+ dar += page_size) {
+ if (dar < vma_start || dar >= vma_end) {
+ /*
+ * We don't hold the mm->mmap_sem semaphore
+ * while iterating, since the semaphore is
+ * required by one of the lower-level page
+ * fault processing functions and it could
+ * create a deadlock.
+ *
+ * It means the VMAs can be altered between 2
+ * loop iterations and we could theoretically
+ * miss a page (however unlikely). But that's
+ * not really a problem, as the driver will
+ * retry access, get another page fault on the
+ * missing page and call us again.
+ */
+ rc = get_vma_info(mm, dar, &vma_start, &vma_end,
+ &page_size);
+ if (rc)
+ return rc;
}
rc = cxl_handle_mm_fault(mm, flags, dar);
- if (rc) {
- pr_err("cxl_handle_mm_fault failed %d", rc);
- rc = -EFAULT;
- goto out;
- }
+ if (rc)
+ return -EFAULT;
}
- rc = 0;
-out:
- up_read(&mm->mmap_sem);
- return rc;
+ return 0;
}
EXPORT_SYMBOL_GPL(cxllib_handle_fault);
--
2.14.1
^ permalink raw reply related
* [PATCH 1/4] powerpc/64/kexec: fix race in kexec when XIVE is shutdowned
From: Cédric Le Goater @ 2018-04-03 7:15 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Ellerman, Benjamin Herrenschmidt, Cédric Le Goater
In-Reply-To: <20180403071548.19829-1-clg@kaod.org>
The kexec_state KEXEC_STATE_IRQS_OFF barrier is reached by all
secondary CPUs before the kexec_cpu_down() operation is called on
secondaries. This can raise conflicts and provoque errors in the XIVE
hcalls when XIVE is shutdowned with H_INT_RESET on the primary CPU.
To synchronize the kexec_cpu_down() operations and make sure the
secondaries have completed their task before the primary starts doing
the same, let's move the primary kexec_cpu_down() after the
KEXEC_STATE_REAL_MODE barrier.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
arch/powerpc/kernel/machine_kexec_64.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 49d34d7271e7..212ecb8e829c 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -230,16 +230,16 @@ static void kexec_prepare_cpus(void)
/* we are sure every CPU has IRQs off at this point */
kexec_all_irq_disabled = 1;
- /* after we tell the others to go down */
- if (ppc_md.kexec_cpu_down)
- ppc_md.kexec_cpu_down(0, 0);
-
/*
* Before removing MMU mappings make sure all CPUs have entered real
* mode:
*/
kexec_prepare_cpus_wait(KEXEC_STATE_REAL_MODE);
+ /* after we tell the others to go down */
+ if (ppc_md.kexec_cpu_down)
+ ppc_md.kexec_cpu_down(0, 0);
+
put_cpu();
}
--
2.13.6
^ permalink raw reply related
* [PATCH 2/4] powerpc/xive: fix hcall H_INT_RESET to support long busy delays
From: Cédric Le Goater @ 2018-04-03 7:15 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Ellerman, Benjamin Herrenschmidt, Cédric Le Goater
In-Reply-To: <20180403071548.19829-1-clg@kaod.org>
The hcall H_INT_RESET can take some time to complete and in such cases
it returns H_LONG_BUSY_* codes requiring the machine to sleep for a
while before retrying.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
arch/powerpc/sysdev/xive/spapr.c | 53 ++++++++++++++++++++++++++++++++++++----
1 file changed, 48 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c
index 091f1d0d0af1..7113f5d87952 100644
--- a/arch/powerpc/sysdev/xive/spapr.c
+++ b/arch/powerpc/sysdev/xive/spapr.c
@@ -19,6 +19,7 @@
#include <linux/spinlock.h>
#include <linux/cpumask.h>
#include <linux/mm.h>
+#include <linux/delay.h>
#include <asm/prom.h>
#include <asm/io.h>
@@ -108,6 +109,52 @@ static void xive_irq_bitmap_free(int irq)
}
}
+
+/* Based on the similar routines in RTAS */
+static unsigned int plpar_busy_delay_time(long rc)
+{
+ unsigned int ms = 0;
+
+ if (H_IS_LONG_BUSY(rc)) {
+ ms = get_longbusy_msecs(rc);
+ } else if (rc == H_BUSY) {
+ ms = 10; /* seems appropriate for XIVE hcalls */
+ }
+
+ return ms;
+}
+
+static unsigned int plpar_busy_delay(int rc)
+{
+ unsigned int ms;
+
+ might_sleep();
+ ms = plpar_busy_delay_time(rc);
+ if (ms && need_resched())
+ msleep(ms);
+
+ return ms;
+}
+
+/*
+ * Note: this call has a partition wide scope and can take a while to
+ * complete. If it returns H_LONG_BUSY_* it should be retried
+ * periodically.
+ */
+static long plpar_int_reset(unsigned long flags)
+{
+ long rc;
+
+ do {
+ rc = plpar_hcall_norets(H_INT_RESET, flags);
+ } while (plpar_busy_delay(rc));
+
+ if (rc)
+ pr_err("H_INT_RESET failed %ld\n", rc);
+
+ return rc;
+}
+
static long plpar_int_get_source_info(unsigned long flags,
unsigned long lisn,
unsigned long *src_flags,
@@ -445,11 +492,7 @@ static void xive_spapr_put_ipi(unsigned int cpu, struct xive_cpu *xc)
static void xive_spapr_shutdown(void)
{
- long rc;
-
- rc = plpar_hcall_norets(H_INT_RESET, 0);
- if (rc)
- pr_err("H_INT_RESET failed %ld\n", rc);
+ plpar_int_reset(0);
}
/*
--
2.13.6
^ permalink raw reply related
* [PATCH 4/4] powerpc/xive: prepare all hcalls to support long busy delays
From: Cédric Le Goater @ 2018-04-03 7:15 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Ellerman, Benjamin Herrenschmidt, Cédric Le Goater
In-Reply-To: <20180403071548.19829-1-clg@kaod.org>
This is not the case for the moment, but future releases of pHyp might
need to introduce some synchronisation routines under the hood which
would make the XIVE hcalls longer to complete.
As this was done for H_INT_RESET, let's wrap the other hcalls in a
loop catching the H_LONG_BUSY_* codes.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
arch/powerpc/sysdev/xive/spapr.c | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c
index 7113f5d87952..97ea0a67a173 100644
--- a/arch/powerpc/sysdev/xive/spapr.c
+++ b/arch/powerpc/sysdev/xive/spapr.c
@@ -165,7 +165,10 @@ static long plpar_int_get_source_info(unsigned long flags,
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
long rc;
- rc = plpar_hcall(H_INT_GET_SOURCE_INFO, retbuf, flags, lisn);
+ do {
+ rc = plpar_hcall(H_INT_GET_SOURCE_INFO, retbuf, flags, lisn);
+ } while (plpar_busy_delay(rc));
+
if (rc) {
pr_err("H_INT_GET_SOURCE_INFO lisn=%ld failed %ld\n", lisn, rc);
return rc;
@@ -198,8 +201,11 @@ static long plpar_int_set_source_config(unsigned long flags,
flags, lisn, target, prio, sw_irq);
- rc = plpar_hcall_norets(H_INT_SET_SOURCE_CONFIG, flags, lisn,
- target, prio, sw_irq);
+ do {
+ rc = plpar_hcall_norets(H_INT_SET_SOURCE_CONFIG, flags, lisn,
+ target, prio, sw_irq);
+ } while (plpar_busy_delay(rc));
+
if (rc) {
pr_err("H_INT_SET_SOURCE_CONFIG lisn=%ld target=%lx prio=%lx failed %ld\n",
lisn, target, prio, rc);
@@ -218,7 +224,11 @@ static long plpar_int_get_queue_info(unsigned long flags,
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
long rc;
- rc = plpar_hcall(H_INT_GET_QUEUE_INFO, retbuf, flags, target, priority);
+ do {
+ rc = plpar_hcall(H_INT_GET_QUEUE_INFO, retbuf, flags, target,
+ priority);
+ } while (plpar_busy_delay(rc));
+
if (rc) {
pr_err("H_INT_GET_QUEUE_INFO cpu=%ld prio=%ld failed %ld\n",
target, priority, rc);
@@ -247,8 +257,11 @@ static long plpar_int_set_queue_config(unsigned long flags,
pr_devel("H_INT_SET_QUEUE_CONFIG flags=%lx target=%lx priority=%lx qpage=%lx qsize=%lx\n",
flags, target, priority, qpage, qsize);
- rc = plpar_hcall_norets(H_INT_SET_QUEUE_CONFIG, flags, target,
- priority, qpage, qsize);
+ do {
+ rc = plpar_hcall_norets(H_INT_SET_QUEUE_CONFIG, flags, target,
+ priority, qpage, qsize);
+ } while (plpar_busy_delay(rc));
+
if (rc) {
pr_err("H_INT_SET_QUEUE_CONFIG cpu=%ld prio=%ld qpage=%lx returned %ld\n",
target, priority, qpage, rc);
@@ -262,7 +275,10 @@ static long plpar_int_sync(unsigned long flags, unsigned long lisn)
{
long rc;
- rc = plpar_hcall_norets(H_INT_SYNC, flags, lisn);
+ do {
+ rc = plpar_hcall_norets(H_INT_SYNC, flags, lisn);
+ } while (plpar_busy_delay(rc));
+
if (rc) {
pr_err("H_INT_SYNC lisn=%ld returned %ld\n", lisn, rc);
return rc;
@@ -285,7 +301,11 @@ static long plpar_int_esb(unsigned long flags,
pr_devel("H_INT_ESB flags=%lx lisn=%lx offset=%lx in=%lx\n",
flags, lisn, offset, in_data);
- rc = plpar_hcall(H_INT_ESB, retbuf, flags, lisn, offset, in_data);
+ do {
+ rc = plpar_hcall(H_INT_ESB, retbuf, flags, lisn, offset,
+ in_data);
+ } while (plpar_busy_delay(rc));
+
if (rc) {
pr_err("H_INT_ESB lisn=%ld offset=%ld returned %ld\n",
lisn, offset, rc);
--
2.13.6
^ permalink raw reply related
* [PATCH 3/4] powerpc/xive: shutdown XIVE when kexec or kdump is performed
From: Cédric Le Goater @ 2018-04-03 7:15 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Ellerman, Benjamin Herrenschmidt, Cédric Le Goater
In-Reply-To: <20180403071548.19829-1-clg@kaod.org>
The hcall H_INT_RESET should be called to make sure XIVE is fully
reseted.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
arch/powerpc/platforms/pseries/kexec.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c
index eeb13429d685..1d9bbf8e7357 100644
--- a/arch/powerpc/platforms/pseries/kexec.c
+++ b/arch/powerpc/platforms/pseries/kexec.c
@@ -52,8 +52,11 @@ void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
}
}
- if (xive_enabled())
+ if (xive_enabled()) {
xive_kexec_teardown_cpu(secondary);
- else
+
+ if (!secondary)
+ xive_shutdown();
+ } else
xics_kexec_teardown_cpu(secondary);
}
--
2.13.6
^ permalink raw reply related
* [PATCH 0/4] powerpc/xive: add support for H_INT_RESET
From: Cédric Le Goater @ 2018-04-03 7:15 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Ellerman, Benjamin Herrenschmidt, Cédric Le Goater
H_INT_RESET performs a reset of the Hypervisor internal interrupt
structures, removing all settings done with H_INT_SET_SOURCE_CONFIG
and H_INT_SET_QUEUE_CONFIG. This is most important for kdump and kexec
to be able to restart in a clean state.
First patch closes a window in the kexec sequence in which the
H_INT_RESET hcall can be run concurrently with other hcalls when CPUs
are brought down. The other patches wire up the reset hcall making
sure it supports H_LONG_BUSY_* returned by the Hypervisor.
Cédric Le Goater (4):
powerpc/64/kexec: fix race in kexec when XIVE is shutdowned
powerpc/xive: fix hcall H_INT_RESET to support long busy delays
powerpc/xive: shutdown XIVE when kexec or kdump is performed
powerpc/xive: prepare all hcalls to support long busy delays
arch/powerpc/kernel/machine_kexec_64.c | 8 +--
arch/powerpc/platforms/pseries/kexec.c | 7 ++-
arch/powerpc/sysdev/xive/spapr.c | 89 +++++++++++++++++++++++++++++-----
3 files changed, 85 insertions(+), 19 deletions(-)
--
2.13.6
^ permalink raw reply
* Re: [PATCH v2 3/3] powerpc/powernv: Always stop secondaries before reboot/shutdown
From: Vasant Hegde @ 2018-04-03 4:36 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev
In-Reply-To: <20180401103615.15454-4-npiggin@gmail.com>
On 04/01/2018 04:06 PM, Nicholas Piggin wrote:
> Currently powernv reboot and shutdown requests just leave secondaries
> to do their own things. This is undesirable because they can trigger
> any number of watchdogs while waiting for reboot, but also we don't
> know what else they might be doing -- they might be causing trouble,
> trampling memory, etc.
>
> The opal scheduled flash update code already ran into watchdog problems
> due to flashing taking a long time, and it was fixed with 2196c6f1ed
> ("powerpc/powernv: Return secondary CPUs to firmware before FW update"),
> which returns secondaries to opal. It's been found that regular reboots
> can take over 10 seconds, which can result in the hard lockup watchdog
> firing,
>
> reboot: Restarting system
> [ 360.038896709,5] OPAL: Reboot request...
> Watchdog CPU:0 Hard LOCKUP
> Watchdog CPU:44 detected Hard LOCKUP other CPUS:16
> Watchdog CPU:16 Hard LOCKUP
> watchdog: BUG: soft lockup - CPU#16 stuck for 3s! [swapper/16:0]
>
> This patch removes the special case for flash update, and calls
> smp_send_stop in all cases before calling reboot/shutdown.
>
> smp_send_stop could return CPUs to OPAL, the main reason not to is
> that the request could come from a NMI that interrupts OPAL code,
> so re-entry to OPAL can cause a number of problems. Putting
> secondaries into simple spin loops improves the chances of a
> successful reboot.
>
> Cc: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Nick,
Patch looks good to me. We have tested this patchset on FSP based system and
everything looks fine.
Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
-Vasant
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> arch/powerpc/include/asm/opal.h | 2 +-
> arch/powerpc/platforms/powernv/opal-flash.c | 28 +---------------------------
> arch/powerpc/platforms/powernv/setup.c | 15 +++++----------
> 3 files changed, 7 insertions(+), 38 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index dde60089d0d4..7159e1a6a61a 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -325,7 +325,7 @@ struct rtc_time;
> extern unsigned long opal_get_boot_time(void);
> extern void opal_nvram_init(void);
> extern void opal_flash_update_init(void);
> -extern void opal_flash_term_callback(void);
> +extern void opal_flash_update_print_message(void);
> extern int opal_elog_init(void);
> extern void opal_platform_dump_init(void);
> extern void opal_sys_param_init(void);
> diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c
> index 1cb0b895a236..b37015101bf6 100644
> --- a/arch/powerpc/platforms/powernv/opal-flash.c
> +++ b/arch/powerpc/platforms/powernv/opal-flash.c
> @@ -303,26 +303,9 @@ static int opal_flash_update(int op)
> return rc;
> }
>
> -/* Return CPUs to OPAL before starting FW update */
> -static void flash_return_cpu(void *info)
> -{
> - int cpu = smp_processor_id();
> -
> - if (!cpu_online(cpu))
> - return;
> -
> - /* Disable IRQ */
> - hard_irq_disable();
> -
> - /* Return the CPU to OPAL */
> - opal_return_cpu();
> -}
> -
> /* This gets called just before system reboots */
> -void opal_flash_term_callback(void)
> +void opal_flash_update_print_message(void)
> {
> - struct cpumask mask;
> -
> if (update_flash_data.status != FLASH_IMG_READY)
> return;
>
> @@ -333,15 +316,6 @@ void opal_flash_term_callback(void)
>
> /* Small delay to help getting the above message out */
> msleep(500);
> -
> - /* Return secondary CPUs to firmware */
> - cpumask_copy(&mask, cpu_online_mask);
> - cpumask_clear_cpu(smp_processor_id(), &mask);
> - if (!cpumask_empty(&mask))
> - smp_call_function_many(&mask,
> - flash_return_cpu, NULL, false);
> - /* Hard disable interrupts */
> - hard_irq_disable();
> }
>
> /*
> diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
> index 5f963286232f..ef8c9ce53a61 100644
> --- a/arch/powerpc/platforms/powernv/setup.c
> +++ b/arch/powerpc/platforms/powernv/setup.c
> @@ -201,17 +201,12 @@ static void pnv_prepare_going_down(void)
> */
> opal_event_shutdown();
>
> - /* Soft disable interrupts */
> - local_irq_disable();
> + /* Print flash update message if one is scheduled. */
> + opal_flash_update_print_message();
>
> - /*
> - * Return secondary CPUs to firwmare if a flash update
> - * is pending otherwise we will get all sort of error
> - * messages about CPU being stuck etc.. This will also
> - * have the side effect of hard disabling interrupts so
> - * past this point, the kernel is effectively dead.
> - */
> - opal_flash_term_callback();
> + smp_send_stop();
> +
> + hard_irq_disable();
> }
>
> static void __noreturn pnv_restart(char *cmd)
>
^ permalink raw reply
* Re: [PATCH 4/5] powerpc/pm: add sleep and deep sleep on QorIQ SoCs
From: kbuild test robot @ 2018-04-03 4:32 UTC (permalink / raw)
To: Ran Wang
Cc: kbuild-all, Benjamin Herrenschmidt, Paul Mackerras,
Michael Ellerman, Rob Herring, Mark Rutland, Scott Wood,
Kumar Gala, Li Yang, Zhao Chenhui, linuxppc-dev, linux-kernel,
devicetree, linux-arm-kernel, Ran Wang
In-Reply-To: <20180329013143.22527-4-ran.wang_1@nxp.com>
[-- Attachment #1: Type: text/plain, Size: 2482 bytes --]
Hi Ran,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on powerpc/next]
[also build test WARNING on v4.16 next-20180329]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Ran-Wang/powerpc-pm-Fix-suspend-n-in-menuconfig-for-e500mc-platforms/20180330-072848
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-ppc64e_defconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=powerpc
All warnings (new ones prefixed by >>):
arch/powerpc/platforms/85xx/sleep.S: Assembler messages:
>> arch/powerpc/platforms/85xx/sleep.S:1174: Warning: invalid register expression
vim +1174 arch/powerpc/platforms/85xx/sleep.S
1137
1138 _GLOBAL(fsl_booke_deep_sleep_resume)
1139 /* disable interrupts */
1140 FSL_DIS_ALL_IRQ
1141
1142 /* switch to 64-bit mode */
1143 bl .enable_64b_mode
1144
1145 /* set TOC pointer */
1146 bl .relative_toc
1147
1148 /* setup initial TLBs, switch to kernel space ... */
1149 bl .start_initialization_book3e
1150
1151 /* address space changed, set TOC pointer again */
1152 bl .relative_toc
1153
1154 /* call a cpu state restore handler */
1155 LOAD_REG_ADDR(r23, cur_cpu_spec)
1156 ld r23,0(r23)
1157 ld r23,CPU_SPEC_RESTORE(r23)
1158 cmpdi 0,r23,0
1159 beq 1f
1160 ld r23,0(r23)
1161 mtctr r23
1162 bctrl
1163 1:
1164 LOAD_REG_ADDR(r3, regs_buffer)
1165 bl e5500_cpu_state_restore
1166
1167 /* Load each CAM entry */
1168 LOAD_REG_ADDR(r3, tlbcam_index)
1169 lwz r3, 0(r3)
1170 mtctr r3
1171 li r0, 0
1172 3: mr r3, r0
1173 bl loadcam_entry
> 1174 addi r0, r0, 1
1175 bdnz 3b
1176
1177 /* restore return address */
1178 LOAD_REG_ADDR(r3, buf_tmp)
1179 ld r4, 16(r3)
1180 mtspr SPRN_TCR, r4
1181 ld r4, 0(r3)
1182 mtlr r4
1183 ld r4, 8(r3)
1184 mtmsr r4
1185 ld r4, 24(r3)
1186 mtcr r4
1187
1188 blr
1189
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 21649 bytes --]
^ permalink raw reply
* Re: [PATCH v3 6/7] powerpc/fadump: Do not allow hot-remove memory from fadump reserved area.
From: Pingfan Liu @ 2018-04-03 3:18 UTC (permalink / raw)
To: Mahesh J Salgaonkar
Cc: linuxppc-dev, Srikar Dronamraju, Aneesh Kumar K.V, Ananth Narayan,
Hari Bathini, Nathan Fontenot, Anshuman Khandual
In-Reply-To: <152265064158.23251.10213309407765206304.stgit@jupiter.in.ibm.com>
I think CMA has protected us from hot-remove, so this patch is not necessary.
Regards,
Pingfan
On Mon, Apr 2, 2018 at 2:30 PM, Mahesh J Salgaonkar
<mahesh@linux.vnet.ibm.com> wrote:
> From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
>
> For fadump to work successfully there should not be any holes in reserved
> memory ranges where kernel has asked firmware to move the content of old
> kernel memory in event of crash. But this memory area is currently not
> protected from hot-remove operations. Hence, fadump service can fail to
> re-register after the hot-remove operation, if hot-removed memory belongs
> to fadump reserved region. To avoid this make sure that memory from fadump
> reserved area is not hot-removable if fadump is registered.
>
> However, if user still wants to remove that memory, he can do so by
> manually stopping fadump service before hot-remove operation.
>
> Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/fadump.h | 2 +-
> arch/powerpc/kernel/fadump.c | 10 ++++++++--
> arch/powerpc/platforms/pseries/hotplug-memory.c | 7 +++++--
> 3 files changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/fadump.h b/arch/powerpc/include/asm/fadump.h
> index 44b6ebfe9be6..d16dc77107a8 100644
> --- a/arch/powerpc/include/asm/fadump.h
> +++ b/arch/powerpc/include/asm/fadump.h
> @@ -207,7 +207,7 @@ struct fad_crash_memory_ranges {
> unsigned long long size;
> };
>
> -extern int is_fadump_boot_memory_area(u64 addr, ulong size);
> +extern int is_fadump_memory_area(u64 addr, ulong size);
> extern int early_init_dt_scan_fw_dump(unsigned long node,
> const char *uname, int depth, void *data);
> extern int fadump_reserve_mem(void);
> diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
> index 59aaf0357a52..2c3c7e655eec 100644
> --- a/arch/powerpc/kernel/fadump.c
> +++ b/arch/powerpc/kernel/fadump.c
> @@ -162,13 +162,19 @@ int __init early_init_dt_scan_fw_dump(unsigned long node,
>
> /*
> * If fadump is registered, check if the memory provided
> - * falls within boot memory area.
> + * falls within boot memory area and reserved memory area.
> */
> -int is_fadump_boot_memory_area(u64 addr, ulong size)
> +int is_fadump_memory_area(u64 addr, ulong size)
> {
> + u64 d_start = fw_dump.reserve_dump_area_start;
> + u64 d_end = d_start + fw_dump.reserve_dump_area_size;
> +
> if (!fw_dump.dump_registered)
> return 0;
>
> + if (((addr + size) > d_start) && (addr <= d_end))
> + return 1;
> +
> return (addr + size) > RMA_START && addr <= fw_dump.boot_memory_size;
> }
>
> diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
> index c1578f54c626..e4c658cda3a7 100644
> --- a/arch/powerpc/platforms/pseries/hotplug-memory.c
> +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
> @@ -389,8 +389,11 @@ static bool lmb_is_removable(struct drmem_lmb *lmb)
> phys_addr = lmb->base_addr;
>
> #ifdef CONFIG_FA_DUMP
> - /* Don't hot-remove memory that falls in fadump boot memory area */
> - if (is_fadump_boot_memory_area(phys_addr, block_sz))
> + /*
> + * Don't hot-remove memory that falls in fadump boot memory area
> + * and memory that is reserved for capturing old kernel memory.
> + */
> + if (is_fadump_memory_area(phys_addr, block_sz))
> return false;
> #endif
>
>
^ permalink raw reply
* Re: [PATCH v2 1/3] powerpc: use NMI IPI for smp_send_stop
From: Nicholas Piggin @ 2018-04-03 2:35 UTC (permalink / raw)
To: Balbir Singh; +Cc: linuxppc-dev, Vasant Hegde
In-Reply-To: <20180403101326.0ca46abb@gmail.com>
On Tue, 3 Apr 2018 10:13:26 +1000
Balbir Singh <bsingharora@gmail.com> wrote:
> On Sun, 1 Apr 2018 20:36:13 +1000
> Nicholas Piggin <npiggin@gmail.com> wrote:
>
> > Use the NMI IPI rather than smp_call_function for smp_send_stop.
> > Have stopped CPUs hard disable interrupts rather than just soft
> > disable.
> >
> > This function is used in crash/panic/shutdown paths to bring other
> > CPUs down as quickly and reliably as possible, and minimizing their
> > potential to cause trouble.
> >
> > Avoiding the Linux smp_call_function infrastructure and (if supported)
> > using true NMI IPIs makes this more robust.
> >
> > Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> > ---
> > arch/powerpc/kernel/smp.c | 8 ++++++++
> > 1 file changed, 8 insertions(+)
> >
> > diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> > index cfc08b099c49..db88660bf6bd 100644
> > --- a/arch/powerpc/kernel/smp.c
> > +++ b/arch/powerpc/kernel/smp.c
> > @@ -565,7 +565,11 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
> > }
> > #endif
> >
> > +#ifdef CONFIG_NMI_IPI
> > +static void stop_this_cpu(struct pt_regs *regs)
> > +#else
> > static void stop_this_cpu(void *dummy)
> > +#endif
> > {
> > /* Remove this CPU */
> > set_cpu_online(smp_processor_id(), false);
> > @@ -577,7 +581,11 @@ static void stop_this_cpu(void *dummy)
> >
> > void smp_send_stop(void)
> > {
> > +#ifdef CONFIG_NMI_IPI
> > + smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, stop_this_cpu, 1000000);
>
> I wonder if the delay_us should be a function of number of cpus and the
> callee should figure this out on its own? May be not in this series, but
> in the longer run.
It possibly should. The big per-cpu/core serialized delay is in firmware
(worst case we have to do a special wakeup on each core and bring it out
of deep stop), and that gets done before the delay starts. So we count
delay from after all threads are woken and given their sreset command, so
this is probably okay even for very big systems.
But it should at least be a #define constant if not something more
sophisticated like you suggest. We have a few delays like that including
in xmon and other crash paths that could use some more thought.
Thanks,
Nick
>
>
> Balbir Singh.
^ permalink raw reply
* Re: [PATCH v2 1/3] powerpc: use NMI IPI for smp_send_stop
From: Balbir Singh @ 2018-04-03 0:13 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: linuxppc-dev, Vasant Hegde
In-Reply-To: <20180401103615.15454-2-npiggin@gmail.com>
On Sun, 1 Apr 2018 20:36:13 +1000
Nicholas Piggin <npiggin@gmail.com> wrote:
> Use the NMI IPI rather than smp_call_function for smp_send_stop.
> Have stopped CPUs hard disable interrupts rather than just soft
> disable.
>
> This function is used in crash/panic/shutdown paths to bring other
> CPUs down as quickly and reliably as possible, and minimizing their
> potential to cause trouble.
>
> Avoiding the Linux smp_call_function infrastructure and (if supported)
> using true NMI IPIs makes this more robust.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> arch/powerpc/kernel/smp.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> index cfc08b099c49..db88660bf6bd 100644
> --- a/arch/powerpc/kernel/smp.c
> +++ b/arch/powerpc/kernel/smp.c
> @@ -565,7 +565,11 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
> }
> #endif
>
> +#ifdef CONFIG_NMI_IPI
> +static void stop_this_cpu(struct pt_regs *regs)
> +#else
> static void stop_this_cpu(void *dummy)
> +#endif
> {
> /* Remove this CPU */
> set_cpu_online(smp_processor_id(), false);
> @@ -577,7 +581,11 @@ static void stop_this_cpu(void *dummy)
>
> void smp_send_stop(void)
> {
> +#ifdef CONFIG_NMI_IPI
> + smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, stop_this_cpu, 1000000);
I wonder if the delay_us should be a function of number of cpus and the
callee should figure this out on its own? May be not in this series, but
in the longer run.
Balbir Singh.
^ permalink raw reply
* Re: [RFC PATCH v2 0/2] Randomization of address chosen by mmap.
From: Ilya Smith @ 2018-04-03 0:11 UTC (permalink / raw)
To: Luck, Tony
Cc: Rich Felker, Matthew Wilcox, Kees Cook, Michal Hocko,
Richard Henderson, ink@jurassic.park.msu.ru, mattst88@gmail.com,
Vineet Gupta, Russell King, Yu, Fenghua, Ralf Baechle,
James E.J. Bottomley, Helge Deller, Benjamin Herrenschmidt,
Paul Mackerras, Michael Ellerman, Martin Schwidefsky,
Heiko Carstens, Yoshinori Sato, David S. Miller, Thomas Gleixner,
Ingo Molnar, H. Peter Anvin, X86 ML, nyc@holomorphy.com, Al Viro,
Arnd Bergmann, Greg KH, Deepa Dinamani, Hugh Dickins,
Kate Stewart, Philippe Ombredanne, Andrew Morton, Steve Capper,
Punit Agrawal, Aneesh Kumar K.V, Nick Piggin, Bhupesh Sharma,
Rik van Riel, nitin.m.gupta@oracle.com, Kirill A. Shutemov,
Williams, Dan J, Jan Kara, Ross Zwisler, Jerome Glisse,
Andrea Arcangeli, Oleg Nesterov, linux-alpha@vger.kernel.org,
LKML, linux-snps-arc@lists.infradead.org,
linux-ia64@vger.kernel.org, linux-metag@vger.kernel.org,
Linux MIPS Mailing List, linux-parisc, PowerPC, linux-s390,
linux-sh, sparclinux, Linux-MM
In-Reply-To: <3908561D78D1C84285E8C5FCA982C28F7B3B8BC5@ORSMSX110.amr.corp.intel.com>
> On 29 Mar 2018, at 00:07, Luck, Tony <tony.luck@intel.com> wrote:
>=20
>> The default limit of only 65536 VMAs will also quickly come into play
>> if consecutive anon mmaps don't get merged. Of course this can be
>> raised, but it has significant resource and performance (fork) costs.
>=20
> Could the random mmap address chooser look for how many existing
> VMAs have space before/after and the right attributes to merge with =
the
> new one you want to create? If this is above some threshold (100?) =
then
> pick one of them randomly and allocate the new address so that it will
> merge from below/above with an existing one.
>=20
> That should still give you a very high degree of randomness, but =
prevent
> out of control numbers of VMAs from being created.
I think this wouldn=E2=80=99t work. For example these 100 allocation may =
happened on=20
process initialization. But when attacker come to the server all his=20
allocations would be made on the predictable offsets from each other. So =
in=20
result we did nothing just decrease performance of first 100 =
allocations. I=20
think I can make ioctl to turn off this randomization per process and it =
could=20
be used if needed. For example if application going to allocate big =
chunk or=20
make big memory pressure, etc.
Best regards,
Ilya
^ permalink raw reply
* Re: [PATCH v9 17/24] mm: Protect mm_rb tree with a rwlock
From: David Rientjes @ 2018-04-03 0:11 UTC (permalink / raw)
To: Laurent Dufour
Cc: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan, linux-kernel, linux-mm, haren, khandual, npiggin,
bsingharora, Tim Chen, linuxppc-dev, x86
In-Reply-To: <1520963994-28477-18-git-send-email-ldufour@linux.vnet.ibm.com>
On Tue, 13 Mar 2018, Laurent Dufour wrote:
> This change is inspired by the Peter's proposal patch [1] which was
> protecting the VMA using SRCU. Unfortunately, SRCU is not scaling well in
> that particular case, and it is introducing major performance degradation
> due to excessive scheduling operations.
>
> To allow access to the mm_rb tree without grabbing the mmap_sem, this patch
> is protecting it access using a rwlock. As the mm_rb tree is a O(log n)
> search it is safe to protect it using such a lock. The VMA cache is not
> protected by the new rwlock and it should not be used without holding the
> mmap_sem.
>
> To allow the picked VMA structure to be used once the rwlock is released, a
> use count is added to the VMA structure. When the VMA is allocated it is
> set to 1. Each time the VMA is picked with the rwlock held its use count
> is incremented. Each time the VMA is released it is decremented. When the
> use count hits zero, this means that the VMA is no more used and should be
> freed.
>
> This patch is preparing for 2 kind of VMA access :
> - as usual, under the control of the mmap_sem,
> - without holding the mmap_sem for the speculative page fault handler.
>
> Access done under the control the mmap_sem doesn't require to grab the
> rwlock to protect read access to the mm_rb tree, but access in write must
> be done under the protection of the rwlock too. This affects inserting and
> removing of elements in the RB tree.
>
> The patch is introducing 2 new functions:
> - vma_get() to find a VMA based on an address by holding the new rwlock.
> - vma_put() to release the VMA when its no more used.
> These services are designed to be used when access are made to the RB tree
> without holding the mmap_sem.
>
> When a VMA is removed from the RB tree, its vma->vm_rb field is cleared and
> we rely on the WMB done when releasing the rwlock to serialize the write
> with the RMB done in a later patch to check for the VMA's validity.
>
> When free_vma is called, the file associated with the VMA is closed
> immediately, but the policy and the file structure remained in used until
> the VMA's use count reach 0, which may happens later when exiting an
> in progress speculative page fault.
>
> [1] https://patchwork.kernel.org/patch/5108281/
>
> Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
> Cc: Matthew Wilcox <willy@infradead.org>
> Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
Can __free_vma() be generalized for mm/nommu.c's delete_vma() and
do_mmap()?
^ permalink raw reply
* Re: [PATCH v9 16/24] mm: Introduce __page_add_new_anon_rmap()
From: David Rientjes @ 2018-04-02 23:57 UTC (permalink / raw)
To: Laurent Dufour
Cc: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan, linux-kernel, linux-mm, haren, khandual, npiggin,
bsingharora, Tim Chen, linuxppc-dev, x86
In-Reply-To: <1520963994-28477-17-git-send-email-ldufour@linux.vnet.ibm.com>
On Tue, 13 Mar 2018, Laurent Dufour wrote:
> When dealing with speculative page fault handler, we may race with VMA
> being split or merged. In this case the vma->vm_start and vm->vm_end
> fields may not match the address the page fault is occurring.
>
> This can only happens when the VMA is split but in that case, the
> anon_vma pointer of the new VMA will be the same as the original one,
> because in __split_vma the new->anon_vma is set to src->anon_vma when
> *new = *vma.
>
> So even if the VMA boundaries are not correct, the anon_vma pointer is
> still valid.
>
> If the VMA has been merged, then the VMA in which it has been merged
> must have the same anon_vma pointer otherwise the merge can't be done.
>
> So in all the case we know that the anon_vma is valid, since we have
> checked before starting the speculative page fault that the anon_vma
> pointer is valid for this VMA and since there is an anon_vma this
> means that at one time a page has been backed and that before the VMA
> is cleaned, the page table lock would have to be grab to clean the
> PTE, and the anon_vma field is checked once the PTE is locked.
>
> This patch introduce a new __page_add_new_anon_rmap() service which
> doesn't check for the VMA boundaries, and create a new inline one
> which do the check.
>
> When called from a page fault handler, if this is not a speculative one,
> there is a guarantee that vm_start and vm_end match the faulting address,
> so this check is useless. In the context of the speculative page fault
> handler, this check may be wrong but anon_vma is still valid as explained
> above.
>
> Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
I'm indifferent on this: it could be argued both sides that the new
function and its variant for a simple VM_BUG_ON() isn't worth it and it
would should rather be done in the callers of page_add_new_anon_rmap().
It feels like it would be better left to the caller and add a comment to
page_add_anon_rmap() itself in mm/rmap.c.
^ permalink raw reply
* Re: [PATCH v9 15/24] mm: Introduce __vm_normal_page()
From: David Rientjes @ 2018-04-02 23:18 UTC (permalink / raw)
To: Laurent Dufour
Cc: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan, linux-kernel, linux-mm, haren, khandual, npiggin,
bsingharora, Tim Chen, linuxppc-dev, x86
In-Reply-To: <1520963994-28477-16-git-send-email-ldufour@linux.vnet.ibm.com>
On Tue, 13 Mar 2018, Laurent Dufour wrote:
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index a84ddc218bbd..73b8b99f482b 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -1263,8 +1263,11 @@ struct zap_details {
> pgoff_t last_index; /* Highest page->index to unmap */
> };
>
> -struct page *_vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
> - pte_t pte, bool with_public_device);
> +struct page *__vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
> + pte_t pte, bool with_public_device,
> + unsigned long vma_flags);
> +#define _vm_normal_page(vma, addr, pte, with_public_device) \
> + __vm_normal_page(vma, addr, pte, with_public_device, (vma)->vm_flags)
> #define vm_normal_page(vma, addr, pte) _vm_normal_page(vma, addr, pte, false)
>
> struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr,
If _vm_normal_page() is a static inline function does it break somehow?
It's nice to avoid the #define's.
> diff --git a/mm/memory.c b/mm/memory.c
> index af0338fbc34d..184a0d663a76 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -826,8 +826,9 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
> #else
> # define HAVE_PTE_SPECIAL 0
> #endif
> -struct page *_vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
> - pte_t pte, bool with_public_device)
> +struct page *__vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
> + pte_t pte, bool with_public_device,
> + unsigned long vma_flags)
> {
> unsigned long pfn = pte_pfn(pte);
>
Would it be possible to update the comment since the function itself is no
longer named vm_normal_page?
^ permalink raw reply
* Re: [PATCH v9 14/24] mm: Introduce __maybe_mkwrite()
From: David Rientjes @ 2018-04-02 23:12 UTC (permalink / raw)
To: Laurent Dufour
Cc: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan, linux-kernel, linux-mm, haren, khandual, npiggin,
bsingharora, Tim Chen, linuxppc-dev, x86
In-Reply-To: <1520963994-28477-15-git-send-email-ldufour@linux.vnet.ibm.com>
On Tue, 13 Mar 2018, Laurent Dufour wrote:
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index dfa81a638b7c..a84ddc218bbd 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -684,13 +684,18 @@ void free_compound_page(struct page *page);
> * pte_mkwrite. But get_user_pages can cause write faults for mappings
> * that do not have writing enabled, when used by access_process_vm.
> */
> -static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
> +static inline pte_t __maybe_mkwrite(pte_t pte, unsigned long vma_flags)
> {
> - if (likely(vma->vm_flags & VM_WRITE))
> + if (likely(vma_flags & VM_WRITE))
> pte = pte_mkwrite(pte);
> return pte;
> }
>
> +static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
> +{
> + return __maybe_mkwrite(pte, vma->vm_flags);
> +}
> +
> int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
> struct page *page);
> int finish_fault(struct vm_fault *vmf);
> diff --git a/mm/memory.c b/mm/memory.c
> index 0a0a483d9a65..af0338fbc34d 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -2472,7 +2472,7 @@ static inline void wp_page_reuse(struct vm_fault *vmf)
>
> flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
> entry = pte_mkyoung(vmf->orig_pte);
> - entry = maybe_mkwrite(pte_mkdirty(entry), vma);
> + entry = __maybe_mkwrite(pte_mkdirty(entry), vmf->vma_flags);
> if (ptep_set_access_flags(vma, vmf->address, vmf->pte, entry, 1))
> update_mmu_cache(vma, vmf->address, vmf->pte);
> pte_unmap_unlock(vmf->pte, vmf->ptl);
> @@ -2549,8 +2549,8 @@ static int wp_page_copy(struct vm_fault *vmf)
> inc_mm_counter_fast(mm, MM_ANONPAGES);
> }
> flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
> - entry = mk_pte(new_page, vma->vm_page_prot);
> - entry = maybe_mkwrite(pte_mkdirty(entry), vma);
> + entry = mk_pte(new_page, vmf->vma_page_prot);
> + entry = __maybe_mkwrite(pte_mkdirty(entry), vmf->vma_flags);
> /*
> * Clear the pte entry and flush it first, before updating the
> * pte with the new entry. This will avoid a race condition
Don't you also need to do this in do_swap_page()?
diff --git a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3067,9 +3067,9 @@ int do_swap_page(struct vm_fault *vmf)
inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES);
dec_mm_counter_fast(vma->vm_mm, MM_SWAPENTS);
- pte = mk_pte(page, vma->vm_page_prot);
+ pte = mk_pte(page, vmf->vma_page_prot);
if ((vmf->flags & FAULT_FLAG_WRITE) && reuse_swap_page(page, NULL)) {
- pte = maybe_mkwrite(pte_mkdirty(pte), vma);
+ pte = __maybe_mkwrite(pte_mkdirty(pte), vmf->vma_flags);
vmf->flags &= ~FAULT_FLAG_WRITE;
ret |= VM_FAULT_WRITE;
exclusive = RMAP_EXCLUSIVE;
^ permalink raw reply
* Re: [PATCH v9 13/24] mm: Introduce __lru_cache_add_active_or_unevictable
From: David Rientjes @ 2018-04-02 23:11 UTC (permalink / raw)
To: Laurent Dufour
Cc: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan, linux-kernel, linux-mm, haren, khandual, npiggin,
bsingharora, Tim Chen, linuxppc-dev, x86
In-Reply-To: <1520963994-28477-14-git-send-email-ldufour@linux.vnet.ibm.com>
On Tue, 13 Mar 2018, Laurent Dufour wrote:
> The speculative page fault handler which is run without holding the
> mmap_sem is calling lru_cache_add_active_or_unevictable() but the vm_flags
> is not guaranteed to remain constant.
> Introducing __lru_cache_add_active_or_unevictable() which has the vma flags
> value parameter instead of the vma pointer.
>
> Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
Acked-by: David Rientjes <rientjes@google.com>
^ permalink raw reply
* Re: [PATCH v9 12/24] mm/migrate: Pass vm_fault pointer to migrate_misplaced_page()
From: David Rientjes @ 2018-04-02 23:00 UTC (permalink / raw)
To: Laurent Dufour
Cc: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan, linux-kernel, linux-mm, haren, khandual, npiggin,
bsingharora, Tim Chen, linuxppc-dev, x86
In-Reply-To: <1520963994-28477-13-git-send-email-ldufour@linux.vnet.ibm.com>
On Tue, 13 Mar 2018, Laurent Dufour wrote:
> migrate_misplaced_page() is only called during the page fault handling so
> it's better to pass the pointer to the struct vm_fault instead of the vma.
>
> This way during the speculative page fault path the saved vma->vm_flags
> could be used.
>
> Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
Acked-by: David Rientjes <rientjes@google.com>
^ permalink raw reply
* Re: [PATCH v9 11/24] mm: Cache some VMA fields in the vm_fault structure
From: David Rientjes @ 2018-04-02 22:24 UTC (permalink / raw)
To: Laurent Dufour
Cc: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan, linux-kernel, linux-mm, haren, khandual, npiggin,
bsingharora, Tim Chen, linuxppc-dev, x86
In-Reply-To: <1520963994-28477-12-git-send-email-ldufour@linux.vnet.ibm.com>
On Tue, 13 Mar 2018, Laurent Dufour wrote:
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index ef6ef0627090..dfa81a638b7c 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -359,6 +359,12 @@ struct vm_fault {
> * page table to avoid allocation from
> * atomic context.
> */
> + /*
> + * These entries are required when handling speculative page fault.
> + * This way the page handling is done using consistent field values.
> + */
> + unsigned long vma_flags;
> + pgprot_t vma_page_prot;
> };
>
> /* page entry size for vm->huge_fault() */
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index 446427cafa19..f71db2b42b30 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -3717,6 +3717,8 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
> .vma = vma,
> .address = address,
> .flags = flags,
> + .vma_flags = vma->vm_flags,
> + .vma_page_prot = vma->vm_page_prot,
> /*
> * Hard to debug if it ends up being
> * used by a callee that assumes
> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> index 32314e9e48dd..a946d5306160 100644
> --- a/mm/khugepaged.c
> +++ b/mm/khugepaged.c
> @@ -882,6 +882,8 @@ static bool __collapse_huge_page_swapin(struct mm_struct *mm,
> .flags = FAULT_FLAG_ALLOW_RETRY,
> .pmd = pmd,
> .pgoff = linear_page_index(vma, address),
> + .vma_flags = vma->vm_flags,
> + .vma_page_prot = vma->vm_page_prot,
> };
>
> /* we only decide to swapin, if there is enough young ptes */
> diff --git a/mm/memory.c b/mm/memory.c
> index 0200340ef089..46fe92b93682 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -2615,7 +2615,7 @@ static int wp_page_copy(struct vm_fault *vmf)
> * Don't let another task, with possibly unlocked vma,
> * keep the mlocked page.
> */
> - if (page_copied && (vma->vm_flags & VM_LOCKED)) {
> + if (page_copied && (vmf->vma_flags & VM_LOCKED)) {
> lock_page(old_page); /* LRU manipulation */
> if (PageMlocked(old_page))
> munlock_vma_page(old_page);
Doesn't wp_page_copy() also need to pass this to anon_vma_prepare() so
that find_mergeable_anon_vma() works correctly?
> @@ -2649,7 +2649,7 @@ static int wp_page_copy(struct vm_fault *vmf)
> */
> int finish_mkwrite_fault(struct vm_fault *vmf)
> {
> - WARN_ON_ONCE(!(vmf->vma->vm_flags & VM_SHARED));
> + WARN_ON_ONCE(!(vmf->vma_flags & VM_SHARED));
> if (!pte_map_lock(vmf))
> return VM_FAULT_RETRY;
> /*
> @@ -2751,7 +2751,7 @@ static int do_wp_page(struct vm_fault *vmf)
> * We should not cow pages in a shared writeable mapping.
> * Just mark the pages writable and/or call ops->pfn_mkwrite.
> */
> - if ((vma->vm_flags & (VM_WRITE|VM_SHARED)) ==
> + if ((vmf->vma_flags & (VM_WRITE|VM_SHARED)) ==
> (VM_WRITE|VM_SHARED))
> return wp_pfn_shared(vmf);
>
> @@ -2798,7 +2798,7 @@ static int do_wp_page(struct vm_fault *vmf)
> return VM_FAULT_WRITE;
> }
> unlock_page(vmf->page);
> - } else if (unlikely((vma->vm_flags & (VM_WRITE|VM_SHARED)) ==
> + } else if (unlikely((vmf->vma_flags & (VM_WRITE|VM_SHARED)) ==
> (VM_WRITE|VM_SHARED))) {
> return wp_page_shared(vmf);
> }
> @@ -3067,7 +3067,7 @@ int do_swap_page(struct vm_fault *vmf)
>
> inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES);
> dec_mm_counter_fast(vma->vm_mm, MM_SWAPENTS);
> - pte = mk_pte(page, vma->vm_page_prot);
> + pte = mk_pte(page, vmf->vma_page_prot);
> if ((vmf->flags & FAULT_FLAG_WRITE) && reuse_swap_page(page, NULL)) {
> pte = maybe_mkwrite(pte_mkdirty(pte), vma);
> vmf->flags &= ~FAULT_FLAG_WRITE;
> @@ -3093,7 +3093,7 @@ int do_swap_page(struct vm_fault *vmf)
>
> swap_free(entry);
> if (mem_cgroup_swap_full(page) ||
> - (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
> + (vmf->vma_flags & VM_LOCKED) || PageMlocked(page))
> try_to_free_swap(page);
> unlock_page(page);
> if (page != swapcache && swapcache) {
> @@ -3150,7 +3150,7 @@ static int do_anonymous_page(struct vm_fault *vmf)
> pte_t entry;
>
> /* File mapping without ->vm_ops ? */
> - if (vma->vm_flags & VM_SHARED)
> + if (vmf->vma_flags & VM_SHARED)
> return VM_FAULT_SIGBUS;
>
> /*
> @@ -3174,7 +3174,7 @@ static int do_anonymous_page(struct vm_fault *vmf)
> if (!(vmf->flags & FAULT_FLAG_WRITE) &&
> !mm_forbids_zeropage(vma->vm_mm)) {
> entry = pte_mkspecial(pfn_pte(my_zero_pfn(vmf->address),
> - vma->vm_page_prot));
> + vmf->vma_page_prot));
> if (!pte_map_lock(vmf))
> return VM_FAULT_RETRY;
> if (!pte_none(*vmf->pte))
> @@ -3207,8 +3207,8 @@ static int do_anonymous_page(struct vm_fault *vmf)
> */
> __SetPageUptodate(page);
>
> - entry = mk_pte(page, vma->vm_page_prot);
> - if (vma->vm_flags & VM_WRITE)
> + entry = mk_pte(page, vmf->vma_page_prot);
> + if (vmf->vma_flags & VM_WRITE)
> entry = pte_mkwrite(pte_mkdirty(entry));
>
> if (!pte_map_lock(vmf)) {
> @@ -3404,7 +3404,7 @@ static int do_set_pmd(struct vm_fault *vmf, struct page *page)
> for (i = 0; i < HPAGE_PMD_NR; i++)
> flush_icache_page(vma, page + i);
>
> - entry = mk_huge_pmd(page, vma->vm_page_prot);
> + entry = mk_huge_pmd(page, vmf->vma_page_prot);
> if (write)
> entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
>
> @@ -3478,11 +3478,11 @@ int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
> return VM_FAULT_NOPAGE;
>
> flush_icache_page(vma, page);
> - entry = mk_pte(page, vma->vm_page_prot);
> + entry = mk_pte(page, vmf->vma_page_prot);
> if (write)
> entry = maybe_mkwrite(pte_mkdirty(entry), vma);
> /* copy-on-write page */
> - if (write && !(vma->vm_flags & VM_SHARED)) {
> + if (write && !(vmf->vma_flags & VM_SHARED)) {
> inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES);
> page_add_new_anon_rmap(page, vma, vmf->address, false);
> mem_cgroup_commit_charge(page, memcg, false, false);
> @@ -3521,7 +3521,7 @@ int finish_fault(struct vm_fault *vmf)
>
> /* Did we COW the page? */
> if ((vmf->flags & FAULT_FLAG_WRITE) &&
> - !(vmf->vma->vm_flags & VM_SHARED))
> + !(vmf->vma_flags & VM_SHARED))
> page = vmf->cow_page;
> else
> page = vmf->page;
> @@ -3775,7 +3775,7 @@ static int do_fault(struct vm_fault *vmf)
> ret = VM_FAULT_SIGBUS;
> else if (!(vmf->flags & FAULT_FLAG_WRITE))
> ret = do_read_fault(vmf);
> - else if (!(vma->vm_flags & VM_SHARED))
> + else if (!(vmf->vma_flags & VM_SHARED))
> ret = do_cow_fault(vmf);
> else
> ret = do_shared_fault(vmf);
> @@ -3832,7 +3832,7 @@ static int do_numa_page(struct vm_fault *vmf)
> * accessible ptes, some can allow access by kernel mode.
> */
> pte = ptep_modify_prot_start(vma->vm_mm, vmf->address, vmf->pte);
> - pte = pte_modify(pte, vma->vm_page_prot);
> + pte = pte_modify(pte, vmf->vma_page_prot);
> pte = pte_mkyoung(pte);
> if (was_writable)
> pte = pte_mkwrite(pte);
> @@ -3866,7 +3866,7 @@ static int do_numa_page(struct vm_fault *vmf)
> * Flag if the page is shared between multiple address spaces. This
> * is later used when determining whether to group tasks together
> */
> - if (page_mapcount(page) > 1 && (vma->vm_flags & VM_SHARED))
> + if (page_mapcount(page) > 1 && (vmf->vma_flags & VM_SHARED))
> flags |= TNF_SHARED;
>
> last_cpupid = page_cpupid_last(page);
> @@ -3911,7 +3911,7 @@ static inline int wp_huge_pmd(struct vm_fault *vmf, pmd_t orig_pmd)
> return vmf->vma->vm_ops->huge_fault(vmf, PE_SIZE_PMD);
>
> /* COW handled on pte level: split pmd */
> - VM_BUG_ON_VMA(vmf->vma->vm_flags & VM_SHARED, vmf->vma);
> + VM_BUG_ON_VMA(vmf->vma_flags & VM_SHARED, vmf->vma);
> __split_huge_pmd(vmf->vma, vmf->pmd, vmf->address, false, NULL);
>
> return VM_FAULT_FALLBACK;
> @@ -4058,6 +4058,8 @@ static int __handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
> .flags = flags,
> .pgoff = linear_page_index(vma, address),
> .gfp_mask = __get_fault_gfp_mask(vma),
> + .vma_flags = vma->vm_flags,
> + .vma_page_prot = vma->vm_page_prot,
> };
> unsigned int dirty = flags & FAULT_FLAG_WRITE;
> struct mm_struct *mm = vma->vm_mm;
Don't you also need to do this?
diff --git a/include/linux/mm.h b/include/linux/mm.h
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -694,9 +694,9 @@ void free_compound_page(struct page *page);
* pte_mkwrite. But get_user_pages can cause write faults for mappings
* that do not have writing enabled, when used by access_process_vm.
*/
-static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
+static inline pte_t maybe_mkwrite(pte_t pte, unsigned long vma_flags)
{
- if (likely(vma->vm_flags & VM_WRITE))
+ if (likely(vma_flags & VM_WRITE))
pte = pte_mkwrite(pte);
return pte;
}
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1195,8 +1195,8 @@ static int do_huge_pmd_wp_page_fallback(struct vm_fault *vmf, pmd_t orig_pmd,
for (i = 0; i < HPAGE_PMD_NR; i++, haddr += PAGE_SIZE) {
pte_t entry;
- entry = mk_pte(pages[i], vma->vm_page_prot);
- entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ entry = mk_pte(pages[i], vmf->vma_page_prot);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vmf->vma_flags);
memcg = (void *)page_private(pages[i]);
set_page_private(pages[i], 0);
page_add_new_anon_rmap(pages[i], vmf->vma, haddr, false);
@@ -2169,7 +2169,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
entry = pte_swp_mksoft_dirty(entry);
} else {
entry = mk_pte(page + i, READ_ONCE(vma->vm_page_prot));
- entry = maybe_mkwrite(entry, vma);
+ entry = maybe_mkwrite(entry, vma->vm_flags);
if (!write)
entry = pte_wrprotect(entry);
if (!young)
diff --git a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1826,7 +1826,7 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr,
out_mkwrite:
if (mkwrite) {
entry = pte_mkyoung(entry);
- entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma->vm_flags);
}
set_pte_at(mm, addr, pte, entry);
@@ -2472,7 +2472,7 @@ static inline void wp_page_reuse(struct vm_fault *vmf)
flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
entry = pte_mkyoung(vmf->orig_pte);
- entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vmf->vma_flags);
if (ptep_set_access_flags(vma, vmf->address, vmf->pte, entry, 1))
update_mmu_cache(vma, vmf->address, vmf->pte);
pte_unmap_unlock(vmf->pte, vmf->ptl);
@@ -2549,8 +2549,8 @@ static int wp_page_copy(struct vm_fault *vmf)
inc_mm_counter_fast(mm, MM_ANONPAGES);
}
flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
- entry = mk_pte(new_page, vma->vm_page_prot);
- entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ entry = mk_pte(new_page, vmf->vma_page_prot);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vmf->vma_flags);
/*
* Clear the pte entry and flush it first, before updating the
* pte with the new entry. This will avoid a race condition
@@ -3069,7 +3069,7 @@ int do_swap_page(struct vm_fault *vmf)
dec_mm_counter_fast(vma->vm_mm, MM_SWAPENTS);
pte = mk_pte(page, vmf->vma_page_prot);
if ((vmf->flags & FAULT_FLAG_WRITE) && reuse_swap_page(page, NULL)) {
- pte = maybe_mkwrite(pte_mkdirty(pte), vma);
+ pte = maybe_mkwrite(pte_mkdirty(pte), vmf->vm_flags);
vmf->flags &= ~FAULT_FLAG_WRITE;
ret |= VM_FAULT_WRITE;
exclusive = RMAP_EXCLUSIVE;
@@ -3481,7 +3481,7 @@ int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
flush_icache_page(vma, page);
entry = mk_pte(page, vmf->vma_page_prot);
if (write)
- entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vmf->vm_flags);
/* copy-on-write page */
if (write && !(vmf->vma_flags & VM_SHARED)) {
inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES);
diff --git a/mm/migrate.c b/mm/migrate.c
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -240,7 +240,7 @@ static bool remove_migration_pte(struct page *page, struct vm_area_struct *vma,
*/
entry = pte_to_swp_entry(*pvmw.pte);
if (is_write_migration_entry(entry))
- pte = maybe_mkwrite(pte, vma);
+ pte = maybe_mkwrite(pte, vma->vm_flags);
if (unlikely(is_zone_device_page(new))) {
if (is_device_private_page(new)) {
^ permalink raw reply
* [PATCH] tty:hvcs: Move Assignment for hvcsd->port.count
From: Bryant G. Ly @ 2018-04-02 14:53 UTC (permalink / raw)
To: mpe; +Cc: linuxppc-dev, Bryant G. Ly
Move the assignment out of hvcsd->port.count from within the
if () block so this patch fixes it. It is bad practice to have
assignments within an if () block.
Signed-off-by: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
---
drivers/tty/hvc/hvcs.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index 1db1d97..333dc76 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -1202,7 +1202,8 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
hvcsd = tty->driver_data;
spin_lock_irqsave(&hvcsd->lock, flags);
- if (--hvcsd->port.count == 0) {
+ --hvcsd->port.count;
+ if (hvcsd->port.count == 0) {
vio_disable_interrupts(hvcsd->vdev);
--
2.7.2
^ permalink raw reply related
* Re: [PATCH 0/3] stop secondaries for reboot/shutdown
From: ppaidipe @ 2018-04-02 14:52 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: linuxppc-dev, Vasant Hegde, Linuxppc-dev
In-Reply-To: <20180401103615.15454-1-npiggin@gmail.com>
On 2018-04-01 16:06, Nicholas Piggin wrote:
> I'm rebasing and resending this series because the hard
> lockup messages are being seen in the field.
>
> Since last time, one of the patches was merged, and patches
> were split and reordered a bit. No major changes.
>
> This still hasn't been tested with the FSP firmware update.
>
I have tested this series on a FSP platform with firmware update
and multiple reboot/shutdown tests. Not seen any issues.
Tested-by: Pridhiviraj Paidipeddi <ppaidipe@linux.vnet.ibm.com>
Thanks
Pridhiviraj
> Thanks,
> Nick
>
> Nicholas Piggin (3):
> powerpc: use NMI IPI for smp_send_stop
> powerpc: hard disable irqs in smp_send_stop loop
> powerpc/powernv: Always stop secondaries before reboot/shutdown
>
> arch/powerpc/include/asm/opal.h | 2 +-
> arch/powerpc/kernel/smp.c | 13 +++++++++++--
> arch/powerpc/platforms/powernv/opal-flash.c | 28
> +---------------------------
> arch/powerpc/platforms/powernv/setup.c | 15 +++++----------
> 4 files changed, 18 insertions(+), 40 deletions(-)
^ permalink raw reply
* Re: RFC on writel and writel_relaxed
From: Sinan Kaya @ 2018-04-02 13:01 UTC (permalink / raw)
To: Benjamin Herrenschmidt, David Miller
Cc: torvalds, alexander.duyck, will.deacon, arnd, jgg, David.Laight,
oohall, linuxppc-dev, linux-rdma, alexander.h.duyck, paulmck,
netdev, linus971
In-Reply-To: <1522374027.21446.64.camel@kernel.crashing.org>
On 3/29/2018 9:40 PM, Benjamin Herrenschmidt wrote:
> On Thu, 2018-03-29 at 09:56 -0400, Sinan Kaya wrote:
>> On 3/28/2018 11:55 AM, David Miller wrote:
>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>> Date: Thu, 29 Mar 2018 02:13:16 +1100
>>>
>>>> Let's fix all archs, it's way easier than fixing all drivers. Half of
>>>> the archs are unused or dead anyway.
>>>
>>> Agreed.
>>>
>>
>> I pinged most of the maintainers yesterday.
>> Which arches do we care about these days?
>> I have not been paying attention any other architecture besides arm64.
>
> Thanks for going through that exercise !
>
> Once sparc, s390, microblaze and mips reply, I think we'll have a good
> coverage, maybe riscv is to put in that lot too.
I posted the following two patches for supporting microblaze and unicore32.
[PATCH v2 1/2] io: prevent compiler reordering on the default writeX() implementation
[PATCH v2 2/2] io: prevent compiler reordering on the default readX() implementation
The rest of the arches except mips and alpha seem OK.
I sent a question email on Friday to mips and alpha mailing lists. I'll follow up with
an actual patch today.
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* Re: [PATCH V2] powerpc: Fix oops due to wrong access of lppaca on non virtualized platform
From: Nicholas Piggin @ 2018-04-02 7:41 UTC (permalink / raw)
To: Aneesh Kumar K.V; +Cc: benh, paulus, mpe, linuxppc-dev
In-Reply-To: <20180402073337.22568-1-aneesh.kumar@linux.ibm.com>
On Mon, 2 Apr 2018 13:03:37 +0530
"Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> wrote:
> Commit 8e0b634b1327 ("powerpc/64s: Do not allocate lppaca if we are not
> virtualized") removed allocation of lppaca on non virtualized platform. But with
> CONFIG_PPC_SPLPAR enabled, we do access lppaca non-virtualized platform in some
> code paths.
>
> Fix this but adding runtime check for virtualized platform.
>
> Fixes: 8e0b634b1327 ("powerpc/64s: Do not allocate lppaca if we are not virtualized")
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Thanks, this looks good to me...
> ---
> Changes from V1:
> * update commit summary
>
> arch/powerpc/include/asm/lppaca.h | 3 +++
> arch/powerpc/include/asm/spinlock.h | 2 ++
> arch/powerpc/kernel/time.c | 3 +++
> 3 files changed, 8 insertions(+)
>
> diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
> index 65d589689f01..7c23ce8a5a4c 100644
> --- a/arch/powerpc/include/asm/lppaca.h
> +++ b/arch/powerpc/include/asm/lppaca.h
> @@ -34,6 +34,7 @@
> #include <linux/threads.h>
> #include <asm/types.h>
> #include <asm/mmu.h>
> +#include <asm/firmware.h>
>
> /*
> * The lppaca is the "virtual processor area" registered with the hypervisor,
> @@ -114,6 +115,8 @@ struct lppaca {
>
> static inline bool lppaca_shared_proc(struct lppaca *l)
> {
> + if (!firmware_has_feature(FW_FEATURE_SPLPAR))
> + return false;
> return !!(l->__old_status & LPPACA_OLD_SHARED_PROC);
> }
>
We should eventually clean this up. There's no need to pass in an lppaca
here AFAIKS. Is it even per-CPU, does it change dynamically? We could set
it up in a FW_FEATURE parameter at boot, which would could make some of
these tests cheaper.
> diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h
> index b9ebc3085fb7..72dc4ddc2972 100644
> --- a/arch/powerpc/include/asm/spinlock.h
> +++ b/arch/powerpc/include/asm/spinlock.h
> @@ -56,6 +56,8 @@
> #define vcpu_is_preempted vcpu_is_preempted
> static inline bool vcpu_is_preempted(int cpu)
> {
> + if (!firmware_has_feature(FW_FEATURE_SPLPAR))
> + return false;
> return !!(be32_to_cpu(lppaca_of(cpu).yield_count) & 1);
> }
> #endif
> diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
> index f7d96a68ecaa..360e71d455cc 100644
> --- a/arch/powerpc/kernel/time.c
> +++ b/arch/powerpc/kernel/time.c
> @@ -266,6 +266,9 @@ void accumulate_stolen_time(void)
>
> static inline u64 calculate_stolen_time(u64 stop_tb)
> {
> + if (!firmware_has_feature(FW_FEATURE_SPLPAR))
> + return 0;
> +
> if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx))
> return scan_dispatch_log(stop_tb);
>
^ permalink raw reply
* [PATCH V2] powerpc: Fix oops due to wrong access of lppaca on non virtualized platform
From: Aneesh Kumar K.V @ 2018-04-02 7:33 UTC (permalink / raw)
To: benh, paulus, mpe, npiggin; +Cc: linuxppc-dev, Aneesh Kumar K.V
Commit 8e0b634b1327 ("powerpc/64s: Do not allocate lppaca if we are not
virtualized") removed allocation of lppaca on non virtualized platform. But with
CONFIG_PPC_SPLPAR enabled, we do access lppaca non-virtualized platform in some
code paths.
Fix this but adding runtime check for virtualized platform.
Fixes: 8e0b634b1327 ("powerpc/64s: Do not allocate lppaca if we are not virtualized")
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
Changes from V1:
* update commit summary
arch/powerpc/include/asm/lppaca.h | 3 +++
arch/powerpc/include/asm/spinlock.h | 2 ++
arch/powerpc/kernel/time.c | 3 +++
3 files changed, 8 insertions(+)
diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
index 65d589689f01..7c23ce8a5a4c 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -34,6 +34,7 @@
#include <linux/threads.h>
#include <asm/types.h>
#include <asm/mmu.h>
+#include <asm/firmware.h>
/*
* The lppaca is the "virtual processor area" registered with the hypervisor,
@@ -114,6 +115,8 @@ struct lppaca {
static inline bool lppaca_shared_proc(struct lppaca *l)
{
+ if (!firmware_has_feature(FW_FEATURE_SPLPAR))
+ return false;
return !!(l->__old_status & LPPACA_OLD_SHARED_PROC);
}
diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h
index b9ebc3085fb7..72dc4ddc2972 100644
--- a/arch/powerpc/include/asm/spinlock.h
+++ b/arch/powerpc/include/asm/spinlock.h
@@ -56,6 +56,8 @@
#define vcpu_is_preempted vcpu_is_preempted
static inline bool vcpu_is_preempted(int cpu)
{
+ if (!firmware_has_feature(FW_FEATURE_SPLPAR))
+ return false;
return !!(be32_to_cpu(lppaca_of(cpu).yield_count) & 1);
}
#endif
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index f7d96a68ecaa..360e71d455cc 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -266,6 +266,9 @@ void accumulate_stolen_time(void)
static inline u64 calculate_stolen_time(u64 stop_tb)
{
+ if (!firmware_has_feature(FW_FEATURE_SPLPAR))
+ return 0;
+
if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx))
return scan_dispatch_log(stop_tb);
--
2.14.3
^ permalink raw reply related
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