Blame SOURCES/github_f701ecad_a812e59a_timer_rhel7.6.patch

5022a5
commit f701ecad0f4b8d54b80455774b3ce4e328725a1b
5022a5
Author: Dave Anderson <anderson@redhat.com>
5022a5
Date:   Wed Nov 7 12:02:51 2018 -0500
5022a5
5022a5
    Implemented the functionality for a new MEMBER_TYPE_NAME() macro,
5022a5
    which will return a pointer to the type name string of a structure
5022a5
    member.  It is being put in place for the support of Linux 4.20
5022a5
    radix tree to xarray replacements, where structure member types may
5022a5
    be changed from radix_tree_root structures to xarray structures.
5022a5
    (anderson@redhat.com)
5022a5
5022a5
diff --git a/defs.h b/defs.h
5022a5
index bea70c5899ef..e8ade5778dd1 100644
5022a5
--- a/defs.h
5022a5
+++ b/defs.h
5022a5
@@ -2232,6 +2232,7 @@ struct array_table {
5022a5
 #define ANON_MEMBER_OFFSET_REQUEST ((struct datatype_member *)(-2))
5022a5
 #define MEMBER_TYPE_REQUEST ((struct datatype_member *)(-3))
5022a5
 #define STRUCT_SIZE_REQUEST ((struct datatype_member *)(-4))
5022a5
+#define MEMBER_TYPE_NAME_REQUEST ((struct datatype_member *)(-5))
5022a5
 
5022a5
 #define STRUCT_SIZE(X)      datatype_info((X), NULL, STRUCT_SIZE_REQUEST)
5022a5
 #define UNION_SIZE(X)       datatype_info((X), NULL, STRUCT_SIZE_REQUEST)
5022a5
@@ -2241,6 +2242,7 @@ struct array_table {
5022a5
 #define MEMBER_EXISTS(X,Y)  (datatype_info((X), (Y), NULL) >= 0)
5022a5
 #define MEMBER_SIZE(X,Y)    datatype_info((X), (Y), MEMBER_SIZE_REQUEST)
5022a5
 #define MEMBER_TYPE(X,Y)    datatype_info((X), (Y), MEMBER_TYPE_REQUEST)
5022a5
+#define MEMBER_TYPE_NAME(X,Y)    ((char *)datatype_info((X), (Y), MEMBER_TYPE_NAME_REQUEST))
5022a5
 #define ANON_MEMBER_OFFSET(X,Y)    datatype_info((X), (Y), ANON_MEMBER_OFFSET_REQUEST)
5022a5
 
5022a5
 /*
5022a5
@@ -4546,6 +4548,10 @@ struct gnu_request {
5022a5
     		struct objfile *obj;
5022a5
   	} global_iterator;
5022a5
 	struct load_module *lm;
5022a5
+	char *member_main_type_name;
5022a5
+	char *member_main_type_tag_name;
5022a5
+	char *member_target_type_name;
5022a5
+	char *member_target_type_tag_name;
5022a5
 };
5022a5
 
5022a5
 /*
5022a5
diff --git a/gdb-7.6.patch b/gdb-7.6.patch
5022a5
index ec63c0df82b9..87447fa44094 100644
5022a5
--- a/gdb-7.6.patch
5022a5
+++ b/gdb-7.6.patch
5022a5
@@ -2407,3 +2407,28 @@ diff -up gdb-7.6/opcodes/configure.orig gdb-7.6/opcodes/configure
5022a5
  #include <sys/ptrace.h>
5022a5
  #include <asm/types.h>
5022a5
  #include <sys/procfs.h>
5022a5
+--- gdb-7.6/gdb/symtab.c.orig
5022a5
++++ gdb-7.6/gdb/symtab.c
5022a5
+@@ -5500,7 +5500,7 @@ get_member_data(struct gnu_request *req,
5022a5
+ 	register short i;
5022a5
+ 	struct field *nextfield;
5022a5
+ 	short nfields;
5022a5
+-	struct type *typedef_type;
5022a5
++	struct type *typedef_type, *target_type;
5022a5
+ 
5022a5
+ 	req->member_offset = -1;
5022a5
+ 
5022a5
+@@ -5523,6 +5523,13 @@ get_member_data(struct gnu_request *req,
5022a5
+ 			req->member_offset = offset + nextfield->loc.bitpos;
5022a5
+ 			req->member_length = TYPE_LENGTH(nextfield->type);
5022a5
+ 			req->member_typecode = TYPE_CODE(nextfield->type);
5022a5
++			req->member_main_type_name = (char *)TYPE_NAME(nextfield->type);
5022a5
++			req->member_main_type_tag_name = (char *)TYPE_TAG_NAME(nextfield->type);
5022a5
++			target_type = TYPE_TARGET_TYPE(nextfield->type);
5022a5
++			if (target_type) {
5022a5
++				req->member_target_type_name = (char *)TYPE_NAME(target_type);
5022a5
++				req->member_target_type_tag_name = (char *)TYPE_TAG_NAME(target_type);
5022a5
++			}
5022a5
+ 			if ((req->member_typecode == TYPE_CODE_TYPEDEF) &&
5022a5
+ 			    (typedef_type = check_typedef(nextfield->type))) 
5022a5
+         			req->member_length = TYPE_LENGTH(typedef_type);
5022a5
diff --git a/gdb_interface.c b/gdb_interface.c
5022a5
index 3cf99c1b6529..608da86058c2 100755
5022a5
--- a/gdb_interface.c
5022a5
+++ b/gdb_interface.c
5022a5
@@ -512,6 +512,10 @@ dump_gnu_request(struct gnu_request *req, int in_gdb)
5022a5
 	console("member_offset: %ld\n", req->member_offset);
5022a5
 	console("member_length: %ld\n", req->member_length);
5022a5
         console("member_typecode: %d\n", req->member_typecode);
5022a5
+	console("member_main_type_name: %s\n", req->member_main_type_name);
5022a5
+	console("member_main_type_tag_name: %s\n", req->member_main_type_tag_name);
5022a5
+	console("member_target_type_name: %s\n", req->member_target_type_name);
5022a5
+	console("member_target_type_tag_name: %s\n", req->member_target_type_tag_name);
5022a5
 	console("value: %lx ", req->value);
5022a5
 	console("tagname: \"%s\" ", req->tagname);
5022a5
 	console("pc: %lx  ", req->pc);
5022a5
diff --git a/symbols.c b/symbols.c
5022a5
index 7966f129f80f..b1164613e342 100644
5022a5
--- a/symbols.c
5022a5
+++ b/symbols.c
5022a5
@@ -5447,6 +5447,7 @@ datatype_init(void)
5022a5
  *   #define MEMBER_EXISTS(X,Y)  (datatype_info((X), (Y), NULL) >= 0)
5022a5
  *   #define MEMBER_SIZE(X,Y)    datatype_info((X), (Y), MEMBER_SIZE_REQUEST)
5022a5
  *   #define MEMBER_TYPE(X,Y)    datatype_info((X), (Y), MEMBER_TYPE_REQUEST)
5022a5
+ *   #define MEMBER_TYPE_NAME(X,Y)      datatype_info((X), (Y), MEMBER_TYPE_NAME_REQUEST)
5022a5
  *   #define ANON_MEMBER_OFFSET(X,Y)    datatype_info((X), (Y), ANON_MEMBER_OFFSET_REQUEST)
5022a5
  *
5022a5
  *  to determine structure or union sizes, or member offsets.
5022a5
@@ -5473,9 +5474,9 @@ datatype_info(char *name, char *member, struct datatype_member *dm)
5022a5
 	req->fp = pc->nullfp;
5022a5
 
5022a5
 	gdb_interface(req);
5022a5
-        if (req->flags & GNU_COMMAND_FAILED) {
5022a5
+	if (req->flags & GNU_COMMAND_FAILED) {
5022a5
 		FREEBUF(req);
5022a5
-		return -1;
5022a5
+		return (dm == MEMBER_TYPE_NAME_REQUEST) ? 0 : -1;
5022a5
 	}
5022a5
 
5022a5
 	if (!req->typecode) {
5022a5
@@ -5591,7 +5592,7 @@ datatype_info(char *name, char *member, struct datatype_member *dm)
5022a5
 	FREEBUF(req);
5022a5
 
5022a5
         if (dm && (dm != MEMBER_SIZE_REQUEST) && (dm != MEMBER_TYPE_REQUEST) &&
5022a5
-	    (dm != STRUCT_SIZE_REQUEST)) {
5022a5
+	    (dm != STRUCT_SIZE_REQUEST) && (dm != MEMBER_TYPE_NAME_REQUEST)) {
5022a5
                 dm->type = type_found;
5022a5
                 dm->size = size;
5022a5
 		dm->member_size = member_size;
5022a5
@@ -5606,14 +5607,25 @@ datatype_info(char *name, char *member, struct datatype_member *dm)
5022a5
 		}
5022a5
         }
5022a5
 
5022a5
-        if (!type_found) 
5022a5
-        	return -1;
5022a5
+	if (!type_found) 
5022a5
+		return (dm == MEMBER_TYPE_NAME_REQUEST) ? 0 : -1;
5022a5
 
5022a5
 	if (dm == MEMBER_SIZE_REQUEST)
5022a5
 		return member_size;
5022a5
 	else if (dm == MEMBER_TYPE_REQUEST)
5022a5
 		return member_typecode;
5022a5
-	else if (dm == STRUCT_SIZE_REQUEST) {
5022a5
+	else if (dm == MEMBER_TYPE_NAME_REQUEST) {
5022a5
+		if (req->member_main_type_name)
5022a5
+			return (ulong)req->member_main_type_name;
5022a5
+		else if (req->member_main_type_tag_name)
5022a5
+			return (ulong)req->member_main_type_tag_name;
5022a5
+		else if (req->member_target_type_name)
5022a5
+			return (ulong)req->member_target_type_name;
5022a5
+		else if (req->member_target_type_tag_name)
5022a5
+			return (ulong)req->member_target_type_tag_name;
5022a5
+		else
5022a5
+			return 0;
5022a5
+	} else if (dm == STRUCT_SIZE_REQUEST) {
5022a5
 		if ((req->typecode == TYPE_CODE_STRUCT) || 
5022a5
 		    (req->typecode == TYPE_CODE_UNION) ||
5022a5
 		     req->is_typedef)
5022a5
commit a812e59a175c8c6197ae3dc78bd5e1613adcc57c
5022a5
Author: Dave Anderson <anderson@redhat.com>
5022a5
Date:   Fri Aug 2 12:03:40 2019 -0400
5022a5
5022a5
    Fix for the "timer" command in RHEL7.6 and later RHEL7 kernels.
5022a5
    Without the patch, the command emits extra faulty timer entries
5022a5
    because the tvec_root.vec[] and tvec.vec[] arrays are tracked using
5022a5
    hlist_head structures where list_head structures should be used.
5022a5
    (k-hagio@ab.jp.nec.com)
5022a5
5022a5
diff --git a/kernel.c b/kernel.c
5022a5
index 3cd5bf1aab73..1ef063226041 100644
5022a5
--- a/kernel.c
5022a5
+++ b/kernel.c
5022a5
@@ -53,7 +53,7 @@ static void dump_timer_data_timer_bases(const ulong *cpus);
5022a5
 struct tv_range;
5022a5
 static void init_tv_ranges(struct tv_range *, int, int, int);
5022a5
 static int do_timer_list(ulong,int, ulong *, void *,ulong *,struct tv_range *);
5022a5
-static int do_timer_list_v3(ulong, int, ulong *, void *,ulong *);
5022a5
+static int do_timer_list_v3(ulong, int, ulong *, void *,ulong *, long);
5022a5
 struct timer_bases_data;
5022a5
 static int do_timer_list_v4(struct timer_bases_data *);
5022a5
 static int compare_timer_data(const void *, const void *);
5022a5
@@ -8237,7 +8237,12 @@ dump_timer_data_tvec_bases_v3(const ulong *cpus)
5022a5
 	char buf3[BUFSIZE];
5022a5
 
5022a5
 	vec_root_size = vec_size = 0;
5022a5
-	head_size = SIZE(hlist_head);
5022a5
+
5022a5
+	if (STREQ(MEMBER_TYPE_NAME("tvec_root", "vec"), "list_head"))
5022a5
+		/* for RHEL7.6 or later */
5022a5
+		head_size = SIZE(list_head);
5022a5
+	else
5022a5
+		head_size = SIZE(hlist_head);
5022a5
 
5022a5
 	if ((i = get_array_length("tvec_root.vec", NULL, head_size)))
5022a5
 		vec_root_size = i;
5022a5
@@ -8275,15 +8280,15 @@ next_cpu:
5022a5
 	init_tv_ranges(tv, vec_root_size, vec_size, cpu);
5022a5
 
5022a5
 	count += do_timer_list_v3(tv[1].base + OFFSET(tvec_root_s_vec),
5022a5
-		vec_root_size, vec, NULL, NULL);
5022a5
+		vec_root_size, vec, NULL, NULL, head_size);
5022a5
 	count += do_timer_list_v3(tv[2].base + OFFSET(tvec_s_vec),
5022a5
-		vec_size, vec, NULL, NULL);
5022a5
+		vec_size, vec, NULL, NULL, head_size);
5022a5
 	count += do_timer_list_v3(tv[3].base + OFFSET(tvec_s_vec),
5022a5
-		vec_size, vec, NULL, NULL);
5022a5
+		vec_size, vec, NULL, NULL, head_size);
5022a5
 	count += do_timer_list_v3(tv[4].base + OFFSET(tvec_s_vec),
5022a5
-		vec_size, vec, NULL, NULL);
5022a5
+		vec_size, vec, NULL, NULL, head_size);
5022a5
 	count += do_timer_list_v3(tv[5].base + OFFSET(tvec_s_vec),
5022a5
-		vec_size, vec, NULL, NULL);
5022a5
+		vec_size, vec, NULL, NULL, head_size);
5022a5
 
