Re: [RFC PATCH v5 1/3] printk-rb: new printk ringbuffer implementation (writer)

2019-12-23 Thread John Ogness
Hi Andrea,

On 2019-12-21, Andrea Parri  wrote:
>> +*desc_out = READ_ONCE(*desc);
>> +
>> +/* Load data before re-checking state. */
>> +smp_rmb(); /* matches LMM_REF(desc_reserve:A) */
>
> I looked for a matching WRITE_ONCE() or some other type of marked write,
> but I could not find it.  What is the rationale?  Or what did I miss?

This smp_rmb() matches LMM_TAG(desc_reserve:A).

>> +do {
>> +next_lpos = get_next_lpos(data_ring, begin_lpos, size);
>> +
>> +if (!data_push_tail(rb, data_ring,
>> +next_lpos - DATA_SIZE(data_ring))) {
>> +/* Failed to allocate, specify a data-less block. */
>> +blk_lpos->begin = INVALID_LPOS;
>> +blk_lpos->next = INVALID_LPOS;
>> +return NULL;
>> +}
>> +} while (!atomic_long_try_cmpxchg(_ring->head_lpos, _lpos,
>> +  next_lpos));
>> +
>> +/*
>> + * No barrier is needed here. The data validity is defined by
>> + * the state of the associated descriptor. They are marked as
>> + * invalid at the moment. And only the winner of the above
>> + * cmpxchg() could write here.
>> + */
>
> The (successful) CMPXCHG provides a full barrier.  This comment suggests
> that that could be somehow relaxed?  Or the comment could be improved?

You are correct. There is no need for the full barrier here. This code
is based on Petr's POC. I focussed on making sure needed barriers are in
place, but did not try to eliminate excessive barriers.

> (The patch introduces a number of CMPXCHG: similar questions would
> apply to those other instances...)

LMM_TAG(data_push_tail:A) is the only CMPXCHG that requires its full
barrier. All others can be relaxed. I will make this change for the next
series.

Thanks for taking time for this.

John Ogness

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v7 4/4] kdump: update Documentation about crashkernel on arm64

2019-12-23 Thread Chen Zhou
Now we support crashkernel=X,[low] on arm64, update the Documentation.

Signed-off-by: Chen Zhou 
---
 Documentation/admin-guide/kdump/kdump.rst   | 13 +++--
 Documentation/admin-guide/kernel-parameters.txt | 12 +++-
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/kdump/kdump.rst 
b/Documentation/admin-guide/kdump/kdump.rst
index ac7e131..e55173e 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -299,7 +299,13 @@ Boot into System Kernel
"crashkernel=64M@16M" tells the system kernel to reserve 64 MB of memory
starting at physical address 0x0100 (16MB) for the dump-capture kernel.
 
-   On x86 and x86_64, use "crashkernel=64M@16M".
+   On x86 use "crashkernel=64M@16M".
+
+   On x86_64, use "crashkernel=Y[@X]" to select a region under 4G first, and
+   fall back to reserve region above 4G when '@offset' hasn't been specified.
+   We can also use "crashkernel=X,high" to select a region above 4G, which
+   also tries to allocate at least 256M below 4G automatically and
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
 
On ppc64, use "crashkernel=128M@32M".
 
@@ -316,8 +322,11 @@ Boot into System Kernel
kernel will automatically locate the crash kernel image within the
first 512MB of RAM if X is not given.
 
-   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
+   On arm64, use "crashkernel=Y[@X]". Note that the start address of
the kernel, X if explicitly specified, must be aligned to 2MiB (0x20).
+   If crashkernel=Z,low is specified simultaneously, reserve spcified size
+   low memory for crash kdump kernel devices firstly and then reserve memory
+   above 4G.
 
 Load the Dump-capture Kernel
 
diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index ade4e6e..bde3ab4 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -706,6 +706,9 @@
[KNL, x86_64] select a region under 4G first, and
fall back to reserve region above 4G when '@offset'
hasn't been specified.
+   [KNL, arm64] If crashkernel=X,low is specified, reserve
+   spcified size low memory for crash kdump kernel devices
+   firstly, and then reserve memory above 4G.
See Documentation/admin-guide/kdump/kdump.rst for 
further details.
 
