@@ -2491,6 +2491,32 @@ static int i915_guc_load_status_info(struct seq_file *m, void *data)
return 0;
}
+static void i915_guc_log_info(struct seq_file *m,
+ struct drm_i915_private *dev_priv)
+{
+ struct intel_guc *guc = &dev_priv->guc;
+
+ seq_puts(m, "\nGuC logging stats:\n");
+
+ seq_printf(m, "\tISR: flush count %10u, overflow count %10u\n",
+ guc->log.flush_count[GUC_ISR_LOG_BUFFER],
+ guc->log.total_overflow_count[GUC_ISR_LOG_BUFFER]);
+
+ seq_printf(m, "\tDPC: flush count %10u, overflow count %10u\n",
+ guc->log.flush_count[GUC_DPC_LOG_BUFFER],
+ guc->log.total_overflow_count[GUC_DPC_LOG_BUFFER]);
+
+ seq_printf(m, "\tCRASH: flush count %10u, overflow count %10u\n",
+ guc->log.flush_count[GUC_CRASH_DUMP_LOG_BUFFER],
+ guc->log.total_overflow_count[GUC_CRASH_DUMP_LOG_BUFFER]);
+
+ seq_printf(m, "\tTotal flush interrupt count: %u\n",
+ guc->log.flush_interrupt_count);
+
+ seq_printf(m, "\tCapture miss count: %u\n",
+ guc->log.capture_miss_count);
+}
+
static void i915_guc_client_info(struct seq_file *m,
struct drm_i915_private *dev_priv,
struct i915_guc_client *client)
@@ -2565,6 +2591,8 @@ static int i915_guc_info(struct seq_file *m, void *data)
seq_printf(m, "\nGuC execbuf client @ %p:\n", guc.execbuf_client);
i915_guc_client_info(m, dev_priv, &client);
+ i915_guc_log_info(m, dev_priv);
+
/* Add more as required ... */
return 0;
@@ -1036,6 +1036,25 @@ static void guc_read_update_log_buffer(struct intel_guc *guc)
sizeof(struct guc_log_buffer_state));
buffer_size = guc_get_log_buffer_size(type);
+ /* Bookkeeping stuff */
+ guc->log.flush_count[type] += log_buffer_state_local.flush_to_file;
+ if (log_buffer_state_local.buffer_full_cnt !=
+ guc->log.prev_overflow_count[type]) {
+ guc->log.total_overflow_count[type] +=
+ (log_buffer_state_local.buffer_full_cnt -
+ guc->log.prev_overflow_count[type]);
+
+ if (log_buffer_state_local.buffer_full_cnt <
+ guc->log.prev_overflow_count[type]) {
+ /* buffer_full_cnt is a 4 bit counter */
+ guc->log.total_overflow_count[type] += 16;
+ }
+
+ guc->log.prev_overflow_count[type] =
+ log_buffer_state_local.buffer_full_cnt;
+ DRM_ERROR_RATELIMITED("GuC log buffer overflow\n");
+ }
+
if (log_buffer_snapshot_state) {
/* First copy the state structure in snapshot buffer */
memcpy(log_buffer_snapshot_state, &log_buffer_state_local,
@@ -1076,6 +1095,7 @@ static void guc_read_update_log_buffer(struct intel_guc *guc)
* getting consumed by User at a slow rate.
*/
DRM_ERROR_RATELIMITED("no sub-buffer to capture log buffer\n");
+ guc->log.capture_miss_count++;
}
}
@@ -1684,6 +1684,8 @@ static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir)
/* Handle flush interrupt in bottom half */
queue_work(dev_priv->guc.log.flush_wq,
&dev_priv->guc.log.flush_work);
+
+ dev_priv->guc.log.flush_interrupt_count++;
} else {
/* Not clearing of unhandled event bits won't result in
* re-triggering of the interrupt.
@@ -128,6 +128,13 @@ struct intel_guc_log {
struct workqueue_struct *flush_wq;
struct work_struct flush_work;
struct rchan *relay_chan;
+
+ /* logging related stats */
+ u32 capture_miss_count;
+ u32 flush_interrupt_count;
+ u32 prev_overflow_count[GUC_MAX_LOG_BUFFER];
+ u32 total_overflow_count[GUC_MAX_LOG_BUFFER];
+ u32 flush_count[GUC_MAX_LOG_BUFFER];
};
struct intel_guc {