Re: [PATCH linux-next 3/3] powerpc/kdump: Split KEXEC_CORE and CRASH_DUMP dependency

2024-02-22 Thread Sourabh Jain

Hello Hari,

Build failure detected.

On 13/02/24 17:01, Hari Bathini wrote:

Remove CONFIG_CRASH_DUMP dependency on CONFIG_KEXEC. CONFIG_KEXEC_CORE
was used at places where CONFIG_CRASH_DUMP or CONFIG_CRASH_RESERVE was
appropriate. Replace with appropriate #ifdefs to support CONFIG_KEXEC
and !CONFIG_CRASH_DUMP configuration option. Also, make CONFIG_FA_DUMP
dependent on CONFIG_CRASH_DUMP to avoid unmet dependencies for FA_DUMP
with !CONFIG_KEXEC_CORE configuration option.

Signed-off-by: Hari Bathini 
---
  arch/powerpc/Kconfig   |  9 +--
  arch/powerpc/include/asm/kexec.h   | 98 +++---
  arch/powerpc/kernel/prom.c |  2 +-
  arch/powerpc/kernel/setup-common.c |  2 +-
  arch/powerpc/kernel/smp.c  |  4 +-
  arch/powerpc/kexec/Makefile|  3 +-
  arch/powerpc/kexec/core.c  |  4 ++
  7 files changed, 60 insertions(+), 62 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5cf8ad8d7e8e..e377deefa2dc 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -607,11 +607,6 @@ config PPC64_SUPPORTS_MEMORY_FAILURE
  config ARCH_SUPPORTS_KEXEC
def_bool PPC_BOOK3S || PPC_E500 || (44x && !SMP)
  
-config ARCH_SELECTS_KEXEC

-   def_bool y
-   depends on KEXEC
-   select CRASH_DUMP
-
  config ARCH_SUPPORTS_KEXEC_FILE
def_bool PPC64
  
@@ -622,7 +617,6 @@ config ARCH_SELECTS_KEXEC_FILE

def_bool y
depends on KEXEC_FILE
select KEXEC_ELF
-   select CRASH_DUMP
select HAVE_IMA_KEXEC if IMA
  
  config PPC64_BIG_ENDIAN_ELF_ABI_V2

@@ -694,8 +688,7 @@ config ARCH_SELECTS_CRASH_DUMP
  
  config FA_DUMP

bool "Firmware-assisted dump"
-   depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
-   select CRASH_DUMP
+   depends on CRASH_DUMP && PPC64 && (PPC_RTAS || PPC_POWERNV)
help
  A robust mechanism to get reliable kernel crash dump with
  assistance from firmware. This approach does not use kexec,
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index e1b43aa12175..fdb90e24dc74 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -55,59 +55,18 @@
  typedef void (*crash_shutdown_t)(void);
  
  #ifdef CONFIG_KEXEC_CORE

-
-/*
- * This function is responsible for capturing register states if coming
- * via panic or invoking dump using sysrq-trigger.
- */
-static inline void crash_setup_regs(struct pt_regs *newregs,
-   struct pt_regs *oldregs)
-{
-   if (oldregs)
-   memcpy(newregs, oldregs, sizeof(*newregs));
-   else
-   ppc_save_regs(newregs);
-}
+struct kimage;
+struct pt_regs;
  
  extern void kexec_smp_wait(void);	/* get and clear naca physid, wait for

  master to copy new code to 0 */
-extern int crashing_cpu;
-extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *));
-extern void crash_ipi_callback(struct pt_regs *);
-extern int crash_wake_offline;
-
-struct kimage;
-struct pt_regs;
  extern void default_machine_kexec(struct kimage *image);
-extern void default_machine_crash_shutdown(struct pt_regs *regs);
-extern int crash_shutdown_register(crash_shutdown_t handler);
-extern int crash_shutdown_unregister(crash_shutdown_t handler);
-
-extern void crash_kexec_prepare(void);
-extern void crash_kexec_secondary(struct pt_regs *regs);
-int __init overlaps_crashkernel(unsigned long start, unsigned long size);
-extern void reserve_crashkernel(void);
  extern void machine_kexec_mask_interrupts(void);
  
-static inline bool kdump_in_progress(void)

-{
-   return crashing_cpu >= 0;
-}
-
  void relocate_new_kernel(unsigned long indirection_page, unsigned long 
reboot_code_buffer,
 unsigned long start_address) __noreturn;
-
  void kexec_copy_flush(struct kimage *image);
  
-#if defined(CONFIG_CRASH_DUMP)

-bool is_kdump_kernel(void);
-#define is_kdump_kernelis_kdump_kernel
-#if defined(CONFIG_PPC_RTAS)
-void crash_free_reserved_phys_range(unsigned long begin, unsigned long end);
-#define crash_free_reserved_phys_range crash_free_reserved_phys_range
-#endif /* CONFIG_PPC_RTAS */
-#endif /* CONFIG_CRASH_DUMP */
-
  #ifdef CONFIG_KEXEC_FILE
  extern const struct kexec_file_ops kexec_elf64_ops;
  
@@ -152,15 +111,56 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
  
  #endif /* CONFIG_KEXEC_FILE */
  
-#else /* !CONFIG_KEXEC_CORE */

-static inline void crash_kexec_secondary(struct pt_regs *regs) { }
+#endif /* CONFIG_KEXEC_CORE */
+
+#ifdef CONFIG_CRASH_RESERVE
+int __init overlaps_crashkernel(unsigned long start, unsigned long size);
+extern void reserve_crashkernel(void);
+#else
+static inline void reserve_crashkernel(void) {}
+static inline int overlaps_crashkernel(unsigned long start, unsigned long 
size) { return 0; }
+#endif
  
-static inline int overlaps_crashkernel(unsigned 

Re: [PATCHv9 2/3] irq: use a struct for the kstat_irqs in the interrupt descriptor

2024-02-22 Thread Thomas Gleixner
On Fri, Feb 23 2024 at 15:18, Bitao Hu wrote:
> On 2024/2/22 21:22, Thomas Gleixner wrote:
>>> -   if (desc->kstat_irqs) {
>>> -   for_each_online_cpu(j)
>>> -   any_count |= data_race(*per_cpu_ptr(desc->kstat_irqs, 
>>> j));
>>> -   }
>>> +   if (desc->kstat_irqs)
>>> +   any_count = data_race(desc->tot_count);
>> 
>> This is an unrelated change and needs to be split out into a separate
>> patch with a proper changelog which explains why this is equivalent.
>> 
>
> Alright, I will remove this change witch is not related to the purpose
> of this patch.
>
> I guess that the purpose of suggesting this change in your V1 response
> was to speedup the 'show_interrupts'. However, after reviewing the
> usage of 'desc->tot_count' in 'unsigned int kstat_irqs(unsigned int 
> irq)', I think the change might be as follows:
>
> diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
> index 623b8136e9af..53b8d6edd7ac 100644
> --- a/kernel/irq/proc.c
> +++ b/kernel/irq/proc.c
> @@ -489,8 +489,13 @@ int show_interrupts(struct seq_file *p, void *v)
>  goto outsparse;
>
>  if (desc->kstat_irqs) {
> -   for_each_online_cpu(j)
> -   any_count |= 
> data_race(per_cpu(desc->kstat_irqs->cnt, j));
> +   if (!irq_settings_is_per_cpu_devid(desc) &&
> +   !irq_settings_is_per_cpu(desc) &&
> +   !irq_is_nmi(desc))
> +   any_count = data_race(desc->tot_count);
> +   else
> +   for_each_online_cpu(j)
> +   any_count |= 
> data_race(per_cpu(desc->kstat_irqs->cnt, j));
>  }
>
>  if ((!desc->action || irq_desc_is_chained(desc)) && !any_count)
>
> Is my idea correct?

Yes.


Re: [PATCHv9 2/3] irq: use a struct for the kstat_irqs in the interrupt descriptor

2024-02-22 Thread Bitao Hu

Hi,

On 2024/2/22 21:22, Thomas Gleixner wrote:

On Thu, Feb 22 2024 at 17:34, Bitao Hu wrote:

First of all the subsystem prefix is 'genirq:'. 'git log kernel/irq/'
gives you a pretty good hint. It's documented

Secondly the subject line does not match what this patch is about. It's
not about using a struct, it's about providing a snapshot mechanism, no?


The current implementation uses an int for the kstat_irqs in the
interrupt descriptor.

However, we need to know the number of interrupts which happened
since softlockup detection took a snapshot in order to analyze
the problem caused by an interrupt storm.

Replacing an int with a struct and providing sensible interfaces
for the watchdog code can keep it self contained to the interrupt
core code.


So something like this makes a useful change log for this:

  Subject: genirq: Provide a snapshot mechanism for interrupt statistics

  The soft lockup detector lacks a mechanism to identify interrupt storms
  as root cause of a lockup. To enable this the detector needs a
  mechanism to snapshot the interrupt count statistics on a CPU when the
  detector observes a potential lockup scenario and compare that against
  the interrupt count when it warns about the lockup later on. The number
  of interrupts in that period give a hint whether the lockup might be
  caused by an interrupt storm.

  Instead of having extra storage in the lockup detector and accessing
  the internals of the interrupt descriptor directly, convert the per CPU
  irq_desc::kstat_irq member to a data structure which contains the
  counter plus a snapshot member and provide interfaces to take a
  snapshot of all interrupts on the current CPU and to retrieve the delta
  of a specific interrupt later on.


Thanks, the changelog you wrote very clearly articulates the purpose of
this patch.


Hmm?


Signed-off-by: Bitao Hu 


Interesting. You fully authored the patch?

That's not how it works. You cannot take work from others and claim that
it is yours. The minimal courtesy is to add a 'Originally-by:' tag.


I'm very sorry, the majority of this patch is your work, I will add an
'Originally-by:' tag.


diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 623b8136e9af..3ad40cf30c66 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -488,18 +488,15 @@ int show_interrupts(struct seq_file *p, void *v)
if (!desc || irq_settings_is_hidden(desc))
goto outsparse;
  
-	if (desc->kstat_irqs) {

-   for_each_online_cpu(j)
-   any_count |= data_race(*per_cpu_ptr(desc->kstat_irqs, 
j));
-   }
+   if (desc->kstat_irqs)
+   any_count = data_race(desc->tot_count);


This is an unrelated change and needs to be split out into a separate
patch with a proper changelog which explains why this is equivalent.



Alright, I will remove this change witch is not related to the purpose
of this patch.

I guess that the purpose of suggesting this change in your V1 response
was to speedup the 'show_interrupts'. However, after reviewing the
usage of 'desc->tot_count' in 'unsigned int kstat_irqs(unsigned int 
irq)', I think the change might be as follows:


diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 623b8136e9af..53b8d6edd7ac 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -489,8 +489,13 @@ int show_interrupts(struct seq_file *p, void *v)
goto outsparse;

if (desc->kstat_irqs) {
-   for_each_online_cpu(j)
-   any_count |= 
data_race(per_cpu(desc->kstat_irqs->cnt, j));

+   if (!irq_settings_is_per_cpu_devid(desc) &&
+   !irq_settings_is_per_cpu(desc) &&
+   !irq_is_nmi(desc))
+   any_count = data_race(desc->tot_count);
+   else
+   for_each_online_cpu(j)
+   any_count |= 
data_race(per_cpu(desc->kstat_irqs->cnt, j));

}

if ((!desc->action || irq_desc_is_chained(desc)) && !any_count)

Is my idea correct?

Best Regards,
Bitao


Re: [kvm-unit-tests PATCH v5 0/8] Multi-migration support

2024-02-22 Thread Thomas Huth

On 21/02/2024 04.27, Nicholas Piggin wrote:

Now that strange arm64 hang is found to be QEMU bug, I'll repost.
Since arm64 requires Thomas's uart patch and it is worse affected
by the QEMU bug, I will just not build it on arm. The QEMU bug
still affects powerpc (and presumably s390x) but it's not causing
so much trouble for this test case.

I have another test case that can hit it reliably and doesn't
cause crashes but that takes some harness and common lib work so
I'll send that another time.

