[PATCH v5 1/3] powerpc: make fadump resilient with memory add/remove events

Sourabh Jain sourabhjain at linux.ibm.com
Mon Nov 13 17:42:07 AEDT 2023


Hello Michael,


On 09/11/23 17:44, Michael Ellerman wrote:
> Hi Sourabh,
>
> This seems like a good change to the design, but I'm confused by
> some things, more below ...

Thanks.

> Sourabh Jain <sourabhjain at linux.ibm.com> writes:
> ...
>> Table 1 below illustrates kernel's ability to collect dump if either the
>> first/crashed kernel or the second/fadump kernel does not have the
>> changes introduced here. Consider the 'old kernel' as the kernel without
>> this patch, and the 'new kernel' as the kernel with this patch included.
>>
>> +----------+------------------------+------------------------+-------+
>> | scenario |  first/crashed kernel  |  second/fadump kernel  |  Dump |
>> +----------+------------------------+------------------------+-------+
>> |    1     |       old kernel       |        new kernel      |  Yes  |
>> +----------+------------------------+------------------------+-------+
>> |    2     |       new kernel       |        old kernel      |  No   |
>> +----------+------------------------+------------------------+-------+
>>
>> 			      Table 1
>>
>> Scenario 1:
>> -----------
>> Since the magic number of fadump header is updated, the second kernel
>> can differentiate the crashed kernel is of type 'new kernel' or
>> 'old kernel' and act accordingly. In this scenario, since the crashed
>> kernel is of type 'old kernel,' the fadump kernel skips elfcorehdr
>> creation and uses the one prepared in the first kernel itself to collect
>> the dump.
>>
>> Scenario 2:
>> -----------
>> Since 'old kernel' as the fadump kernel is NOT capable of processing
>> fadump header with updated magic number from 'new kernel' hence it
>> gracefully fails with the below error and dump collection fails in this
>> scenario.
>>
>> [    0.007365] rtas fadump: Crash info header is not valid.
>>
>> Add a version field to the fadump_crash_info_header structure to avoid
>> the need to change its magic number in the future. Adding a version
>> field to the fadump header was one of the TODO items listed in
>> Documentation/powerpc/firmware-assisted-dump.rst.
> This is a good analysis of the issues with different kernel versions,
> and seems like an OK trade off, ie. that old kernels can't process dumps
> from new kernels.
>
> But do we actually support using different kernel versions for the
> crash/dump kernel?
>
> Because AFAICS the fadump_crash_info_header is not safe across kernel
> versions, in its current form or with your changes.

Yeah, I was also under the impression that it is not supported, but I 
was not aware
that the size of pt_regs and cpumask can change based on the configuration.

>
>> diff --git a/arch/powerpc/include/asm/fadump-internal.h b/arch/powerpc/include/asm/fadump-internal.h
>> index 27f9e11eda28..7be3d8894520 100644
>> --- a/arch/powerpc/include/asm/fadump-internal.h
>> +++ b/arch/powerpc/include/asm/fadump-internal.h
>> @@ -42,7 +42,25 @@ static inline u64 fadump_str_to_u64(const char *str)
>>   
>>   #define FADUMP_CPU_UNKNOWN		(~((u32)0))
>>   
>> -#define FADUMP_CRASH_INFO_MAGIC		fadump_str_to_u64("FADMPINF")
>> +/*
>> + * The introduction of new fields in the fadump crash info header has
>> + * led to a change in the magic key, from `FADMPINF` to `FADMPSIG`.
>> + * This alteration ensures backward compatibility, enabling the kernel
>> + * with the updated fadump crash info to handle kernel dumps from older
>> + * kernels.
>> + *
>> + * To prevent the need for further changes to the magic number in the
>> + * event of future modifications to the fadump header, a version field
>> + * has been introduced to track the fadump crash info header version.
>> + *
>> + * Historically, there was no connection between the magic number and
>> + * the fadump crash info header version. However, moving forward, the
>> + * `FADMPINF` magic number in header will be treated as version 0, while
>> + * the `FADMPSIG` magic number in header will include a version field to
>> + * determine its version.
>> + */
>> +#define FADUMP_CRASH_INFO_MAGIC		fadump_str_to_u64("FADMPSIG")
>> +#define FADUMP_VERSION			1
>>   
>>   /* fadump crash info structure */
>>   struct fadump_crash_info_header {
>> @@ -51,6 +69,10 @@ struct fadump_crash_info_header {
>>
> struct fadump_crash_info_header {
> 	u64		magic_number;
> 	u64		elfcorehdr_addr;
>
>>   	u32		crashing_cpu;
>>   	struct pt_regs	regs;
>>   	struct cpumask	cpu_mask;
>> +	u32		version;
>> +	u64		elfcorehdr_size;
>> +	u64		vmcoreinfo_raddr;
>> +	u64		vmcoreinfo_size;
>>   };
> The reason I say it's not safe is because pt_regs and especially cpumask
> can change size depending on the kernel configuration.
>
> pt_regs probably doesn't change size in practice for common kernel
> configurations, but some of the fields are under #ifdef.
>
> cpumask on the other hand is directly controlled by CONFIG_NR_CPUS. So
> if the first and second kernel have a different value for NR_CPUS they
> will disagree on the size of the struct.
>
> That has presumably worked OK so far because folks tend to use the same, or
> similar kernels for the first/second kernel. And also the cpumask is the
> last element of the struct, so a disagreement about it size doesn't
> affect the location of other fields.
>
> However with your new design the version field will move based on the
> cpumask size, which will potentially break detection of the version by
> the second kernel.
>
> At least that's how it looks to me, I don't see any checks anywhere that
> will save us, or did I miss something?
I agree with you. If the sizes of pt_regs and cpu_mask are different between
the first/crash kernel and the fadump/second kernel, the dump collection
might not work correctly.

Given that dump capture is not supported across kernel versions, I think 
it is
better to keep new attributes introduced in this patch to struct 
fadump_crash_info_header
before pt_regs and cpumask. For example:

/* fadump crash info structure */
struct fadump_crash_info_header {
     u64        magic_number;
+  u32        version;
+  u64        vmcoreinfo_raddr;
+  u64        vmcoreinfo_size;
     u64        elfcorehdr_addr;
+  u64        elfcorehdr_size;
     u32        crashing_cpu;
     struct pt_regs    regs;
     struct cpumask    cpu_mask;
};

Kernel with this patch included will not process the dump if 
fadump_crash_info_header
holds old magic number.

Something like:

     if (fdh->magic_number == fadump_str_to_u64("FADMPINF")) {
         pr_err("Incompatible fadump header, can't process the dump");
     }

Does this approach look good to you?

Thanks,
Sourabh


More information about the Linuxppc-dev mailing list