Blame SOURCES/github_361f050e_dev-d.patch

608733
commit 361f050e3148c6188afb45942e06d4a509852b86
608733
Author: Dave Anderson <anderson@redhat.com>
608733
Date:   Mon Jan 7 13:56:15 2019 -0500
608733
608733
    Fix for the "dev -[dD]" options in kernels containing Linux 5.0-rc1
608733
    commit 7ff4f8035695984c513598e2d49c8277d5d234ca, titled "block:
608733
    remove dead queue members", in which the number of I/Os issued to
608733
    a disk driver are no longer stored in the request_queue structure.
608733
    Without the patch, the options indicate "dev: -d option not supported
608733
    or applicable on this architecture or kernel".  With the patch, the
608733
    "DRV" column is not shown.
608733
    (m.mizuma@jp.fujitsu.com)
608733
608733
diff --git a/defs.h b/defs.h
608733
index a3cb5a4..9ebdde6 100644
608733
--- a/defs.h
608733
+++ b/defs.h
608733
@@ -2043,6 +2043,8 @@ struct offset_table {
608733
         long pci_bus_self;
608733
         long device_kobj;
608733
         long kobject_name;
608733
+	long hd_struct_dkstats;
608733
+	long disk_stats_in_flight;
608733
 };
608733
 
608733
 struct size_table {         /* stash of commonly-used sizes */
608733
diff --git a/dev.c b/dev.c
608733
index 7ce2422..24efea2 100644
608733
--- a/dev.c
608733
+++ b/dev.c
608733
@@ -3974,7 +3974,7 @@ struct iter {
608733
 	 * this function reads request_list.count[2], and the first argument
608733
 	 * is the address of request_queue.
608733
 	 */
608733
-	void (*get_diskio)(unsigned long , struct diskio *);
608733
+	void (*get_diskio)(unsigned long , unsigned long, struct diskio *);
608733
 
608733
 	/*
608733
 	 * check if device.type == &disk_type
608733
@@ -4187,24 +4187,55 @@ get_mq_diskio(unsigned long q, unsigned long *mq_count)
608733
 	}
608733
 }
608733
 
608733
+static void
608733
+get_one_diskio_from_dkstats(unsigned long dkstats, unsigned long *count)
608733
+{
608733
+	int cpu;
608733
+	unsigned long dkstats_addr;
608733
+	unsigned long in_flight[2];
608733
+
608733
+	for (cpu = 0; cpu < kt->cpus; cpu++) {
608733
+		if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) {
608733
+			dkstats_addr = dkstats + kt->__per_cpu_offset[cpu];
608733
+			readmem(dkstats_addr + OFFSET(disk_stats_in_flight),
608733
+				KVADDR, in_flight, sizeof(long) * 2,
608733
+				"disk_stats.in_flight", FAULT_ON_ERROR);
608733
+			count[0] += in_flight[0];
608733
+			count[1] += in_flight[1];
608733
+		}
608733
+	}
608733
+}
608733
+
608733
+
608733
 /* read request_queue.rq.count[2] */
608733
 static void 
608733
-get_diskio_1(unsigned long rq, struct diskio *io)
608733
+get_diskio_1(unsigned long rq, unsigned long gendisk, struct diskio *io)
608733
 {
608733
 	int count[2];
608733
-	unsigned long mq_count[2] = { 0 };
608733
+	unsigned long io_counts[2] = { 0 };
608733
+	unsigned long dkstats;
608733
 
608733
 	if (!use_mq_interface(rq)) {
608733
-		readmem(rq + OFFSET(request_queue_rq) +
608733
-			OFFSET(request_list_count), KVADDR, count,
608733
-			sizeof(int) * 2, "request_list.count", FAULT_ON_ERROR);
608733
+		if (VALID_MEMBER(request_queue_rq)) {
608733
+			readmem(rq + OFFSET(request_queue_rq) +
608733
+				OFFSET(request_list_count), KVADDR, count,
608733
+				sizeof(int) * 2, "request_list.count", FAULT_ON_ERROR);
608733
+
608733
+			io->read = count[0];
608733
+			io->write = count[1];
608733
+		} else {
608733
+			readmem(gendisk + OFFSET(gendisk_part0) +
608733
+				OFFSET(hd_struct_dkstats), KVADDR, &dkstats,
608733
+				sizeof(ulong), "gendisk.part0.dkstats", FAULT_ON_ERROR);
608733
+			get_one_diskio_from_dkstats(dkstats, io_counts);
608733
 
608733
-		io->read = count[0];
608733
-		io->write = count[1];
608733
+			io->read = io_counts[0];
608733
+			io->write = io_counts[1];
608733
+		}
608733
 	} else {
608733
-		get_mq_diskio(rq, mq_count);
608733
-		io->read = mq_count[0];
608733
-		io->write = mq_count[1];
608733
+		get_mq_diskio(rq, io_counts);
608733
+		io->read = io_counts[0];
608733
+		io->write = io_counts[1];
608733
 	}
608733
 }
608733
 
608733
@@ -4250,9 +4281,6 @@ init_iter(struct iter *i)
608733
 		i->get_in_flight = get_in_flight_1;
608733
 	} else if (SIZE(rq_in_flight) == sizeof(int) * 2) {
608733
 		i->get_in_flight = get_in_flight_2;
608733
-	} else {
608733
-		option_not_supported('d');
608733
-		return;
608733
 	}
608733
 	i->get_diskio = get_diskio_1;
608733
 
608733
@@ -4354,7 +4382,7 @@ display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)
608733
 		sizeof(ulong), "gen_disk.queue", FAULT_ON_ERROR);