Since v4:
- Don't build selftest-migration on arm.
- Reduce selftest-migration iterations from 100 to 30 to make the
   test run faster (it's ~0.5s per migration).


Thanks, I think the series is ready to go now ... we just have to wait for 
your QEMU TCG migration fix to get merged first. Or should we maybe mark the 
selftest-migration with "accel = kvm" for now and remove that line later 
once QEMU has been fixed?


 Thomas




Re: "test_ip_fast_csum: ASSERTION FAILED at lib/checksum_kunit.c:589" at boot with CONFIG_CHECKSUM_KUNIT=y enabled on a Talos II, kernel 6.8-rc5

2024-02-22 Thread Christophe Leroy


Le 23/02/2024 à 07:12, Charlie Jenkins a écrit :
> On Fri, Feb 23, 2024 at 05:59:07AM +, Christophe Leroy wrote:
>> Hi Erhard, hi Charlie,
>>
>> Le 23/02/2024 à 02:26, Erhard Furtner a écrit :
>>> Greetings!
>>>
>>> Looks like my Talos II (running a BE kernel+system) fails some of the 
>>> kernels internal unit tests. One of the failing tests is checksum_kunit, 
>>> enabled via CONFIG_CHECKSUM_KUNIT=y:
>>>
>>> [...]
>>>  KTAP version 1
>>>   # Subtest: checksum
>>>   # module: checksum_kunit
>>>   1..5
>>> entry-flush: disabled on command line.
>>>   ok 1 test_csum_fixed_random_inputs
>>>   ok 2 test_csum_all_carry_inputs
>>>   ok 3 test_csum_no_carry_inputs
>>>   # test_ip_fast_csum: ASSERTION FAILED at lib/checksum_kunit.c:589
>>>   Expected ( u64)expected == ( u64)csum_result, but
>>>   ( u64)expected == 55939 (0xda83)
>>>   ( u64)csum_result == 33754 (0x83da)
>>>   not ok 4 test_ip_fast_csum
>>>   # test_csum_ipv6_magic: ASSERTION FAILED at lib/checksum_kunit.c:617
>>>   Expected ( u64)expected_csum_ipv6_magic[i] == ( 
>>> u64)csum_ipv6_magic(saddr, daddr, len, proto, csum), but
>>>   ( u64)expected_csum_ipv6_magic[i] == 6356 (0x18d4)
>>>   ( u64)csum_ipv6_magic(saddr, daddr, len, proto, csum) == 43586 
>>> (0xaa42)
>>>   not ok 5 test_csum_ipv6_magic
>>> # checksum: pass:3 fail:2 skip:0 total:5
>>> # Totals: pass:3 fail:2 skip:0 total:5
>>> not ok 4 checksum
>>> [...]
>>>
>>> Full dmesg + kernel .config attached.
>>
>> Looks like the same problem as the one I fixed with commit b38460bc463c
>> ("kunit: Fix checksum tests on big endian CPUs")
>>
>> The new tests implemented through commit 6f4c45cbcb00 ("kunit: Add tests
>> for csum_ipv6_magic and ip_fast_csum") create a lot of type issues as
>> reported by sparse when built with C=2 (see below).
>>
>> Once those issues are fixed, it should work.
>>
>> Charlie, can you provide a fix ?
>>
>> Thanks,
>> Christophe
> 
> The "lib: checksum: Fix issues with checksum tests" patch should fix all of 
> these issues [1].
> 
> [1] 
> https://lore.kernel.org/all/20240221-fix_sparse_errors_checksum_tests-v9-1-bff4d73ab...@rivosinc.com/T/#m189783a9b2a7d12e3c34c4a412e65408658db2c9

It doesn't fix the issues, I still get the following with your patch 1/2 
applied:

[6.893141] KTAP version 1
[6.896118] 1..1
[6.897764] KTAP version 1
[6.900800] # Subtest: checksum
[6.904518] # module: checksum_kunit
[6.904601] 1..5
[7.139784] ok 1 test_csum_fixed_random_inputs
[7.590056] ok 2 test_csum_all_carry_inputs
[8.064415] ok 3 test_csum_no_carry_inputs
[8.070065] # test_ip_fast_csum: ASSERTION FAILED at 
lib/checksum_kunit.c:589
[8.070065] Expected ( u64)expected == ( u64)csum_result, but
[8.070065] ( u64)expected == 55939 (0xda83)
[8.070065] ( u64)csum_result == 33754 (0x83da)
[8.075836] not ok 4 test_ip_fast_csum
[8.101039] # test_csum_ipv6_magic: ASSERTION FAILED at 
lib/checksum_kunit.c:617
[8.101039] Expected ( u64)( __sum16)expected_csum_ipv6_magic[i] 
== ( u64)csum_ipv6_magic(saddr, daddr, len, proto, ( __wsum)csum), but
[8.101039] ( u64)( __sum16)expected_csum_ipv6_magic[i] == 
6356 (0x18d4)
[8.101039] ( u64)csum_ipv6_magic(saddr, daddr, len, proto, ( 
__wsum)csum) == 43586 (0xaa42)
[8.106446] not ok 5 test_csum_ipv6_magic
[8.143829] # checksum: pass:3 fail:2 skip:0 total:5
[8.148334] # Totals: pass:3 fail:2 skip:0 total:5
[8.153173] not ok 1 checksum

All your patch does is to hide the sparse warnings. But forcing a cast 
doesn't fix byte orders.

Please have a look at commit b38460bc463c ("kunit: Fix checksum tests on 
big endian CPUs"), there are helpers to put checksums in the correct 
byte order.

Christophe


Re: [PATCH 1/2] powerpc: Refactor __kernel_map_pages()

2024-02-22 Thread Michael Ellerman
Christophe Leroy  writes:
> Le 22/02/2024 à 06:32, Michael Ellerman a écrit :
>> Christophe Leroy  writes:
>>> __kernel_map_pages() is almost identical for PPC32 and RADIX.
>>>
>>> Refactor it.
>>>
>>> On PPC32 it is not needed for KFENCE, but to keep it simple
>>> just make it similar to PPC64.
>>>
>>> Signed-off-by: Christophe Leroy 
>>> ---
>>>   arch/powerpc/include/asm/book3s/64/pgtable.h | 10 --
>>>   arch/powerpc/include/asm/book3s/64/radix.h   |  2 --
>>>   arch/powerpc/mm/book3s64/radix_pgtable.c | 14 --
>>>   arch/powerpc/mm/pageattr.c   | 19 +++
>>>   arch/powerpc/mm/pgtable_32.c | 15 ---
>>>   5 files changed, 19 insertions(+), 41 deletions(-)
>>>
>>> diff --git a/arch/powerpc/mm/pageattr.c b/arch/powerpc/mm/pageattr.c
>>> index 421db7c4f2a4..16b8d20d6ca8 100644
>>> --- a/arch/powerpc/mm/pageattr.c
>>> +++ b/arch/powerpc/mm/pageattr.c
>>> @@ -101,3 +101,22 @@ int change_memory_attr(unsigned long addr, int 
>>> numpages, long action)
>>> return apply_to_existing_page_range(_mm, start, size,
>>> change_page_attr, (void *)action);
>>>   }
>>> +
>>> +#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE)
>>> +#ifdef CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC
>>> +void __kernel_map_pages(struct page *page, int numpages, int enable)
>>> +{
>>> +   unsigned long addr = (unsigned long)page_address(page);
>>> +
>>> +   if (PageHighMem(page))
>>> +   return;
>>> +
>>> +   if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !radix_enabled())
>>> +   hash__kernel_map_pages(page, numpages, enable);
>>> +   else if (enable)
>>> +   set_memory_p(addr, numpages);
>>> +   else
>>> +   set_memory_np(addr, numpages);
>>> +}
>> 
>> This doesn't build on 32-bit, eg. ppc32_allmodconfig:
>> 
>> ../arch/powerpc/mm/pageattr.c: In function '__kernel_map_pages':
>> ../arch/powerpc/mm/pageattr.c:116:23: error: implicit declaration of 
>> function 'hash__kernel_map_pages' [-Werror=implicit-function-declaration]
>>116 | err = hash__kernel_map_pages(page, numpages, 
>> enable);
>>|   ^~
>> 
>> I couldn't see a nice way to get around it, so ended up with:
>> 
>> void __kernel_map_pages(struct page *page, int numpages, int enable)
>> {
>>  int err;
>>  unsigned long addr = (unsigned long)page_address(page);
>> 
>>  if (PageHighMem(page))
>>  return;
>> 
>> #ifdef CONFIG_PPC_BOOK3S_64
>>  if (!radix_enabled())
>>  err = hash__kernel_map_pages(page, numpages, enable);
>>  else
>> #endif
>>  if (enable)
>>  err = set_memory_p(addr, numpages);
>>  else
>>  err = set_memory_np(addr, numpages);
>> 
>
>
> I missed something it seems. Not good to leave something unterminated 
> when you leave for vacation and think it was finished when you come back.
>
> The best solution I see is to move hash__kernel_map_pages() prototype 
> somewhere else.

> $ git grep -e hash__ -e radix__ -- arch/powerpc/include/asm/*.h
> arch/powerpc/include/asm/bug.h:void hash__do_page_fault(struct pt_regs *);
> arch/powerpc/include/asm/mmu.h:extern void radix__mmu_cleanup_all(void);
> arch/powerpc/include/asm/mmu_context.h:extern void 
> radix__switch_mmu_context(struct mm_struct *prev,
> arch/powerpc/include/asm/mmu_context.h: return 
> radix__switch_mmu_context(prev, next);
> arch/powerpc/include/asm/mmu_context.h:extern int 
> hash__alloc_context_id(void);
> arch/powerpc/include/asm/mmu_context.h:void __init 
> hash__reserve_context_id(int id);
> arch/powerpc/include/asm/mmu_context.h: context_id = hash__alloc_context_id();
> arch/powerpc/include/asm/mmu_context.h:  * radix__flush_all_mm() to determine 
> the scope (local/global)
> arch/powerpc/include/asm/mmu_context.h: radix__flush_all_mm(mm);

If anything I'd prefer to move those out of there into the book3s/64/
headers :)

> Maybe asm/mmu.h ?
>
> Or mm/mmu_decl.h ?

Yeah I'll do that. It's a bit of a dumping ground, but at least it's
internal to arch code, not exported to the rest of the kernel.

cheers


Re: [PATCH] powerpc/rtas: use correct function name for resetting TCE tables

2024-02-22 Thread Michael Ellerman
Nathan Lynch via B4 Relay 
writes:
> From: Nathan Lynch 
>
> The PAPR spec spells the function name as
>
>   "ibm,reset-pe-dma-windows"
>
> but in practice firmware uses the singular form:

Just to be clear, you're talking about IBM firmware on PowerVM machines.

>   "ibm,reset-pe-dma-window"
>
> in the device tree. Since we have the wrong spelling in the RTAS
> function table, reverse lookups (token -> name) fail and warn:
>
>   unexpected failed lookup for token 86
>   WARNING: CPU: 1 PID: 545 at arch/powerpc/kernel/rtas.c:659 
> __do_enter_rtas_trace+0x2a4/0x2b4
...
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index 7e793b503e29..8064d9c3de86 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -375,8 +375,13 @@ static struct rtas_function rtas_function_table[] 
> __ro_after_init = {
>   [RTAS_FNIDX__IBM_REMOVE_PE_DMA_WINDOW] = {
>   .name = "ibm,remove-pe-dma-window",
>   },
> - [RTAS_FNIDX__IBM_RESET_PE_DMA_WINDOWS] = {
> - .name = "ibm,reset-pe-dma-windows",
> + [RTAS_FNIDX__IBM_RESET_PE_DMA_WINDOW] = {
> + /*
> +  * Note: PAPR+ v2.13 7.3.31.4.1 spells this as
> +  * "ibm,reset-pe-dma-windows" (plural), but RTAS
> +  * implementations use the singular form in practice.
> +  */
> + .name = "ibm,reset-pe-dma-window",

Qemu also spells it that way:

$ grep -C 12 ibm,reset-pe-dma-window hw/ppc/spapr_rtas_ddw.c
static void spapr_rtas_ddw_init(void)
{
spapr_rtas_register(RTAS_IBM_QUERY_PE_DMA_WINDOW,
"ibm,query-pe-dma-window",
rtas_ibm_query_pe_dma_window);
spapr_rtas_register(RTAS_IBM_CREATE_PE_DMA_WINDOW,
"ibm,create-pe-dma-window",
rtas_ibm_create_pe_dma_window);
spapr_rtas_register(RTAS_IBM_REMOVE_PE_DMA_WINDOW,
"ibm,remove-pe-dma-window",
rtas_ibm_remove_pe_dma_window);
spapr_rtas_register(RTAS_IBM_RESET_PE_DMA_WINDOW,
"ibm,reset-pe-dma-window",
rtas_ibm_reset_pe_dma_window);
}

There's no version in SLOF, it delegates to Qemu.

The old platforms that use RTAS won't implement this call at all, so
there's no issue with the naming there.

So LGTM.

cheers


Re: "test_ip_fast_csum: ASSERTION FAILED at lib/checksum_kunit.c:589" at boot with CONFIG_CHECKSUM_KUNIT=y enabled on a Talos II, kernel 6.8-rc5

2024-02-22 Thread Christophe Leroy
Hi Erhard, hi Charlie,

Le 23/02/2024 à 02:26, Erhard Furtner a écrit :
> Greetings!
> 
> Looks like my Talos II (running a BE kernel+system) fails some of the kernels 
> internal unit tests. One of the failing tests is checksum_kunit, enabled via 
> CONFIG_CHECKSUM_KUNIT=y:
> 
> [...]
> KTAP version 1
>  # Subtest: checksum
>  # module: checksum_kunit
>  1..5
> entry-flush: disabled on command line.
>  ok 1 test_csum_fixed_random_inputs
>  ok 2 test_csum_all_carry_inputs
>  ok 3 test_csum_no_carry_inputs
>  # test_ip_fast_csum: ASSERTION FAILED at lib/checksum_kunit.c:589
>  Expected ( u64)expected == ( u64)csum_result, but
>  ( u64)expected == 55939 (0xda83)
>  ( u64)csum_result == 33754 (0x83da)
>  not ok 4 test_ip_fast_csum
>  # test_csum_ipv6_magic: ASSERTION FAILED at lib/checksum_kunit.c:617
>  Expected ( u64)expected_csum_ipv6_magic[i] == ( 
> u64)csum_ipv6_magic(saddr, daddr, len, proto, csum), but
>  ( u64)expected_csum_ipv6_magic[i] == 6356 (0x18d4)
>  ( u64)csum_ipv6_magic(saddr, daddr, len, proto, csum) == 43586 
> (0xaa42)
>  not ok 5 test_csum_ipv6_magic
> # checksum: pass:3 fail:2 skip:0 total:5
> # Totals: pass:3 fail:2 skip:0 total:5
> not ok 4 checksum
> [...]
> 
> Full dmesg + kernel .config attached.

Looks like the same problem as the one I fixed with commit b38460bc463c 
("kunit: Fix checksum tests on big endian CPUs")

The new tests implemented through commit 6f4c45cbcb00 ("kunit: Add tests 
for csum_ipv6_magic and ip_fast_csum") create a lot of type issues as 
reported by sparse when built with C=2 (see below).

Once those issues are fixed, it should work.

Charlie, can you provide a fix ?

Thanks,
Christophe

   CC  lib/checksum_kunit.o
   CHECK   lib/checksum_kunit.c
lib/checksum_kunit.c:219:9: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:219:9:expected restricted __sum16
lib/checksum_kunit.c:219:9:got int
lib/checksum_kunit.c:219:17: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:219:17:expected restricted __sum16
lib/checksum_kunit.c:219:17:got int
lib/checksum_kunit.c:219:25: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:219:25:expected restricted __sum16
lib/checksum_kunit.c:219:25:got int
lib/checksum_kunit.c:219:33: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:219:33:expected restricted __sum16
lib/checksum_kunit.c:219:33:got int
lib/checksum_kunit.c:219:41: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:219:41:expected restricted __sum16
lib/checksum_kunit.c:219:41:got int
lib/checksum_kunit.c:219:49: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:219:49:expected restricted __sum16
lib/checksum_kunit.c:219:49:got int
lib/checksum_kunit.c:219:57: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:219:57:expected restricted __sum16
lib/checksum_kunit.c:219:57:got int
lib/checksum_kunit.c:219:65: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:219:65:expected restricted __sum16
lib/checksum_kunit.c:219:65:got int
lib/checksum_kunit.c:219:73: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:219:73:expected restricted __sum16
lib/checksum_kunit.c:219:73:got int
lib/checksum_kunit.c:220:9: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:220:9:expected restricted __sum16
lib/checksum_kunit.c:220:9:got int
lib/checksum_kunit.c:220:17: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:220:17:expected restricted __sum16
lib/checksum_kunit.c:220:17:got int
lib/checksum_kunit.c:220:25: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:220:25:expected restricted __sum16
lib/checksum_kunit.c:220:25:got int
lib/checksum_kunit.c:220:33: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:220:33:expected restricted __sum16
lib/checksum_kunit.c:220:33:got int
lib/checksum_kunit.c:220:41: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:220:41:expected restricted __sum16
lib/checksum_kunit.c:220:41:got int
lib/checksum_kunit.c:220:49: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:220:49:expected restricted __sum16
lib/checksum_kunit.c:220:49:got int
lib/checksum_kunit.c:220:57: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:220:57:expected restricted __sum16
lib/checksum_kunit.c:220:57:got int
lib/checksum_kunit.c:220:65: warning: incorrect type in initializer 
(different base types)
lib/checksum_kunit.c:220:65:  

Re: [PATCH v2 00/14] Split crash out from kexec and clean up related config items

2024-02-22 Thread Hari Bathini




On 23/02/24 2:59 am, Andrew Morton wrote:

On Thu, 22 Feb 2024 10:47:29 +0530 Hari Bathini  wrote:




On 22/02/24 2:27 am, Andrew Morton wrote:

On Wed, 21 Feb 2024 11:15:00 +0530 Hari Bathini  wrote:


On 04/02/24 8:56 am, Baoquan He wrote:

Hope Hari and Pingfan can help have a look, see if
it's doable. Now, I make it either have both kexec and crash enabled, or
disable both of them altogether.


Sure. I will take a closer look...

Thanks a lot. Please feel free to post patches to make that, or I can do
it with your support or suggestion.


Tested your changes and on top of these changes, came up with the below
changes to get it working for powerpc:

   
https://lore.kernel.org/all/20240213113150.1148276-1-hbath...@linux.ibm.com/


So can we take it that you're OK with Baoquan's series as-is?


Hi Andrew,

If you mean

v3 (https://lore.kernel.org/all/20240124051254.67105-1-...@redhat.com/)
+
follow-up from Baoquan
(https://lore.kernel.org/all/Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv/)

Yes.



Can I add your Acked-by: and/or Tested-by: to the patches in this series?


Sure, Andrew.

Acked-by: Hari Bathini 

for..

Patches 1-5 & 8 in:

  https://lore.kernel.org/all/20240124051254.67105-1-...@redhat.com/

and this follow-up patch:

  https://lore.kernel.org/all/Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv/

Thanks
Hari


Re: [RESEND2 PATCH net v4 2/2] soc: fsl: qbman: Use raw spinlock for cgr_lock

2024-02-22 Thread Christophe Leroy


Le 22/02/2024 à 18:07, Sean Anderson a écrit :
> [Vous ne recevez pas souvent de courriers de sean.ander...@linux.dev. 
> Découvrez pourquoi ceci est important à 
> https://aka.ms/LearnAboutSenderIdentification ]
> 
> cgr_lock may be locked with interrupts already disabled by
> smp_call_function_single. As such, we must use a raw spinlock to avoid
> problems on PREEMPT_RT kernels. Although this bug has existed for a
> while, it was not apparent until commit ef2a8d5478b9 ("net: dpaa: Adjust
> queue depth on rate change") which invokes smp_call_function_single via
> qman_update_cgr_safe every time a link goes up or down.

Why a raw spinlock to avoid problems on PREEMPT_RT, can you elaborate ?

If the problem is that interrupts are already disabled, shouldn't you 
just change the spin_lock_irq() by spin_lock_irqsave() ?

Christophe


> 
> Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
> CC: sta...@vger.kernel.org
> Reported-by: Vladimir Oltean 
> Closes: https://lore.kernel.org/all/20230323153935.nofnjucqjqnz34ej@skbuf/
> Reported-by: Steffen Trumtrar 
> Closes: 
> https://lore.kernel.org/linux-arm-kernel/87wmsyvclu@pengutronix.de/
> Signed-off-by: Sean Anderson 
> Reviewed-by: Camelia Groza 
> Tested-by: Vladimir Oltean 
> 
> ---
> 
> Changes in v4:
> - Add a note about how raw spinlocks aren't quite right
> 
> Changes in v3:
> - Change blamed commit to something more appropriate
> 
>   drivers/soc/fsl/qbman/qman.c | 25 ++---
>   1 file changed, 14 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
> index 1bf1f1ea67f0..7e9074519ad2 100644
> --- a/drivers/soc/fsl/qbman/qman.c
> +++ b/drivers/soc/fsl/qbman/qman.c
> @@ -991,7 +991,7 @@ struct qman_portal {
>  /* linked-list of CSCN handlers. */
>  struct list_head cgr_cbs;
>  /* list lock */
> -   spinlock_t cgr_lock;
> +   raw_spinlock_t cgr_lock;
>  struct work_struct congestion_work;
>  struct work_struct mr_work;
>  char irqname[MAX_IRQNAME];
> @@ -1281,7 +1281,7 @@ static int qman_create_portal(struct qman_portal 
> *portal,
>  /* if the given mask is NULL, assume all CGRs can be seen */
>  qman_cgrs_fill(>cgrs[0]);
>  INIT_LIST_HEAD(>cgr_cbs);
> -   spin_lock_init(>cgr_lock);
> +   raw_spin_lock_init(>cgr_lock);
>  INIT_WORK(>congestion_work, qm_congestion_task);
>  INIT_WORK(>mr_work, qm_mr_process_task);
>  portal->bits = 0;
> @@ -1456,11 +1456,14 @@ static void qm_congestion_task(struct work_struct 
> *work)
>  union qm_mc_result *mcr;
>  struct qman_cgr *cgr;
> 
> -   spin_lock_irq(>cgr_lock);
> +   /*
> +* FIXME: QM_MCR_TIMEOUT is 10ms, which is too long for a raw 
> spinlock!
> +*/
> +   raw_spin_lock_irq(>cgr_lock);
>  qm_mc_start(>p);
>  qm_mc_commit(>p, QM_MCC_VERB_QUERYCONGESTION);
>  if (!qm_mc_result_timeout(>p, )) {
> -   spin_unlock_irq(>cgr_lock);
> +   raw_spin_unlock_irq(>cgr_lock);
>  dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
>  qman_p_irqsource_add(p, QM_PIRQ_CSCI);
>  return;
> @@ -1476,7 +1479,7 @@ static void qm_congestion_task(struct work_struct *work)
>  list_for_each_entry(cgr, >cgr_cbs, node)
>  if (cgr->cb && qman_cgrs_get(, cgr->cgrid))
>  cgr->cb(p, cgr, qman_cgrs_get(, cgr->cgrid));
> -   spin_unlock_irq(>cgr_lock);
> +   raw_spin_unlock_irq(>cgr_lock);
>  qman_p_irqsource_add(p, QM_PIRQ_CSCI);
>   }
> 
> @@ -2440,7 +2443,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
>  preempt_enable();
> 
>  cgr->chan = p->config->channel;
> -   spin_lock_irq(>cgr_lock);
> +   raw_spin_lock_irq(>cgr_lock);
> 
>  if (opts) {
>  struct qm_mcc_initcgr local_opts = *opts;
> @@ -2477,7 +2480,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
>  qman_cgrs_get(>cgrs[1], cgr->cgrid))
>  cgr->cb(p, cgr, 1);
>   out:
> -   spin_unlock_irq(>cgr_lock);
> +   raw_spin_unlock_irq(>cgr_lock);
>  put_affine_portal();
>  return ret;
>   }
> @@ -2512,7 +2515,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
>  return -EINVAL;
> 
>  memset(_opts, 0, sizeof(struct qm_mcc_initcgr));
> -   spin_lock_irqsave(>cgr_lock, irqflags);
> +   raw_spin_lock_irqsave(>cgr_lock, irqflags);
>  list_del(>node);
>  /*
>   * If there are no other CGR objects for this CGRID in the list,
> @@ -2537,7 +2540,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
>  /* add back to the list */
>  list_add(>node, >cgr_cbs);
>   release_lock:
> -   spin_unlock_irqrestore(>cgr_lock, irqflags);
> +   raw_spin_unlock_irqrestore(>cgr_lock, 

Re: BUG: KASAN: vmalloc-out-of-bounds in memset32 (bpf_prog_pack_free)

2024-02-22 Thread Benjamin Gray
On Wed, 2024-01-31 at 11:46 +, Christophe Leroy wrote:
> Hi,
> 
> Got the following BUG while loading module test_bpf.ko
> 
> No time to investigate for now.
> 
> root@vgoip:~# insmod test_bpf.ko
> [  263.409030] 
> ==
> [  263.416415] BUG: KASAN: vmalloc-out-of-bounds in
> memset32+0x5c/0xa0
> [  263.422952] Write of size 4 at addr c9000e40 by task kworker/0:0/7
> [  263.429322]
> [  263.430816] CPU: 0 PID: 7 Comm: kworker/0:0 Not tainted 
> 6.8.0-rc1-s3k-dev-02364-gc626219462a6-dirty #606
> [  263.440580] Hardware name: MIAE 8xx 0x50 CMPC885
> [  263.445658] Workqueue: events bpf_prog_free_deferred
> [  263.450973] Call Trace:
> [  263.453411] [c905bd00] [c0c114e8] dump_stack_lvl+0x34/0x50
> (unreliable)
> [  263.460744] [c905bd20] [c026b9d4] print_report+0x174/0x608
> [  263.466853] [c905bd70] [c026c01c] kasan_report+0xc0/0x130
> [  263.472788] [c905bdd0] [c0c43cb0] memset32+0x5c/0xa0
> [  263.478198] [c905bdf0] [c0030690] patch_instructions+0x70/0x17c
> [  263.484656] [c905be30] [c00389b0]
> bpf_arch_text_invalidate+0xa8/0x120
> [  263.491638] [c905be90] [c018e63c] bpf_prog_pack_free+0xec/0x24c
> [  263.498096] [c905bec0] [c018ea34]
> bpf_jit_binary_pack_free+0x3c/0x80
> [  263.504991] [c905bee0] [c0038ae8] bpf_jit_free+0xc0/0x128
> [  263.510925] [c905bf00] [c00790f8] process_one_work+0x310/0x6e8
> [  263.517209] [c905bf50] [c0079b2c] worker_thread+0x65c/0x868
> [  263.523232] [c905bfc0] [c0084b78] kthread+0x17c/0x1ac
> [  263.528817] [c905bff0] [c00181fc] start_kernel_thread+0x10/0x14
> [  263.535279]
> [  263.536782] The buggy address belongs to the virtual mapping at
> [  263.536782]  [c900, c9008000) created by:
> [  263.536782]  text_area_cpu_up+0x28/0x1d4
> [  263.551418]
> [  263.552902] The buggy address belongs to the physical page:
> [  263.560228]
> [  263.561713] Memory state around the buggy address:
> [  263.566585]  c9000d00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
> f8 f8
> [  263.573307]  c9000d80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
> f8 f8
> [  263.580027] >c9000e00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
> f8 f8
> [  263.586677]    ^
> [  263.591370]  c9000e80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
> f8 f8
> [  263.598093]  c9000f00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
> f8 f8
> [  263.604743] 
> ==
> 
> Christophe
> 

Looks like a false positive. It's clearly in range of the poking
allocation after all. KASAN apparently leaves VM_ALLOC areas as
poisoned, expecting some kind of subsequent allocator to come and
unpoison specific parts. Except we call map_patch_area() instead of
whatever path generic code was expecting, so we never unpoison the
range. The issue would be pre-existing from the beginning, and gone
unnoticed because the original code path that does the patching (i.e.,
actually interacts with the poking page) isn't instrumented.


Re: [PATCH 2/3] arch: Remove struct fb_info from video helpers

2024-02-22 Thread kernel test robot
Hi Thomas,

kernel test robot noticed the following build errors:

[auto build test ERROR on tip/x86/core]
[also build test ERROR on deller-parisc/for-next arnd-asm-generic/master 
linus/master v6.8-rc5]
[cannot apply to next-20240222]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Thomas-Zimmermann/arch-Select-fbdev-helpers-with-CONFIG_VIDEO/20240222-001622
base:   tip/x86/core
patch link:
https://lore.kernel.org/r/20240221161431.8245-3-tzimmermann%40suse.de
patch subject: [PATCH 2/3] arch: Remove struct fb_info from video helpers
config: x86_64-rhel-8.3 
(https://download.01.org/0day-ci/archive/20240223/202402230941.jzdvhhex-...@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20240223/202402230941.jzdvhhex-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202402230941.jzdvhhex-...@intel.com/

All errors (new ones prefixed by >>):

   ld: vmlinux.o: in function `fbcon_select_primary':
>> drivers/video/fbdev/core/fbcon.c:2944: undefined reference to 
>> `video_is_primary_device'
   ld: vmlinux.o: in function `fb_io_mmap':
   drivers/video/fbdev/core/fb_io_fops.c:164: undefined reference to 
`pgprot_framebuffer'


vim +2944 drivers/video/fbdev/core/fbcon.c

  2939  
  2940  #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
  2941  static void fbcon_select_primary(struct fb_info *info)
  2942  {
  2943  if (!map_override && primary_device == -1 &&
> 2944  video_is_primary_device(info->device)) {
  2945  int i;
  2946  
  2947  printk(KERN_INFO "fbcon: %s (fb%i) is primary device\n",
  2948 info->fix.id, info->node);
  2949  primary_device = info->node;
  2950  
  2951  for (i = first_fb_vc; i <= last_fb_vc; i++)
  2952  con2fb_map_boot[i] = primary_device;
  2953  
  2954  if (con_is_bound(_con)) {
  2955  printk(KERN_INFO "fbcon: Remapping primary 
device, "
  2956 "fb%i, to tty %i-%i\n", info->node,
  2957 first_fb_vc + 1, last_fb_vc + 1);
  2958  info_idx = primary_device;
  2959  }
  2960  }
  2961  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


Re: [PATCH 3/3] arch: Rename fbdev header and source files

2024-02-22 Thread kernel test robot
Hi Thomas,

kernel test robot noticed the following build errors:

[auto build test ERROR on tip/x86/core]
[also build test ERROR on deller-parisc/for-next arnd-asm-generic/master 
linus/master v6.8-rc5]
[cannot apply to next-20240222]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Thomas-Zimmermann/arch-Select-fbdev-helpers-with-CONFIG_VIDEO/20240222-001622
base:   tip/x86/core
patch link:
https://lore.kernel.org/r/20240221161431.8245-4-tzimmermann%40suse.de
patch subject: [PATCH 3/3] arch: Rename fbdev header and source files
config: um-randconfig-002-20240222 
(https://download.01.org/0day-ci/archive/20240223/202402230737.e7gwpgup-...@intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 
edd4aee4dd9b5b98b2576a6f783e4086173d902a)
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20240223/202402230737.e7gwpgup-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202402230737.e7gwpgup-...@intel.com/

All errors (new ones prefixed by >>):

   /usr/bin/ld: warning: .tmp_vmlinux.kallsyms1 has a LOAD segment with RWX 
permissions
   /usr/bin/ld: drivers/video/fbdev/core/fb_io_fops.o: in function `fb_io_mmap':
>> drivers/video/fbdev/core/fb_io_fops.c:164: undefined reference to 
>> `pgprot_framebuffer'
   clang: error: linker command failed with exit code 1 (use -v to see 
invocation)


vim +164 drivers/video/fbdev/core/fb_io_fops.c

6b180f66c0dd62 Thomas Zimmermann 2023-09-27  140  
33253d9e01d405 Thomas Zimmermann 2023-11-27  141  int fb_io_mmap(struct fb_info 
*info, struct vm_area_struct *vma)
33253d9e01d405 Thomas Zimmermann 2023-11-27  142  {
33253d9e01d405 Thomas Zimmermann 2023-11-27  143unsigned long start = 
info->fix.smem_start;
33253d9e01d405 Thomas Zimmermann 2023-11-27  144u32 len = 
info->fix.smem_len;
33253d9e01d405 Thomas Zimmermann 2023-11-27  145unsigned long 
mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
33253d9e01d405 Thomas Zimmermann 2023-11-27  146  
b3e8813773c568 Thomas Zimmermann 2023-11-27  147if (info->flags & 
FBINFO_VIRTFB)
b3e8813773c568 Thomas Zimmermann 2023-11-27  148
fb_warn_once(info, "Framebuffer is not in I/O address space.");
b3e8813773c568 Thomas Zimmermann 2023-11-27  149  
33253d9e01d405 Thomas Zimmermann 2023-11-27  150/*
33253d9e01d405 Thomas Zimmermann 2023-11-27  151 * This can be either 
the framebuffer mapping, or if pgoff points
33253d9e01d405 Thomas Zimmermann 2023-11-27  152 * past it, the mmio 
mapping.
33253d9e01d405 Thomas Zimmermann 2023-11-27  153 */
33253d9e01d405 Thomas Zimmermann 2023-11-27  154if (vma->vm_pgoff >= 
mmio_pgoff) {
33253d9e01d405 Thomas Zimmermann 2023-11-27  155if 
(info->var.accel_flags)
33253d9e01d405 Thomas Zimmermann 2023-11-27  156return 
-EINVAL;
33253d9e01d405 Thomas Zimmermann 2023-11-27  157  
33253d9e01d405 Thomas Zimmermann 2023-11-27  158vma->vm_pgoff 
-= mmio_pgoff;
33253d9e01d405 Thomas Zimmermann 2023-11-27  159start = 
info->fix.mmio_start;
33253d9e01d405 Thomas Zimmermann 2023-11-27  160len = 
info->fix.mmio_len;
33253d9e01d405 Thomas Zimmermann 2023-11-27  161}
33253d9e01d405 Thomas Zimmermann 2023-11-27  162  
33253d9e01d405 Thomas Zimmermann 2023-11-27  163vma->vm_page_prot = 
vm_get_page_prot(vma->vm_flags);
33253d9e01d405 Thomas Zimmermann 2023-11-27 @164vma->vm_page_prot = 
pgprot_framebuffer(vma->vm_page_prot, vma->vm_start,
33253d9e01d405 Thomas Zimmermann 2023-11-27  165
   vma->vm_end, start);
33253d9e01d405 Thomas Zimmermann 2023-11-27  166  
33253d9e01d405 Thomas Zimmermann 2023-11-27  167return 
vm_iomap_memory(vma, start, len);
33253d9e01d405 Thomas Zimmermann 2023-11-27  168  }
33253d9e01d405 Thomas Zimmermann 2023-11-27  169  EXPORT_SYMBOL(fb_io_mmap);
33253d9e01d405 Thomas Zimmermann 2023-11-27  170  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


[PATCH] powerpc/rtas: use correct function name for resetting TCE tables

2024-02-22 Thread Nathan Lynch via B4 Relay
From: Nathan Lynch 

The PAPR spec spells the function name as

  "ibm,reset-pe-dma-windows"

but in practice firmware uses the singular form:

  "ibm,reset-pe-dma-window"

in the device tree. Since we have the wrong spelling in the RTAS
function table, reverse lookups (token -> name) fail and warn:

  unexpected failed lookup for token 86
  WARNING: CPU: 1 PID: 545 at arch/powerpc/kernel/rtas.c:659 
__do_enter_rtas_trace+0x2a4/0x2b4
  CPU: 1 PID: 545 Comm: systemd-udevd Not tainted 6.8.0-rc4 #30
  Hardware name: IBM,9105-22A POWER10 (raw) 0x800200 0xf06 of:IBM,FW1060.00 
(NL1060_028) hv:phyp pSeries
  NIP [c00417f0] __do_enter_rtas_trace+0x2a4/0x2b4
  LR [c00417ec] __do_enter_rtas_trace+0x2a0/0x2b4
  Call Trace:
   __do_enter_rtas_trace+0x2a0/0x2b4 (unreliable)
   rtas_call+0x1f8/0x3e0
   enable_ddw.constprop.0+0x4d0/0xc84
   dma_iommu_dma_supported+0xe8/0x24c
   dma_set_mask+0x5c/0xd8
   mlx5_pci_init.constprop.0+0xf0/0x46c [mlx5_core]
   probe_one+0xfc/0x32c [mlx5_core]
   local_pci_probe+0x68/0x12c
   pci_call_probe+0x68/0x1ec
   pci_device_probe+0xbc/0x1a8
   really_probe+0x104/0x570
   __driver_probe_device+0xb8/0x224
   driver_probe_device+0x54/0x130
   __driver_attach+0x158/0x2b0
   bus_for_each_dev+0xa8/0x120
   driver_attach+0x34/0x48
   bus_add_driver+0x174/0x304
   driver_register+0x8c/0x1c4
   __pci_register_driver+0x68/0x7c
   mlx5_init+0xb8/0x118 [mlx5_core]
   do_one_initcall+0x60/0x388
   do_init_module+0x7c/0x2a4
   init_module_from_file+0xb4/0x108
   idempotent_init_module+0x184/0x34c
   sys_finit_module+0x90/0x114

And oopses are possible when lockdep is enabled or the RTAS
tracepoints are active, since those paths dereference the result of
the lookup.

Use the correct spelling to match firmware's behavior, adjusting the
related constants to match.

Signed-off-by: Nathan Lynch 
Reported-by: Gaurav Batra 
Fixes: 8252b88294d2 ("powerpc/rtas: improve function information lookups")
---
 arch/powerpc/include/asm/rtas.h | 4 ++--
 arch/powerpc/kernel/rtas.c  | 9 +++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 9bb2210c8d44..065ffd1b2f8a 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -69,7 +69,7 @@ enum rtas_function_index {
RTAS_FNIDX__IBM_READ_SLOT_RESET_STATE,
RTAS_FNIDX__IBM_READ_SLOT_RESET_STATE2,
RTAS_FNIDX__IBM_REMOVE_PE_DMA_WINDOW,
-   RTAS_FNIDX__IBM_RESET_PE_DMA_WINDOWS,
+   RTAS_FNIDX__IBM_RESET_PE_DMA_WINDOW,
RTAS_FNIDX__IBM_SCAN_LOG_DUMP,
RTAS_FNIDX__IBM_SET_DYNAMIC_INDICATOR,
RTAS_FNIDX__IBM_SET_EEH_OPTION,
@@ -164,7 +164,7 @@ typedef struct {
 #define RTAS_FN_IBM_READ_SLOT_RESET_STATE 
rtas_fn_handle(RTAS_FNIDX__IBM_READ_SLOT_RESET_STATE)
 #define RTAS_FN_IBM_READ_SLOT_RESET_STATE2
rtas_fn_handle(RTAS_FNIDX__IBM_READ_SLOT_RESET_STATE2)
 #define RTAS_FN_IBM_REMOVE_PE_DMA_WINDOW  
rtas_fn_handle(RTAS_FNIDX__IBM_REMOVE_PE_DMA_WINDOW)
-#define RTAS_FN_IBM_RESET_PE_DMA_WINDOWS  
rtas_fn_handle(RTAS_FNIDX__IBM_RESET_PE_DMA_WINDOWS)
+#define RTAS_FN_IBM_RESET_PE_DMA_WINDOW   
rtas_fn_handle(RTAS_FNIDX__IBM_RESET_PE_DMA_WINDOW)
 #define RTAS_FN_IBM_SCAN_LOG_DUMP 
rtas_fn_handle(RTAS_FNIDX__IBM_SCAN_LOG_DUMP)
 #define RTAS_FN_IBM_SET_DYNAMIC_INDICATOR 
rtas_fn_handle(RTAS_FNIDX__IBM_SET_DYNAMIC_INDICATOR)
 #define RTAS_FN_IBM_SET_EEH_OPTION
rtas_fn_handle(RTAS_FNIDX__IBM_SET_EEH_OPTION)
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 7e793b503e29..8064d9c3de86 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -375,8 +375,13 @@ static struct rtas_function rtas_function_table[] 
__ro_after_init = {
[RTAS_FNIDX__IBM_REMOVE_PE_DMA_WINDOW] = {
.name = "ibm,remove-pe-dma-window",
},
-   [RTAS_FNIDX__IBM_RESET_PE_DMA_WINDOWS] = {
-   .name = "ibm,reset-pe-dma-windows",
+   [RTAS_FNIDX__IBM_RESET_PE_DMA_WINDOW] = {
+   /*
+* Note: PAPR+ v2.13 7.3.31.4.1 spells this as
+* "ibm,reset-pe-dma-windows" (plural), but RTAS
+* implementations use the singular form in practice.
+*/
+   .name = "ibm,reset-pe-dma-window",
},
[RTAS_FNIDX__IBM_SCAN_LOG_DUMP] = {
.name = "ibm,scan-log-dump",

---
base-commit: b22ea627225b53ec7ce25c19d6df9fa8217d1643
change-id: 20240222-rtas-fix-ibm-reset-pe-dma-window-745dd1824011

Best regards,
-- 
Nathan Lynch 



Re: [PATCH v4 3/5] lib/bitmap: Introduce bitmap_scatter() and bitmap_gather() helpers

2024-02-22 Thread Yury Norov
On Thu, Feb 22, 2024 at 05:49:59PM +0100, Herve Codina wrote:
> Hi Andy, Yury,
> 
> On Thu, 22 Feb 2024 17:39:27 +0200
> Andy Shevchenko  wrote:
> 
> ...
> > > + * bitmap_scatter() for the bitmap scatter detailed operations).  
> > 
> > > + * Suppose scattered computed using bitmap_scatter(scattered, src, mask, 
> > > n).
> > > + * The operation bitmap_gather(result, scattered, mask, n) leads to a 
> > > result
> > > + * equal or equivalent to src.  
> > 
> > This paragraph...
> > 
> > > + * The result can be 'equivalent' because bitmap_scatter() and 
> > > bitmap_gather()
> > > + * are not bijective.  
> > 
> > 
> > > + * The result and src values are equivalent in that sense that a call to
> > > + * bitmap_scatter(res, src, mask, n) and a call to bitmap_scatter(res, 
> > > result,
> > > + * mask, n) will lead to the same res value.  
> > 
> > ...seems duplicating this one.
> > 
> > I would drop the latter one.
> 
> I would like to give details about the 'equivalent' in this scatter/gather 
> case.

If you would like - please do! :)
 
> If Yury is ok, I can drop this last paragraph.

The original bitmap_onto() description is 3 times longer, and barely
that descriptive. I'm OK with your working and especially pictures.

Thanks,
Yury


Re: [PATCH v2 RESEND 2/5] sched/vtime: get rid of generic vtime_task_switch() implementation

2024-02-22 Thread Michael Ellerman
Alexander Gordeev  writes:
> The generic vtime_task_switch() implementation gets built only
> if __ARCH_HAS_VTIME_TASK_SWITCH is not defined, but requires an
> architecture to implement arch_vtime_task_switch() callback at
> the same time, which is confusing.
>
> Further, arch_vtime_task_switch() is implemented for 32-bit PowerPC
> architecture only and vtime_task_switch() generic variant is rather
> superfluous.
>
> Simplify the whole vtime_task_switch() wiring by moving the existing
> generic implementation to PowerPC.
>
> Reviewed-by: Frederic Weisbecker 
> Reviewed-by: Nicholas Piggin 
> Signed-off-by: Alexander Gordeev 
> ---
>  arch/powerpc/include/asm/cputime.h | 13 -
>  arch/powerpc/kernel/time.c | 22 ++
>  kernel/sched/cputime.c | 13 -
>  3 files changed, 22 insertions(+), 26 deletions(-)

Acked-by: Michael Ellerman  (powerpc)

cheers

> diff --git a/arch/powerpc/include/asm/cputime.h 
> b/arch/powerpc/include/asm/cputime.h
> index 4961fb38e438..aff858ca99c0 100644
> --- a/arch/powerpc/include/asm/cputime.h
> +++ b/arch/powerpc/include/asm/cputime.h
> @@ -32,23 +32,10 @@
>  #ifdef CONFIG_PPC64
>  #define get_accounting(tsk)  (_paca()->accounting)
>  #define raw_get_accounting(tsk)  (_paca->accounting)
> -static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
>  
>  #else
>  #define get_accounting(tsk)  (_thread_info(tsk)->accounting)
>  #define raw_get_accounting(tsk)  get_accounting(tsk)
> -/*
> - * Called from the context switch with interrupts disabled, to charge all
> - * accumulated times to the current process, and to prepare accounting on
> - * the next process.
> - */
> -static inline void arch_vtime_task_switch(struct task_struct *prev)
> -{
> - struct cpu_accounting_data *acct = get_accounting(current);
> - struct cpu_accounting_data *acct0 = get_accounting(prev);
> -
> - acct->starttime = acct0->starttime;
> -}
>  #endif
>  
>  /*
> diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
> index df20cf201f74..c0fdc6d94fee 100644
> --- a/arch/powerpc/kernel/time.c
> +++ b/arch/powerpc/kernel/time.c
> @@ -354,6 +354,28 @@ void vtime_flush(struct task_struct *tsk)
>   acct->hardirq_time = 0;
>   acct->softirq_time = 0;
>  }
> +
> +/*
> + * Called from the context switch with interrupts disabled, to charge all
> + * accumulated times to the current process, and to prepare accounting on
> + * the next process.
> + */
> +void vtime_task_switch(struct task_struct *prev)
> +{
> + if (is_idle_task(prev))
> + vtime_account_idle(prev);
> + else
> + vtime_account_kernel(prev);
> +
> + vtime_flush(prev);
> +
> + if (!IS_ENABLED(CONFIG_PPC64)) {
> + struct cpu_accounting_data *acct = get_accounting(current);
> + struct cpu_accounting_data *acct0 = get_accounting(prev);
> +
> + acct->starttime = acct0->starttime;
> + }
> +}
>  #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
>  
>  void __no_kcsan __delay(unsigned long loops)
> diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
> index af7952f12e6c..aa48b2ec879d 100644
> --- a/kernel/sched/cputime.c
> +++ b/kernel/sched/cputime.c
> @@ -424,19 +424,6 @@ static inline void irqtime_account_process_tick(struct 
> task_struct *p, int user_
>   */
>  #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
>  
> -# ifndef __ARCH_HAS_VTIME_TASK_SWITCH
> -void vtime_task_switch(struct task_struct *prev)
> -{
> - if (is_idle_task(prev))
> - vtime_account_idle(prev);
> - else
> - vtime_account_kernel(prev);
> -
> - vtime_flush(prev);
> - arch_vtime_task_switch(prev);
> -}
> -# endif
> -
>  void vtime_account_irq(struct task_struct *tsk, unsigned int offset)
>  {
>   unsigned int pc = irq_count() - offset;
> -- 
> 2.40.1


[RESEND2 PATCH net v4 2/2] soc: fsl: qbman: Use raw spinlock for cgr_lock

2024-02-22 Thread Sean Anderson
cgr_lock may be locked with interrupts already disabled by
smp_call_function_single. As such, we must use a raw spinlock to avoid
problems on PREEMPT_RT kernels. Although this bug has existed for a
while, it was not apparent until commit ef2a8d5478b9 ("net: dpaa: Adjust
queue depth on rate change") which invokes smp_call_function_single via
qman_update_cgr_safe every time a link goes up or down.

Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
CC: sta...@vger.kernel.org
Reported-by: Vladimir Oltean 
Closes: https://lore.kernel.org/all/20230323153935.nofnjucqjqnz34ej@skbuf/
Reported-by: Steffen Trumtrar 
Closes: https://lore.kernel.org/linux-arm-kernel/87wmsyvclu@pengutronix.de/
Signed-off-by: Sean Anderson 
Reviewed-by: Camelia Groza 
Tested-by: Vladimir Oltean 

---

Changes in v4:
- Add a note about how raw spinlocks aren't quite right

Changes in v3:
- Change blamed commit to something more appropriate

 drivers/soc/fsl/qbman/qman.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 1bf1f1ea67f0..7e9074519ad2 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -991,7 +991,7 @@ struct qman_portal {
/* linked-list of CSCN handlers. */
struct list_head cgr_cbs;
/* list lock */
-   spinlock_t cgr_lock;
+   raw_spinlock_t cgr_lock;
struct work_struct congestion_work;
struct work_struct mr_work;
char irqname[MAX_IRQNAME];
@@ -1281,7 +1281,7 @@ static int qman_create_portal(struct qman_portal *portal,
/* if the given mask is NULL, assume all CGRs can be seen */
qman_cgrs_fill(>cgrs[0]);
INIT_LIST_HEAD(>cgr_cbs);
-   spin_lock_init(>cgr_lock);
+   raw_spin_lock_init(>cgr_lock);
INIT_WORK(>congestion_work, qm_congestion_task);
INIT_WORK(>mr_work, qm_mr_process_task);
portal->bits = 0;
@@ -1456,11 +1456,14 @@ static void qm_congestion_task(struct work_struct *work)
union qm_mc_result *mcr;
struct qman_cgr *cgr;
 
-   spin_lock_irq(>cgr_lock);
+   /*
+* FIXME: QM_MCR_TIMEOUT is 10ms, which is too long for a raw spinlock!
+*/
+   raw_spin_lock_irq(>cgr_lock);
qm_mc_start(>p);
qm_mc_commit(>p, QM_MCC_VERB_QUERYCONGESTION);
if (!qm_mc_result_timeout(>p, )) {
-   spin_unlock_irq(>cgr_lock);
+   raw_spin_unlock_irq(>cgr_lock);
dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
qman_p_irqsource_add(p, QM_PIRQ_CSCI);
return;
@@ -1476,7 +1479,7 @@ static void qm_congestion_task(struct work_struct *work)
list_for_each_entry(cgr, >cgr_cbs, node)
if (cgr->cb && qman_cgrs_get(, cgr->cgrid))
cgr->cb(p, cgr, qman_cgrs_get(, cgr->cgrid));
-   spin_unlock_irq(>cgr_lock);
+   raw_spin_unlock_irq(>cgr_lock);
qman_p_irqsource_add(p, QM_PIRQ_CSCI);
 }
 
@@ -2440,7 +2443,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
preempt_enable();
 
cgr->chan = p->config->channel;
-   spin_lock_irq(>cgr_lock);
+   raw_spin_lock_irq(>cgr_lock);
 
if (opts) {
struct qm_mcc_initcgr local_opts = *opts;
@@ -2477,7 +2480,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
qman_cgrs_get(>cgrs[1], cgr->cgrid))
cgr->cb(p, cgr, 1);
 out:
-   spin_unlock_irq(>cgr_lock);
+   raw_spin_unlock_irq(>cgr_lock);
put_affine_portal();
return ret;
 }
@@ -2512,7 +2515,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
return -EINVAL;
 
memset(_opts, 0, sizeof(struct qm_mcc_initcgr));
-   spin_lock_irqsave(>cgr_lock, irqflags);
+   raw_spin_lock_irqsave(>cgr_lock, irqflags);
list_del(>node);
/*
 * If there are no other CGR objects for this CGRID in the list,
@@ -2537,7 +2540,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
/* add back to the list */
list_add(>node, >cgr_cbs);
 release_lock:
-   spin_unlock_irqrestore(>cgr_lock, irqflags);
+   raw_spin_unlock_irqrestore(>cgr_lock, irqflags);
put_affine_portal();
return ret;
 }
@@ -2577,9 +2580,9 @@ static int qman_update_cgr(struct qman_cgr *cgr, struct 
qm_mcc_initcgr *opts)
if (!p)
return -EINVAL;
 
-   spin_lock_irqsave(>cgr_lock, irqflags);
+   raw_spin_lock_irqsave(>cgr_lock, irqflags);
ret = qm_modify_cgr(cgr, 0, opts);
-   spin_unlock_irqrestore(>cgr_lock, irqflags);
+   raw_spin_unlock_irqrestore(>cgr_lock, irqflags);
put_affine_portal();
return ret;
 }
-- 
2.35.1.1320.gc452695387.dirty



[RESEND2 PATCH net v4 1/2] soc: fsl: qbman: Always disable interrupts when taking cgr_lock

2024-02-22 Thread Sean Anderson
smp_call_function_single disables IRQs when executing the callback. To
prevent deadlocks, we must disable IRQs when taking cgr_lock elsewhere.
This is already done by qman_update_cgr and qman_delete_cgr; fix the
other lockers.

Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
CC: sta...@vger.kernel.org
Signed-off-by: Sean Anderson 
Reviewed-by: Camelia Groza 
Tested-by: Vladimir Oltean 
---
Resent from a non-mangling email.

(no changes since v3)

Changes in v3:
- Change blamed commit to something more appropriate

Changes in v2:
- Fix one additional call to spin_unlock

 drivers/soc/fsl/qbman/qman.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 739e4eee6b75..1bf1f1ea67f0 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -1456,11 +1456,11 @@ static void qm_congestion_task(struct work_struct *work)
union qm_mc_result *mcr;
struct qman_cgr *cgr;
 
-   spin_lock(>cgr_lock);
+   spin_lock_irq(>cgr_lock);
qm_mc_start(>p);
qm_mc_commit(>p, QM_MCC_VERB_QUERYCONGESTION);
if (!qm_mc_result_timeout(>p, )) {
-   spin_unlock(>cgr_lock);
+   spin_unlock_irq(>cgr_lock);
dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
qman_p_irqsource_add(p, QM_PIRQ_CSCI);
return;
@@ -1476,7 +1476,7 @@ static void qm_congestion_task(struct work_struct *work)
list_for_each_entry(cgr, >cgr_cbs, node)
if (cgr->cb && qman_cgrs_get(, cgr->cgrid))
cgr->cb(p, cgr, qman_cgrs_get(, cgr->cgrid));
-   spin_unlock(>cgr_lock);
+   spin_unlock_irq(>cgr_lock);
qman_p_irqsource_add(p, QM_PIRQ_CSCI);
 }
 
@@ -2440,7 +2440,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
preempt_enable();
 
cgr->chan = p->config->channel;
-   spin_lock(>cgr_lock);
+   spin_lock_irq(>cgr_lock);
 
if (opts) {
struct qm_mcc_initcgr local_opts = *opts;
@@ -2477,7 +2477,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
qman_cgrs_get(>cgrs[1], cgr->cgrid))
cgr->cb(p, cgr, 1);
 out:
-   spin_unlock(>cgr_lock);
+   spin_unlock_irq(>cgr_lock);
put_affine_portal();
return ret;
 }
-- 
2.35.1.1320.gc452695387.dirty



Re: [PATCH v2 00/14] Split crash out from kexec and clean up related config items

2024-02-22 Thread Andrew Morton
On Thu, 22 Feb 2024 10:47:29 +0530 Hari Bathini  wrote:

> 
> 
> On 22/02/24 2:27 am, Andrew Morton wrote:
> > On Wed, 21 Feb 2024 11:15:00 +0530 Hari Bathini  
> > wrote:
> > 
> >> On 04/02/24 8:56 am, Baoquan He wrote:
> > Hope Hari and Pingfan can help have a look, see if
> > it's doable. Now, I make it either have both kexec and crash enabled, or
> > disable both of them altogether.
> 
>  Sure. I will take a closer look...
> >>> Thanks a lot. Please feel free to post patches to make that, or I can do
> >>> it with your support or suggestion.
> >>
> >> Tested your changes and on top of these changes, came up with the below
> >> changes to get it working for powerpc:
> >>
> >>   
> >> https://lore.kernel.org/all/20240213113150.1148276-1-hbath...@linux.ibm.com/
> > 
> > So can we take it that you're OK with Baoquan's series as-is?
> 
> Hi Andrew,
> 
> If you mean
> 
> v3 (https://lore.kernel.org/all/20240124051254.67105-1-...@redhat.com/)
> +
> follow-up from Baoquan 
> (https://lore.kernel.org/all/Zb8D1ASrgX0qVm9z@MiWiFi-R3L-srv/)
> 
> Yes.
> 

Can I add your Acked-by: and/or Tested-by: to the patches in this series?


[PATCH v5 15/20] EDAC/mc: Re-use generic unique MC index allocation procedure

2024-02-22 Thread Serge Semin
The EDAC drivers locally maintaining a statically defined
memory-controllers counter don't care much about the MC index assigned as
long as it's unique so the EDAC core perceives it. Convert these drivers
to be using the generic MC index allocation procedure recently added to
the EDAC core.

Signed-off-by: Serge Semin 

---

Changelog v4:
- Initial patch introduction.
---
 drivers/edac/dmc520_edac.c | 4 +---
 drivers/edac/pasemi_edac.c | 5 +
 drivers/edac/ppc4xx_edac.c | 5 +
 3 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/edac/dmc520_edac.c b/drivers/edac/dmc520_edac.c
index 4e30b989a1a4..93734a97a67b 100644
--- a/drivers/edac/dmc520_edac.c
+++ b/drivers/edac/dmc520_edac.c
@@ -173,8 +173,6 @@ struct dmc520_edac {
int masks[NUMBER_OF_IRQS];
 };
 
-static int dmc520_mc_idx;
-
 static u32 dmc520_read_reg(struct dmc520_edac *pvt, u32 offset)
 {
return readl(pvt->reg_base + offset);
@@ -517,7 +515,7 @@ static int dmc520_edac_probe(struct platform_device *pdev)
layers[0].size = dmc520_get_rank_count(reg_base);
layers[0].is_virt_csrow = true;
 
-   mci = edac_mc_alloc(dmc520_mc_idx++, ARRAY_SIZE(layers), layers, 
sizeof(*pvt));
+   mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers, 
sizeof(*pvt));
if (!mci) {
edac_printk(KERN_ERR, EDAC_MOD_NAME,
"Failed to allocate memory for mc instance\n");
diff --git a/drivers/edac/pasemi_edac.c b/drivers/edac/pasemi_edac.c
index 1a1c3296ccc8..afebfbda1ea0 100644
--- a/drivers/edac/pasemi_edac.c
+++ b/drivers/edac/pasemi_edac.c
@@ -57,8 +57,6 @@
 #define PASEMI_EDAC_ERROR_GRAIN64
 
 static int last_page_in_mmc;
-static int system_mmc_id;
-
 
 static u32 pasemi_edac_get_error_info(struct mem_ctl_info *mci)
 {
@@ -203,8 +201,7 @@ static int pasemi_edac_probe(struct pci_dev *pdev,
layers[1].type = EDAC_MC_LAYER_CHANNEL;
layers[1].size = PASEMI_EDAC_NR_CHANS;
layers[1].is_virt_csrow = false;
-   mci = edac_mc_alloc(system_mmc_id++, ARRAY_SIZE(layers), layers,
-   0);
+   mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers, 0);
if (mci == NULL)
return -ENOMEM;
 
diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c
index 1eea3341a916..06d267d40a6a 100644
--- a/drivers/edac/ppc4xx_edac.c
+++ b/drivers/edac/ppc4xx_edac.c
@@ -1214,7 +1214,6 @@ static int ppc4xx_edac_probe(struct platform_device *op)
const struct device_node *np = op->dev.of_node;
struct mem_ctl_info *mci = NULL;
struct edac_mc_layer layers[2];
-   static int ppc4xx_edac_instance;
 
/*
 * At this point, we only support the controller realized on
@@ -1265,7 +1264,7 @@ static int ppc4xx_edac_probe(struct platform_device *op)
layers[1].type = EDAC_MC_LAYER_CHANNEL;
layers[1].size = ppc4xx_edac_nr_chans;
layers[1].is_virt_csrow = false;
-   mci = edac_mc_alloc(ppc4xx_edac_instance, ARRAY_SIZE(layers), layers,
+   mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers,
sizeof(struct ppc4xx_edac_pdata));
if (mci == NULL) {
ppc4xx_edac_printk(KERN_ERR, "%pOF: "
@@ -1303,8 +1302,6 @@ static int ppc4xx_edac_probe(struct platform_device *op)
goto fail1;
}
 
-   ppc4xx_edac_instance++;
-
return 0;
 
  fail1:
-- 
2.43.0



[PATCH RESEND v10 0/1] dt-bindings: usb: Harmonize xHCI/EHCI/OHCI/DWC3 nodes name

2024-02-22 Thread Serge Semin
As the subject states this series is an attempt to harmonize the xHCI,
EHCI, OHCI and DWC USB3 DT nodes with the DT schema introduced in the
framework of the patchset [1].

Firstly as Krzysztof suggested we've deprecated a support of DWC USB3
controllers with "synopsys,"-vendor prefix compatible string in favor of
the ones with valid "snps,"-prefix. It's done in all the DTS files,
which have been unfortunate to define such nodes.

Secondly we suggest to fix the snps,quirk-frame-length-adjustment property
declaration in the Amlogic meson-g12-common.dtsi DTS file, since it has
been erroneously declared as boolean while having uint32 type. Neil said
it was ok to init that property with 0x20 value.

Thirdly the main part of the patchset concern fixing the xHCI, EHCI/OHCI
and DWC USB3 DT nodes name as in accordance with their DT schema the
corresponding node name is suppose to comply with the Generic USB HCD DT
schema, which requires the USB nodes to have the name acceptable by the
regexp: "^usb(@.*)?". Such requirement had been applicable even before we
introduced the new DT schema in [1], but as we can see it hasn't been
strictly implemented for a lot the DTS files. Since DT schema is now
available the automated DTS validation shall make sure that the rule isn't
violated.

Note most of these patches have been a part of the last three patches of
[1]. But since there is no way to have them merged in in a combined
manner, I had to move them to the dedicated series and split them up so to
be accepted by the corresponding subsystem maintainers one-by-one.

[1] Link: 
https://lore.kernel.org/linux-usb/20201014101402.18271-1-sergey.se...@baikalelectronics.ru
Changelog v1:
- As Krzysztof suggested I've created a script which checked whether the
  node names had been also updated in all the depended dts files. As a
  result I found two more files which should have been also modified:
  arch/arc/boot/dts/{axc003.dtsi,axc003_idu.dtsi}
- Correct the USB DWC3 nodes name found in
  arch/arm64/boot/dts/apm/{apm-storm.dtsi,apm-shadowcat.dtsi} too.

Link: 
https://lore.kernel.org/linux-usb/20201020115959.2658-1-sergey.se...@baikalelectronics.ru
Changelog v2:
- Drop the patch:
  [PATCH 01/29] usb: dwc3: Discard synopsys,dwc3 compatibility string
  and get back the one which marks the "synopsys,dwc3" compatible string
  as deprecated into the DT schema related series.
- Drop the patches:
  [PATCH 03/29] arm: dts: am437x: Correct DWC USB3 compatible string
  [PATCH 04/29] arm: dts: exynos: Correct DWC USB3 compatible string
  [PATCH 07/29] arm: dts: bcm53x: Harmonize EHCI/OHCI DT nodes name
  [PATCH 08/29] arm: dts: stm32: Harmonize EHCI/OHCI DT nodes name
  [PATCH 16/29] arm: dts: bcm5301x: Harmonize xHCI DT nodes name
  [PATCH 19/29] arm: dts: exynos: Harmonize DWC USB3 DT nodes name
  [PATCH 21/29] arm: dts: ls1021a: Harmonize DWC USB3 DT nodes name
  [PATCH 22/29] arm: dts: omap5: Harmonize DWC USB3 DT nodes name
  [PATCH 24/29] arm64: dts: allwinner: h6: Harmonize DWC USB3 DT nodes name
  [PATCH 26/29] arm64: dts: exynos: Harmonize DWC USB3 DT nodes name
  [PATCH 27/29] arm64: dts: layerscape: Harmonize DWC USB3 DT nodes name
  since they have been applied to the corresponding maintainers repos.
- Fix drivers/usb/dwc3/dwc3-qcom.c to be looking for the "usb@"-prefixed
  sub-node and falling back to the "dwc3@"-prefixed one on failure.

Link: 
https://lore.kernel.org/linux-usb/2020091552.15593-1-sergey.se...@baikalelectronics.ru
Changelog v3:
- Drop the patches:
  [PATCH v2 04/18] arm: dts: hisi-x5hd2: Harmonize EHCI/OHCI DT nodes name
  [PATCH v2 06/18] arm64: dts: hisi: Harmonize EHCI/OHCI DT nodes name
  [PATCH v2 07/18] mips: dts: jz47x: Harmonize EHCI/OHCI DT nodes name
  [PATCH v2 08/18] mips: dts: sead3: Harmonize EHCI/OHCI DT nodes name
  [PATCH v2 09/18] mips: dts: ralink: mt7628a: Harmonize EHCI/OHCI DT nodes name
  [PATCH v2 11/18] arm64: dts: marvell: cp11x: Harmonize xHCI DT nodes name
  [PATCH v2 12/18] arm: dts: marvell: armada-375: Harmonize DWC USB3 DT nodes 
name
  [PATCH v2 16/18] arm64: dts: hi3660: Harmonize DWC USB3 DT nodes name
  since they have been applied to the corresponding maintainers repos.

Link: 
https://lore.kernel.org/linux-usb/20201205155621.3045-1-sergey.se...@baikalelectronics.ru
Changelog v4:
- Just resend.

Link: 
https://lore.kernel.org/linux-usb/20201210091756.18057-1-sergey.se...@baikalelectronics.ru
Changelog v5:
- Drop the patch:
  [PATCH v4 02/10] arm64: dts: amlogic: meson-g12: Set FL-adj property value
  since it has been applied to the corresponding maintainers repos.
- Get back the patch:
  [PATCH 21/29] arm: dts: ls1021a: Harmonize DWC USB3 DT nodes name
  as it has been missing in the kernel 5.11-rc7
- Rebase onto the kernel 5.11-rc7.

Link: 
https://lore.kernel.org/lkml/20210208135154.6645-1-sergey.se...@baikalelectronics.ru
Changelog v6:
- Just resend and add linux-usb.vger.kernel.org to the list of Ccecipients.

Link: 

[PATCH RESEND v10 1/1] powerpc: dts: akebono: Harmonize EHCI/OHCI DT nodes name

2024-02-22 Thread Serge Semin
In accordance with the Generic EHCI/OHCI bindings the corresponding node
name is suppose to comply with the Generic USB HCD DT schema, which
requires the USB nodes to have the name acceptable by the regexp:
"^usb(@.*)?" . Make sure the "generic-ehci" and "generic-ohci"-compatible
nodes are correctly named.

Signed-off-by: Serge Semin 
Acked-by: Krzysztof Kozlowski 
---
 arch/powerpc/boot/dts/akebono.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/boot/dts/akebono.dts 
b/arch/powerpc/boot/dts/akebono.dts
index df18f8dc4642..343326c30380 100644
--- a/arch/powerpc/boot/dts/akebono.dts
+++ b/arch/powerpc/boot/dts/akebono.dts
@@ -126,7 +126,7 @@ SATA0: sata@301 {
interrupts = <93 2>;
};
 
-   EHCI0: ehci@3001000 {
+   EHCI0: usb@3001000 {
compatible = "ibm,476gtr-ehci", "generic-ehci";
reg = <0x300 0x1000 0x0 0x1>;
interrupt-parent = <>;
@@ -140,14 +140,14 @@ SD0: sd@300 {
interrupt-parent = <>;
};
 
-   OHCI0: ohci@3001001 {
+   OHCI0: usb@3001001 {
compatible = "ibm,476gtr-ohci", "generic-ohci";
reg = <0x300 0x1001 0x0 0x1>;
interrupt-parent = <>;
interrupts = <89 1>;
};
 
-   OHCI1: ohci@3001002 {
+   OHCI1: usb@3001002 {
compatible = "ibm,476gtr-ohci", "generic-ohci";
reg = <0x300 0x1002 0x0 0x1>;
interrupt-parent = <>;
-- 
2.43.0




Re: [PATCH v4 1/5] net: wan: Add support for QMC HDLC

2024-02-22 Thread Herve Codina
Andy, Jakub,

On Thu, 22 Feb 2024 18:56:26 +0200
Andy Shevchenko  wrote:

> On Thu, Feb 22, 2024 at 05:45:01PM +0100, Herve Codina wrote:
> > On Thu, 22 Feb 2024 17:29:05 +0200
> > Andy Shevchenko  wrote:  
> > > On Thu, Feb 22, 2024 at 03:22:14PM +0100, Herve Codina wrote:  
> 
> ...
> 
> > > > +   spin_lock_irqsave(_hdlc->tx_lock, flags);
> > > 
> > > Why not using cleanup.h from day 1?  
> > 
> > I don't know about cleanup.h.
> > Can you tell me more ?
> > How should I use it ?
> >   
> > > > +end:
> > > 
> > > This label, in particular, will not be needed with above in place.
> > >   
> > > > +   spin_unlock_irqrestore(_hdlc->tx_lock, flags);
> > > > +   return ret;
> > > > +}
> 
> Here are the examples:
> 6191e49de389 ("pinctrl: baytrail: Simplify code with cleanup helpers")
> 1d1b4770d4b6 ("platform/x86/intel/vsec: Use cleanup.h")
> e2eeddefb046 ("pstore: inode: Convert mutex usage to guard(mutex)")
> 
> Some advanced stuff:
> ced085ef369a ("PCI: Introduce cleanup helpers for device reference counts and 
> locks")
> 
> Hope this helps.

Sure, thanks for the pointer.

Jakub,
nothing in drivers/net seems to use the guard() (from cleanup.h) family
macro.
Are you ok with having this HDLC driver that uses guard() macros ?

Best regards,
Hervé

-- 
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


Re: [PATCH v4 1/5] net: wan: Add support for QMC HDLC

2024-02-22 Thread Andy Shevchenko
On Thu, Feb 22, 2024 at 05:45:01PM +0100, Herve Codina wrote:
> On Thu, 22 Feb 2024 17:29:05 +0200
> Andy Shevchenko  wrote:
> > On Thu, Feb 22, 2024 at 03:22:14PM +0100, Herve Codina wrote:

...

> > > + spin_lock_irqsave(_hdlc->tx_lock, flags);  
> > 
> > Why not using cleanup.h from day 1?
> 
> I don't know about cleanup.h.
> Can you tell me more ?
> How should I use it ?
> 
> > > +end:  
> > 
> > This label, in particular, will not be needed with above in place.
> > 
> > > + spin_unlock_irqrestore(_hdlc->tx_lock, flags);
> > > + return ret;
> > > +}  

Here are the examples:
6191e49de389 ("pinctrl: baytrail: Simplify code with cleanup helpers")
1d1b4770d4b6 ("platform/x86/intel/vsec: Use cleanup.h")
e2eeddefb046 ("pstore: inode: Convert mutex usage to guard(mutex)")

Some advanced stuff:
ced085ef369a ("PCI: Introduce cleanup helpers for device reference counts and 
locks")

Hope this helps.

-- 
With Best Regards,
Andy Shevchenko




Re: [PATCH v4 3/5] lib/bitmap: Introduce bitmap_scatter() and bitmap_gather() helpers

2024-02-22 Thread Herve Codina
Hi Andy, Yury,

On Thu, 22 Feb 2024 17:39:27 +0200
Andy Shevchenko  wrote:

...
> > + * bitmap_scatter() for the bitmap scatter detailed operations).  
> 
> > + * Suppose scattered computed using bitmap_scatter(scattered, src, mask, 
> > n).
> > + * The operation bitmap_gather(result, scattered, mask, n) leads to a 
> > result
> > + * equal or equivalent to src.  
> 
> This paragraph...
> 
> > + * The result can be 'equivalent' because bitmap_scatter() and 
> > bitmap_gather()
> > + * are not bijective.  
> 
> 
> > + * The result and src values are equivalent in that sense that a call to
> > + * bitmap_scatter(res, src, mask, n) and a call to bitmap_scatter(res, 
> > result,
> > + * mask, n) will lead to the same res value.  
> 
> ...seems duplicating this one.
> 
> I would drop the latter one.

I would like to give details about the 'equivalent' in this scatter/gather case.

If Yury is ok, I can drop this last paragraph.


Thanks for the review,

Regards,
Hervé


Re: [PATCH v4 1/5] net: wan: Add support for QMC HDLC

2024-02-22 Thread Herve Codina
On Thu, 22 Feb 2024 17:29:05 +0200
Andy Shevchenko  wrote:

> On Thu, Feb 22, 2024 at 03:22:14PM +0100, Herve Codina wrote:
> > The QMC HDLC driver provides support for HDLC using the QMC (QUICC
> > Multichannel Controller) to transfer the HDLC data.  
> 
> ...
> 
> > +struct qmc_hdlc {
> > +   struct device *dev;
> > +   struct qmc_chan *qmc_chan;
> > +   struct net_device *netdev;
> > +   bool is_crc32;
> > +   spinlock_t tx_lock; /* Protect tx descriptors */  
> 
> Just wondering if above tx/rx descriptors should be aligned on a cacheline
> for DMA?

These descriptors are not used by DMA.
Not sure that aligning them to a cacheline is really needed.

> 
> > +   struct qmc_hdlc_desc tx_descs[8];
> > +   unsigned int tx_out;
> > +   struct qmc_hdlc_desc rx_descs[4];
> > +};  
> 
> ...
> 
> > +#define QMC_HDLC_RX_ERROR_FLAGS (QMC_RX_FLAG_HDLC_OVF | \
> > +QMC_RX_FLAG_HDLC_UNA | \
> > +QMC_RX_FLAG_HDLC_ABORT | \
> > +QMC_RX_FLAG_HDLC_CRC)  
> 
> Wouldn't be slightly better to have it as
> 
> #define QMC_HDLC_RX_ERROR_FLAGS   \
>   (QMC_RX_FLAG_HDLC_OVF | QMC_RX_FLAG_HDLC_UNA |  \
>QMC_RX_FLAG_HDLC_CRC | QMC_RX_FLAG_HDLC_ABORT)
> 
> ?

Will be done in the next iteration.

> 
> ...
> 
> > +   ret = qmc_chan_write_submit(qmc_hdlc->qmc_chan, desc->dma_addr, 
> > desc->dma_size,
> > +   qmc_hdlc_xmit_complete, desc);
> > +   if (ret) {  
> 
> > +   dev_err(qmc_hdlc->dev, "qmc chan write returns %d\n", ret);
> > +   dma_unmap_single(qmc_hdlc->dev, desc->dma_addr, desc->dma_size, 
> > DMA_TO_DEVICE);
> > +   return ret;  
> 
> I would do other way around, i.e. release resource followed up by printing
> a message. Printing a message is a slow operation and may prevent the (soon
> freed) resources to be re-used earlier.

Will do that in the next iteration.

> 
> > +   }  
> 
> ...
> 
> > +   spin_lock_irqsave(_hdlc->tx_lock, flags);  
> 
> Why not using cleanup.h from day 1?

I don't know about cleanup.h.
Can you tell me more ?
How should I use it ?

> 
> > +end:  
> 
> This label, in particular, will not be needed with above in place.
> 
> > +   spin_unlock_irqrestore(_hdlc->tx_lock, flags);
> > +   return ret;
> > +}  
> 
> ...
> 
> > +   /* Queue as many recv descriptors as possible */
> > +   for (i = 0; i < ARRAY_SIZE(qmc_hdlc->rx_descs); i++) {
> > +   desc = _hdlc->rx_descs[i];
> > +
> > +   desc->netdev = netdev;
> > +   ret = qmc_hdlc_recv_queue(qmc_hdlc, desc, 
> > chan_param.hdlc.max_rx_buf_size);  
> 
> > +   if (ret) {
> > +   if (ret == -EBUSY && i != 0)
> > +   break; /* We use all the QMC chan capability */
> > +   goto free_desc;
> > +   }  
> 
> Can be unfolded to
> 
>   if (ret == -EBUSY && i)
>   break; /* We use all the QMC chan capability */
>   if (ret)
>   goto free_desc;
> 
> Easy to read and understand.

Sure, will be changed.

> 
> > +   }  
> 
> ...
> 
> > +static int qmc_hdlc_probe(struct platform_device *pdev)
> > +{  
> 
> With
> 
>   struct device *dev = >dev;
> 
> the below code will be neater (see other comments for the examples).

Will use that.

> 
> > +   struct device_node *np = pdev->dev.of_node;  
> 
> It is used only once, drop it (see below).

Ok.

> 
> > +   struct qmc_hdlc *qmc_hdlc;
> > +   struct qmc_chan_info info;
> > +   hdlc_device *hdlc;
> > +   int ret;
> > +
> > +   qmc_hdlc = devm_kzalloc(>dev, sizeof(*qmc_hdlc), GFP_KERNEL);
> > +   if (!qmc_hdlc)
> > +   return -ENOMEM;
> > +
> > +   qmc_hdlc->dev = >dev;
> > +   spin_lock_init(_hdlc->tx_lock);
> > +
> > +   qmc_hdlc->qmc_chan = devm_qmc_chan_get_bychild(qmc_hdlc->dev, np);  
> 
>   qmc_hdlc->qmc_chan = devm_qmc_chan_get_bychild(dev, dev->of_node);
> 
> > +   if (IS_ERR(qmc_hdlc->qmc_chan)) {
> > +   ret = PTR_ERR(qmc_hdlc->qmc_chan);
> > +   return dev_err_probe(qmc_hdlc->dev, ret, "get QMC channel 
> > failed\n");  
> 
>   return dev_err_probe(dev, PTR_ERR(qmc_hdlc->qmc_chan), "get QMC 
> channel failed\n");
> 
> > +   }
> > +
> > +   ret = qmc_chan_get_info(qmc_hdlc->qmc_chan, );
> > +   if (ret) {  
> 
> > +   dev_err(qmc_hdlc->dev, "get QMC channel info failed %d\n", ret);
> > +   return ret;  
> 
> Why not using same message pattern everywhere, i.e. dev_err_probe()?
> 
>   return dev_err_probe(dev, ret, "get QMC channel info failed\n");
> 
> (and so on...)

No reason. Just because I missed them.
Will be updated using dev_err_probe().

> 
> > +   }
> > +
> > +   if (info.mode != QMC_HDLC) {
> > +   dev_err(qmc_hdlc->dev, "QMC chan mode %d is not QMC_HDLC\n",
> > +   info.mode);
> > +   return -EINVAL;
> > +   }
> > +
> > +   qmc_hdlc->netdev = alloc_hdlcdev(qmc_hdlc);
> > +  

Re: [PATCH 3/3] arch: Rename fbdev header and source files

2024-02-22 Thread kernel test robot
Hi Thomas,

kernel test robot noticed the following build errors:

[auto build test ERROR on tip/x86/core]
[also build test ERROR on deller-parisc/for-next arnd-asm-generic/master 
linus/master v6.8-rc5 next-20240221]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Thomas-Zimmermann/arch-Select-fbdev-helpers-with-CONFIG_VIDEO/20240222-001622
base:   tip/x86/core
patch link:
https://lore.kernel.org/r/20240221161431.8245-4-tzimmermann%40suse.de
patch subject: [PATCH 3/3] arch: Rename fbdev header and source files
config: um-randconfig-r052-20240222 
(https://download.01.org/0day-ci/archive/20240223/202402230023.xa2jjwui-...@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20240223/202402230023.xa2jjwui-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202402230023.xa2jjwui-...@intel.com/

All errors (new ones prefixed by >>):

   /usr/bin/ld: drivers/video/fbdev/core/fb_io_fops.o: in function `fb_io_mmap':
>> fb_io_fops.c:(.text+0x591): undefined reference to `pgprot_framebuffer'
   collect2: error: ld returned 1 exit status

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


Re: [PATCH v4 0/5] Add support for QMC HDLC

2024-02-22 Thread Andy Shevchenko
On Thu, Feb 22, 2024 at 03:22:13PM +0100, Herve Codina wrote:
> Hi,
> 
> This series introduces the QMC HDLC support.
> 
> Patches were previously sent as part of a full feature series and were
> previously reviewed in that context:
> "Add support for QMC HDLC, framer infrastructure and PEF2256 framer" [1]
> 
> In order to ease the merge, the full feature series has been split and
> needed parts were merged in v6.8-rc1:
>  - "Prepare the PowerQUICC QMC and TSA for the HDLC QMC driver" [2]
>  - "Add support for framer infrastructure and PEF2256 framer" [3]
> 
> This series contains patches related to the QMC HDLC part (QMC HDLC
> driver):
>  - Introduce the QMC HDLC driver (patches 1 and 2)
>  - Add timeslots change support in QMC HDLC (patch 3)
>  - Add framer support as a framer consumer in QMC HDLC (patch 4)
> 
> Compare to the original full feature series, a modification was done on
> patch 3 in order to use a coherent prefix in the commit title.
> 
> I kept the patches unsquashed as they were previously sent and reviewed.
> Of course, I can squash them if needed.
> 
> Compared to the previous iteration:
>   
> https://lore.kernel.org/linux-kernel/20240212075646.19114-1-herve.cod...@bootlin.com/
> this v4 series mainly:

>From my point of view after addressing the few non-critical issues
the v4 will be final. Thank you!

-- 
With Best Regards,
Andy Shevchenko




Re: [PATCH v4 5/5] net: wan: fsl_qmc_hdlc: Add framer support

2024-02-22 Thread Andy Shevchenko
On Thu, Feb 22, 2024 at 03:22:18PM +0100, Herve Codina wrote:
> Add framer support in the fsl_qmc_hdlc driver in order to be able to
> signal carrier changes to the network stack based on the framer status
> Also use this framer to provide information related to the E1/T1 line
> interface on IF_GET_IFACE and configure the line interface according to
> IF_IFACE_{E1,T1} information.

...

> +static int qmc_hdlc_framer_set_carrier(struct qmc_hdlc *qmc_hdlc)
> +{
> + struct framer_status framer_status;
> + unsigned long flags;
> + int ret;
> +
> + if (!qmc_hdlc->framer)
> + return 0;

> + spin_lock_irqsave(_hdlc->carrier_lock, flags);

cleanup.h ?

> + ret = framer_get_status(qmc_hdlc->framer, _status);
> + if (ret) {
> + dev_err(qmc_hdlc->dev, "get framer status failed (%d)\n", ret);
> + goto end;
> + }
> + if (framer_status.link_is_on)
> + netif_carrier_on(qmc_hdlc->netdev);
> + else
> + netif_carrier_off(qmc_hdlc->netdev);
> +
> +end:
> + spin_unlock_irqrestore(_hdlc->carrier_lock, flags);
> + return ret;
> +}

-- 
With Best Regards,
Andy Shevchenko




Re: [PATCH v4 4/5] net: wan: fsl_qmc_hdlc: Add runtime timeslots changes support

2024-02-22 Thread Andy Shevchenko
On Thu, Feb 22, 2024 at 03:22:17PM +0100, Herve Codina wrote:
> QMC channels support runtime timeslots changes but nothing is done at
> the QMC HDLC driver to handle these changes.
> 
> Use existing IFACE ioctl in order to configure the timeslots to use.

...

> +static int qmc_hdlc_xlate_slot_map(struct qmc_hdlc *qmc_hdlc,
> +u32 slot_map, struct qmc_chan_ts_info 
> *ts_info)
> +{
> + DECLARE_BITMAP(ts_mask_avail, 64);
> + DECLARE_BITMAP(ts_mask, 64);
> + DECLARE_BITMAP(map, 64);

Perhaps more 1:1 naming?

DECLARE_BITMAP(rx_ts_mask_avail, 64);
DECLARE_BITMAP(tx_ts_mask, 64);
DECLARE_BITMAP(slot_map, 64);

> + /* Tx and Rx available masks must be identical */
> + if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) {
> + dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch 
> (0x%llx, 0x%llx)\n",
> + ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail);
> + return -EINVAL;
> + }
> +
> + bitmap_from_u64(ts_mask_avail, ts_info->rx_ts_mask_avail);
> + bitmap_from_u64(map, slot_map);
> + bitmap_scatter(ts_mask, map, ts_mask_avail, 64);
> +
> + if (bitmap_weight(ts_mask, 64) != bitmap_weight(map, 64)) {
> + dev_err(qmc_hdlc->dev, "Cannot translate timeslots %*pb -> 
> (%*pb, %*pb)\n",
> + 64, map, 64, ts_mask_avail, 64, ts_mask);


You can save a bit of code and stack:

dev_err(qmc_hdlc->dev, "Cannot translate timeslots %64pb -> 
(%64pb, %64pb)\n",
slot_map, rx_ts_mask_avail, tx_ts_mask);

> + return -EINVAL;
> + }
> +
> + bitmap_to_arr64(_info->tx_ts_mask, ts_mask, 64);
> + ts_info->rx_ts_mask = ts_info->tx_ts_mask;
> + return 0;
> +}

...

> +static int qmc_hdlc_xlate_ts_info(struct qmc_hdlc *qmc_hdlc,
> +   const struct qmc_chan_ts_info *ts_info, u32 
> *slot_map)

Similar comments apply as per above function.

...

> + ret = qmc_chan_get_ts_info(qmc_hdlc->qmc_chan, _info);
> + if (ret) {
> + dev_err(qmc_hdlc->dev, "get QMC channel ts info failed %d\n", 
> ret);
> + return ret;

return dev_err_probe(...);

> + }

-- 
With Best Regards,
Andy Shevchenko




Re: [PATCH v4 3/5] lib/bitmap: Introduce bitmap_scatter() and bitmap_gather() helpers

2024-02-22 Thread Andy Shevchenko
On Thu, Feb 22, 2024 at 05:39:27PM +0200, Andy Shevchenko wrote:
> On Thu, Feb 22, 2024 at 03:22:16PM +0100, Herve Codina wrote:
> > From: Andy Shevchenko 

> > The original work was done by Andy Shevchenko.
> 
> Mine SoB is enough for a credit, but thank you :-)

That said, you forgot to add your Co-developed-by.

-- 
With Best Regards,
Andy Shevchenko




Re: [PATCH v4 3/5] lib/bitmap: Introduce bitmap_scatter() and bitmap_gather() helpers

2024-02-22 Thread Andy Shevchenko
On Thu, Feb 22, 2024 at 03:22:16PM +0100, Herve Codina wrote:
> From: Andy Shevchenko 
> 
> These helpers scatters or gathers a bitmap with the help of the mask
> position bits parameter.
> 
> bitmap_scatter() does the following:
>   src:  01011010
>   ||
>+--+|
>|  ++
>|  |++|||
>|  ||   +-+||
>|  ||   |  ||
>   mask: ...v..vv...v..vv
> ...0..11...0..10
>   dst:  00110010
> 
> and bitmap_gather() performs this one:
>mask: ...v..vv...v..vv
>src:  00110010
> ^  ^^   ^   0
> |  ||   |  10
> |  ||   > 010
> |  |+--> 1010
> |  +--> 11010
> +> 011010
>dst:  00011010
> 
> bitmap_gather() can the seen as the reverse bitmap_scatter() operation.

> The original work was done by Andy Shevchenko.

Mine SoB is enough for a credit, but thank you :-)

...

> +/**
> + * bitmap_gather - Gather a bitmap according to given mask
> + * @dst: gathered bitmap
> + * @src: scattered bitmap
> + * @mask: mask representing bits to extract from in the scattered bitmap
> + * @nbits: number of bits in each of these bitmaps
> + *
> + * Gathers bitmap with sparse bits according to the given @mask.
> + *
> + * Example:
> + * If @src bitmap = 0x0302, with @mask = 0x1313, @dst will be 0x001a.
> + *
> + * Or in binary form
> + * @src  @mask   @dst
> + * 00110010  000100110001001100011010
> + *
> + * (Bits 0, 1, 4, 8, 9, 12 are copied to the bits 0, 1, 2, 3, 4, 5)
> + *
> + * A more 'visual' description of the operation:
> + * mask: ...v..vv...v..vv
> + * src:  00110010
> + *  ^  ^^   ^   0
> + *  |  ||   |  10
> + *  |  ||   > 010
> + *  |  |+--> 1010
> + *  |  +--> 11010
> + *  +> 011010
> + * dst:  00011010

Cool!

> + * A relationship exists between bitmap_gather() and bitmap_scatter() (See

Either '... (see'
or '(). See'

> + * bitmap_scatter() for the bitmap scatter detailed operations).

> + * Suppose scattered computed using bitmap_scatter(scattered, src, mask, n).
> + * The operation bitmap_gather(result, scattered, mask, n) leads to a result
> + * equal or equivalent to src.

This paragraph...

> + * The result can be 'equivalent' because bitmap_scatter() and 
> bitmap_gather()
> + * are not bijective.


> + * The result and src values are equivalent in that sense that a call to
> + * bitmap_scatter(res, src, mask, n) and a call to bitmap_scatter(res, 
> result,
> + * mask, n) will lead to the same res value.

...seems duplicating this one.

I would drop the latter one.

> + */

-- 
With Best Regards,
Andy Shevchenko




Re: [PATCH v4 1/5] net: wan: Add support for QMC HDLC

2024-02-22 Thread Andy Shevchenko
On Thu, Feb 22, 2024 at 03:22:14PM +0100, Herve Codina wrote:
> The QMC HDLC driver provides support for HDLC using the QMC (QUICC
> Multichannel Controller) to transfer the HDLC data.

...

> +struct qmc_hdlc {
> + struct device *dev;
> + struct qmc_chan *qmc_chan;
> + struct net_device *netdev;
> + bool is_crc32;
> + spinlock_t tx_lock; /* Protect tx descriptors */

Just wondering if above tx/rx descriptors should be aligned on a cacheline
for DMA?

> + struct qmc_hdlc_desc tx_descs[8];
> + unsigned int tx_out;
> + struct qmc_hdlc_desc rx_descs[4];
> +};

...

> +#define QMC_HDLC_RX_ERROR_FLAGS (QMC_RX_FLAG_HDLC_OVF | \
> +  QMC_RX_FLAG_HDLC_UNA | \
> +  QMC_RX_FLAG_HDLC_ABORT | \
> +  QMC_RX_FLAG_HDLC_CRC)

Wouldn't be slightly better to have it as

#define QMC_HDLC_RX_ERROR_FLAGS \
(QMC_RX_FLAG_HDLC_OVF | QMC_RX_FLAG_HDLC_UNA |  \
 QMC_RX_FLAG_HDLC_CRC | QMC_RX_FLAG_HDLC_ABORT)

?

...

> + ret = qmc_chan_write_submit(qmc_hdlc->qmc_chan, desc->dma_addr, 
> desc->dma_size,
> + qmc_hdlc_xmit_complete, desc);
> + if (ret) {

> + dev_err(qmc_hdlc->dev, "qmc chan write returns %d\n", ret);
> + dma_unmap_single(qmc_hdlc->dev, desc->dma_addr, desc->dma_size, 
> DMA_TO_DEVICE);
> + return ret;

I would do other way around, i.e. release resource followed up by printing
a message. Printing a message is a slow operation and may prevent the (soon
freed) resources to be re-used earlier.

> + }

...

> + spin_lock_irqsave(_hdlc->tx_lock, flags);

Why not using cleanup.h from day 1?

> +end:

This label, in particular, will not be needed with above in place.

> + spin_unlock_irqrestore(_hdlc->tx_lock, flags);
> + return ret;
> +}

...

> + /* Queue as many recv descriptors as possible */
> + for (i = 0; i < ARRAY_SIZE(qmc_hdlc->rx_descs); i++) {
> + desc = _hdlc->rx_descs[i];
> +
> + desc->netdev = netdev;
> + ret = qmc_hdlc_recv_queue(qmc_hdlc, desc, 
> chan_param.hdlc.max_rx_buf_size);

> + if (ret) {
> + if (ret == -EBUSY && i != 0)
> + break; /* We use all the QMC chan capability */
> + goto free_desc;
> + }

Can be unfolded to

if (ret == -EBUSY && i)
break; /* We use all the QMC chan capability */
if (ret)
goto free_desc;

Easy to read and understand.

> + }

...

> +static int qmc_hdlc_probe(struct platform_device *pdev)
> +{

With

struct device *dev = >dev;

the below code will be neater (see other comments for the examples).

> + struct device_node *np = pdev->dev.of_node;

It is used only once, drop it (see below).

> + struct qmc_hdlc *qmc_hdlc;
> + struct qmc_chan_info info;
> + hdlc_device *hdlc;
> + int ret;
> +
> + qmc_hdlc = devm_kzalloc(>dev, sizeof(*qmc_hdlc), GFP_KERNEL);
> + if (!qmc_hdlc)
> + return -ENOMEM;
> +
> + qmc_hdlc->dev = >dev;
> + spin_lock_init(_hdlc->tx_lock);
> +
> + qmc_hdlc->qmc_chan = devm_qmc_chan_get_bychild(qmc_hdlc->dev, np);

qmc_hdlc->qmc_chan = devm_qmc_chan_get_bychild(dev, dev->of_node);

> + if (IS_ERR(qmc_hdlc->qmc_chan)) {
> + ret = PTR_ERR(qmc_hdlc->qmc_chan);
> + return dev_err_probe(qmc_hdlc->dev, ret, "get QMC channel 
> failed\n");

return dev_err_probe(dev, PTR_ERR(qmc_hdlc->qmc_chan), "get QMC 
channel failed\n");

> + }
> +
> + ret = qmc_chan_get_info(qmc_hdlc->qmc_chan, );
> + if (ret) {

> + dev_err(qmc_hdlc->dev, "get QMC channel info failed %d\n", ret);
> + return ret;

Why not using same message pattern everywhere, i.e. dev_err_probe()?

return dev_err_probe(dev, ret, "get QMC channel info failed\n");

(and so on...)

> + }
> +
> + if (info.mode != QMC_HDLC) {
> + dev_err(qmc_hdlc->dev, "QMC chan mode %d is not QMC_HDLC\n",
> + info.mode);
> + return -EINVAL;
> + }
> +
> + qmc_hdlc->netdev = alloc_hdlcdev(qmc_hdlc);
> + if (!qmc_hdlc->netdev) {

> + dev_err(qmc_hdlc->dev, "failed to alloc hdlc dev\n");
> + return -ENOMEM;

We do not issue a message for -ENOMEM.

> + }
> +
> + hdlc = dev_to_hdlc(qmc_hdlc->netdev);
> + hdlc->attach = qmc_hdlc_attach;
> + hdlc->xmit = qmc_hdlc_xmit;
> + SET_NETDEV_DEV(qmc_hdlc->netdev, qmc_hdlc->dev);
> + qmc_hdlc->netdev->tx_queue_len = ARRAY_SIZE(qmc_hdlc->tx_descs);
> + qmc_hdlc->netdev->netdev_ops = _hdlc_netdev_ops;
> + ret = register_hdlc_device(qmc_hdlc->netdev);
> + if (ret) {
> + dev_err(qmc_hdlc->dev, "failed to register hdlc device (%d)\n", 
> ret);
> +   

[PATCH v2 RESEND 4/5] s390/irq,nmi: include header directly

2024-02-22 Thread Alexander Gordeev
update_timer_sys() and update_timer_mcck() are inlines used for
CPU time accounting from the interrupt and machine-check handlers.
These routines are specific to s390 architecture, but included
via  header implicitly. Avoid the extra loop and
include  header directly.

Acked-by: Heiko Carstens 
Signed-off-by: Alexander Gordeev 
---
 arch/s390/kernel/irq.c | 1 +
 arch/s390/kernel/nmi.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 6f71b0ce1068..259496fe0ef9 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "entry.h"
 
 DEFINE_PER_CPU_SHARED_ALIGNED(struct irq_stat, irq_stat);
diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c
index 9ad44c26d1a2..4422a27faace 100644
--- a/arch/s390/kernel/nmi.c
+++ b/arch/s390/kernel/nmi.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 struct mcck_struct {
-- 
2.40.1



[PATCH v2 RESEND 3/5] s390/vtime: remove unused __ARCH_HAS_VTIME_TASK_SWITCH leftover

2024-02-22 Thread Alexander Gordeev
__ARCH_HAS_VTIME_TASK_SWITCH macro is not used anymore.

Reviewed-by: Frederic Weisbecker 
Acked-by: Heiko Carstens 
Acked-by: Nicholas Piggin 
Signed-off-by: Alexander Gordeev 
---
 arch/s390/include/asm/vtime.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/s390/include/asm/vtime.h b/arch/s390/include/asm/vtime.h
index fe17e448c0c5..561c91c1a87c 100644
--- a/arch/s390/include/asm/vtime.h
+++ b/arch/s390/include/asm/vtime.h
@@ -2,8 +2,6 @@
 #ifndef _S390_VTIME_H
 #define _S390_VTIME_H
 
-#define __ARCH_HAS_VTIME_TASK_SWITCH
-
 static inline void update_timer_sys(void)
 {
S390_lowcore.system_timer += S390_lowcore.last_update_timer - 
S390_lowcore.exit_timer;
-- 
2.40.1



[PATCH v2 RESEND 2/5] sched/vtime: get rid of generic vtime_task_switch() implementation

2024-02-22 Thread Alexander Gordeev
The generic vtime_task_switch() implementation gets built only
if __ARCH_HAS_VTIME_TASK_SWITCH is not defined, but requires an
architecture to implement arch_vtime_task_switch() callback at
the same time, which is confusing.

Further, arch_vtime_task_switch() is implemented for 32-bit PowerPC
architecture only and vtime_task_switch() generic variant is rather
superfluous.

Simplify the whole vtime_task_switch() wiring by moving the existing
generic implementation to PowerPC.

Reviewed-by: Frederic Weisbecker 
Reviewed-by: Nicholas Piggin 
Signed-off-by: Alexander Gordeev 
---
 arch/powerpc/include/asm/cputime.h | 13 -
 arch/powerpc/kernel/time.c | 22 ++
 kernel/sched/cputime.c | 13 -
 3 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/include/asm/cputime.h 
b/arch/powerpc/include/asm/cputime.h
index 4961fb38e438..aff858ca99c0 100644
--- a/arch/powerpc/include/asm/cputime.h
+++ b/arch/powerpc/include/asm/cputime.h
@@ -32,23 +32,10 @@
 #ifdef CONFIG_PPC64
 #define get_accounting(tsk)(_paca()->accounting)
 #define raw_get_accounting(tsk)(_paca->accounting)
-static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
 
 #else
 #define get_accounting(tsk)(_thread_info(tsk)->accounting)
 #define raw_get_accounting(tsk)get_accounting(tsk)
-/*
- * Called from the context switch with interrupts disabled, to charge all
- * accumulated times to the current process, and to prepare accounting on
- * the next process.
- */
-static inline void arch_vtime_task_switch(struct task_struct *prev)
-{
-   struct cpu_accounting_data *acct = get_accounting(current);
-   struct cpu_accounting_data *acct0 = get_accounting(prev);
-
-   acct->starttime = acct0->starttime;
-}
 #endif
 
 /*
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index df20cf201f74..c0fdc6d94fee 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -354,6 +354,28 @@ void vtime_flush(struct task_struct *tsk)
acct->hardirq_time = 0;
acct->softirq_time = 0;
 }
+
+/*
+ * Called from the context switch with interrupts disabled, to charge all
+ * accumulated times to the current process, and to prepare accounting on
+ * the next process.
+ */
+void vtime_task_switch(struct task_struct *prev)
+{
+   if (is_idle_task(prev))
+   vtime_account_idle(prev);
+   else
+   vtime_account_kernel(prev);
+
+   vtime_flush(prev);
+
+   if (!IS_ENABLED(CONFIG_PPC64)) {
+   struct cpu_accounting_data *acct = get_accounting(current);
+   struct cpu_accounting_data *acct0 = get_accounting(prev);
+
+   acct->starttime = acct0->starttime;
+   }
+}
 #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
 
 void __no_kcsan __delay(unsigned long loops)
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index af7952f12e6c..aa48b2ec879d 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -424,19 +424,6 @@ static inline void irqtime_account_process_tick(struct 
task_struct *p, int user_
  */
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
 
-# ifndef __ARCH_HAS_VTIME_TASK_SWITCH
-void vtime_task_switch(struct task_struct *prev)
-{
-   if (is_idle_task(prev))
-   vtime_account_idle(prev);
-   else
-   vtime_account_kernel(prev);
-
-   vtime_flush(prev);
-   arch_vtime_task_switch(prev);
-}
-# endif
-
 void vtime_account_irq(struct task_struct *tsk, unsigned int offset)
 {
unsigned int pc = irq_count() - offset;
-- 
2.40.1



[PATCH v2 RESEND 1/5] sched/vtime: remove confusing arch_vtime_task_switch() declaration

2024-02-22 Thread Alexander Gordeev
Callback arch_vtime_task_switch() is only defined when
CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is selected. Yet, the
function prototype forward declaration is present for
CONFIG_VIRT_CPU_ACCOUNTING_GEN variant. Remove it.

Reviewed-by: Frederic Weisbecker 
Reviewed-by: Nicholas Piggin 
Signed-off-by: Alexander Gordeev 
---
 include/linux/vtime.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/linux/vtime.h b/include/linux/vtime.h
index 3684487d01e1..593466ceebed 100644
--- a/include/linux/vtime.h
+++ b/include/linux/vtime.h
@@ -18,7 +18,6 @@ extern void vtime_account_idle(struct task_struct *tsk);
 #endif /* !CONFIG_VIRT_CPU_ACCOUNTING */
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
-extern void arch_vtime_task_switch(struct task_struct *tsk);
 extern void vtime_user_enter(struct task_struct *tsk);
 extern void vtime_user_exit(struct task_struct *tsk);
 extern void vtime_guest_enter(struct task_struct *tsk);
-- 
2.40.1



[PATCH v2 RESEND 5/5] sched/vtime: do not include header

2024-02-22 Thread Alexander Gordeev
There is no architecture-specific code or data left
that generic  needs to know about.
Thus, avoid the inclusion of  header.

Reviewed-by: Frederic Weisbecker 
Acked-by: Nicholas Piggin 
Signed-off-by: Alexander Gordeev 
---
 arch/powerpc/include/asm/Kbuild | 1 -
 include/asm-generic/vtime.h | 1 -
 include/linux/vtime.h   | 4 
 3 files changed, 6 deletions(-)
 delete mode 100644 include/asm-generic/vtime.h

diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
index 61a8dcd7..e5fdc336c9b2 100644
--- a/arch/powerpc/include/asm/Kbuild
+++ b/arch/powerpc/include/asm/Kbuild
@@ -6,5 +6,4 @@ generic-y += agp.h
 generic-y += kvm_types.h
 generic-y += mcs_spinlock.h
 generic-y += qrwlock.h
-generic-y += vtime.h
 generic-y += early_ioremap.h
diff --git a/include/asm-generic/vtime.h b/include/asm-generic/vtime.h
deleted file mode 100644
index b1a49677fe25..
--- a/include/asm-generic/vtime.h
+++ /dev/null
@@ -1 +0,0 @@
-/* no content, but patch(1) dislikes empty files */
diff --git a/include/linux/vtime.h b/include/linux/vtime.h
index 593466ceebed..29dd5b91dd7d 100644
--- a/include/linux/vtime.h
+++ b/include/linux/vtime.h
@@ -5,10 +5,6 @@
 #include 
 #include 
 
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
-#include 
-#endif
-
 /*
  * Common vtime APIs
  */
-- 
2.40.1



[PATCH v2 RESEND 0/5] sched/vtime: vtime.h headers cleanup

2024-02-22 Thread Alexander Gordeev
Hi All,

There are no changes since the last post, just a re-send.

v2:

- patch 4: commit message reworded (Heiko)
- patch 5: vtime.h is removed from Kbuild scripts (PowerPC only) (Heiko)

v1:

Please find a small cleanup to vtime_task_switch() wiring.
I split it into smaller patches to allow separate PowerPC
vs s390 reviews. Otherwise patches 2+3 and 4+5 could have
been merged.

I tested it on s390 and compile-tested it on 32- and 64-bit
PowerPC and few other major architectures only, but it is
only of concern for CONFIG_VIRT_CPU_ACCOUNTING_NATIVE-capable
ones (AFAICT).

Thanks!

Alexander Gordeev (5):
  sched/vtime: remove confusing arch_vtime_task_switch() declaration
  sched/vtime: get rid of generic vtime_task_switch() implementation
  s390/vtime: remove unused __ARCH_HAS_VTIME_TASK_SWITCH leftover
  s390/irq,nmi: include  header directly
  sched/vtime: do not include  header

 arch/powerpc/include/asm/Kbuild|  1 -
 arch/powerpc/include/asm/cputime.h | 13 -
 arch/powerpc/kernel/time.c | 22 ++
 arch/s390/include/asm/vtime.h  |  2 --
 arch/s390/kernel/irq.c |  1 +
 arch/s390/kernel/nmi.c |  1 +
 include/asm-generic/vtime.h|  1 -
 include/linux/vtime.h  |  5 -
 kernel/sched/cputime.c | 13 -
 9 files changed, 24 insertions(+), 35 deletions(-)
 delete mode 100644 include/asm-generic/vtime.h

-- 
2.40.1



[PATCH v4 5/5] net: wan: fsl_qmc_hdlc: Add framer support

2024-02-22 Thread Herve Codina
Add framer support in the fsl_qmc_hdlc driver in order to be able to
signal carrier changes to the network stack based on the framer status
Also use this framer to provide information related to the E1/T1 line
interface on IF_GET_IFACE and configure the line interface according to
IF_IFACE_{E1,T1} information.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/net/wan/fsl_qmc_hdlc.c | 239 -
 1 file changed, 235 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c
index 1b7f1d5af273..5e80d3ce4e51 100644
--- a/drivers/net/wan/fsl_qmc_hdlc.c
+++ b/drivers/net/wan/fsl_qmc_hdlc.c
@@ -9,6 +9,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -28,6 +29,9 @@ struct qmc_hdlc {
struct device *dev;
struct qmc_chan *qmc_chan;
struct net_device *netdev;
+   struct framer *framer;
+   spinlock_t carrier_lock; /* Protect carrier detection */
+   struct notifier_block nb;
bool is_crc32;
spinlock_t tx_lock; /* Protect tx descriptors */
struct qmc_hdlc_desc tx_descs[8];
@@ -41,6 +45,195 @@ static struct qmc_hdlc *netdev_to_qmc_hdlc(struct 
net_device *netdev)
return dev_to_hdlc(netdev)->priv;
 }
 
+static int qmc_hdlc_framer_set_carrier(struct qmc_hdlc *qmc_hdlc)
+{
+   struct framer_status framer_status;
+   unsigned long flags;
+   int ret;
+
+   if (!qmc_hdlc->framer)
+   return 0;
+
+   spin_lock_irqsave(_hdlc->carrier_lock, flags);
+
+   ret = framer_get_status(qmc_hdlc->framer, _status);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "get framer status failed (%d)\n", ret);
+   goto end;
+   }
+   if (framer_status.link_is_on)
+   netif_carrier_on(qmc_hdlc->netdev);
+   else
+   netif_carrier_off(qmc_hdlc->netdev);
+
+end:
+   spin_unlock_irqrestore(_hdlc->carrier_lock, flags);
+   return ret;
+}
+
+static int qmc_hdlc_framer_notifier(struct notifier_block *nb, unsigned long 
action,
+   void *data)
+{
+   struct qmc_hdlc *qmc_hdlc = container_of(nb, struct qmc_hdlc, nb);
+   int ret;
+
+   if (action != FRAMER_EVENT_STATUS)
+   return NOTIFY_DONE;
+
+   ret = qmc_hdlc_framer_set_carrier(qmc_hdlc);
+   return ret ? NOTIFY_DONE : NOTIFY_OK;
+}
+
+static int qmc_hdlc_framer_start(struct qmc_hdlc *qmc_hdlc)
+{
+   struct framer_status framer_status;
+   int ret;
+
+   if (!qmc_hdlc->framer)
+   return 0;
+
+   ret = framer_power_on(qmc_hdlc->framer);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "framer power-on failed (%d)\n", ret);
+   return ret;
+   }
+
+   /* Be sure that get_status is supported */
+   ret = framer_get_status(qmc_hdlc->framer, _status);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "get framer status failed (%d)\n", ret);
+   goto framer_power_off;
+   }
+
+   qmc_hdlc->nb.notifier_call = qmc_hdlc_framer_notifier;
+   ret = framer_notifier_register(qmc_hdlc->framer, _hdlc->nb);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "framer notifier register failed 
(%d)\n", ret);
+   goto framer_power_off;
+   }
+
+   return 0;
+
+framer_power_off:
+   framer_power_off(qmc_hdlc->framer);
+   return ret;
+}
+
+static void qmc_hdlc_framer_stop(struct qmc_hdlc *qmc_hdlc)
+{
+   if (!qmc_hdlc->framer)
+   return;
+
+   framer_notifier_unregister(qmc_hdlc->framer, _hdlc->nb);
+   framer_power_off(qmc_hdlc->framer);
+}
+
+static int qmc_hdlc_framer_set_iface(struct qmc_hdlc *qmc_hdlc, int if_iface,
+const te1_settings *te1)
+{
+   struct framer_config config;
+   int ret;
+
+   if (!qmc_hdlc->framer)
+   return 0;
+
+   ret = framer_get_config(qmc_hdlc->framer, );
+   if (ret)
+   return ret;
+
+   switch (if_iface) {
+   case IF_IFACE_E1:
+   config.iface = FRAMER_IFACE_E1;
+   break;
+   case IF_IFACE_T1:
+   config.iface = FRAMER_IFACE_T1;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   switch (te1->clock_type) {
+   case CLOCK_DEFAULT:
+   /* Keep current value */
+   break;
+   case CLOCK_EXT:
+   config.clock_type = FRAMER_CLOCK_EXT;
+   break;
+   case CLOCK_INT:
+   config.clock_type = FRAMER_CLOCK_INT;
+   break;
+   default:
+   return -EINVAL;
+   }
+   config.line_clock_rate = te1->clock_rate;
+
+   return framer_set_config(qmc_hdlc->framer, );
+}
+
+static int qmc_hdlc_framer_get_iface(struct qmc_hdlc *qmc_hdlc, int *if_iface, 
te1_settings *te1)
+{
+   struct framer_config config;
+   int 

[PATCH v4 4/5] net: wan: fsl_qmc_hdlc: Add runtime timeslots changes support

2024-02-22 Thread Herve Codina
QMC channels support runtime timeslots changes but nothing is done at
the QMC HDLC driver to handle these changes.

Use existing IFACE ioctl in order to configure the timeslots to use.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
Acked-by: Jakub Kicinski 
---
 drivers/net/wan/fsl_qmc_hdlc.c | 152 -
 1 file changed, 151 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c
index ec08ab217a72..1b7f1d5af273 100644
--- a/drivers/net/wan/fsl_qmc_hdlc.c
+++ b/drivers/net/wan/fsl_qmc_hdlc.c
@@ -7,6 +7,7 @@
  * Author: Herve Codina 
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -32,6 +33,7 @@ struct qmc_hdlc {
struct qmc_hdlc_desc tx_descs[8];
unsigned int tx_out;
struct qmc_hdlc_desc rx_descs[4];
+   u32 slot_map;
 };
 
 static struct qmc_hdlc *netdev_to_qmc_hdlc(struct net_device *netdev)
@@ -206,6 +208,144 @@ static netdev_tx_t qmc_hdlc_xmit(struct sk_buff *skb, 
struct net_device *netdev)
return ret;
 }
 
+static int qmc_hdlc_xlate_slot_map(struct qmc_hdlc *qmc_hdlc,
+  u32 slot_map, struct qmc_chan_ts_info 
*ts_info)
+{
+   DECLARE_BITMAP(ts_mask_avail, 64);
+   DECLARE_BITMAP(ts_mask, 64);
+   DECLARE_BITMAP(map, 64);
+
+   /* Tx and Rx available masks must be identical */
+   if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) {
+   dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch 
(0x%llx, 0x%llx)\n",
+   ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail);
+   return -EINVAL;
+   }
+
+   bitmap_from_u64(ts_mask_avail, ts_info->rx_ts_mask_avail);
+   bitmap_from_u64(map, slot_map);
+   bitmap_scatter(ts_mask, map, ts_mask_avail, 64);
+
+   if (bitmap_weight(ts_mask, 64) != bitmap_weight(map, 64)) {
+   dev_err(qmc_hdlc->dev, "Cannot translate timeslots %*pb -> 
(%*pb, %*pb)\n",
+   64, map, 64, ts_mask_avail, 64, ts_mask);
+   return -EINVAL;
+   }
+
+   bitmap_to_arr64(_info->tx_ts_mask, ts_mask, 64);
+   ts_info->rx_ts_mask = ts_info->tx_ts_mask;
+   return 0;
+}
+
+static int qmc_hdlc_xlate_ts_info(struct qmc_hdlc *qmc_hdlc,
+ const struct qmc_chan_ts_info *ts_info, u32 
*slot_map)
+{
+   DECLARE_BITMAP(ts_mask_avail, 64);
+   DECLARE_BITMAP(ts_mask, 64);
+   DECLARE_BITMAP(map, 64);
+   u32 array32[2];
+
+   /* Tx and Rx masks and available masks must be identical */
+   if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) {
+   dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch 
(0x%llx, 0x%llx)\n",
+   ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail);
+   return -EINVAL;
+   }
+   if (ts_info->rx_ts_mask != ts_info->tx_ts_mask) {
+   dev_err(qmc_hdlc->dev, "tx and rx timeslots mismatch (0x%llx, 
0x%llx)\n",
+   ts_info->rx_ts_mask, ts_info->tx_ts_mask);
+   return -EINVAL;
+   }
+
+   bitmap_from_u64(ts_mask_avail, ts_info->rx_ts_mask_avail);
+   bitmap_from_u64(ts_mask, ts_info->rx_ts_mask);
+   bitmap_gather(map, ts_mask, ts_mask_avail, 64);
+
+   if (bitmap_weight(ts_mask, 64) != bitmap_weight(map, 64)) {
+   dev_err(qmc_hdlc->dev, "Cannot translate timeslots (%*pb, %*pb) 
-> %*pb\n",
+   64, ts_mask_avail, 64, ts_mask, 64, map);
+   return -EINVAL;
+   }
+
+   bitmap_to_arr32(array32, map, 64);
+   if (array32[1]) {
+   dev_err(qmc_hdlc->dev, "Slot map out of 32bit (%*pb, %*pb) -> 
%*pb\n",
+   64, ts_mask_avail, 64, ts_mask, 64, map);
+   return -EINVAL;
+   }
+
+   *slot_map = array32[0];
+   return 0;
+}
+
+static int qmc_hdlc_set_iface(struct qmc_hdlc *qmc_hdlc, int if_iface, const 
te1_settings *te1)
+{
+   struct qmc_chan_ts_info ts_info;
+   int ret;
+
+   ret = qmc_chan_get_ts_info(qmc_hdlc->qmc_chan, _info);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "get QMC channel ts info failed %d\n", 
ret);
+   return ret;
+   }
+   ret = qmc_hdlc_xlate_slot_map(qmc_hdlc, te1->slot_map, _info);
+   if (ret)
+   return ret;
+
+   ret = qmc_chan_set_ts_info(qmc_hdlc->qmc_chan, _info);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "set QMC channel ts info failed %d\n", 
ret);
+   return ret;
+   }
+
+   qmc_hdlc->slot_map = te1->slot_map;
+
+   return 0;
+}
+
+static int qmc_hdlc_ioctl(struct net_device *netdev, struct if_settings *ifs)
+{
+   struct qmc_hdlc *qmc_hdlc = netdev_to_qmc_hdlc(netdev);
+   te1_settings te1;
+
+   switch (ifs->type) {
+   case IF_GET_IFACE:
+   ifs->type = IF_IFACE_E1;
+   if (ifs->size < 

[PATCH v4 3/5] lib/bitmap: Introduce bitmap_scatter() and bitmap_gather() helpers

2024-02-22 Thread Herve Codina
From: Andy Shevchenko 

These helpers scatters or gathers a bitmap with the help of the mask
position bits parameter.

bitmap_scatter() does the following:
  src:  01011010
  ||
   +--+|
   |  ++
   |  |++|||
   |  ||   +-+||
   |  ||   |  ||
  mask: ...v..vv...v..vv
...0..11...0..10
  dst:  00110010

and bitmap_gather() performs this one:
   mask: ...v..vv...v..vv
   src:  00110010
^  ^^   ^   0
|  ||   |  10
|  ||   > 010
|  |+--> 1010
|  +--> 11010
+> 011010
   dst:  00011010

bitmap_gather() can the seen as the reverse bitmap_scatter() operation.

The original work was done by Andy Shevchenko.

Signed-off-by: Andy Shevchenko 
Link: 
https://lore.kernel.org/lkml/20230926052007.3917389-3-andriy.shevche...@linux.intel.com/
Signed-off-by: Herve Codina 
---
Yury, Andy, I hope I correctly took into accounts the comments
reveived on Andy's v1 series and found good compromise to satisfy
your different point of view.

 include/linux/bitmap.h | 101 +
 lib/test_bitmap.c  |  42 +
 2 files changed, 143 insertions(+)

diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 99451431e4d6..a171030ff71c 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -62,6 +62,8 @@ struct device;
  *  bitmap_shift_left(dst, src, n, nbits)   *dst = *src << n
  *  bitmap_cut(dst, src, first, n, nbits)   Cut n bits from first, copy 
rest
  *  bitmap_replace(dst, old, new, mask, nbits)  *dst = (*old & ~(*mask)) | 
(*new & *mask)
+ *  bitmap_scatter(dst, src, mask, nbits)  *dst = map(dense, sparse)(src)
+ *  bitmap_gather(dst, src, mask, nbits)   *dst = map(sparse, dense)(src)
  *  bitmap_remap(dst, src, old, new, nbits) *dst = map(old, new)(src)
  *  bitmap_bitremap(oldbit, old, new, nbits)newbit = map(old, new)(oldbit)
  *  bitmap_onto(dst, orig, relmap, nbits)   *dst = orig relative to relmap
@@ -487,6 +489,105 @@ static inline void bitmap_replace(unsigned long *dst,
__bitmap_replace(dst, old, new, mask, nbits);
 }
 
+/**
+ * bitmap_scatter - Scatter a bitmap according to the given mask
+ * @dst: scattered bitmap
+ * @src: gathered bitmap
+ * @mask: mask representing bits to assign to in the scattered bitmap
+ * @nbits: number of bits in each of these bitmaps
+ *
+ * Scatters bitmap with sequential bits according to the given @mask.
+ *
+ * Example:
+ * If @src bitmap = 0x005a, with @mask = 0x1313, @dst will be 0x0302.
+ *
+ * Or in binary form
+ * @src@mask   @dst
+ * 01011010000100110001001100110010
+ *
+ * (Bits 0, 1, 2, 3, 4, 5 are copied to the bits 0, 1, 4, 8, 9, 12)
+ *
+ * A more 'visual' description of the operation:
+ * src:  01011010
+ * ||
+ *  +--+|
+ *  |  ++
+ *  |  |++|||
+ *  |  ||   +-+||
+ *  |  ||   |  ||
+ * mask: ...v..vv...v..vv
+ *   ...0..11...0..10
+ * dst:  00110010
+ *
+ * A relationship exists between bitmap_scatter() and bitmap_gather().
+ * bitmap_gather() can be seen as the 'reverse' bitmap_scatter() operation.
+ * See bitmap_scatter() for details related to this relationship.
+ */
+static inline void bitmap_scatter(unsigned long *dst, const unsigned long *src,
+ const unsigned long *mask, unsigned int nbits)
+{
+   unsigned int n = 0;
+   unsigned int bit;
+
+   bitmap_zero(dst, nbits);
+
+   for_each_set_bit(bit, mask, nbits)
+   __assign_bit(bit, dst, test_bit(n++, src));
+}
+
+/**
+ * bitmap_gather - Gather a bitmap according to given mask
+ * @dst: gathered bitmap
+ * @src: scattered bitmap
+ * @mask: mask representing bits to extract from in the scattered bitmap
+ * @nbits: number of bits in each of these bitmaps
+ *
+ * Gathers bitmap with sparse bits according to the given @mask.
+ *
+ * Example:
+ * If @src bitmap = 0x0302, with @mask = 0x1313, @dst will be 0x001a.
+ *
+ * Or in binary form
+ * @src@mask   @dst
+ * 00110010000100110001001100011010
+ *
+ * (Bits 0, 1, 4, 8, 9, 12 are copied to the bits 0, 1, 2, 3, 4, 5)
+ *
+ * A more 'visual' description of the operation:
+ * mask: ...v..vv...v..vv
+ * src:  00110010
+ *  ^  ^^   ^   0
+ *  |  ||   |  10
+ *  |  ||   > 010
+ *  |  |+--> 1010
+ *  |  +--> 11010
+ *  +> 011010
+ * dst:  00011010
+ *
+ * A relationship exists between bitmap_gather() and bitmap_scatter() (See
+ * bitmap_scatter() for the bitmap scatter detailed operations).
+ * Suppose scattered computed using bitmap_scatter(scattered, src, mask, n).
+ * The operation bitmap_gather(result, scattered, 

[PATCH v4 2/5] MAINTAINERS: Add the Freescale QMC HDLC driver entry

2024-02-22 Thread Herve Codina
After contributing the driver, add myself as the maintainer for the
Freescale QMC HDLC driver.

Signed-off-by: Herve Codina 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8d1052fa6a69..15cd3a8e5866 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8584,6 +8584,13 @@ F:   
Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-scc-qmc.yaml
 F: drivers/soc/fsl/qe/qmc.c
 F: include/soc/fsl/qe/qmc.h
 
+FREESCALE QUICC ENGINE QMC HDLC DRIVER
+M: Herve Codina 
+L: net...@vger.kernel.org
+L: linuxppc-dev@lists.ozlabs.org
+S: Maintained
+F: drivers/net/wan/fsl_qmc_hdlc.c
+
 FREESCALE QUICC ENGINE TSA DRIVER
 M: Herve Codina 
 L: linuxppc-dev@lists.ozlabs.org
-- 
2.43.0



[PATCH v4 0/5] Add support for QMC HDLC

2024-02-22 Thread Herve Codina
Hi,

This series introduces the QMC HDLC support.

Patches were previously sent as part of a full feature series and were
previously reviewed in that context:
"Add support for QMC HDLC, framer infrastructure and PEF2256 framer" [1]

In order to ease the merge, the full feature series has been split and
needed parts were merged in v6.8-rc1:
 - "Prepare the PowerQUICC QMC and TSA for the HDLC QMC driver" [2]
 - "Add support for framer infrastructure and PEF2256 framer" [3]

This series contains patches related to the QMC HDLC part (QMC HDLC
driver):
 - Introduce the QMC HDLC driver (patches 1 and 2)
 - Add timeslots change support in QMC HDLC (patch 3)
 - Add framer support as a framer consumer in QMC HDLC (patch 4)

Compare to the original full feature series, a modification was done on
patch 3 in order to use a coherent prefix in the commit title.

I kept the patches unsquashed as they were previously sent and reviewed.
Of course, I can squash them if needed.

Compared to the previous iteration:
  
https://lore.kernel.org/linux-kernel/20240212075646.19114-1-herve.cod...@bootlin.com/
this v4 series mainly:
- Introduces and use bitmap_{scatter,gather}().

Best regards,
Hervé

[1]: 
https://lore.kernel.org/linux-kernel/20231115144007.478111-1-herve.cod...@bootlin.com/
[2]: 
https://lore.kernel.org/linux-kernel/20231205152116.122512-1-herve.cod...@bootlin.com/
[3]: 
https://lore.kernel.org/linux-kernel/20231128132534.258459-1-herve.cod...@bootlin.com/

Changes v3 -> v4
  - Patch 1
Remove of.h and of_platform.h includes, add mod_devicetable.h.
Add a blank line in the includes list.

  - Path 2
No changes.

  - v3 patches 3 and 4 removed

  - Patch 3 (new patch in v4)
Introduce bitmap_{scatter,gather}() based on the original patch done
by Andy Shevchenko.
Address comments already done on the original patch:

https://lore.kernel.org/lkml/20230926052007.3917389-3-andriy.shevche...@linux.intel.com/
  - Removed the returned values.
  - Used 'unsigned int' for all indexes.
  - Added a 'visual' description of the operations in kernel-doc.
  - Described the relationship between bitmap_scatter() and
bitmap_gather().
  - Moved bitmap_{scatter,gather}() to the bitmap.h file.
  - Improved bitmap_{scatter,gather}() test.
  - Reworked the commit log.

  - Patch 4 (v3 patch 5)
Use bitmap_{scatter,gather}()

  - Patches 5 (v3 patch 6)
No changes.

Changes v2 -> v3
  - Patch 1
Remove 'inline' function specifier from .c file.
Fix a bug introduced when added WARN_ONCE(). The warn condition must
be desc->skb (descriptor used) instead of !desc->skb.
Remove a lock/unlock section locking the entire qmc_hdlc_xmit()
function.

  - Patch 5
Use bitmap_from_u64() everywhere instead of bitmap_from_arr32() and
bitmap_from_arr64().

Changes v1 -> v2
  - Patch 1
Use the same qmc_hdlc initialisation in qmc_hcld_recv_complete()
than the one present in qmc_hcld_xmit_complete().
Use WARN_ONCE()

  - Patch 3 (new patch in v2)
Make bitmap_onto() available to users

  - Patch 4 (new patch in v2)
Introduce bitmap_off()

  - Patch 5 (patch 3 in v1)
Use bitmap_*() functions

  - Patch 6 (patch 4 in v1)
No changes

Changes compare to the full feature series:
  - Patch 3
Use 'net: wan: fsl_qmc_hdlc:' as commit title prefix

Patches extracted:
  - Patch 1 : full feature series patch 7
  - Patch 2 : full feature series patch 8
  - Patch 3 : full feature series patch 20
  - Patch 4 : full feature series patch 27

Andy Shevchenko (1):
  lib/bitmap: Introduce bitmap_scatter() and bitmap_gather() helpers

Herve Codina (4):
  net: wan: Add support for QMC HDLC
  MAINTAINERS: Add the Freescale QMC HDLC driver entry
  net: wan: fsl_qmc_hdlc: Add runtime timeslots changes support
  net: wan: fsl_qmc_hdlc: Add framer support

 MAINTAINERS|   7 +
 drivers/net/wan/Kconfig|  12 +
 drivers/net/wan/Makefile   |   1 +
 drivers/net/wan/fsl_qmc_hdlc.c | 807 +
 include/linux/bitmap.h | 101 +
 lib/test_bitmap.c  |  42 ++
 6 files changed, 970 insertions(+)
 create mode 100644 drivers/net/wan/fsl_qmc_hdlc.c

-- 
2.43.0



[PATCH v4 1/5] net: wan: Add support for QMC HDLC

2024-02-22 Thread Herve Codina
The QMC HDLC driver provides support for HDLC using the QMC (QUICC
Multichannel Controller) to transfer the HDLC data.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
Acked-by: Jakub Kicinski 
---
 drivers/net/wan/Kconfig|  12 +
 drivers/net/wan/Makefile   |   1 +
 drivers/net/wan/fsl_qmc_hdlc.c | 426 +
 3 files changed, 439 insertions(+)
 create mode 100644 drivers/net/wan/fsl_qmc_hdlc.c

diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 7dda87756d3f..31ab2136cdf1 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -197,6 +197,18 @@ config FARSYNC
  To compile this driver as a module, choose M here: the
  module will be called farsync.
 
+config FSL_QMC_HDLC
+   tristate "Freescale QMC HDLC support"
+   depends on HDLC
+   depends on CPM_QMC
+   help
+ HDLC support using the Freescale QUICC Multichannel Controller (QMC).
+
+ To compile this driver as a module, choose M here: the
+ module will be called fsl_qmc_hdlc.
+
+ If unsure, say N.
+
 config FSL_UCC_HDLC
tristate "Freescale QUICC Engine HDLC support"
depends on HDLC
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
index 8119b49d1da9..00e9b7ee1e01 100644
--- a/drivers/net/wan/Makefile
+++ b/drivers/net/wan/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_WANXL)   += wanxl.o
 obj-$(CONFIG_PCI200SYN)+= pci200syn.o
 obj-$(CONFIG_PC300TOO) += pc300too.o
 obj-$(CONFIG_IXP4XX_HSS)   += ixp4xx_hss.o
+obj-$(CONFIG_FSL_QMC_HDLC) += fsl_qmc_hdlc.o
 obj-$(CONFIG_FSL_UCC_HDLC) += fsl_ucc_hdlc.o
 obj-$(CONFIG_SLIC_DS26522) += slic_ds26522.o
 
diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c
new file mode 100644
index ..ec08ab217a72
--- /dev/null
+++ b/drivers/net/wan/fsl_qmc_hdlc.c
@@ -0,0 +1,426 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Freescale QMC HDLC Device Driver
+ *
+ * Copyright 2023 CS GROUP France
+ *
+ * Author: Herve Codina 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+struct qmc_hdlc_desc {
+   struct net_device *netdev;
+   struct sk_buff *skb; /* NULL if the descriptor is not in use */
+   dma_addr_t dma_addr;
+   size_t dma_size;
+};
+
+struct qmc_hdlc {
+   struct device *dev;
+   struct qmc_chan *qmc_chan;
+   struct net_device *netdev;
+   bool is_crc32;
+   spinlock_t tx_lock; /* Protect tx descriptors */
+   struct qmc_hdlc_desc tx_descs[8];
+   unsigned int tx_out;
+   struct qmc_hdlc_desc rx_descs[4];
+};
+
+static struct qmc_hdlc *netdev_to_qmc_hdlc(struct net_device *netdev)
+{
+   return dev_to_hdlc(netdev)->priv;
+}
+
+static int qmc_hdlc_recv_queue(struct qmc_hdlc *qmc_hdlc, struct qmc_hdlc_desc 
*desc, size_t size);
+
+#define QMC_HDLC_RX_ERROR_FLAGS (QMC_RX_FLAG_HDLC_OVF | \
+QMC_RX_FLAG_HDLC_UNA | \
+QMC_RX_FLAG_HDLC_ABORT | \
+QMC_RX_FLAG_HDLC_CRC)
+
+static void qmc_hcld_recv_complete(void *context, size_t length, unsigned int 
flags)
+{
+   struct qmc_hdlc_desc *desc = context;
+   struct net_device *netdev = desc->netdev;
+   struct qmc_hdlc *qmc_hdlc = netdev_to_qmc_hdlc(netdev);
+   int ret;
+
+   dma_unmap_single(qmc_hdlc->dev, desc->dma_addr, desc->dma_size, 
DMA_FROM_DEVICE);
+
+   if (flags & QMC_HDLC_RX_ERROR_FLAGS) {
+   netdev->stats.rx_errors++;
+   if (flags & QMC_RX_FLAG_HDLC_OVF) /* Data overflow */
+   netdev->stats.rx_over_errors++;
+   if (flags & QMC_RX_FLAG_HDLC_UNA) /* bits received not multiple 
of 8 */
+   netdev->stats.rx_frame_errors++;
+   if (flags & QMC_RX_FLAG_HDLC_ABORT) /* Received an abort 
sequence */
+   netdev->stats.rx_frame_errors++;
+   if (flags & QMC_RX_FLAG_HDLC_CRC) /* CRC error */
+   netdev->stats.rx_crc_errors++;
+   kfree_skb(desc->skb);
+   } else {
+   netdev->stats.rx_packets++;
+   netdev->stats.rx_bytes += length;
+
+   skb_put(desc->skb, length);
+   desc->skb->protocol = hdlc_type_trans(desc->skb, netdev);
+   netif_rx(desc->skb);
+   }
+
+   /* Re-queue a transfer using the same descriptor */
+   ret = qmc_hdlc_recv_queue(qmc_hdlc, desc, desc->dma_size);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "queue recv desc failed (%d)\n", ret);
+   netdev->stats.rx_errors++;
+   }
+}
+
+static int qmc_hdlc_recv_queue(struct qmc_hdlc *qmc_hdlc, struct qmc_hdlc_desc 
*desc, size_t size)
+{
+   int ret;
+
+   desc->skb = dev_alloc_skb(size);
+   if (!desc->skb)
+   return -ENOMEM;
+
+   desc->dma_size = size;
+   

Re: [PATCHv9 2/3] irq: use a struct for the kstat_irqs in the interrupt descriptor

2024-02-22 Thread Thomas Gleixner
On Thu, Feb 22 2024 at 17:34, Bitao Hu wrote:

First of all the subsystem prefix is 'genirq:'. 'git log kernel/irq/'
gives you a pretty good hint. It's documented

Secondly the subject line does not match what this patch is about. It's
not about using a struct, it's about providing a snapshot mechanism, no?

> The current implementation uses an int for the kstat_irqs in the
> interrupt descriptor.
>
> However, we need to know the number of interrupts which happened
> since softlockup detection took a snapshot in order to analyze
> the problem caused by an interrupt storm.
>
> Replacing an int with a struct and providing sensible interfaces
> for the watchdog code can keep it self contained to the interrupt
> core code.

So something like this makes a useful change log for this:

 Subject: genirq: Provide a snapshot mechanism for interrupt statistics

 The soft lockup detector lacks a mechanism to identify interrupt storms
 as root cause of a lockup. To enable this the detector needs a
 mechanism to snapshot the interrupt count statistics on a CPU when the
 detector observes a potential lockup scenario and compare that against
 the interrupt count when it warns about the lockup later on. The number
 of interrupts in that period give a hint whether the lockup might be
 caused by an interrupt storm.

 Instead of having extra storage in the lockup detector and accessing
 the internals of the interrupt descriptor directly, convert the per CPU
 irq_desc::kstat_irq member to a data structure which contains the
 counter plus a snapshot member and provide interfaces to take a
 snapshot of all interrupts on the current CPU and to retrieve the delta
 of a specific interrupt later on.

Hmm?

> Signed-off-by: Bitao Hu 

Interesting. You fully authored the patch?

That's not how it works. You cannot take work from others and claim that
it is yours. The minimal courtesy is to add a 'Originally-by:' tag.

> diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
> index 623b8136e9af..3ad40cf30c66 100644
> --- a/kernel/irq/proc.c
> +++ b/kernel/irq/proc.c
> @@ -488,18 +488,15 @@ int show_interrupts(struct seq_file *p, void *v)
>   if (!desc || irq_settings_is_hidden(desc))
>   goto outsparse;
>  
> - if (desc->kstat_irqs) {
> - for_each_online_cpu(j)
> - any_count |= data_race(*per_cpu_ptr(desc->kstat_irqs, 
> j));
> - }
> + if (desc->kstat_irqs)
> + any_count = data_race(desc->tot_count);

This is an unrelated change and needs to be split out into a separate
patch with a proper changelog which explains why this is equivalent.
  
Thanks,

tglx


Re: [PATCH v3 RESEND 1/6] net: wan: Add support for QMC HDLC

2024-02-22 Thread Herve Codina
On Thu, 22 Feb 2024 15:19:11 +0200
Andy Shevchenko  wrote:

> On Thu, Feb 22, 2024 at 01:05:16PM +0100, Herve Codina wrote:
> > On Mon, 12 Feb 2024 14:22:56 +0200
> > Andy Shevchenko  wrote:  
> 
> ...
> 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > >   
> > > > +#include 
> > > > +#include 
> > > 
> > > I do not see how these are being used, am I right?
> > > What's is missing OTOH is the mod_devicetable.h.  
> > 
> > Agree for removing of.h and of_platform.h.
> > 
> > Why do I need mod_devicetable.h ?
> > Isn't including module.h enough ?  
> 
> In that header the definitions of many of ID table data structures are 
> located.
> You are using that in the code.
> 

Ok, thanks.

Hervé


Re: [PATCH v3 RESEND 1/6] net: wan: Add support for QMC HDLC

2024-02-22 Thread Andy Shevchenko
On Thu, Feb 22, 2024 at 01:05:16PM +0100, Herve Codina wrote:
> On Mon, 12 Feb 2024 14:22:56 +0200
> Andy Shevchenko  wrote:

...

> > > +#include 
> > > +#include 
> > > +#include   
> > 
> > > +#include 
> > > +#include   
> > 
> > I do not see how these are being used, am I right?
> > What's is missing OTOH is the mod_devicetable.h.
> 
> Agree for removing of.h and of_platform.h.
> 
> Why do I need mod_devicetable.h ?
> Isn't including module.h enough ?

In that header the definitions of many of ID table data structures are located.
You are using that in the code.

-- 
With Best Regards,
Andy Shevchenko




Re: [PATCH v3 RESEND 1/6] net: wan: Add support for QMC HDLC

2024-02-22 Thread Herve Codina
Hi Andy,

On Mon, 12 Feb 2024 14:22:56 +0200
Andy Shevchenko  wrote:

...

> 
> > +#include 
> > +#include 
> > +#include   
> 
> > +#include 
> > +#include   
> 
> I do not see how these are being used, am I right?
> What's is missing OTOH is the mod_devicetable.h.

Agree for removing of.h and of_platform.h.

Why do I need mod_devicetable.h ?
Isn't including module.h enough ?

Best regards,
Hervé


[PATCHv9 3/3] watchdog/softlockup: report the most frequent interrupts

2024-02-22 Thread Bitao Hu
When the watchdog determines that the current soft lockup is due
to an interrupt storm based on CPU utilization, reporting the
most frequent interrupts could be good enough for further
troubleshooting.

Below is an example of interrupt storm. The call tree does not
provide useful information, but we can analyze which interrupt
caused the soft lockup by comparing the counts of interrupts.

[  638.870231] watchdog: BUG: soft lockup - CPU#9 stuck for 26s! [swapper/9:0]
[  638.870825] CPU#9 Utilization every 4s during lockup:
[  638.871194]  #1:   0% system,  0% softirq,   100% hardirq, 0% 
idle
[  638.871652]  #2:   0% system,  0% softirq,   100% hardirq, 0% 
idle
[  638.872107]  #3:   0% system,  0% softirq,   100% hardirq, 0% 
idle
[  638.872563]  #4:   0% system,  0% softirq,   100% hardirq, 0% 
idle
[  638.873018]  #5:   0% system,  0% softirq,   100% hardirq, 0% 
idle
[  638.873494] CPU#9 Detect HardIRQ Time exceeds 50%. Most frequent HardIRQs:
[  638.873994]  #1: 330945  irq#7
[  638.874236]  #2: 31  irq#82
[  638.874493]  #3: 10  irq#10
[  638.874744]  #4: 2   irq#89
[  638.874992]  #5: 1   irq#102
...
[  638.875313] Call trace:
[  638.875315]  __do_softirq+0xa8/0x364

Signed-off-by: Bitao Hu 
---
 kernel/watchdog.c | 115 --
 1 file changed, 111 insertions(+), 4 deletions(-)

diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 69e72d7e461d..c9d49ae8d045 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -12,22 +12,25 @@
 
 #define pr_fmt(fmt) "watchdog: " fmt
 
-#include 
 #include 
-#include 
 #include 
+#include 
+#include 
 #include 
+#include 
 #include 
+#include 
 #include 
+#include 
+#include 
 #include 
 #include 
+
 #include 
 #include 
 #include 
-#include 
 
 #include 
-#include 
 
 static DEFINE_MUTEX(watchdog_mutex);
 
@@ -417,13 +420,104 @@ static void print_cpustat(void)
}
 }
 
+#define HARDIRQ_PERCENT_THRESH  50
+#define NUM_HARDIRQ_REPORT  5
+struct irq_counts {
+   int irq;
+   u32 counts;
+};
+
+static DEFINE_PER_CPU(bool, snapshot_taken);
+
+/* Tabulate the most frequent interrupts. */
+static void tabulate_irq_count(struct irq_counts *irq_counts, int irq, u32 
counts, int rank)
+{
+   int i;
+   struct irq_counts new_count = {irq, counts};
+
+   for (i = 0; i < rank; i++) {
+   if (counts > irq_counts[i].counts)
+   swap(new_count, irq_counts[i]);
+   }
+}
+
+/*
+ * If the hardirq time exceeds HARDIRQ_PERCENT_THRESH% of the sample_period,
+ * then the cause of softlockup might be interrupt storm. In this case, it
+ * would be useful to start interrupt counting.
+ */
+static bool need_counting_irqs(void)
+{
+   u8 util;
+   int tail = __this_cpu_read(cpustat_tail);
+
+   tail = (tail + NUM_HARDIRQ_REPORT - 1) % NUM_HARDIRQ_REPORT;
+   util = __this_cpu_read(cpustat_util[tail][STATS_HARDIRQ]);
+   return util > HARDIRQ_PERCENT_THRESH;
+}
+
+static void start_counting_irqs(void)
+{
+   if (!__this_cpu_read(snapshot_taken)) {
+   kstat_snapshot_irqs();
+   __this_cpu_write(snapshot_taken, true);
+   }
+}
+
+static void stop_counting_irqs(void)
+{
+   __this_cpu_write(snapshot_taken, false);
+}
+
+static void print_irq_counts(void)
+{
+   unsigned int i, count;
+   struct irq_counts irq_counts_sorted[NUM_HARDIRQ_REPORT] = {
+   {-1, 0}, {-1, 0}, {-1, 0}, {-1, 0}, {-1, 0}
+   };
+
+   if (__this_cpu_read(snapshot_taken)) {
+   for_each_active_irq(i) {
+   count = kstat_get_irq_since_snapshot(i);
+   tabulate_irq_count(irq_counts_sorted, i, count, 
NUM_HARDIRQ_REPORT);
+   }
+
+   /*
+* We do not want the "watchdog: " prefix on every line,
+* hence we use "printk" instead of "pr_crit".
+*/
+   printk(KERN_CRIT "CPU#%d Detect HardIRQ Time exceeds %d%%. Most 
frequent HardIRQs:\n",
+  smp_processor_id(), HARDIRQ_PERCENT_THRESH);
+
+   for (i = 0; i < NUM_HARDIRQ_REPORT; i++) {
+   if (irq_counts_sorted[i].irq == -1)
+   break;
+
+   printk(KERN_CRIT "\t#%u: %-10u\tirq#%d\n",
+  i + 1, irq_counts_sorted[i].counts,
+  irq_counts_sorted[i].irq);
+   }
+
+   /*
+* If the hardirq time is less than HARDIRQ_PERCENT_THRESH% in 
the last
+* sample_period, then we suspect the interrupt storm might be 
subsiding.
+*/
+   if (!need_counting_irqs())
+   stop_counting_irqs();
+   }
+}
+
 static void report_cpu_status(void)
 {
print_cpustat();
+   print_irq_counts();
 }
 #else
 static 

[PATCHv9 2/3] irq: use a struct for the kstat_irqs in the interrupt descriptor

2024-02-22 Thread Bitao Hu
The current implementation uses an int for the kstat_irqs in the
interrupt descriptor.

However, we need to know the number of interrupts which happened
since softlockup detection took a snapshot in order to analyze
the problem caused by an interrupt storm.

Replacing an int with a struct and providing sensible interfaces
for the watchdog code can keep it self contained to the interrupt
core code.

Signed-off-by: Bitao Hu 
---
 arch/mips/dec/setup.c|  2 +-
 arch/parisc/kernel/smp.c |  2 +-
 arch/powerpc/kvm/book3s_hv_rm_xics.c |  2 +-
 include/linux/irqdesc.h  |  9 ++--
 include/linux/kernel_stat.h  |  3 +++
 kernel/irq/internals.h   |  2 +-
 kernel/irq/irqdesc.c | 34 ++--
 kernel/irq/proc.c|  9 +++-
 scripts/gdb/linux/interrupts.py  |  6 ++---
 9 files changed, 47 insertions(+), 22 deletions(-)

diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
index 6c3704f51d0d..87f0a1436bf9 100644
--- a/arch/mips/dec/setup.c
+++ b/arch/mips/dec/setup.c
@@ -756,7 +756,7 @@ void __init arch_init_irq(void)
NULL))
pr_err("Failed to register fpu interrupt\n");
desc_fpu = irq_to_desc(irq_fpu);
-   fpu_kstat_irq = this_cpu_ptr(desc_fpu->kstat_irqs);
+   fpu_kstat_irq = this_cpu_ptr(_fpu->kstat_irqs->cnt);
}
if (dec_interrupt[DEC_IRQ_CASCADE] >= 0) {
if (request_irq(dec_interrupt[DEC_IRQ_CASCADE], no_action,
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 444154271f23..800eb64e91ad 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -344,7 +344,7 @@ static int smp_boot_one_cpu(int cpuid, struct task_struct 
*idle)
struct irq_desc *desc = irq_to_desc(i);
 
if (desc && desc->kstat_irqs)
-   *per_cpu_ptr(desc->kstat_irqs, cpuid) = 0;
+   *per_cpu_ptr(desc->kstat_irqs, cpuid) = (struct 
irqstat) { };
}
 #endif
 
diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c 
b/arch/powerpc/kvm/book3s_hv_rm_xics.c
index e42984878503..f2636414d82a 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_xics.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c
@@ -837,7 +837,7 @@ static inline void this_cpu_inc_rm(unsigned int __percpu 
*addr)
  */
 static void kvmppc_rm_handle_irq_desc(struct irq_desc *desc)
 {
-   this_cpu_inc_rm(desc->kstat_irqs);
+   this_cpu_inc_rm(>kstat_irqs->cnt);
__this_cpu_inc(kstat.irqs_sum);
 }
 
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index d9451d456a73..2912b1998670 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -17,6 +17,11 @@ struct irq_desc;
 struct irq_domain;
 struct pt_regs;
 
+struct irqstat {
+   unsigned intcnt;
+   unsigned intref;
+};
+
 /**
  * struct irq_desc - interrupt descriptor
  * @irq_common_data:   per irq and chip data passed down to chip functions
@@ -55,7 +60,7 @@ struct pt_regs;
 struct irq_desc {
struct irq_common_data  irq_common_data;
struct irq_data irq_data;
-   unsigned int __percpu   *kstat_irqs;
+   struct irqstat __percpu *kstat_irqs;
irq_flow_handler_t  handle_irq;
struct irqaction*action;/* IRQ action list */
unsigned intstatus_use_accessors;
@@ -119,7 +124,7 @@ extern struct irq_desc irq_desc[NR_IRQS];
 static inline unsigned int irq_desc_kstat_cpu(struct irq_desc *desc,
  unsigned int cpu)
 {
-   return desc->kstat_irqs ? *per_cpu_ptr(desc->kstat_irqs, cpu) : 0;
+   return desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, cpu) : 0;
 }
 
 static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 9935f7ecbfb9..98b3043ea5e6 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -79,6 +79,9 @@ static inline unsigned int kstat_cpu_softirqs_sum(int cpu)
return sum;
 }
 
+extern void kstat_snapshot_irqs(void);
+extern unsigned int kstat_get_irq_since_snapshot(unsigned int irq);
+
 /*
  * Number of interrupts per specific IRQ source, since bootup
  */
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index bcc7f21db9ee..1d92532c2aae 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -258,7 +258,7 @@ static inline void irq_state_set_masked(struct irq_desc 
*desc)
 
 static inline void __kstat_incr_irqs_this_cpu(struct irq_desc *desc)
 {
-   __this_cpu_inc(*desc->kstat_irqs);
+   __this_cpu_inc(desc->kstat_irqs->cnt);
__this_cpu_inc(kstat.irqs_sum);
 }
 
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 27ca1c866f29..9cd17080b2d8 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -122,7 +122,7 @@ static void 

[PATCHv9 1/3] watchdog/softlockup: low-overhead detection of interrupt storm

2024-02-22 Thread Bitao Hu
The following softlockup is caused by interrupt storm, but it cannot be
identified from the call tree. Because the call tree is just a snapshot
and doesn't fully capture the behavior of the CPU during the soft lockup.
  watchdog: BUG: soft lockup - CPU#28 stuck for 23s! [fio:83921]
  ...
  Call trace:
__do_softirq+0xa0/0x37c
__irq_exit_rcu+0x108/0x140
irq_exit+0x14/0x20
__handle_domain_irq+0x84/0xe0
gic_handle_irq+0x80/0x108
el0_irq_naked+0x50/0x58

Therefore,I think it is necessary to report CPU utilization during the
softlockup_thresh period (report once every sample_period, for a total
of 5 reportings), like this:
  watchdog: BUG: soft lockup - CPU#28 stuck for 23s! [fio:83921]
  CPU#28 Utilization every 4s during lockup:
#1: 0% system, 0% softirq, 100% hardirq, 0% idle
#2: 0% system, 0% softirq, 100% hardirq, 0% idle
#3: 0% system, 0% softirq, 100% hardirq, 0% idle
#4: 0% system, 0% softirq, 100% hardirq, 0% idle
#5: 0% system, 0% softirq, 100% hardirq, 0% idle
  ...

This would be helpful in determining whether an interrupt storm has
occurred or in identifying the cause of the softlockup. The criteria for
determination are as follows:
  a. If the hardirq utilization is high, then interrupt storm should be
  considered and the root cause cannot be determined from the call tree.
  b. If the softirq utilization is high, then we could analyze the call
  tree but it may cannot reflect the root cause.
  c. If the system utilization is high, then we could analyze the root
  cause from the call tree.

The mechanism requires a considerable amount of global storage space
when configured for the maximum number of CPUs. Therefore, adding a
SOFTLOCKUP_DETECTOR_INTR_STORM Kconfig knob that defaults to "yes"
if the max number of CPUs is <= 128.

Signed-off-by: Bitao Hu 
Reviewed-by: Douglas Anderson 
Reviewed-by: Liu Song 
---
 kernel/watchdog.c | 98 ++-
 lib/Kconfig.debug | 13 +++
 2 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 81a8862295d6..69e72d7e461d 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -16,6 +16,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -35,6 +37,8 @@ static DEFINE_MUTEX(watchdog_mutex);
 # define WATCHDOG_HARDLOCKUP_DEFAULT   0
 #endif
 
+#define NUM_SAMPLE_PERIODS 5
+
 unsigned long __read_mostly watchdog_enabled;
 int __read_mostly watchdog_user_enabled = 1;
 static int __read_mostly watchdog_hardlockup_user_enabled = 
WATCHDOG_HARDLOCKUP_DEFAULT;
@@ -333,6 +337,95 @@ __setup("watchdog_thresh=", watchdog_thresh_setup);
 
 static void __lockup_detector_cleanup(void);
 
+#ifdef CONFIG_SOFTLOCKUP_DETECTOR_INTR_STORM
+enum stats_per_group {
+   STATS_SYSTEM,
+   STATS_SOFTIRQ,
+   STATS_HARDIRQ,
+   STATS_IDLE,
+   NUM_STATS_PER_GROUP,
+};
+
+static const enum cpu_usage_stat tracked_stats[NUM_STATS_PER_GROUP] = {
+   CPUTIME_SYSTEM,
+   CPUTIME_SOFTIRQ,
+   CPUTIME_IRQ,
+   CPUTIME_IDLE,
+};
+
+static DEFINE_PER_CPU(u16, cpustat_old[NUM_STATS_PER_GROUP]);
+static DEFINE_PER_CPU(u8, 
cpustat_util[NUM_SAMPLE_PERIODS][NUM_STATS_PER_GROUP]);
+static DEFINE_PER_CPU(u8, cpustat_tail);
+
+/*
+ * We don't need nanosecond resolution. A granularity of 16ms is
+ * sufficient for our precision, allowing us to use u16 to store
+ * cpustats, which will roll over roughly every ~1000 seconds.
+ * 2^24 ~= 16 * 10^6
+ */
+static u16 get_16bit_precision(u64 data_ns)
+{
+   return data_ns >> 24LL; /* 2^24ns ~= 16.8ms */
+}
+
+static void update_cpustat(void)
+{
+   int i;
+   u8 util;
+   u16 old_stat, new_stat;
+   struct kernel_cpustat kcpustat;
+   u64 *cpustat = kcpustat.cpustat;
+   u8 tail = __this_cpu_read(cpustat_tail);
+   u16 sample_period_16 = get_16bit_precision(sample_period);
+
+   kcpustat_cpu_fetch(, smp_processor_id());
+
+   for (i = 0; i < NUM_STATS_PER_GROUP; i++) {
+   old_stat = __this_cpu_read(cpustat_old[i]);
+   new_stat = get_16bit_precision(cpustat[tracked_stats[i]]);
+   util = DIV_ROUND_UP(100 * (new_stat - old_stat), 
sample_period_16);
+   __this_cpu_write(cpustat_util[tail][i], util);
+   __this_cpu_write(cpustat_old[i], new_stat);
+   }
+
+   __this_cpu_write(cpustat_tail, (tail + 1) % NUM_SAMPLE_PERIODS);
+}
+
+static void print_cpustat(void)
+{
+   int i, group;
+   u8 tail = __this_cpu_read(cpustat_tail);
+   u64 sample_period_second = sample_period;
+
+   do_div(sample_period_second, NSEC_PER_SEC);
+
+   /*
+* We do not want the "watchdog: " prefix on every line,
+* hence we use "printk" instead of "pr_crit".
+*/
+   printk(KERN_CRIT "CPU#%d Utilization every %llus during lockup:\n",
+  smp_processor_id(), sample_period_second);
+
+   for (i = 0; i < 

[PATCHv9 0/3] *** Detect interrupt storm in softlockup ***

2024-02-22 Thread Bitao Hu
Hi, guys.
I have implemented a low-overhead method for detecting interrupt
storm in softlockup. Please review it, all comments are welcome.

Changes from v8 to v9:

- Patch #1 remains unchanged.

- From Thomas Gleixner, split patch #2 into two patches. Interrupt
infrastructure first and then the actual usage site in the
watchdog code.

Changes from v7 to v8:

- From Thomas Gleixner, implement statistics within the interrupt
core code and provide sensible interfaces for the watchdog code.

- Patch #1 remains unchanged. Patch #2 has significant changes
based on Thomas's suggestions, which is why I have removed
Liu Song and Douglas's Reviewed-by from patch #2. Please review
it again, and all comments are welcome.

Changes from v6 to v7:

- Remove "READ_ONCE" in "start_counting_irqs"

- Replace the hard-coded 5 with "NUM_SAMPLE_PERIODS" macro in
"set_sample_period".

- Add empty lines to help with reading the code.

- Remove the branch that processes IRQs where "counts_diff = 0".

- Add the Reviewed-by of Liu Song and Douglas.

Changes from v5 to v6:

- Use "./scripts/checkpatch.pl --strict" to get a few extra
style nits and fix them.

- Squash patch #3 into patch #1, and wrapp the help text to
80 columns.

- Sort existing headers alphabetically in watchdog.c

- Drop "softlockup_hardirq_cpus", just read "hardirq_counts"
and see if it's non-NULL.

- Store "nr_irqs" in a local variable.

- Simplify the calculation of "cpu_diff".

Changes from v4 to v5:

- Rearranging variable placement to make code look neater.

Changes from v3 to v4:

- Renaming some variable and function names to make the code logic
more readable.

- Change the code location to avoid predeclaring.

- Just swap rather than a double loop in tabulate_irq_count.

- Since nr_irqs has the potential to grow at runtime, bounds-check
logic has been implemented.

- Add SOFTLOCKUP_DETECTOR_INTR_STORM Kconfig knob.

Changes from v2 to v3:

- From Liu Song, using enum instead of macro for cpu_stats, shortening
the name 'idx_to_stat' to 'stats', adding 'get_16bit_precesion' instead
of using right shift operations, and using 'struct irq_counts'.

- From kernel robot test, using '__this_cpu_read' and '__this_cpu_write'
instead of accessing to an per-cpu array directly, in order to avoid
this warning.
'sparse: incorrect type in initializer (different modifiers)'

Changes from v1 to v2:

- From Douglas, optimize the memory of cpustats. With the maximum number
of CPUs, that's now this.
2 * 8192 * 4 + 1 * 8192 * 5 * 4 + 1 * 8192 = 237,568 bytes.

- From Liu Song, refactor the code format and add necessary comments.

- From Douglas, use interrupt counts instead of interrupt time to
determine the cause of softlockup.

- Remove the cmdline parameter added in PATCHv1.

Bitao Hu (3):
  watchdog/softlockup: low-overhead detection of interrupt storm
  irq: use a struct for the kstat_irqs in the interrupt descriptor
  watchdog/softlockup: report the most frequent interrupts

 arch/mips/dec/setup.c|   2 +-
 arch/parisc/kernel/smp.c |   2 +-
 arch/powerpc/kvm/book3s_hv_rm_xics.c |   2 +-
 include/linux/irqdesc.h  |   9 +-
 include/linux/kernel_stat.h  |   3 +
 kernel/irq/internals.h   |   2 +-
 kernel/irq/irqdesc.c |  34 -
 kernel/irq/proc.c|   9 +-
 kernel/watchdog.c| 213 ++-
 lib/Kconfig.debug|  13 ++
 scripts/gdb/linux/interrupts.py  |   6 +-
 11 files changed, 268 insertions(+), 27 deletions(-)

-- 
2.37.1 (Apple Git-137.1)



Re: [PATCH RFC net] ps3/gelic: Fix possible NULL pointer dereference

2024-02-22 Thread Geert Uytterhoeven
Hi Simon,

On Wed, Feb 21, 2024 at 5:57 PM Simon Horman  wrote:
> Fix possible NULL pointer dereference in gelic_card_release_tx_chain()
>
> The cited commit introduced a netdev variable to
> gelic_card_release_tx_chain() which is set unconditionally on each
> iteration of a for loop.
>
> It is set to the value of tx_chain->tail->skb->dev.  However, in some
> cases it is assumed that tx_chain->tail->skb may be NULL. And if that
> occurs, setting netdev will cause a NULl pointer dereference.

Thanks for your patch!

> Given the age of this code I do wonder if this can occur in practice.
> But to be on the safe side this patch assumes that it can and aims to
> avoid the dereference in the case where tx_chain->tail->skb may be NULL.

The compiler may also lazy-load netdev until it's actually used,
avoiding the crash?

> Fixes: 589866f9f1cb ("PS3: gelic: Add support for dual network interface")
> Signed-off-by: Simon Horman 

Reviewed-by: Geert Uytterhoeven 

Gr{oetje,eeting}s,

Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


Re: [PATCH] powerpc/hv-gpci: Fix the hcall return value checks in single_gpci_request function

2024-02-22 Thread kajoljain



On 2/20/24 18:08, Michael Ellerman wrote:
> Kajol Jain  writes:
>> Running event 
>> hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
>> in one of the system throws below error:
>>
>>  ---Logs---
>>  # perf list | grep 
>> hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles
>>   
>> hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=?/[Kernel
>>  PMU event]
>>
>>
>>  # perf stat -v -e 
>> hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
>>  sleep 2
>> Using CPUID 00800200
>> Control descriptor is not initialized
>> Warning:
>> hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
>>  event is not supported by the kernel.
>> failed to read counter 
>> hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
>>
>>  Performance counter stats for 'system wide':
>>
>>  
>> hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
>>
>>2.000700771 seconds time elapsed
>>
>> The above error is because of the hcall failure as required
>> permission "Enable Performance Information Collection" is not set.
>> Based on current code, single_gpci_request function did not check the
>> error type incase hcall fails and by default returns EINVAL. But we can
>> have other reasons for hcall failures like H_AUTHORITY/H_PARAMETER for which
>> we need to act accordingly.
>> Fix this issue by adding new checks in the single_gpci_request function.
>>
>> Result after fix patch changes:
>>
>>  # perf stat -e 
>> hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
>>  sleep 2
>> Error:
>> No permission to enable 
>> hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
>>  event.
>>
>> Fixes: 220a0c609ad1 ("powerpc/perf: Add support for the hv gpci (get 
>> performance counter info) interface")
>> Reported-by: Akanksha J N 
>> Signed-off-by: Kajol Jain 
>> ---
>>  arch/powerpc/perf/hv-gpci.c | 29 +
>>  1 file changed, 25 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
>> index 27f18119fda1..101060facd81 100644
>> --- a/arch/powerpc/perf/hv-gpci.c
>> +++ b/arch/powerpc/perf/hv-gpci.c
>> @@ -695,7 +695,17 @@ static unsigned long single_gpci_request(u32 req, u32 
>> starting_index,
>>  
>>  ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
>>  virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE);
>> -if (ret) {
>> +
>> +/*
>> + * ret value as 'H_PARAMETER' corresponds to 'GEN_BUF_TOO_SMALL',
> 
> Don't we expect H_PARAMETER if any parameter value is incorrect?
> 
>> + * which means that the current buffer size cannot accommodate
>> + * all the information and a partial buffer returned.
> 
> I don't see how we can infer that H_PARAMETER means the buffer is too
> small and accessing the first entry is OK?

Hi Michael,
  Based on getCounterInfo documentation and the name convention it uses,
we actually used H_PARAMETER to specify the buffer issue incase buffer
cannot accommodate all the data.
Hence we are using that return value in the check.

Since based on hv-gpci event counter we only want data for specific
starting index and the hv-gpci hcall actually store data starting from
given starting index in the result buffer. We can ensure that accessing
first entry will be enough.

Thanks,
Kajol Jain


> 
> cheers
> 
>> + * Since in this function we are only accessing data for a given 
>> starting index,
>> + * we don't need to accommodate whole data and can get required count by
>> + * accessing very first entry.
>> + * Hence hcall fails only incase the ret value is other than H_SUCCESS 
>> or H_PARAMETER.
>> + */
>> +if (ret && (ret != H_PARAMETER)) {
>>  pr_devel("hcall failed: 0x%lx\n", ret);
>>  goto out;
>>  }


Re: [PATCH v2 03/13] mm: Provide generic pmd_thp_or_huge()

2024-02-22 Thread Peter Xu
On Wed, Feb 21, 2024 at 08:57:53AM -0400, Jason Gunthorpe wrote:
> On Wed, Feb 21, 2024 at 05:37:37PM +0800, Peter Xu wrote:
> > On Mon, Jan 15, 2024 at 01:55:51PM -0400, Jason Gunthorpe wrote:
> > > On Wed, Jan 03, 2024 at 05:14:13PM +0800, pet...@redhat.com wrote:
> > > > From: Peter Xu 
> > > > 
> > > > ARM defines pmd_thp_or_huge(), detecting either a THP or a huge PMD.  It
> > > > can be a helpful helper if we want to merge more THP and hugetlb code
> > > > paths.  Make it a generic default implementation, only exist when
> > > > CONFIG_MMU.  Arch can overwrite it by defining its own version.
> > > > 
> > > > For example, ARM's pgtable-2level.h defines it to always return false.
> > > > 
> > > > Keep the macro declared with all config, it should be optimized to a 
> > > > false
> > > > anyway if !THP && !HUGETLB.
> > > > 
> > > > Signed-off-by: Peter Xu 
> > > > ---
> > > >  include/linux/pgtable.h | 4 
> > > >  mm/gup.c| 3 +--
> > > >  2 files changed, 5 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> > > > index 466cf477551a..2b42e95a4e3a 100644
> > > > --- a/include/linux/pgtable.h
> > > > +++ b/include/linux/pgtable.h
> > > > @@ -1362,6 +1362,10 @@ static inline int pmd_write(pmd_t pmd)
> > > >  #endif /* pmd_write */
> > > >  #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
> > > >  
> > > > +#ifndef pmd_thp_or_huge
> > > > +#define pmd_thp_or_huge(pmd)   (pmd_huge(pmd) || pmd_trans_huge(pmd))
> > > > +#endif
> > > 
> > > Why not just use pmd_leaf() ?
> > > 
> > > This GUP case seems to me exactly like what pmd_leaf() should really
> > > do and be used for..
> > 
> > I think I mostly agree with you, and these APIs are indeed confusing.  IMHO
> > the challenge is about the risk of breaking others on small changes in the
> > details where evil resides.
> 
> These APIs are super confusing, which is why I brought it up.. Adding
> even more subtly different variations is not helping.
> 
> I think pmd_leaf means the entry is present and refers to a physical
> page not another radix level.
> 
> > > eg x86 does:
> > > 
> > > #define pmd_leaf  pmd_large
> > > static inline int pmd_large(pmd_t pte)
> > >   return pmd_flags(pte) & _PAGE_PSE;
> > > 
> > > static inline int pmd_trans_huge(pmd_t pmd)
> > >   return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE;
> > > 
> > > int pmd_huge(pmd_t pmd)
> > > return !pmd_none(pmd) &&
> > > (pmd_val(pmd) & (_PAGE_PRESENT|_PAGE_PSE)) != 
> > > _PAGE_PRESENT;
> > 
> > For example, here I don't think it's strictly pmd_leaf()? As pmd_huge()
> > will return true if PRESENT=0 && PSE=0 (as long as none pte ruled out
> > first), while pmd_leaf() will return false; I think that came from
> > cbef8478bee5. 
> 
> Yikes, but do you even want to handle non-present entries in GUP
> world? Isn't everything gated by !present in the first place?

I am as confused indeed.

> 
> > Besides that, there're also other cases where it's not clear of such direct
> > replacement, not until further investigated.  E.g., arm-3level has:
> > 
> > #define pmd_leaf(pmd)   pmd_sect(pmd)
> > #define pmd_sect(pmd)   ((pmd_val(pmd) & PMD_TYPE_MASK) == \
> >  PMD_TYPE_SECT)
> > #define PMD_TYPE_SECT   (_AT(pmdval_t, 1) << 0)
> > 
> > While pmd_huge() there relies on PMD_TABLE_BIT ()
> 
> I looked at tht, it looked OK.. 
> 
> #define PMD_TYPE_MASK   (_AT(pmdval_t, 3) << 0)
> #define PMD_TABLE_BIT   (_AT(pmdval_t, 1) << 1)
> 
> It is the same stuff, just a little confusingly written

True, my eyes decided to skip all the shifts. :-( Ok then, let me see
whether I can give it a stab on the pXd_huge() mess.

Thanks,

-- 
Peter Xu



Re: [PATCH 1/2] powerpc: Refactor __kernel_map_pages()

2024-02-22 Thread Christophe Leroy


Le 22/02/2024 à 06:32, Michael Ellerman a écrit :
> Christophe Leroy  writes:
>> __kernel_map_pages() is almost identical for PPC32 and RADIX.
>>
>> Refactor it.
>>
>> On PPC32 it is not needed for KFENCE, but to keep it simple
>> just make it similar to PPC64.
>>
>> Signed-off-by: Christophe Leroy 
>> ---
>>   arch/powerpc/include/asm/book3s/64/pgtable.h | 10 --
>>   arch/powerpc/include/asm/book3s/64/radix.h   |  2 --
>>   arch/powerpc/mm/book3s64/radix_pgtable.c | 14 --
>>   arch/powerpc/mm/pageattr.c   | 19 +++
>>   arch/powerpc/mm/pgtable_32.c | 15 ---
>>   5 files changed, 19 insertions(+), 41 deletions(-)
>>
>> diff --git a/arch/powerpc/mm/pageattr.c b/arch/powerpc/mm/pageattr.c
>> index 421db7c4f2a4..16b8d20d6ca8 100644
>> --- a/arch/powerpc/mm/pageattr.c
>> +++ b/arch/powerpc/mm/pageattr.c
>> @@ -101,3 +101,22 @@ int change_memory_attr(unsigned long addr, int 
>> numpages, long action)
>>  return apply_to_existing_page_range(_mm, start, size,
>>  change_page_attr, (void *)action);
>>   }
>> +
>> +#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE)
>> +#ifdef CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC
>> +void __kernel_map_pages(struct page *page, int numpages, int enable)
>> +{
>> +unsigned long addr = (unsigned long)page_address(page);
>> +
>> +if (PageHighMem(page))
>> +return;
>> +
>> +if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !radix_enabled())
>> +hash__kernel_map_pages(page, numpages, enable);
>> +else if (enable)
>> +set_memory_p(addr, numpages);
>> +else
>> +set_memory_np(addr, numpages);
>> +}
> 
> This doesn't build on 32-bit, eg. ppc32_allmodconfig:
> 
> ../arch/powerpc/mm/pageattr.c: In function '__kernel_map_pages':
> ../arch/powerpc/mm/pageattr.c:116:23: error: implicit declaration of function 
> 'hash__kernel_map_pages' [-Werror=implicit-function-declaration]
>116 | err = hash__kernel_map_pages(page, numpages, enable);
>|   ^~
> 
> I couldn't see a nice way to get around it, so ended up with:
> 
> void __kernel_map_pages(struct page *page, int numpages, int enable)
> {
>   int err;
>   unsigned long addr = (unsigned long)page_address(page);
> 
>   if (PageHighMem(page))
>   return;
> 
> #ifdef CONFIG_PPC_BOOK3S_64
>   if (!radix_enabled())
>   err = hash__kernel_map_pages(page, numpages, enable);
>   else
> #endif
>   if (enable)
>   err = set_memory_p(addr, numpages);
>   else
>   err = set_memory_np(addr, numpages);
> 


I missed something it seems. Not good to leave something unterminated 
when you leave for vacation and think it was finished when you come back.

The best solution I see is to move hash__kernel_map_pages() prototype 
somewhere else.

$ git grep -e hash__ -e radix__ -- arch/powerpc/include/asm/*.h
arch/powerpc/include/asm/bug.h:void hash__do_page_fault(struct pt_regs *);
arch/powerpc/include/asm/mmu.h:extern void radix__mmu_cleanup_all(void);
arch/powerpc/include/asm/mmu_context.h:extern void 
radix__switch_mmu_context(struct mm_struct *prev,
arch/powerpc/include/asm/mmu_context.h: return 
radix__switch_mmu_context(prev, next);
arch/powerpc/include/asm/mmu_context.h:extern int 
hash__alloc_context_id(void);
arch/powerpc/include/asm/mmu_context.h:void __init 
hash__reserve_context_id(int id);
arch/powerpc/include/asm/mmu_context.h: context_id = 
hash__alloc_context_id();
arch/powerpc/include/asm/mmu_context.h:  * radix__flush_all_mm() to 
determine the scope (local/global)
arch/powerpc/include/asm/mmu_context.h: radix__flush_all_mm(mm);


Maybe asm/mmu.h ?

Or mm/mmu_decl.h ?

Christophe