Re: [PATCH] crash: s390x: Auto-detect the correct MAX_PHYSMEM_BITS used in vmcore being analyzed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Dave and Mahesh,

We also tried to solve the problem and came up with an alternative solution.

The function s390x_max_physmem_bits() solves the following equation:

array_len == NR_MEM_SECTIONS / SECTIONS_PER_ROOT
          
                 2^(MAX_PYSMEM_BITS - SECTION_SIZE_BITS)
                 ---------------------------------------
          ==                    PAGE_SIZE
                        -------------------------
                        sizeof(struct mem_section)

This leads to the following:

MAX_PYSMEM_BITS  == SECTION_SIZE_BITS + log2(array_len) + log2(PAGE_SIZE)
                         - log2(sizeof(struct mem_section));

I tested the patch with 42 and 46 bits and for both it seems to work.
I will leave now for vacation and will return January the 9th 2012.

I leave it to you which solution to take.

Merry Christmas!

Michael

PS: I think this patch also fixes a bug in verify_ptn()...
    BTOP vs. PTOB :-)
---
 kernel.c |    2 +-
 memory.c |    2 +-
 s390x.c  |   17 ++++++++++++++++-
 3 files changed, 18 insertions(+), 3 deletions(-)

--- a/kernel.c
+++ b/kernel.c
@@ -275,7 +275,7 @@ kernel_init()
         MEMBER_OFFSET_INIT(prio_array_nr_active, "prio_array", "nr_active");
 	STRUCT_SIZE_INIT(runqueue, rqstruct); 
 	STRUCT_SIZE_INIT(prio_array, "prio_array"); 
-
+	STRUCT_SIZE_INIT(mem_section, "mem_section");
 	MEMBER_OFFSET_INIT(rq_cfs, "rq", "cfs");
 
        /*
--- a/memory.c
+++ b/memory.c
@@ -13601,7 +13601,7 @@ verify_pfn(ulong pfn)
 	for (i = machdep->max_physmem_bits; i < machdep->bits; i++)
 		mask |= ((physaddr_t)1 << i);
 		
-	if (mask & BTOP(pfn))
+	if (mask & PTOB(pfn))
 		return FALSE;
 
 	return TRUE;
--- a/s390x.c
+++ b/s390x.c
@@ -17,6 +17,7 @@
  */
 #ifdef S390X
 #include <elf.h>
+#include <math.h>
 #include "defs.h"
 #include "netdump.h"
 
@@ -283,6 +284,19 @@ static void s390x_process_elf_notes(void
 }
 
 /*
+ * The older s390x kernels use _MAX_PHYSMEM_BITS as 42 and the
+ * newer kernels use 46 bits. This function calculates the bits
+ * via a generic function.
+ */
+static int s390x_max_physmem_bits(void)
+{
+	unsigned long array_len = get_array_length("mem_section", NULL, 0);
+
+	return _SECTION_SIZE_BITS + log2(array_len) + 12 /* log2(PAGE_SIZE) */
+		- log2(SIZE(mem_section));
+}
+
+/*
  *  Do all necessary machine-specific setup here.  This is called several
  *  times during initialization.
  */
@@ -350,13 +364,14 @@ s390x_init(int when)
 		if (!machdep->hz)
 			machdep->hz = HZ;
 		machdep->section_size_bits = _SECTION_SIZE_BITS;
-		machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
+		machdep->max_physmem_bits = s390x_max_physmem_bits();
 		s390x_offsets_init();
 		break;
 
 	case POST_INIT:
 		break;
 	}
+	fprintf(stderr, "XXX %d\n", machdep->max_physmem_bits);
 }
 
 /*

Hello Dave and Mahesh,

We also tried to solve the problem and came up with an alternative solution.

The function s390x_max_physmem_bits() solves the following equation:

array_len == NR_MEM_SECTIONS / SECTIONS_PER_ROOT
          
                 2^(MAX_PYSMEM_BITS - SECTION_SIZE_BITS)
                 ---------------------------------------
          ==                    PAGE_SIZE
                        -------------------------
                        sizeof(struct mem_section)

This leads to the following:

MAX_PYSMEM_BITS  == SECTION_SIZE_BITS + log2(array_len) + log2(PAGE_SIZE)
                         - log2(sizeof(struct mem_section));

I tested the patch with 42 and 46 bits and for both it seems to work.
I will leave now for vacation and will return January the 9th 2012.

I leave it to you which solution to take.

Merry Christmas!

Michael

PS: I think this patch also fixes a bug in verify_ptn()...
    BTOP vs. PTOB :-)
---
 kernel.c |    2 +-
 memory.c |    2 +-
 s390x.c  |   17 ++++++++++++++++-
 3 files changed, 18 insertions(+), 3 deletions(-)

--- a/kernel.c
+++ b/kernel.c
@@ -275,7 +275,7 @@ kernel_init()
         MEMBER_OFFSET_INIT(prio_array_nr_active, "prio_array", "nr_active");
 	STRUCT_SIZE_INIT(runqueue, rqstruct); 
 	STRUCT_SIZE_INIT(prio_array, "prio_array"); 
-
+	STRUCT_SIZE_INIT(mem_section, "mem_section");
 	MEMBER_OFFSET_INIT(rq_cfs, "rq", "cfs");
 
        /*
--- a/memory.c
+++ b/memory.c
@@ -13601,7 +13601,7 @@ verify_pfn(ulong pfn)
 	for (i = machdep->max_physmem_bits; i < machdep->bits; i++)
 		mask |= ((physaddr_t)1 << i);
 		
-	if (mask & BTOP(pfn))
+	if (mask & PTOB(pfn))
 		return FALSE;
 
 	return TRUE;
--- a/s390x.c
+++ b/s390x.c
@@ -17,6 +17,7 @@
  */
 #ifdef S390X
 #include <elf.h>
+#include <math.h>
 #include "defs.h"
 #include "netdump.h"
 
@@ -283,6 +284,19 @@ static void s390x_process_elf_notes(void
 }
 
 /*
+ * The older s390x kernels use _MAX_PHYSMEM_BITS as 42 and the
+ * newer kernels use 46 bits. This function calculates the bits
+ * via a generic function.
+ */
+static int s390x_max_physmem_bits(void)
+{
+	unsigned long array_len = get_array_length("mem_section", NULL, 0);
+
+	return _SECTION_SIZE_BITS + log2(array_len) + 12 /* log2(PAGE_SIZE) */
+		- log2(SIZE(mem_section));
+}
+
+/*
  *  Do all necessary machine-specific setup here.  This is called several
  *  times during initialization.
  */
@@ -350,13 +364,14 @@ s390x_init(int when)
 		if (!machdep->hz)
 			machdep->hz = HZ;
 		machdep->section_size_bits = _SECTION_SIZE_BITS;
-		machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
+		machdep->max_physmem_bits = s390x_max_physmem_bits();
 		s390x_offsets_init();
 		break;
 
 	case POST_INIT:
 		break;
 	}
+	fprintf(stderr, "XXX %d\n", machdep->max_physmem_bits);
 }
 
 /*
--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux