Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de400d6b authored by Peter Oberparleiter's avatar Peter Oberparleiter Committed by Martin Schwidefsky
Browse files

[S390] fix mismatch in summation of I/O IRQ statistics



Current IRQ statistics support does not show detail counts for I/O
interrupts which are processed internally only. The result is a
summation count which is way off such as this one:

           CPU0       CPU1       CPU2
I/O:       1331        710        442
[...]
QAI:         15         16         16   [I/O] QDIO Adapter Interrupt
QDI:          1          0          0   [I/O] QDIO Interrupt
DAS:        706        645        381   [I/O] DASD
C15:         26         10          0   [I/O] 3215
C70:          0          0          0   [I/O] 3270
TAP:          0          0          0   [I/O] Tape
VMR:          0          0          0   [I/O] Unit Record Devices
LCS:          0          0          0   [I/O] LCS
CLW:          0          0          0   [I/O] CLAW
CTC:          0          0          0   [I/O] CTC
APB:          0          0          0   [I/O] AP Bus

Fix this by moving I/O interrupt accounting into the common I/O layer.

Signed-off-by: default avatarPeter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent ce949717
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/device.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <linux/mod_devicetable.h>
#include <asm/fcx.h>
#include <asm/fcx.h>
#include <asm/irq.h>


/* structs from asm/cio.h */
/* structs from asm/cio.h */
struct irb;
struct irb;
@@ -127,6 +128,7 @@ enum uc_todo {
 * @restore: callback for restoring after hibernation
 * @restore: callback for restoring after hibernation
 * @uc_handler: callback for unit check handler
 * @uc_handler: callback for unit check handler
 * @driver: embedded device driver structure
 * @driver: embedded device driver structure
 * @int_class: interruption class to use for accounting interrupts
 */
 */
struct ccw_driver {
struct ccw_driver {
	struct ccw_device_id *ids;
	struct ccw_device_id *ids;
@@ -144,6 +146,7 @@ struct ccw_driver {
	int (*restore)(struct ccw_device *);
	int (*restore)(struct ccw_device *);
	enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *);
	enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *);
	struct device_driver driver;
	struct device_driver driver;
	enum interruption_class int_class;
};
};


extern struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv,
extern struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv,
+1 −1
Original line number Original line Diff line number Diff line
@@ -17,8 +17,8 @@ enum interruption_class {
	EXTINT_SCP,
	EXTINT_SCP,
	EXTINT_IUC,
	EXTINT_IUC,
	EXTINT_CPM,
	EXTINT_CPM,
	IOINT_CIO,
	IOINT_QAI,
	IOINT_QAI,
	IOINT_QDI,
	IOINT_DAS,
	IOINT_DAS,
	IOINT_C15,
	IOINT_C15,
	IOINT_C70,
	IOINT_C70,
+1 −1
Original line number Original line Diff line number Diff line
@@ -42,8 +42,8 @@ static const struct irq_class intrclass_names[] = {
	{.name = "SCP", .desc = "[EXT] Service Call" },
	{.name = "SCP", .desc = "[EXT] Service Call" },
	{.name = "IUC", .desc = "[EXT] IUCV" },
	{.name = "IUC", .desc = "[EXT] IUCV" },
	{.name = "CPM", .desc = "[EXT] CPU Measurement" },
	{.name = "CPM", .desc = "[EXT] CPU Measurement" },
	{.name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt" },
	{.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt" },
	{.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt" },
	{.name = "QDI", .desc = "[I/O] QDIO Interrupt" },
	{.name = "DAS", .desc = "[I/O] DASD" },
	{.name = "DAS", .desc = "[I/O] DASD" },
	{.name = "C15", .desc = "[I/O] 3215" },
	{.name = "C15", .desc = "[I/O] 3215" },
	{.name = "C70", .desc = "[I/O] 3270" },
	{.name = "C70", .desc = "[I/O] 3270" },
+0 −2
Original line number Original line Diff line number Diff line
@@ -11,7 +11,6 @@
#define KMSG_COMPONENT "dasd"
#define KMSG_COMPONENT "dasd"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt


#include <linux/kernel_stat.h>
#include <linux/kmod.h>
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
@@ -1594,7 +1593,6 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
	unsigned long long now;
	unsigned long long now;
	int expires;
	int expires;


	kstat_cpu(smp_processor_id()).irqs[IOINT_DAS]++;
	if (IS_ERR(irb)) {
	if (IS_ERR(irb)) {
		switch (PTR_ERR(irb)) {
		switch (PTR_ERR(irb)) {
		case -EIO:
		case -EIO:
+1 −0
Original line number Original line Diff line number Diff line
@@ -3998,6 +3998,7 @@ static struct ccw_driver dasd_eckd_driver = {
	.thaw	     = dasd_generic_restore_device,
	.thaw	     = dasd_generic_restore_device,
	.restore     = dasd_generic_restore_device,
	.restore     = dasd_generic_restore_device,
	.uc_handler  = dasd_generic_uc_handler,
	.uc_handler  = dasd_generic_uc_handler,
	.int_class   = IOINT_DAS,
};
};


/*
/*
Loading