5022a5
 	if (count)
5022a5
 		td = (struct timer_data *)
5022a5
@@ -8293,15 +8298,15 @@ next_cpu:
5022a5
 	get_symbol_data("jiffies", sizeof(ulong), &jiffies);
5022a5
 
5022a5
 	do_timer_list_v3(tv[1].base + OFFSET(tvec_root_s_vec),
5022a5
-		vec_root_size, vec, (void *)td, &highest);
5022a5
+		vec_root_size, vec, (void *)td, &highest, head_size);
5022a5
 	do_timer_list_v3(tv[2].base + OFFSET(tvec_s_vec),
5022a5
-		vec_size, vec, (void *)td, &highest);
5022a5
+		vec_size, vec, (void *)td, &highest, head_size);
5022a5
 	do_timer_list_v3(tv[3].base + OFFSET(tvec_s_vec),
5022a5
-		vec_size, vec, (void *)td, &highest);
5022a5
+		vec_size, vec, (void *)td, &highest, head_size);
5022a5
 	do_timer_list_v3(tv[4].base + OFFSET(tvec_s_vec),
5022a5
-		vec_size, vec, (void *)td, &highest);
5022a5
+		vec_size, vec, (void *)td, &highest, head_size);
5022a5
 	tdx = do_timer_list_v3(tv[5].base + OFFSET(tvec_s_vec),
5022a5
-		vec_size, vec, (void *)td, &highest);
5022a5
+		vec_size, vec, (void *)td, &highest, head_size);
5022a5
 
