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>
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;
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) {
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;
*/
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 */
}
qdio_deliver_irq(irq);
+ irq->last_data_irq_time = irq_time;
QDIO_PERF_STAT_INC(irq, adapter_int);
}