Blame SOURCES/github_f852f5ce_to_03a3e57b.patch

4eb2a4
commit f852f5ce4d28f88308f0e555c067e63e3edd7f37
4eb2a4
Author: Dave Anderson <anderson@redhat.com>
4eb2a4
Date:   Fri Nov 3 09:21:22 2017 -0400
4eb2a4
4eb2a4
    Fix for a "ps -l" regression introduced by the new "ps -y" option
4eb2a4
    introduced above.  Without the patch, the -l option generates a
4eb2a4
    segmentation violation if not accompanied by a -C cpu specifier
4eb2a4
    option.
4eb2a4
    (vinayakm.list@gmail.com)
4eb2a4
4eb2a4
diff --git a/task.c b/task.c
4eb2a4
index 5754159..f2628b7 100644
4eb2a4
--- a/task.c
4eb2a4
+++ b/task.c
4eb2a4
@@ -3485,7 +3485,7 @@ show_last_run(struct task_context *tc, struct psinfo *psi)
4eb2a4
 	sprintf(format, "[%c%dll%c] ", '%', c, 
4eb2a4
 		pc->output_radix == 10 ? 'u' : 'x');
4eb2a4
 
4eb2a4
-	if (psi) {
4eb2a4
+	if (psi && psi->cpus) {
4eb2a4
 		for (c = others = 0; c < kt->cpus; c++) {
4eb2a4
 			if (!NUM_IN_BITMAP(psi->cpus, c))
4eb2a4
 				continue;
4eb2a4
4eb2a4
commit 7ac1368cdca0fc2013bb3963456fcd2574c7cdd7
4eb2a4
Author: Dave Anderson <anderson@redhat.com>
4eb2a4
Date:   Mon Nov 6 10:48:40 2017 -0500
4eb2a4
4eb2a4
    Fix for the "kmem -i" and "kmem -V" options in Linux 4.8 and later
4eb2a4
    kernels containing commit 75ef7184053989118d3814c558a9af62e7376a58,
4eb2a4
    titled "mm, vmstat: add infrastructure for per-node vmstats".
4eb2a4
    Without the patch, the CACHED line of "kmem -i" shows 0, and the
4eb2a4
    VM_STAT section of "kmem -V" is missing entirely.
4eb2a4
    (vinayakm.list@gmail.com)
4eb2a4
4eb2a4
diff --git a/memory.c b/memory.c
4eb2a4
index ebd671a..3097558 100644
4eb2a4
--- a/memory.c
4eb2a4
+++ b/memory.c
4eb2a4
@@ -17340,30 +17340,43 @@ vm_stat_init(void)
4eb2a4
 	int c ATTRIBUTE_UNUSED;
4eb2a4
         struct gnu_request *req;
4eb2a4
 	char *start;
4eb2a4
-	long enum_value;
4eb2a4
+	long enum_value, zc = -1;
4eb2a4
+	int split_vmstat = 0, ni = 0;
4eb2a4
 
4eb2a4
 	if (vt->flags & VM_STAT)
4eb2a4
 		return TRUE;
4eb2a4
 
4eb2a4
-	if ((vt->nr_vm_stat_items == -1) || !symbol_exists("vm_stat"))
4eb2a4
+	if ((vt->nr_vm_stat_items == -1) ||
4eb2a4
+		(!symbol_exists("vm_stat") && !symbol_exists("vm_zone_stat")))
4eb2a4
 		goto bailout;
4eb2a4
 
4eb2a4
         /*
4eb2a4
          *  look for type: type = atomic_long_t []
4eb2a4
          */
4eb2a4
 	if (LKCD_KERNTYPES()) {
4eb2a4
-        	if (!symbol_exists("vm_stat"))
4eb2a4
+		if ((!symbol_exists("vm_stat") &&
4eb2a4
+				!symbol_exists("vm_zone_stat")))
4eb2a4
 			goto bailout;
4eb2a4
 		/* 
4eb2a4
 		 *  Just assume that vm_stat is an array; there is
4eb2a4
 		 *  no symbol info in a kerntypes file. 
4eb2a4
 		 */
4eb2a4
 	} else {
4eb2a4
-		if (!symbol_exists("vm_stat") ||
4eb2a4
-		    get_symbol_type("vm_stat", NULL, NULL) != TYPE_CODE_ARRAY)
4eb2a4
+		if (symbol_exists("vm_stat") &&
4eb2a4
+		    get_symbol_type("vm_stat", NULL, NULL) == TYPE_CODE_ARRAY) {
4eb2a4
+			vt->nr_vm_stat_items =
4eb2a4
+				get_array_length("vm_stat", NULL, 0);
4eb2a4
+		} else if (symbol_exists("vm_zone_stat") &&
4eb2a4
+			get_symbol_type("vm_zone_stat",
4eb2a4
+			NULL, NULL) == TYPE_CODE_ARRAY) {
4eb2a4
+			vt->nr_vm_stat_items =
4eb2a4
+				get_array_length("vm_zone_stat", NULL, 0)
4eb2a4
+				+ get_array_length("vm_node_stat", NULL, 0);
4eb2a4
+			split_vmstat = 1;
4eb2a4
+			enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zc);
4eb2a4
+		} else {
4eb2a4
 			goto bailout;
4eb2a4
-
4eb2a4
-		vt->nr_vm_stat_items = get_array_length("vm_stat", NULL, 0);
4eb2a4
+		}
4eb2a4
 	}
4eb2a4
 
4eb2a4
         open_tmpfile();
4eb2a4
@@ -17372,6 +17385,14 @@ vm_stat_init(void)
4eb2a4
         req->name = "zone_stat_item";
4eb2a4
         req->flags = GNU_PRINT_ENUMERATORS;
4eb2a4
         gdb_interface(req);
4eb2a4
+
4eb2a4
+	if (split_vmstat) {
4eb2a4
+		req->command = GNU_GET_DATATYPE;
4eb2a4
+		req->name = "node_stat_item";
4eb2a4
+		req->flags = GNU_PRINT_ENUMERATORS;
4eb2a4
+		gdb_interface(req);
4eb2a4
+	}
4eb2a4
+
4eb2a4
         FREEBUF(req);
4eb2a4
 
4eb2a4
 	stringlen = 1;
4eb2a4
@@ -17383,11 +17404,17 @@ vm_stat_init(void)
4eb2a4
 			continue;
4eb2a4
 		clean_line(buf);
4eb2a4
 		c = parse_line(buf, arglist);
4eb2a4
-		if (STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) {
4eb2a4
+		if ((!split_vmstat &&
4eb2a4
+			STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) ||
4eb2a4
+			(split_vmstat &&
4eb2a4
+			STREQ(arglist[0], "NR_VM_NODE_STAT_ITEMS"))) {
4eb2a4
 			if (LKCD_KERNTYPES())
4eb2a4
 				vt->nr_vm_stat_items = 
4eb2a4
 					MAX(atoi(arglist[2]), count);
4eb2a4
 			break;
4eb2a4
+		} else if (split_vmstat &&
4eb2a4
+			STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) {
4eb2a4
+			continue;
4eb2a4
 		} else {
4eb2a4
 			stringlen += strlen(arglist[0]);
4eb2a4
 			count++;
4eb2a4
@@ -17409,18 +17436,24 @@ vm_stat_init(void)
4eb2a4
                 if (strstr(buf, "{") || strstr(buf, "}"))
4eb2a4
                         continue;
4eb2a4
 		c = parse_line(buf, arglist);
4eb2a4
-		if (enumerator_value(arglist[0], &enum_value))
4eb2a4
-			i = enum_value;
4eb2a4
-		else {
4eb2a4
+		if (!enumerator_value(arglist[0], &enum_value)) {
4eb2a4
 			close_tmpfile();
4eb2a4
 			goto bailout;
4eb2a4
 		}
4eb2a4
+
4eb2a4
+		i = ni + enum_value;
4eb2a4
+		if (!ni && (enum_value == zc)) {
4eb2a4
+			ni = zc;
4eb2a4
+			continue;
4eb2a4
+		}
4eb2a4
+
4eb2a4
 		if (i < vt->nr_vm_stat_items) {
4eb2a4
 			vt->vm_stat_items[i] = start;
4eb2a4
 			strcpy(start, arglist[0]);
4eb2a4
 			start += strlen(arglist[0]) + 1;
4eb2a4
 		}
4eb2a4
         }
4eb2a4
+
4eb2a4
 	close_tmpfile();
4eb2a4
 
4eb2a4
 	vt->flags |= VM_STAT;
4eb2a4
@@ -17443,39 +17476,61 @@ dump_vm_stat(char *item, long *retval, ulong zone)
4eb2a4
 	ulong *vp;
4eb2a4
 	ulong location;
4eb2a4
 	int i, maxlen, len;
4eb2a4
+	long tc, zc = 0, nc = 0;
4eb2a4
+	int split_vmstat = 0;
4eb2a4
 
4eb2a4
 	if (!vm_stat_init()) {
4eb2a4
 		if (!item)
4eb2a4
 			if (CRASHDEBUG(1))
4eb2a4
-				error(INFO, 
4eb2a4
+				error(INFO,
4eb2a4
 			    	    "vm_stat not available in this kernel\n");
4eb2a4
 		return FALSE;
4eb2a4
 	}
4eb2a4
 
4eb2a4
 	buf = GETBUF(sizeof(ulong) * vt->nr_vm_stat_items);
4eb2a4
 
4eb2a4
-	location = zone ? zone : symbol_value("vm_stat");
4eb2a4
-
4eb2a4
-	readmem(location, KVADDR, buf, 
4eb2a4
-	    sizeof(ulong) * vt->nr_vm_stat_items, 
4eb2a4
-	    "vm_stat", FAULT_ON_ERROR);
4eb2a4
+	if (symbol_exists("vm_node_stat") && symbol_exists("vm_zone_stat"))
4eb2a4
+		split_vmstat = 1;
4eb2a4
+	else
4eb2a4
+		location = zone ? zone : symbol_value("vm_stat");
4eb2a4
+
4eb2a4
+	if (split_vmstat) {
4eb2a4
+		enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zc);
4eb2a4
+		location = zone ? zone : symbol_value("vm_zone_stat");
4eb2a4
+		readmem(location, KVADDR, buf,
4eb2a4
+			sizeof(ulong) * zc,
4eb2a4
+			"vm_zone_stat", FAULT_ON_ERROR);
4eb2a4
+		if (!zone) {
4eb2a4
+			location = symbol_value("vm_node_stat");
4eb2a4
+			enumerator_value("NR_VM_NODE_STAT_ITEMS", &nc);
4eb2a4
+			readmem(location, KVADDR, buf + (sizeof(ulong) * zc),
4eb2a4
+				sizeof(ulong) * nc,
4eb2a4
+				"vm_node_stat", FAULT_ON_ERROR);
4eb2a4
+		}
4eb2a4
+		tc = zc + nc;
4eb2a4
+	} else {
4eb2a4
+		readmem(location, KVADDR, buf,
4eb2a4
+			sizeof(ulong) * vt->nr_vm_stat_items,
4eb2a4
+			"vm_stat", FAULT_ON_ERROR);
4eb2a4
+		tc = vt->nr_vm_stat_items;
4eb2a4
+	}
4eb2a4
 
4eb2a4
 	if (!item) {
4eb2a4
 		if (!zone)
4eb2a4
 			fprintf(fp, "  VM_STAT:\n");
4eb2a4
-		for (i = maxlen = 0; i < vt->nr_vm_stat_items; i++)
4eb2a4
+		for (i = maxlen = 0; i < tc; i++)
4eb2a4
 			if ((len = strlen(vt->vm_stat_items[i])) > maxlen)
4eb2a4
 				maxlen = len;
4eb2a4
 		vp = (ulong *)buf;
4eb2a4
-		for (i = 0; i < vt->nr_vm_stat_items; i++)
4eb2a4
-			fprintf(fp, "%s%s: %ld\n", 
4eb2a4
+		for (i = 0; i < tc; i++)
4eb2a4
+			fprintf(fp, "%s%s: %ld\n",
4eb2a4
 				space(maxlen - strlen(vt->vm_stat_items[i])),
4eb2a4
 				 vt->vm_stat_items[i], vp[i]);
4eb2a4
 		return TRUE;
4eb2a4
 	}
4eb2a4
 
4eb2a4
 	vp = (ulong *)buf;
4eb2a4
-	for (i = 0; i < vt->nr_vm_stat_items; i++) {
4eb2a4
+	for (i = 0; i < tc; i++) {
4eb2a4
 		if (STREQ(vt->vm_stat_items[i], item)) {
4eb2a4
 			*retval = vp[i];
4eb2a4
 			return TRUE;
4eb2a4
4eb2a4
commit 333df037bc72aa81faf0904aaea29d43be2c724d
4eb2a4
Author: Dave Anderson <anderson@redhat.com>
4eb2a4
Date:   Mon Nov 6 11:01:45 2017 -0500
4eb2a4
4eb2a4
    Fix for Linux 4.11 and later kernels that contain kernel commit
4eb2a4
    4b3ef9daa4fc0bba742a79faecb17fdaaead083b, titled "mm/swap: split
4eb2a4
    swap cache into 64MB trunks".  Without the patch, the CACHED line
4eb2a4
    of "kmem -i" may show nonsensical data.
4eb2a4
    (vinayakm.list@gmail.com)
4eb2a4
4eb2a4
diff --git a/memory.c b/memory.c
4eb2a4
index 3097558..7537c43 100644
4eb2a4
--- a/memory.c
4eb2a4
+++ b/memory.c
4eb2a4
@@ -8236,7 +8236,44 @@ dump_kmeminfo(void)
4eb2a4
 		char *swapper_space = GETBUF(SIZE(address_space));
4eb2a4
 
4eb2a4
 		swapper_space_nrpages = 0;
4eb2a4
-		if (symbol_exists("swapper_spaces") && 
4eb2a4
+		if (symbol_exists("nr_swapper_spaces") &&
4eb2a4
+			(len = get_array_length("nr_swapper_spaces",
4eb2a4
+				NULL, 0))) {
4eb2a4
+			char *nr_swapper_space =
4eb2a4
+				GETBUF(len * sizeof(unsigned int));
4eb2a4
+			readmem(symbol_value("nr_swapper_spaces"), KVADDR,
4eb2a4
+				nr_swapper_space,  len * sizeof(unsigned int),
4eb2a4
+				"nr_swapper_space", RETURN_ON_ERROR);
4eb2a4
+			for (i = 0; i < len; i++) {
4eb2a4
+				int j;
4eb2a4
+				unsigned long sa;
4eb2a4
+				unsigned int banks = UINT(nr_swapper_space +
4eb2a4
+					(i * sizeof(unsigned int)));
4eb2a4
+
4eb2a4
+				if (!banks)
4eb2a4
+					continue;
4eb2a4
+
4eb2a4
+				readmem(symbol_value("swapper_spaces") +
4eb2a4
+					(i * sizeof(void *)),KVADDR,
4eb2a4
+					&sa, sizeof(void *),
4eb2a4
+					"swapper_space", RETURN_ON_ERROR);
4eb2a4
+
4eb2a4
+				if (!sa)
4eb2a4
+					continue;
4eb2a4
+
4eb2a4
+				for (j = 0; j < banks; j++) {
4eb2a4
+					readmem(sa + j * SIZE(address_space),
4eb2a4
+						KVADDR, swapper_space,
4eb2a4
+						SIZE(address_space),
4eb2a4
+						"swapper_space",
4eb2a4
+						RETURN_ON_ERROR);
4eb2a4
+					swapper_space_nrpages +=
4eb2a4
+						ULONG(swapper_space +
4eb2a4
+						OFFSET(address_space_nrpages));
4eb2a4
+				}
4eb2a4
+			}
4eb2a4
+			FREEBUF(nr_swapper_space);
4eb2a4
+		} else if (symbol_exists("swapper_spaces") &&
4eb2a4
 		    (len = get_array_length("swapper_spaces", NULL, 0))) {
4eb2a4
 			for (i = 0; i < len; i++) {
4eb2a4
 		    		if (!readmem(symbol_value("swapper_spaces") + 
4eb2a4
@@ -8253,7 +8290,7 @@ dump_kmeminfo(void)
4eb2a4
 		    RETURN_ON_ERROR))
4eb2a4
 			swapper_space_nrpages = ULONG(swapper_space + 
4eb2a4
 				OFFSET(address_space_nrpages));
4eb2a4
-			
4eb2a4
+
4eb2a4
 		page_cache_size = nr_file_pages - swapper_space_nrpages -
4eb2a4
 			buffer_pages;
4eb2a4
 		FREEBUF(swapper_space);
4eb2a4
4eb2a4
commit 613e5c7d6998c61880498537b4f288ef095cbe14
4eb2a4
Author: Dave Anderson <anderson@redhat.com>
4eb2a4
Date:   Mon Nov 6 15:12:59 2017 -0500
4eb2a4
4eb2a4
    Implemented a new "dev -D" option that is the same as "dev -d", but
4eb2a4
    filters out the display of disks that have no I/O in progress.
4eb2a4
    (oleksandr@redhat.com)
4eb2a4
4eb2a4
diff --git a/dev.c b/dev.c
4eb2a4
index e46081e..3db898a 100644
4eb2a4
--- a/dev.c
4eb2a4
+++ b/dev.c
4eb2a4
@@ -31,7 +31,7 @@ static const char *pci_strclass (uint, char *);
4eb2a4
 static const char *pci_strvendor(uint, char *); 
4eb2a4
 static const char *pci_strdev(uint, uint, char *); 
4eb2a4
 
4eb2a4
-static void diskio_option(void);
4eb2a4
+static void diskio_option(ulong flags);
4eb2a4
  
4eb2a4
 static struct dev_table {
4eb2a4
         ulong flags;
4eb2a4
@@ -42,6 +42,9 @@ struct dev_table *dt = &dev_table;
4eb2a4
 #define DEV_INIT    0x1
4eb2a4
 #define DISKIO_INIT 0x2
4eb2a4
 
4eb2a4
+#define DIOF_ALL	1 << 0
4eb2a4
+#define DIOF_NONZERO	1 << 1
4eb2a4
+
4eb2a4
 void
4eb2a4
 dev_init(void)
4eb2a4
 {
4eb2a4
@@ -93,11 +96,15 @@ cmd_dev(void)
4eb2a4
 
4eb2a4
 	flags = 0;
4eb2a4
 
4eb2a4
-        while ((c = getopt(argcnt, args, "dpi")) != EOF) {
4eb2a4
+        while ((c = getopt(argcnt, args, "dDpi")) != EOF) {
4eb2a4
                 switch(c)
4eb2a4
                 {
4eb2a4
 		case 'd':
4eb2a4
-			diskio_option();
4eb2a4
+			diskio_option(DIOF_ALL);
4eb2a4
+			return;
4eb2a4
+
4eb2a4
+		case 'D':
4eb2a4
+			diskio_option(DIOF_NONZERO);
4eb2a4
 			return;
4eb2a4
 
4eb2a4
 		case 'i':
4eb2a4
@@ -4002,7 +4009,7 @@ init_iter(struct iter *i)
4eb2a4
 }
4eb2a4
 
4eb2a4
 static void 
4eb2a4
-display_one_diskio(struct iter *i, unsigned long gendisk)
4eb2a4
+display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)
4eb2a4
 {
4eb2a4
 	char disk_name[BUFSIZE + 1];
4eb2a4
 	char buf0[BUFSIZE];
4eb2a4
@@ -4028,6 +4035,10 @@ display_one_diskio(struct iter *i, unsigned long gendisk)
4eb2a4
 		"gen_disk.major", FAULT_ON_ERROR);
4eb2a4
 	i->get_diskio(queue_addr, &io);
4eb2a4
 
4eb2a4
+	if ((flags & DIOF_NONZERO)
4eb2a4
+		&& (io.read + io.write == 0))
4eb2a4
+		return;
4eb2a4
+
4eb2a4
 	fprintf(fp, "%s%s%s  %s%s%s%s  %s%5d%s%s%s%s%s",
4eb2a4
 		mkstring(buf0, 5, RJUST|INT_DEC, (char *)(unsigned long)major),
4eb2a4
 		space(MINSPACE),
4eb2a4
@@ -4055,7 +4066,7 @@ display_one_diskio(struct iter *i, unsigned long gendisk)
4eb2a4
 }
4eb2a4
 
4eb2a4
 static void 
4eb2a4
-display_all_diskio(void)
4eb2a4
+display_all_diskio(ulong flags)
4eb2a4
 {
4eb2a4
 	struct iter i;
4eb2a4
 	unsigned long gendisk;
4eb2a4
@@ -4089,7 +4100,7 @@ display_all_diskio(void)
4eb2a4
 		mkstring(buf5, 5, RJUST, "DRV"));
4eb2a4
 
4eb2a4
 	while ((gendisk = i.next_disk(&i)) != 0)
4eb2a4
-		display_one_diskio(&i, gendisk);
4eb2a4
+		display_one_diskio(&i, gendisk, flags);
4eb2a4
 }
4eb2a4
 
4eb2a4
 static 
4eb2a4
@@ -4149,8 +4160,8 @@ void diskio_init(void)
4eb2a4
 }
4eb2a4
 
4eb2a4
 static void 
4eb2a4
-diskio_option(void)
4eb2a4
+diskio_option(ulong flags)
4eb2a4
 {
4eb2a4
 	diskio_init();
4eb2a4
-	display_all_diskio();
4eb2a4
+	display_all_diskio(flags);
4eb2a4
 }
4eb2a4
diff --git a/help.c b/help.c
4eb2a4
index f7f61a1..fa01bfb 100644
4eb2a4
--- a/help.c
4eb2a4
+++ b/help.c
4eb2a4
@@ -2722,7 +2722,7 @@ NULL
4eb2a4
 char *help_dev[] = {
4eb2a4
 "dev",
4eb2a4
 "device data",
4eb2a4
-"[-i | -p | -d]",
4eb2a4
+"[-i | -p | -d | -D]",
4eb2a4
 "  If no argument is entered, this command dumps character and block",
4eb2a4
 "  device data.\n",
4eb2a4
 "    -i  display I/O port usage; on 2.4 kernels, also display I/O memory usage.",
4eb2a4
@@ -2736,6 +2736,7 @@ char *help_dev[] = {
4eb2a4
 "           DRV: I/O requests that are in-flight in the device driver.",
4eb2a4
 "                If the device driver uses blk-mq interface, this field",
4eb2a4
 "                shows N/A(MQ).",
4eb2a4
+"    -D  same as -d, but filter out disks with no in-progress I/O requests.",
4eb2a4
 "\nEXAMPLES",
4eb2a4
 "  Display character and block device data:\n",
4eb2a4
 "    %s> dev",
4eb2a4
4eb2a4
commit 57eaba59bff54ab3158d3a909e9f64551e27accf
4eb2a4
Author: Dave Anderson <anderson@redhat.com>
4eb2a4
Date:   Wed Nov 8 14:22:16 2017 -0500
4eb2a4
4eb2a4
    If a line number request for a module text address initially fails,
4eb2a4
    force the embedded gdb module to complete its two-stage strategy
4eb2a4
    used for reading debuginfo symbol tables from module object files,
4eb2a4
    and then retry the line number extraction.  This automatically does
4eb2a4
    what the "mod -r" or "crash --readnow" options accomplish.
4eb2a4
    (anderson@redhat.com)
4eb2a4
4eb2a4
diff --git a/defs.h b/defs.h
4eb2a4
index 967fce0..18f36b3 100644
4eb2a4
--- a/defs.h
4eb2a4
+++ b/defs.h
4eb2a4
@@ -2688,6 +2688,7 @@ struct load_module {
4eb2a4
 	struct syment *mod_init_symend;
4eb2a4
 	ulong mod_percpu;
4eb2a4
 	ulong mod_percpu_size;
4eb2a4
+	struct objfile *loaded_objfile;
4eb2a4
 };
4eb2a4
 
4eb2a4
 #define IN_MODULE(A,L) \
4eb2a4
@@ -4479,6 +4480,7 @@ struct gnu_request {
4eb2a4
     		struct symbol *sym;
4eb2a4
     		struct objfile *obj;
4eb2a4
   	} global_iterator;
4eb2a4
+	struct load_module *lm;
4eb2a4
 };
4eb2a4
 
4eb2a4
 /*
4eb2a4
diff --git a/gdb-7.6.patch b/gdb-7.6.patch
4eb2a4
index 094f01a..6aeffda 100644
4eb2a4
--- a/gdb-7.6.patch
4eb2a4
+++ b/gdb-7.6.patch
4eb2a4
@@ -2323,3 +2323,72 @@ diff -up gdb-7.6/opcodes/configure.orig gdb-7.6/opcodes/configure
4eb2a4
      NO_WERROR="-Wno-error"
4eb2a4
  fi
4eb2a4
  
4eb2a4
+--- gdb-7.6/gdb/symtab.c.orig
4eb2a4
++++ gdb-7.6/gdb/symtab.c
4eb2a4
+@@ -5266,6 +5266,7 @@ gdb_get_line_number(struct gnu_request *
4eb2a4
+ {
4eb2a4
+         struct symtab_and_line sal;
4eb2a4
+ 	struct symbol *sym;
4eb2a4
++	struct objfile *objfile;
4eb2a4
+         CORE_ADDR pc;
4eb2a4
+ 
4eb2a4
+ #define LASTCHAR(s)      (s[strlen(s)-1])
4eb2a4
+@@ -5281,8 +5282,22 @@ gdb_get_line_number(struct gnu_request *
4eb2a4
+         sal = find_pc_line(pc, 0);
4eb2a4
+ 
4eb2a4
+ 	if (!sal.symtab) {
4eb2a4
+-		req->buf[0] = '\0';
4eb2a4
+-		return;
4eb2a4
++		/*
4eb2a4
++		 *  If a module address line number can't be found, it's typically
4eb2a4
++		 *  due to its addrmap still containing offset values because its 
4eb2a4
++		 *  objfile doesn't have full symbols loaded.
4eb2a4
++		 */
4eb2a4
++		if (req->lm) {
4eb2a4
++			objfile = req->lm->loaded_objfile;
4eb2a4
++			if (!objfile_has_full_symbols(objfile) && objfile->sf) { 
4eb2a4
++				objfile->sf->qf->expand_all_symtabs(objfile);
4eb2a4
++				sal = find_pc_line(pc, 0);
4eb2a4
++			}
4eb2a4
++		}
4eb2a4
++		if (!sal.symtab) {
4eb2a4
++			req->buf[0] = '\0';
4eb2a4
++			return;
4eb2a4
++		}
4eb2a4
+ 	}
4eb2a4
+ 
4eb2a4
+         if (sal.symtab->filename && sal.symtab->dirname) {
4eb2a4
+@@ -5557,7 +5572,6 @@ struct load_module *gdb_current_load_mod
4eb2a4
+ static void 
4eb2a4
+ gdb_add_symbol_file(struct gnu_request *req)
4eb2a4
+ {
4eb2a4
+-	register struct objfile *loaded_objfile = NULL;
4eb2a4
+ 	register struct objfile *objfile;
4eb2a4
+ 	register struct minimal_symbol *m;
4eb2a4
+ 	struct load_module *lm;
4eb2a4
+@@ -5576,6 +5590,7 @@ gdb_add_symbol_file(struct gnu_request *
4eb2a4
+ 
4eb2a4
+ 	req->name = lm->mod_namelist;
4eb2a4
+ 	gdb_delete_symbol_file(req);
4eb2a4
++	lm->loaded_objfile = NULL;
4eb2a4
+ 
4eb2a4
+ 	if ((lm->mod_flags & MOD_NOPATCH) == 0) {
4eb2a4
+ 	        for (i = 0 ; i < lm->mod_sections; i++) {
4eb2a4
+@@ -5623,12 +5638,15 @@ gdb_add_symbol_file(struct gnu_request *
4eb2a4
+ 
4eb2a4
+         ALL_OBJFILES(objfile) {
4eb2a4
+ 		if (same_file(objfile->name, lm->mod_namelist)) {
4eb2a4
+-                        loaded_objfile = objfile;
4eb2a4
++			if (objfile->separate_debug_objfile)
4eb2a4
++				lm->loaded_objfile = objfile->separate_debug_objfile;
4eb2a4
++			else
4eb2a4
++				lm->loaded_objfile = objfile;
4eb2a4
+ 			break;
4eb2a4
+ 		}
4eb2a4
+         }
4eb2a4
+ 
4eb2a4
+-	if (!loaded_objfile)
4eb2a4
++	if (!lm->loaded_objfile)
4eb2a4
+                 req->flags |= GNU_COMMAND_FAILED;
4eb2a4
+ }
4eb2a4
+ 
4eb2a4
diff --git a/symbols.c b/symbols.c
4eb2a4
index 8a4c878..0d85ff7 100644
4eb2a4
--- a/symbols.c
4eb2a4
+++ b/symbols.c
4eb2a4
@@ -3284,6 +3284,8 @@ dump_symbol_table(void)
4eb2a4
 				lm->mod_section_data[s].size);
4eb2a4
 		}
4eb2a4
 
4eb2a4
+		fprintf(fp, "        loaded_objfile: %lx\n", (ulong)lm->loaded_objfile);
4eb2a4
+
4eb2a4
 		if (CRASHDEBUG(1)) {
4eb2a4
         		for (sp = lm->mod_load_symtable; 
4eb2a4
 			     sp < lm->mod_load_symend; sp++) {
4eb2a4
@@ -4100,6 +4102,7 @@ get_line_number(ulong addr, char *buf, int reserved)
4eb2a4
 	struct load_module *lm;
4eb2a4
 
4eb2a4
 	buf[0] = NULLCHAR;
4eb2a4
+	lm = NULL;
4eb2a4
 
4eb2a4
 	if (NO_LINE_NUMBERS() || !is_kernel_text(addr))
4eb2a4
 		return(buf);
4eb2a4
@@ -4129,6 +4132,8 @@ get_line_number(ulong addr, char *buf, int reserved)
4eb2a4
 		req->command = GNU_GET_LINE_NUMBER;
4eb2a4
 		req->addr = addr;
4eb2a4
 		req->buf = buf;
4eb2a4
+		if (lm && lm->loaded_objfile)
4eb2a4
+			req->lm = lm;
4eb2a4
 		if ((sp = value_search(addr, NULL)))
4eb2a4
 			req->name = sp->name;
4eb2a4
 		gdb_interface(req);
4eb2a4
@@ -12025,6 +12030,7 @@ delete_load_module(ulong base_addr)
4eb2a4
 			if (lm->mod_section_data)
4eb2a4
 				free(lm->mod_section_data);
4eb2a4
 			lm->mod_section_data = (struct mod_section_data *)0;
4eb2a4
+			lm->loaded_objfile = NULL;
4eb2a4
 		}
4eb2a4
 		st->flags &= ~LOAD_MODULE_SYMS;
4eb2a4
 		return;
4eb2a4
@@ -12061,6 +12067,7 @@ delete_load_module(ulong base_addr)
4eb2a4
 			if (lm->mod_section_data)
4eb2a4
 				free(lm->mod_section_data);
4eb2a4
 			lm->mod_section_data = (struct mod_section_data *)0;
4eb2a4
+			lm->loaded_objfile = NULL;
4eb2a4
                 } else if (lm->mod_flags & MOD_LOAD_SYMS)
4eb2a4
 			st->flags |= LOAD_MODULE_SYMS;
4eb2a4
         }
4eb2a4
4eb2a4
commit c8178eca9c74f81a7f803a58d339635cc152e8d9
4eb2a4
Author: Dave Anderson <anderson@redhat.com>
4eb2a4
Date:   Thu Nov 9 11:39:05 2017 -0500
4eb2a4
4eb2a4
    Update for support of Linux 4.14 and later PPC64 kernels where the
4eb2a4
    hash page table geometry accomodates a larger virtual address range.
4eb2a4
    Without the patch, the virtual-to-physical translation of user space
4eb2a4
    virtual addresses by "vm -p", "vtop", and "rd -u" may generate an
4eb2a4
    invalid translation or otherwise fail.
4eb2a4
    (hbathini@linux.vnet.ibm.com)
4eb2a4
4eb2a4
diff --git a/defs.h b/defs.h
4eb2a4
index 18f36b3..9132075 100644
4eb2a4
--- a/defs.h
4eb2a4
+++ b/defs.h
4eb2a4
@@ -3915,6 +3915,9 @@ struct efi_memory_desc_t {
4eb2a4
 #define PGD_INDEX_SIZE_L4_64K_3_10  12
4eb2a4
 #define PMD_INDEX_SIZE_L4_64K_4_6  5
4eb2a4
 #define PUD_INDEX_SIZE_L4_64K_4_6  5
4eb2a4
+#define PMD_INDEX_SIZE_L4_64K_4_12 10
4eb2a4
+#define PUD_INDEX_SIZE_L4_64K_4_12 7
4eb2a4
+#define PGD_INDEX_SIZE_L4_64K_4_12 8
4eb2a4
 #define PTE_INDEX_SIZE_RADIX_64K  5
4eb2a4
 #define PMD_INDEX_SIZE_RADIX_64K  9
4eb2a4
 #define PUD_INDEX_SIZE_RADIX_64K  9
4eb2a4
diff --git a/ppc64.c b/ppc64.c
4eb2a4
index 84cec09..672ee60 100644
4eb2a4
--- a/ppc64.c
4eb2a4
+++ b/ppc64.c
4eb2a4
@@ -447,10 +447,16 @@ ppc64_init(int when)
4eb2a4
 				} else if (!(machdep->flags & BOOK3E) &&
4eb2a4
 				    (THIS_KERNEL_VERSION >= LINUX(4,6,0))) {
4eb2a4
 					m->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
4eb2a4
-					m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
4eb2a4
-					m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_6;
4eb2a4
-					m->l4_index_size = PGD_INDEX_SIZE_L4_64K_3_10;
4eb2a4
 
4eb2a4
+					if (THIS_KERNEL_VERSION >= LINUX(4,12,0)) {
4eb2a4
+						m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_12;
4eb2a4
+						m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_12;
4eb2a4
+						m->l4_index_size = PGD_INDEX_SIZE_L4_64K_4_12;
4eb2a4
+					} else {
4eb2a4
+						m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
4eb2a4
+						m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_6;
4eb2a4
+						m->l4_index_size = PGD_INDEX_SIZE_L4_64K_3_10;
4eb2a4
+					}
4eb2a4
 				} else if (THIS_KERNEL_VERSION >= LINUX(3,10,0)) {
4eb2a4
 					m->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
4eb2a4
 					m->l2_index_size = PMD_INDEX_SIZE_L4_64K_3_10;
4eb2a4
4eb2a4
commit 03a3e57b9ad849314e262cac37787604a9fe8362
4eb2a4
Author: Dave Anderson <anderson@redhat.com>
4eb2a4
Date:   Thu Nov 9 14:04:08 2017 -0500
4eb2a4
4eb2a4
    Implemented a new "runq -T" option that displays the time lag of each
4eb2a4
    CPU relative to the most recent runqueue timestamp.
4eb2a4
    (oleksandr@redhat.com)
4eb2a4
4eb2a4
diff --git a/help.c b/help.c
4eb2a4
index fa01bfb..e017b03 100644
4eb2a4
--- a/help.c
4eb2a4
+++ b/help.c
4eb2a4
@@ -2532,7 +2532,7 @@ NULL
4eb2a4
 char *help_runq[] = {
4eb2a4
 "runq",
4eb2a4
 "run queue",
4eb2a4
-"[-t] [-m] [-g] [-c cpu(s)]",
4eb2a4
+"[-t] [-T] [-m] [-g] [-c cpu(s)]",
4eb2a4
 "  With no argument, this command displays the tasks on the run queues",
4eb2a4
 "  of each cpu.",
4eb2a4
 " ",
4eb2a4
@@ -2541,6 +2541,8 @@ char *help_runq[] = {
4eb2a4
 "         whichever applies; following each cpu timestamp is the last_run or ",
4eb2a4
 "         timestamp value of the active task on that cpu, whichever applies, ",
4eb2a4
 "         along with the task identification.",
4eb2a4
+"     -T  Display the time lag of each CPU relative to the most recent runqueue",
4eb2a4
+"         timestamp.",
4eb2a4
 "     -m  Display the amount of time that the active task on each cpu has been",
4eb2a4
 "         running, expressed in a format consisting of days, hours, minutes, ",
4eb2a4
 "         seconds and milliseconds.",
4eb2a4
diff --git a/task.c b/task.c
4eb2a4
index f2628b7..724532d 100644
4eb2a4
--- a/task.c
4eb2a4
+++ b/task.c
4eb2a4
@@ -55,6 +55,7 @@ static long rq_idx(int);
4eb2a4
 static long cpu_idx(int);
4eb2a4
 static void dump_runq(void);
4eb2a4
 static void dump_on_rq_timestamp(void);
4eb2a4
+static void dump_on_rq_lag(void);
4eb2a4
 static void dump_on_rq_milliseconds(void);
4eb2a4
 static void dump_runqueues(void);
4eb2a4
 static void dump_prio_array(int, ulong, char *);
4eb2a4
@@ -8045,10 +8046,11 @@ cmd_runq(void)
4eb2a4
 	ulong *cpus = NULL;
4eb2a4
 	int sched_debug = 0;
4eb2a4
 	int dump_timestamp_flag = 0;
4eb2a4
+	int dump_lag_flag = 0;
4eb2a4
 	int dump_task_group_flag = 0;
4eb2a4
 	int dump_milliseconds_flag = 0;
4eb2a4
 
4eb2a4
-        while ((c = getopt(argcnt, args, "dtgmc:")) != EOF) {
4eb2a4
+        while ((c = getopt(argcnt, args, "dtTgmc:")) != EOF) {
4eb2a4
                 switch(c)
4eb2a4
                 {
4eb2a4
 		case 'd':
4eb2a4
@@ -8057,6 +8059,9 @@ cmd_runq(void)
4eb2a4
 		case 't':
4eb2a4
 			dump_timestamp_flag = 1;
4eb2a4
 			break;
4eb2a4
+		case 'T':
4eb2a4
+			dump_lag_flag = 1;
4eb2a4
+			break;
4eb2a4
 		case 'm':
4eb2a4
 			dump_milliseconds_flag = 1;
4eb2a4
 			break;
4eb2a4
@@ -8092,6 +8097,8 @@ cmd_runq(void)
4eb2a4
 
4eb2a4
 	if (dump_timestamp_flag)
4eb2a4
                 dump_on_rq_timestamp();
4eb2a4
+	else if (dump_lag_flag)
4eb2a4
+		dump_on_rq_lag();
4eb2a4
 	else if (dump_milliseconds_flag)
4eb2a4
                 dump_on_rq_milliseconds();
4eb2a4
 	else if (sched_debug)
4eb2a4
@@ -8177,6 +8184,90 @@ dump_on_rq_timestamp(void)
4eb2a4
 }
4eb2a4
 
4eb2a4
 /*
4eb2a4
+ * Runqueue timestamp struct for dump_on_rq_lag().
4eb2a4
+ */
4eb2a4
+struct runq_ts_info {
4eb2a4
+	int cpu;
4eb2a4
+	ulonglong ts;
4eb2a4
+};
4eb2a4
+
4eb2a4
+/*
4eb2a4
+ * Comparison function for dump_on_rq_lag().
4eb2a4
+ * Sorts runqueue timestamps in a descending order.
4eb2a4
+ */
4eb2a4
+static int
4eb2a4
+compare_runq_ts(const void *p1, const void *p2)
4eb2a4
+{
4eb2a4
+	const struct runq_ts_info *ts1 = p1;
4eb2a4
+	const struct runq_ts_info *ts2 = p2;
4eb2a4
+
4eb2a4
+	if (ts1->ts > ts2->ts)
4eb2a4
+		return -1;
4eb2a4
+
4eb2a4
+	if (ts1->ts < ts2->ts)
4eb2a4
+		return 1;
4eb2a4
+
4eb2a4
+	return 0;
4eb2a4
+}
4eb2a4
+
4eb2a4
+/*
4eb2a4
+ * Calculates integer log10
4eb2a4
+ */
4eb2a4
+static ulong
4eb2a4
+__log10ul(ulong x)
4eb2a4
+{
4eb2a4
+	ulong ret = 1;
4eb2a4
+
4eb2a4
+	while (x > 9) {
4eb2a4
+		ret++;
4eb2a4
+		x /= 10;
4eb2a4
+	}
4eb2a4
+
4eb2a4
+	return ret;
4eb2a4
+}
4eb2a4
+
4eb2a4
+/*
4eb2a4
+ * Displays relative CPU lag.
4eb2a4
+ */
4eb2a4
+static void
4eb2a4
+dump_on_rq_lag(void)
4eb2a4
+{
4eb2a4
+	struct syment *rq_sp;
4eb2a4
+	int cpu;
4eb2a4
+	ulong runq;
4eb2a4
+	ulonglong timestamp;
4eb2a4
+	struct runq_ts_info runq_ts[kt->cpus];
4eb2a4
+
4eb2a4
+	if (!(rq_sp = per_cpu_symbol_search("per_cpu__runqueues")))
4eb2a4
+		error(FATAL, "per-cpu runqueues do not exist\n");
4eb2a4
+	if (INVALID_MEMBER(rq_timestamp))
4eb2a4
+		option_not_supported('T');
4eb2a4
+
4eb2a4
+	for (cpu = 0; cpu < kt->cpus; cpu++) {
4eb2a4
+		if ((kt->flags & SMP) && (kt->flags &PER_CPU_OFF))
4eb2a4
+			runq = rq_sp->value + kt->__per_cpu_offset[cpu];
4eb2a4
+		else
4eb2a4
+			runq = rq_sp->value;
4eb2a4
+
4eb2a4
+		readmem(runq + OFFSET(rq_timestamp), KVADDR, &timestamp,
4eb2a4
+				sizeof(ulonglong), "per-cpu rq timestamp",
4eb2a4
+				FAULT_ON_ERROR);
4eb2a4
+
4eb2a4
+		runq_ts[cpu].cpu = cpu;
4eb2a4
+		runq_ts[cpu].ts = timestamp;
4eb2a4
+	}
4eb2a4
+
4eb2a4
+	qsort(runq_ts, (size_t)kt->cpus, sizeof(struct runq_ts_info), compare_runq_ts);
4eb2a4
+
4eb2a4
+	for (cpu = 0; cpu < kt->cpus; cpu++) {
4eb2a4
+		fprintf(fp, "%sCPU %d: %.2lf secs\n",
4eb2a4
+			space(2 + __log10ul(kt->cpus) - __log10ul(runq_ts[cpu].cpu)),
4eb2a4
+			runq_ts[cpu].cpu,
4eb2a4
+			((double)runq_ts[0].ts - (double)runq_ts[cpu].ts) / 1000000000.0);
4eb2a4
+	}
4eb2a4
+}
4eb2a4
+
4eb2a4
+/*
4eb2a4
  *  Displays the runqueue and active task timestamps of each cpu.
4eb2a4
  */
4eb2a4
 static void