crashkernel=range1:size1[,range2:size2,...][@offset]
@@ -730,12 +733,19 @@
requires at least 64M+32K low memory, also enough extra
low memory is needed to make sure DMA buffers for 32-bit
devices won't run out. Kernel would try to allocate at
-   at least 256M below 4G automatically.
+   least 256M below 4G automatically.
This one let user to specify own low range under 4G
for second kernel instead.
0: to disable low allocation.
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
+   [KNL, arm64] range under 4G.
+   This one let user to specify own low range under 4G
+   for crash dump kernel instead.
+   Different with x86_64, kernel allocates specified size
+   physical memory region only when this parameter is 
specified
+   instead of trying to allocate at least 256M below 4G
+   automatically.
 
cryptomgr.notests
[KNL] Disable crypto self-tests
-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v7 3/4] arm64: kdump: add memory for devices by DT property, low-memory-range

2019-12-23 Thread Chen Zhou
If we want to reserve crashkernel above 4G, we could use parameters
"crashkernel=X crashkernel=Y,low", in this case, specified size low
memory is reserved for crash dump kernel devices and never mapped by
the first kernel. This memory range is advertised to crash dump kernel
via DT property under /chosen,
linux,low-memory-range=

Crash dump kernel reads this property at boot time and call
memblock_add() after memblock_cap_memory_range() has been called.

Signed-off-by: Chen Zhou 
---
 arch/arm64/mm/init.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 0d7afd5..1c4a6ad 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -322,6 +322,26 @@ static int __init early_mem(char *p)
 }
 early_param("mem", early_mem);
 
+static int __init early_init_dt_scan_lowmem(unsigned long node,
+   const char *uname, int depth, void *data)
+{
+   struct memblock_region *lowmem = data;
+   const __be32 *reg;
+   int len;
+
+   if (depth != 1 || strcmp(uname, "chosen") != 0)
+   return 0;
+
+   reg = of_get_flat_dt_prop(node, "linux,low-memory-range", );
+   if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
+   return 1;
+
+   lowmem->base = dt_mem_next_cell(dt_root_addr_cells, );
+   lowmem->size = dt_mem_next_cell(dt_root_size_cells, );
+
+   return 1;
+}
+
 static int __init early_init_dt_scan_usablemem(unsigned long node,
const char *uname, int depth, void *data)
 {
@@ -352,13 +372,21 @@ static void __init fdt_enforce_memory_region(void)
 
if (reg.size)
memblock_cap_memory_range(reg.base, reg.size);
+
+   of_scan_flat_dt(early_init_dt_scan_lowmem, );
+
+   if (reg.size)
+   memblock_add(reg.base, reg.size);
 }
 
 void __init arm64_memblock_init(void)
 {
const s64 linear_region_size = BIT(vabits_actual - 1);
 
-   /* Handle linux,usable-memory-range property */
+   /*
+* Handle linux,usable-memory-range and linux,low-memory-range
+* properties.
+*/
fdt_enforce_memory_region();
 
/* Remove memory above our supported physical address size */
-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v7 1/4] x86: kdump: move reserve_crashkernel_low() into crash_core.c

2019-12-23 Thread Chen Zhou
In preparation for supporting reserve_crashkernel_low in arm64 as
x86_64 does, move reserve_crashkernel_low() into kernel/crash_core.c.

Note, in arm64, we reserve low memory if and only if crashkernel=X,low
is specified. Different with x86_64, don't set low memory automatically.

Reported-by: kbuild test robot 
Signed-off-by: Chen Zhou 
---
 arch/x86/kernel/setup.c| 62 -
 include/linux/crash_core.h |  3 ++
 include/linux/kexec.h  |  2 --
 kernel/crash_core.c| 87 ++
 kernel/kexec_core.c| 17 -
 5 files changed, 96 insertions(+), 75 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cedfe20..5f38942 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -486,59 +486,6 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
 # define CRASH_ADDR_HIGH_MAX   SZ_64T
 #endif
 
