s390/qdio: track time of last data IRQ for each device
authorJulian Wiedmann <jwi@linux.ibm.com>
Tue, 15 Sep 2020 07:04:39 +0000 (10:04 +0300)
committerVasily Gorbik <gor@linux.ibm.com>
Tue, 9 Feb 2021 14:57:04 +0000 (15:57 +0100)
We currently track the time of the most recent QDIO Adapter Interrupt.
This is a system-wide timestamp (as such interrupts are not bound to
one specific qdio device).

If interrupt processing stalls on one device but is functional for a
different device, the timestamp continues to be updated and is of no
help for problem diagnosis.
So for debugging purposes also track the time of the last Data IRQ on
a per-device level. Collect this data in the legacy non-AI path as well.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
drivers/s390/cio/qdio.h
drivers/s390/cio/qdio_debug.c
drivers/s390/cio/qdio_main.c
drivers/s390/cio/qdio_thinint.c

index 4a4e4de..da29c37 100644 (file)
@@ -252,6 +252,7 @@ struct qdio_irq {
        struct ccw_device *cdev;
        struct list_head entry;         /* list of thinint devices */
        struct dentry *debugfs_dev;
+       u64 last_data_irq_time;
 
        unsigned long int_parm;
        struct subchannel_id schid;
index 728abf7..d091ae1 100644 (file)
@@ -105,8 +105,9 @@ static int qstat_show(struct seq_file *m, void *v)
        if (!q)
                return 0;
 
-       seq_printf(m, "Timestamp: %Lx  Last AI: %Lx\n",
-                  q->timestamp, last_ai_time);
+       seq_printf(m, "Timestamp: %llx\n", q->timestamp);
+       seq_printf(m, "Last Data IRQ: %llx  Last AI: %llx\n",
+                  q->irq_ptr->last_data_irq_time, last_ai_time);
        seq_printf(m, "nr_used: %d  ftc: %d\n",
                   atomic_read(&q->nr_buf_used), q->first_to_check);
        if (q->is_input_q) {
index 3b1e8ed..c56b690 100644 (file)
@@ -804,6 +804,7 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
                return;
 
        qdio_deliver_irq(irq_ptr);
+       irq_ptr->last_data_irq_time = S390_lowcore.int_clock;
 
        if (!pci_out_supported(irq_ptr) || !irq_ptr->scan_threshold)
                return;
index e1b9236..8e09bf3 100644 (file)
@@ -97,10 +97,11 @@ static inline u32 clear_shared_ind(void)
  */
 static void tiqdio_thinint_handler(struct airq_struct *airq, bool floating)
 {
+       u64 irq_time = S390_lowcore.int_clock;
        u32 si_used = clear_shared_ind();
        struct qdio_irq *irq;
 
-       last_ai_time = S390_lowcore.int_clock;
+       last_ai_time = irq_time;
        inc_irq_stat(IRQIO_QAI);
 
        /* protect tiq_list entries, only changed in activate or shutdown */
@@ -119,6 +120,7 @@ static void tiqdio_thinint_handler(struct airq_struct *airq, bool floating)
                }
 
                qdio_deliver_irq(irq);
+               irq->last_data_irq_time = irq_time;
 
                QDIO_PERF_STAT_INC(irq, adapter_int);
        }