Re: [PATCH 2/3] powerpc/kexec_load: add hotplug support

2024-06-10 Thread Sourabh Jain

Hello Hari,

On 10/06/24 15:08, Hari Bathini wrote:



On 22/05/24 6:43 pm, Sourabh Jain wrote:

Kernel commits b741092d5976 ("powerpc/crash: add crash CPU hotplug
support") and 849599b702ef ("powerpc/crash: add crash memory hotplug
support") added crash CPU/Memory hotplug support on PowerPC. This patch
extends that support for the kexec_load syscall.

During CPU/Memory hotplug events on PowerPC, two kexec segments,
elfcorehdr, and FDT, get updated by the kernel. To ensure the kernel
can safely update these two kexec segments for the kdump image loaded
using the kexec_load system call, the following changes are made:

1. Extra size is allocated for both elfcorehdr and FDT to accommodate
    additional resources in the future. For the elfcorehdr, the size 
hint
    is taken from /sys/kernel/crash_elfcorehdr_size sysfs, while for 
FDT,

    extra size is allocated to hold possible CPU nodes.

2. Both elfcorehdr and FDT are skipped from SHA calculation.

Cc: Aditya Gupta 
Cc: Baoquan He 
Cc: Coiby Xu 
Cc: Hari Bathini 
Cc: Mahesh Salgaonkar 
Signed-off-by: Sourabh Jain 
---
  kexec/arch/ppc64/crashdump-ppc64.c  |  16 ++-
  kexec/arch/ppc64/fdt.c  | 200 +++-
  kexec/arch/ppc64/include/arch/fdt.h |   2 +-
  kexec/arch/ppc64/kexec-elf-ppc64.c  |   2 +-
  kexec/arch/ppc64/kexec-ppc64.c  |  12 +-
  5 files changed, 225 insertions(+), 7 deletions(-)

diff --git a/kexec/arch/ppc64/crashdump-ppc64.c 
b/kexec/arch/ppc64/crashdump-ppc64.c

index 6d47898..c14b593 100644
--- a/kexec/arch/ppc64/crashdump-ppc64.c
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
@@ -476,7 +476,7 @@ int load_crashdump_segments(struct kexec_info 
*info, char* mod_cmdline,

  uint64_t max_addr, unsigned long min_base)
  {
  void *tmp;
-    unsigned long sz;
+    unsigned long sz, memsz;
  uint64_t elfcorehdr;
  int nr_ranges, align = 1024, i;
  unsigned long long end;
@@ -531,8 +531,18 @@ int load_crashdump_segments(struct kexec_info 
*info, char* mod_cmdline,

  }
  }
  -    elfcorehdr = add_buffer(info, tmp, sz, sz, align, min_base,
-    max_addr, 1);
+    memsz = sz;
+    /* To support --hotplug, replace the calculated minimum size 
with the
+ * value from /sys/kernel/crash_elfcorehdr_size and align it 
correctly.

+ */
+    if (do_hotplug) {
+    if (elfcorehdrsz > sz)
+    memsz = _ALIGN(elfcorehdrsz, align);
+    }
+
+    /* Record the location of the elfcorehdr for hotplug handling */
+    info->elfcorehdr = elfcorehdr = add_buffer(info, tmp, sz, memsz, 
align,

+   min_base, max_addr, 1);
  reserve(elfcorehdr, sz);
  /* modify and store the cmdline in a global array. This is later
   * read by flatten_device_tree and modified if required
diff --git a/kexec/arch/ppc64/fdt.c b/kexec/arch/ppc64/fdt.c
index 8bc6d2d..10abc29 100644
--- a/kexec/arch/ppc64/fdt.c
+++ b/kexec/arch/ppc64/fdt.c
@@ -17,6 +17,13 @@
  #include 
  #include 
  #include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../../kexec.h"
+#include "../../kexec-syscall.h"
    /*
   * Let the kernel know it booted from kexec, as some things (e.g.
@@ -46,17 +53,208 @@ static int fixup_kexec_prop(void *fdt)
  return 0;
  }
  +static inline bool is_dot_dir(char * d_path)
+{
+    return d_path[0] == '.';
+}
+
+/*
+ * Returns size of files including file name size under the given
+ * @cpu_node_path.
+ */
+static unsigned int get_cpu_node_size(char *cpu_node_path)
+{
+    DIR *d;
+    struct dirent *de;
+    struct stat statbuf;
+    unsigned int cpu_node_size = 0;
+    char cpu_prop_path[2 * PATH_MAX];
+
+    d = opendir(cpu_node_path);
+    if (!d)
+    return 0;
+
+    while ((de = readdir(d)) != NULL) {
+    if (de->d_type != DT_REG)
+    continue;
+
+    memset(cpu_prop_path, '\0', PATH_MAX);
+    snprintf(cpu_prop_path, 2 * PATH_MAX, "%s/%s", 
cpu_node_path, de->d_name);

+
+    if (stat(cpu_prop_path, &statbuf))
+    continue;
+
+    cpu_node_size += statbuf.st_size;
+    cpu_node_size += strlen(de->d_name);
+    }
+
+    return cpu_node_size;
+}
+
+/*
+ * Checks if the node specified by the given @path represents a CPU 
node.

+ *
+ * Returns true if the @path has a "device_type" file containing "cpu";
+ * otherwise, returns false.
+ */
+static bool is_cpu_node(char *path)
+{
+    FILE *file;
+    bool ret = false;
+    char device_type[4];
+
+    file = fopen(path, "r");
+    if (!file)
+    return false;
+
+    memset(device_type, '\0', 4);
+    if (fread(device_type, 1, 3, file) < 3)
+    goto out;
+
+    if (strcmp(device_type, "cpu"))
+    goto out;
+
+    ret = true;
+
+out:
+    fclose(file);
+    return ret;
+}
+
+static unsigned int get_threads_per_cpu(char *path)
+{
+    struct stat statbuf;
+    if (stat(path, &statbuf))
+    return 0;
+
+    return statbuf.st_size / 4;
+}
+
+/*
+ * Finds the following CPU attributes:
+ *
+ * cpus_in_system: Current

Re: [PATCH 2/3] powerpc/kexec_load: add hotplug support

2024-06-10 Thread Hari Bathini




On 22/05/24 6:43 pm, Sourabh Jain wrote:

Kernel commits b741092d5976 ("powerpc/crash: add crash CPU hotplug
support") and 849599b702ef ("powerpc/crash: add crash memory hotplug
support") added crash CPU/Memory hotplug support on PowerPC. This patch
extends that support for the kexec_load syscall.

During CPU/Memory hotplug events on PowerPC, two kexec segments,
elfcorehdr, and FDT, get updated by the kernel. To ensure the kernel
can safely update these two kexec segments for the kdump image loaded
using the kexec_load system call, the following changes are made:

1. Extra size is allocated for both elfcorehdr and FDT to accommodate
additional resources in the future. For the elfcorehdr, the size hint
is taken from /sys/kernel/crash_elfcorehdr_size sysfs, while for FDT,
extra size is allocated to hold possible CPU nodes.

2. Both elfcorehdr and FDT are skipped from SHA calculation.

Cc: Aditya Gupta 
Cc: Baoquan He 
Cc: Coiby Xu 
Cc: Hari Bathini 
Cc: Mahesh Salgaonkar 
Signed-off-by: Sourabh Jain 
---
  kexec/arch/ppc64/crashdump-ppc64.c  |  16 ++-
  kexec/arch/ppc64/fdt.c  | 200 +++-
  kexec/arch/ppc64/include/arch/fdt.h |   2 +-
  kexec/arch/ppc64/kexec-elf-ppc64.c  |   2 +-
  kexec/arch/ppc64/kexec-ppc64.c  |  12 +-
  5 files changed, 225 insertions(+), 7 deletions(-)

diff --git a/kexec/arch/ppc64/crashdump-ppc64.c 
b/kexec/arch/ppc64/crashdump-ppc64.c
index 6d47898..c14b593 100644
--- a/kexec/arch/ppc64/crashdump-ppc64.c
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
@@ -476,7 +476,7 @@ int load_crashdump_segments(struct kexec_info *info, char* 
mod_cmdline,
uint64_t max_addr, unsigned long min_base)
  {
void *tmp;
-   unsigned long sz;
+   unsigned long sz, memsz;
uint64_t elfcorehdr;
int nr_ranges, align = 1024, i;
unsigned long long end;
@@ -531,8 +531,18 @@ int load_crashdump_segments(struct kexec_info *info, char* 
mod_cmdline,
}
}
  
-	elfcorehdr = add_buffer(info, tmp, sz, sz, align, min_base,

-   max_addr, 1);
+   memsz = sz;
+   /* To support --hotplug, replace the calculated minimum size with the
+* value from /sys/kernel/crash_elfcorehdr_size and align it correctly.
+*/
+   if (do_hotplug) {
+   if (elfcorehdrsz > sz)
+   memsz = _ALIGN(elfcorehdrsz, align);
+   }
+
+   /* Record the location of the elfcorehdr for hotplug handling */
+   info->elfcorehdr = elfcorehdr = add_buffer(info, tmp, sz, memsz, align,
+  min_base, max_addr, 1);
reserve(elfcorehdr, sz);
/* modify and store the cmdline in a global array. This is later
 * read by flatten_device_tree and modified if required
diff --git a/kexec/arch/ppc64/fdt.c b/kexec/arch/ppc64/fdt.c
index 8bc6d2d..10abc29 100644
--- a/kexec/arch/ppc64/fdt.c
+++ b/kexec/arch/ppc64/fdt.c
@@ -17,6 +17,13 @@
  #include 
  #include 
  #include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../../kexec.h"
+#include "../../kexec-syscall.h"
  
  /*

   * Let the kernel know it booted from kexec, as some things (e.g.
@@ -46,17 +53,208 @@ static int fixup_kexec_prop(void *fdt)
return 0;
  }
  
+static inline bool is_dot_dir(char * d_path)

+{
+   return d_path[0] == '.';
+}
+
+/*
+ * Returns size of files including file name size under the given
+ * @cpu_node_path.
+ */
+static unsigned int get_cpu_node_size(char *cpu_node_path)
+{
+   DIR *d;
+   struct dirent *de;
+   struct stat statbuf;
+   unsigned int cpu_node_size = 0;
+   char cpu_prop_path[2 * PATH_MAX];
+
+   d = opendir(cpu_node_path);
+   if (!d)
+   return 0;
+
+   while ((de = readdir(d)) != NULL) {
+   if (de->d_type != DT_REG)
+   continue;
+
+   memset(cpu_prop_path, '\0', PATH_MAX);
+   snprintf(cpu_prop_path, 2 * PATH_MAX, "%s/%s", cpu_node_path, 
de->d_name);
+
+   if (stat(cpu_prop_path, &statbuf))
+   continue;
+
+   cpu_node_size += statbuf.st_size;
+   cpu_node_size += strlen(de->d_name);
+   }
+
+   return cpu_node_size;
+}
+
+/*
+ * Checks if the node specified by the given @path represents a CPU node.
+ *
+ * Returns true if the @path has a "device_type" file containing "cpu";
+ * otherwise, returns false.
+ */
+static bool is_cpu_node(char *path)
+{
+   FILE *file;
+   bool ret = false;
+   char device_type[4];
+
+   file = fopen(path, "r");
+   if (!file)
+   return false;
+
+   memset(device_type, '\0', 4);
+   if (fread(device_type, 1, 3, file) < 3)
+   goto out;
+
+   if (strcmp(device_type, "cpu"))
+   goto out;
+
+   ret = true;
+
+out:
+   fclose(file);
+   return ret;
+}
+
+static unsigned int get_thr

[PATCH 2/3] powerpc/kexec_load: add hotplug support

2024-05-22 Thread Sourabh Jain
Kernel commits b741092d5976 ("powerpc/crash: add crash CPU hotplug
support") and 849599b702ef ("powerpc/crash: add crash memory hotplug
support") added crash CPU/Memory hotplug support on PowerPC. This patch
extends that support for the kexec_load syscall.

During CPU/Memory hotplug events on PowerPC, two kexec segments,
elfcorehdr, and FDT, get updated by the kernel. To ensure the kernel
can safely update these two kexec segments for the kdump image loaded
using the kexec_load system call, the following changes are made:

1. Extra size is allocated for both elfcorehdr and FDT to accommodate
   additional resources in the future. For the elfcorehdr, the size hint
   is taken from /sys/kernel/crash_elfcorehdr_size sysfs, while for FDT,
   extra size is allocated to hold possible CPU nodes.

2. Both elfcorehdr and FDT are skipped from SHA calculation.

Cc: Aditya Gupta 
Cc: Baoquan He 
Cc: Coiby Xu 
Cc: Hari Bathini 
Cc: Mahesh Salgaonkar 
Signed-off-by: Sourabh Jain 
---
 kexec/arch/ppc64/crashdump-ppc64.c  |  16 ++-
 kexec/arch/ppc64/fdt.c  | 200 +++-
 kexec/arch/ppc64/include/arch/fdt.h |   2 +-
 kexec/arch/ppc64/kexec-elf-ppc64.c  |   2 +-
 kexec/arch/ppc64/kexec-ppc64.c  |  12 +-
 5 files changed, 225 insertions(+), 7 deletions(-)

diff --git a/kexec/arch/ppc64/crashdump-ppc64.c 
b/kexec/arch/ppc64/crashdump-ppc64.c
index 6d47898..c14b593 100644
--- a/kexec/arch/ppc64/crashdump-ppc64.c
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
@@ -476,7 +476,7 @@ int load_crashdump_segments(struct kexec_info *info, char* 
mod_cmdline,
uint64_t max_addr, unsigned long min_base)
 {
void *tmp;
-   unsigned long sz;
+   unsigned long sz, memsz;
uint64_t elfcorehdr;
int nr_ranges, align = 1024, i;
unsigned long long end;
@@ -531,8 +531,18 @@ int load_crashdump_segments(struct kexec_info *info, char* 
mod_cmdline,
}
}
 
-   elfcorehdr = add_buffer(info, tmp, sz, sz, align, min_base,
-   max_addr, 1);
+   memsz = sz;
+   /* To support --hotplug, replace the calculated minimum size with the
+* value from /sys/kernel/crash_elfcorehdr_size and align it correctly.
+*/
+   if (do_hotplug) {
+   if (elfcorehdrsz > sz)
+   memsz = _ALIGN(elfcorehdrsz, align);
+   }
+
+   /* Record the location of the elfcorehdr for hotplug handling */
+   info->elfcorehdr = elfcorehdr = add_buffer(info, tmp, sz, memsz, align,
+  min_base, max_addr, 1);
reserve(elfcorehdr, sz);
/* modify and store the cmdline in a global array. This is later
 * read by flatten_device_tree and modified if required
diff --git a/kexec/arch/ppc64/fdt.c b/kexec/arch/ppc64/fdt.c
index 8bc6d2d..10abc29 100644
--- a/kexec/arch/ppc64/fdt.c
+++ b/kexec/arch/ppc64/fdt.c
@@ -17,6 +17,13 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../../kexec.h"
+#include "../../kexec-syscall.h"
 
 /*
  * Let the kernel know it booted from kexec, as some things (e.g.
@@ -46,17 +53,208 @@ static int fixup_kexec_prop(void *fdt)
return 0;
 }
 
+static inline bool is_dot_dir(char * d_path)
+{
+   return d_path[0] == '.';
+}
+
+/*
+ * Returns size of files including file name size under the given
+ * @cpu_node_path.
+ */
+static unsigned int get_cpu_node_size(char *cpu_node_path)
+{
+   DIR *d;
+   struct dirent *de;
+   struct stat statbuf;
+   unsigned int cpu_node_size = 0;
+   char cpu_prop_path[2 * PATH_MAX];
+
+   d = opendir(cpu_node_path);
+   if (!d)
+   return 0;
+
+   while ((de = readdir(d)) != NULL) {
+   if (de->d_type != DT_REG)
+   continue;
+
+   memset(cpu_prop_path, '\0', PATH_MAX);
+   snprintf(cpu_prop_path, 2 * PATH_MAX, "%s/%s", cpu_node_path, 
de->d_name);
+
+   if (stat(cpu_prop_path, &statbuf))
+   continue;
+
+   cpu_node_size += statbuf.st_size;
+   cpu_node_size += strlen(de->d_name);
+   }
+
+   return cpu_node_size;
+}
+
+/*
+ * Checks if the node specified by the given @path represents a CPU node.
+ *
+ * Returns true if the @path has a "device_type" file containing "cpu";
+ * otherwise, returns false.
+ */
+static bool is_cpu_node(char *path)
+{
+   FILE *file;
+   bool ret = false;
+   char device_type[4];
+
+   file = fopen(path, "r");
+   if (!file)
+   return false;
+
+   memset(device_type, '\0', 4);
+   if (fread(device_type, 1, 3, file) < 3)
+   goto out;
+
+   if (strcmp(device_type, "cpu"))
+   goto out;
+
+   ret = true;
+
+out:
+   fclose(file);
+   return ret;
+}
+
+static unsigned int get_threads_per_cpu(char *path)
+{
+   struct stat statbuf;
+