-static int __init reserve_crashkernel_low(void)
-{
-#ifdef CONFIG_X86_64
-   unsigned long long base, low_base = 0, low_size = 0;
-   unsigned long total_low_mem;
-   int ret;
-
-   total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
-
-   /* crashkernel=Y,low */
-   ret = parse_crashkernel_low(boot_command_line, total_low_mem, 
_size, );
-   if (ret) {
-   /*
-* two parts from kernel/dma/swiotlb.c:
-* -swiotlb size: user-specified with swiotlb= or default.
-*
-* -swiotlb overflow buffer: now hardcoded to 32k. We round it
-* to 8M for other buffers that may need to stay low too. Also
-* make sure we allocate enough extra low memory so that we
-* don't run out of DMA buffers for 32-bit devices.
-*/
-   low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL 
<< 20);
-   } else {
-   /* passed with crashkernel=0,low ? */
-   if (!low_size)
-   return 0;
-   }
-
-   low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
-   if (!low_base) {
-   pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
smaller size.\n",
-  (unsigned long)(low_size >> 20));
-   return -ENOMEM;
-   }
-
-   ret = memblock_reserve(low_base, low_size);
-   if (ret) {
-   pr_err("%s: Error reserving crashkernel low memblock.\n", 
__func__);
-   return ret;
-   }
-
-   pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System 
low RAM: %ldMB)\n",
-   (unsigned long)(low_size >> 20),
-   (unsigned long)(low_base >> 20),
-   (unsigned long)(total_low_mem >> 20));
-
-   crashk_low_res.start = low_base;
-   crashk_low_res.end   = low_base + low_size - 1;
-   insert_resource(_resource, _low_res);
-#endif
-   return 0;
-}
-
 static void __init reserve_crashkernel(void)
 {
unsigned long long crash_size, crash_base, total_mem;
@@ -602,9 +549,12 @@ static void __init reserve_crashkernel(void)
return;
}
 
-   if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
-   memblock_free(crash_base, crash_size);
-   return;
+   if (crash_base >= (1ULL << 32)) {
+   if (reserve_crashkernel_low()) {
+   memblock_free(crash_base, crash_size);
+   return;
+   }
+   insert_resource(_resource, _low_res);
}
 
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System 
RAM: %ldMB)\n",
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index 525510a..4df8c0b 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -63,6 +63,8 @@ phys_addr_t paddr_vmcoreinfo_note(void);
 extern unsigned char *vmcoreinfo_data;
 extern size_t vmcoreinfo_size;
 extern u32 *vmcoreinfo_note;
+extern struct resource crashk_res;
+extern struct resource crashk_low_res;
 
 Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
  void *data, size_t data_len);
@@ -74,5 +76,6 @@ int parse_crashkernel_high(char *cmdline, unsigned long long 
system_ram,
unsigned long long *crash_size, unsigned long long *crash_base);
 int parse_crashkernel_low(char *cmdline, unsigned long long system_ram,
unsigned long long *crash_size, unsigned long long *crash_base);
+int __init reserve_crashkernel_low(void);
 
 #endif /* LINUX_CRASH_CORE_H */
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 1776eb2..5d5d963 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -330,8 +330,6 @@ extern int kexec_load_disabled;
 
 /* Location of a reserved region to hold the crash kernel.
  */
-extern struct resource crashk_res;
-extern struct resource 

[PATCH v7 2/4] arm64: kdump: reserve crashkenel above 4G for crash dump kernel

2019-12-23 Thread Chen Zhou
Crashkernel=X tries to reserve memory for the crash dump kernel under
4G. If crashkernel=X,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G.

Signed-off-by: Chen Zhou 
---
 arch/arm64/kernel/setup.c |  8 +++-
 arch/arm64/mm/init.c  | 31 +--
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 56f6645..04d1c87 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -238,7 +238,13 @@ static void __init request_standard_resources(void)
kernel_data.end <= res->end)
request_resource(res, _data);
 #ifdef CONFIG_KEXEC_CORE
-   /* Userspace will find "Crash kernel" region in /proc/iomem. */
+   /*
+* Userspace will find "Crash kernel" region in /proc/iomem.
+* Note: the low region is renamed as Crash kernel (low).
+*/
+   if (crashk_low_res.end && crashk_low_res.start >= res->start &&
+   crashk_low_res.end <= res->end)
+   request_resource(res, _low_res);
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
request_resource(res, _res);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index b65dffd..0d7afd5 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -80,6 +80,7 @@ static void __init reserve_crashkernel(void)
 {
unsigned long long crash_base, crash_size;
int ret;
+   phys_addr_t crash_max = arm64_dma32_phys_limit;
 
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
_size, _base);
@@ -87,12 +88,38 @@ static void __init reserve_crashkernel(void)
if (ret || !crash_size)
return;
 
+   ret = reserve_crashkernel_low();
+   if (!ret && crashk_low_res.end) {
+   /*
+* If crashkernel=X,low specified, there may be two regions,
+* we need to make some changes as follows:
+*
+* 1. rename the low region as "Crash kernel (low)"
+* In order to distinct from the high region and make no effect
+* to the use of existing kexec-tools, rename the low region as
+* "Crash kernel (low)".
+*
+* 2. change the upper bound for crash memory
+* Set MEMBLOCK_ALLOC_ACCESSIBLE upper bound for crash memory.
+*
+* 3. mark the low region as "nomap"
+* The low region is intended to be used for crash dump kernel
+* devices, just mark the low region as "nomap" simply.
+*/
+   const char *rename = "Crash kernel (low)";
+
+   crashk_low_res.name = rename;
+   crash_max = MEMBLOCK_ALLOC_ACCESSIBLE;
+   memblock_mark_nomap(crashk_low_res.start,
+   resource_size(_low_res));
+   }
+
crash_size = PAGE_ALIGN(crash_size);
 