608733
 	readmem(gendisk + OFFSET(gendisk_major), KVADDR, &major, sizeof(int),
608733
 		"gen_disk.major", FAULT_ON_ERROR);
608733
-	i->get_diskio(queue_addr, &io);
608733
+	i->get_diskio(queue_addr, gendisk, &io);
608733
 
608733
 	if ((flags & DIOF_NONZERO)
608733
 		&& (io.read + io.write == 0))
608733
@@ -4379,11 +4407,14 @@ display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)
608733
 			(char *)(unsigned long)io.write),
608733
 		space(MINSPACE));
608733
 
608733
-	if (!use_mq_interface(queue_addr)) {
608733
-		in_flight = i->get_in_flight(queue_addr);
608733
-		fprintf(fp, "%5u\n", in_flight);
608733
+	if (VALID_MEMBER(request_queue_in_flight)) {
608733
+		if (!use_mq_interface(queue_addr)) {
608733
+			in_flight = i->get_in_flight(queue_addr);
608733
+			fprintf(fp, "%5u\n", in_flight);
608733
+		} else
608733
+			fprintf(fp, "%s\n", "N/A(MQ)");
608733
 	} else
608733
-		fprintf(fp, "%s\n", "N/A(MQ)");
608733
+		fprintf(fp, "\n");
608733
 }
608733
 
608733
 static void 
608733
@@ -4418,7 +4449,7 @@ display_all_diskio(ulong flags)
608733
 		i.sync_count ? mkstring(buf4, 5, RJUST, "SYNC") :
608733
 			mkstring(buf4, 5, RJUST, "WRITE"),
608733
 		space(MINSPACE),
608733
-		mkstring(buf5, 5, RJUST, "DRV"));
608733
+		VALID_MEMBER(request_queue_in_flight) ? mkstring(buf5, 5, RJUST, "DRV") : "");
608733
 
608733
 	while ((gendisk = i.next_disk(&i)) != 0)
608733
 		display_one_diskio(&i, gendisk, flags);
608733
@@ -4446,6 +4477,7 @@ void diskio_init(void)
608733
 	MEMBER_OFFSET_INIT(gendisk_part0, "gendisk", "part0");
608733
 	MEMBER_OFFSET_INIT(gendisk_queue, "gendisk", "queue");
608733
 	MEMBER_OFFSET_INIT(hd_struct_dev, "hd_struct", "__dev");
608733
+	MEMBER_OFFSET_INIT(hd_struct_dkstats, "hd_struct", "dkstats");
608733
 	MEMBER_OFFSET_INIT(klist_k_list, "klist", "k_list");
608733
 	MEMBER_OFFSET_INIT(klist_node_n_klist, "klist_node", "n_klist");
608733
 	MEMBER_OFFSET_INIT(klist_node_n_node, "klist_node", "n_node");
608733
@@ -4476,6 +4508,7 @@ void diskio_init(void)
608733
 	MEMBER_SIZE_INIT(rq_in_flight, "request_queue", "in_flight");
608733
 	MEMBER_SIZE_INIT(class_private_devices, "class_private",
608733
 		"class_devices");
608733
+	MEMBER_OFFSET_INIT(disk_stats_in_flight, "disk_stats", "in_flight");
608733
 
608733
 	dt->flags |= DISKIO_INIT;
608733
 }
608733
diff --git a/help.c b/help.c
608733
index aadd2ed..1593e82 100644
608733
--- a/help.c
608733
+++ b/help.c
608733
@@ -3218,7 +3218,7 @@ char *help_dev[] = {
608733
 "         WRITE: I/O requests that are writes (older kernels)",
608733
 "           DRV: I/O requests that are in-flight in the device driver.",
608733
 "                If the device driver uses blk-mq interface, this field",
608733
-"                shows N/A(MQ).",
608733
+"                shows N/A(MQ).  If not available, this column is not shown.",
608733
 "    -D  same as -d, but filter out disks with no in-progress I/O requests.",
608733
 "\nEXAMPLES",
608733
 "  Display character and block device data:\n",
608733
diff --git a/symbols.c b/symbols.c
608733
index ef6f934..5f77e27 100644
608733
--- a/symbols.c
608733
+++ b/symbols.c
608733
@@ -10021,6 +10021,10 @@ dump_offset_table(char *spec, ulong makestruct)
608733
 		OFFSET(gendisk_queue));
608733
 	fprintf(fp, "                 hd_struct_dev: %ld\n",
608733
 		OFFSET(hd_struct_dev));
608733
+	fprintf(fp, "             hd_struct_dkstats: %ld\n",
608733
+		OFFSET(hd_struct_dkstats));
608733
+	fprintf(fp, "          disk_stats_in_flight: %ld\n",
608733
+		OFFSET(disk_stats_in_flight));
608733
 	fprintf(fp, "                  klist_k_list: %ld\n",
608733
 		OFFSET(klist_k_list));
608733
 	fprintf(fp, "            klist_node_n_klist: %ld\n",