5022a5
 	qsort(td, tdx, sizeof(struct timer_data), compare_timer_data);
5022a5
 
5022a5
@@ -8627,7 +8632,8 @@ do_timer_list_v3(ulong vec_kvaddr,
5022a5
 	      int size, 
5022a5
 	      ulong *vec, 
5022a5
 	      void *option, 
5022a5
-	      ulong *highest)
5022a5
+	      ulong *highest,
5022a5
+	      long head_size)
5022a5
 {
5022a5
 	int i, t; 
5022a5
 	int count, tdx;
5022a5
@@ -8645,19 +8651,24 @@ do_timer_list_v3(ulong vec_kvaddr,
5022a5
 			tdx++;
5022a5
 	}
5022a5
 
5022a5
-	readmem(vec_kvaddr, KVADDR, vec, SIZE(hlist_head) * size, 
5022a5
+	readmem(vec_kvaddr, KVADDR, vec, head_size * size,
5022a5
 		"timer_list vec array", FAULT_ON_ERROR);
5022a5
 
5022a5
 	ld = &list_data;
5022a5
 	timer_list_buf = GETBUF(SIZE(timer_list));
5022a5
 
5022a5
-	for (i = count = 0; i < size; i++, vec_kvaddr += SIZE(hlist_head)) {
5022a5
+	for (i = count = 0; i < size; i++, vec_kvaddr += head_size) {
5022a5
 
5022a5
-		if (vec[i] == 0)
5022a5
-			continue;
5022a5
+		if (head_size == SIZE(list_head)) {
5022a5
+			if (vec[i*2] == vec_kvaddr)
5022a5
+				continue;
5022a5
+		} else {
5022a5
+			if (vec[i] == 0)
5022a5
+				continue;
5022a5
+		}
5022a5
 
5022a5
 		BZERO(ld, sizeof(struct list_data));
5022a5
-		ld->start = vec[i];
5022a5
+		ld->start = (head_size == SIZE(list_head)) ? vec[i*2] : vec[i];
5022a5
 		ld->list_head_offset = OFFSET(timer_list_entry);
5022a5
 		ld->end = vec_kvaddr;
5022a5
 		ld->flags = RETURN_ON_LIST_ERROR;
5022a5