if (crash_base == 0) {
/* Current arm64 boot protocol requires 2MB alignment */
-   crash_base = memblock_find_in_range(0, arm64_dma32_phys_limit,
-   crash_size, SZ_2M);
+   crash_base = memblock_find_in_range(0, crash_max, crash_size,
+   SZ_2M);
if (crash_base == 0) {
pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v7 0/4] support reserving crashkernel above 4G on arm64 kdump

2019-12-23 Thread Chen Zhou
This patch series enable reserving crashkernel above 4G in arm64.

There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which will fail
when there is no enough low memory.
2. Currently, crashkernel=Y@X can be used to reserve crashkernel above 4G,
in this case, if swiotlb or DMA buffers are required, crash dump kernel
will boot failure because there is no low memory available for allocation.

To solve these issues, introduce crashkernel=X,low to reserve specified
size low memory.
Crashkernel=X tries to reserve memory for the crash dump kernel under
4G. If crashkernel=Y,low is specified simultaneously, reserve spcified
size low memory for crash kdump kernel devices firstly and then reserve
memory above 4G.

When crashkernel is reserved above 4G in memory, that is, crashkernel=X,low
is specified simultaneously, kernel should reserve specified size low memory
for crash dump kernel devices. So there may be two crash kernel regions, one
is below 4G, the other is above 4G.
In order to distinct from the high region and make no effect to the use of
kexec-tools, rename the low region as "Crash kernel (low)", and add DT property
"linux,low-memory-range" to crash dump kernel's dtb to pass the low region.

Besides, we need to modify kexec-tools:
arm64: kdump: add another DT property to crash dump kernel's dtb(see [1])

The previous changes and discussions can be retrieved from:

Changes since [v6]
- Fix build errors reported by kbuild test robot.

Changes since [v5]
- Move reserve_crashkernel_low() into kernel/crash_core.c.
- Delete crashkernel=X,high.
- Modify crashkernel=X,low.
If crashkernel=X,low is specified simultaneously, reserve spcified size low
memory for crash kdump kernel devices firstly and then reserve memory above 4G.
In addition, rename crashk_low_res as "Crash kernel (low)" for arm64, and then
pass to crash dump kernel by DT property "linux,low-memory-range".
- Update Documentation/admin-guide/kdump/kdump.rst.

Changes since [v4]
- Reimplement memblock_cap_memory_ranges for multiple ranges by Mike.

Changes since [v3]
- Add memblock_cap_memory_ranges back for multiple ranges.
- Fix some compiling warnings.

Changes since [v2]
- Split patch "arm64: kdump: support reserving crashkernel above 4G" as
two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
patch.

Changes since [v1]:
- Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
- Remove memblock_cap_memory_ranges() i added in v1 and implement that
in fdt_enforce_memory_region().
There are at most two crash kernel regions, for two crash kernel regions
case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
and then remove the memory range in the middle.

[1]: http://lists.infradead.org/pipermail/kexec/2019-August/023569.html
[v1]: https://lkml.org/lkml/2019/4/2/1174
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/9/306
[v4]: https://lkml.org/lkml/2019/4/15/273
[v5]: https://lkml.org/lkml/2019/5/6/1360
[v6]: https://lkml.org/lkml/2019/8/30/142

Chen Zhou (4):
  x86: kdump: move reserve_crashkernel_low() into crash_core.c
  arm64: kdump: reserve crashkenel above 4G for crash dump kernel
  arm64: kdump: add memory for devices by DT property, low-memory-range
  kdump: update Documentation about crashkernel on arm64

 Documentation/admin-guide/kdump/kdump.rst   | 13 +++-
 Documentation/admin-guide/kernel-parameters.txt | 12 +++-
 arch/arm64/kernel/setup.c   |  8 ++-
 arch/arm64/mm/init.c| 61 -
 arch/x86/kernel/setup.c | 62 ++
 include/linux/crash_core.h  |  3 +
 include/linux/kexec.h   |  2 -
 kernel/crash_core.c | 87 +
 kernel/kexec_core.c | 17 -
 9 files changed, 183 insertions(+), 82 deletions(-)

-- 
2.7.4


___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec