diff --git a/data/gputop.proto b/data/gputop.proto index 8ad5a825..e7dce796 100644 --- a/data/gputop.proto +++ b/data/gputop.proto @@ -96,8 +96,9 @@ message Features repeated string notices = 12; required int32 server_pid = 13; repeated string events = 14; - required bool has_i915_oa_cpu_timestamps = 15; - required bool has_i915_oa_gpu_timestamps = 16; + required bool has_i915_oa_interrupt = 15; + required bool has_i915_oa_cpu_timestamps = 16; + required bool has_i915_oa_gpu_timestamps = 17; } message ProcessInfo @@ -185,10 +186,12 @@ message OAStreamInfo required uint32 period_exponent = 3; //TODO: allow specifying a specific context to profile required bool per_ctx_mode = 4; + // Use OA interrupt + required bool interrupt = 5; // Adds GPU timestamps in the i915 perf reports - required bool gpu_timestamps = 5; + required bool gpu_timestamps = 6; // Adds CPU timestamps in the i915 perf reports - required bool cpu_timestamps = 6; + required bool cpu_timestamps = 7; } message TracepointConfig diff --git a/lib/gputop-client-context.c b/lib/gputop-client-context.c index 15429772..c4a54872 100644 --- a/lib/gputop-client-context.c +++ b/lib/gputop-client-context.c @@ -1241,6 +1241,7 @@ open_i915_perf_stream(struct gputop_client_context *ctx) oa_stream.period_exponent = gputop_time_to_oa_exponent(&ctx->devinfo, ctx->oa_sampling_period_ns); oa_stream.per_ctx_mode = false; + oa_stream.interrupt = ctx->i915_perf_config.oa_interrupt; oa_stream.cpu_timestamps = ctx->i915_perf_config.cpu_timestamps; oa_stream.gpu_timestamps = ctx->i915_perf_config.gpu_timestamps; @@ -1485,6 +1486,8 @@ handle_protobuf_message(struct gputop_client_context *ctx, gputop__message__free_unpacked(ctx->features, NULL); ctx->features = message; register_platform_metrics(ctx, message->features->devinfo); + ctx->i915_perf_config.oa_interrupt = + message->features->has_i915_oa_interrupt; ctx->i915_perf_config.cpu_timestamps = message->features->has_i915_oa_cpu_timestamps && message->features->has_i915_oa_gpu_timestamps; diff --git a/lib/gputop-oa-counters.h b/lib/gputop-oa-counters.h index 79b35b44..bd95b0a6 100644 --- a/lib/gputop-oa-counters.h +++ b/lib/gputop-oa-counters.h @@ -154,6 +154,7 @@ gputop_cc_oa_report_get_reason(const struct gputop_devinfo *devinfo, struct gputop_i915_perf_configuration { bool oa_reports; + bool oa_interrupt; bool cpu_timestamps; bool gpu_timestamps; }; diff --git a/mesa/include/drm-uapi/i915_drm.h b/mesa/include/drm-uapi/i915_drm.h index 0872eb0c..82757db9 100644 --- a/mesa/include/drm-uapi/i915_drm.h +++ b/mesa/include/drm-uapi/i915_drm.h @@ -1510,6 +1510,37 @@ enum drm_i915_perf_property_id { */ DRM_I915_PERF_PROP_OA_EXPONENT, + /** + * Specifying this property sets up a hrtimer in nanoseconds at which + * the i915 driver will check the OA buffer for available data. A + * value of 0 means no hrtimer will be started. Values below 100 + * microseconds are not allowed. + */ + DRM_I915_PERF_PROP_POLL_OA_DELAY, + + /** + * Specifying this property sets up the interrupt mechanism for the OA + * buffer in i915. This option in conjuction with a long polling delay + * for avaibility of OA data can reduce CPU load significantly if you + * do not care about OA data being read as soon as it's available. + */ + DRM_I915_PERF_PROP_OA_ENABLE_INTERRUPT, + + /** + * Specify a global OA buffer size to be allocated in bytes. The size + * specified must be supported by HW (currently supported sizes are + * powers of 2 ranging from 128Kb to 16Mb). + */ + DRM_I915_PERF_PROP_OA_BUFFER_SIZE, + + /** + * Specifying this property is only valid when specify a context to + * filter with DRM_I915_PERF_PROP_CTX_HANDLE. Specifying this property + * will hold preemption of the particular context we want to gather + * performance data about. + */ + DRM_I915_PERF_PROP_HOLD_PREEMPTION, + /** * The value of this property set to 1 requests inclusion of GPU * timestamp in the perf sample data. diff --git a/server/gputop-perf.c b/server/gputop-perf.c index a7e69e3d..457782a2 100644 --- a/server/gputop-perf.c +++ b/server/gputop-perf.c @@ -241,6 +241,13 @@ kernel_supports_open_property(uint64_t prop, uint64_t value) } +bool +gputop_perf_kernel_has_i915_oa_interrupt(void) +{ + return kernel_supports_open_property(DRM_I915_PERF_PROP_OA_ENABLE_INTERRUPT, + true); +} + bool gputop_perf_kernel_has_i915_oa_cpu_timestamps(void) { @@ -462,6 +469,7 @@ struct gputop_perf_stream * gputop_open_i915_perf_oa_stream(struct gputop_metric_set *metric_set, int period_exponent, struct ctx_handle *ctx, + bool interrupt, bool cpu_timestamps, bool gpu_timestamps, void (*ready_cb)(struct gputop_perf_stream *), @@ -511,6 +519,11 @@ gputop_open_i915_perf_oa_stream(struct gputop_metric_set *metric_set, ctx->fd, ctx->id); } + if (interrupt) { + properties[p++] = DRM_I915_PERF_PROP_OA_ENABLE_INTERRUPT; + properties[p++] = true; + } + if (cpu_timestamps) { properties[p++] = DRM_I915_PERF_PROP_SAMPLE_SYSTEM_TS; properties[p++] = true; @@ -538,6 +551,7 @@ gputop_open_i915_perf_oa_stream(struct gputop_metric_set *metric_set, stream->metric_set = metric_set; stream->ready_cb = ready_cb; stream->per_ctx_mode = ctx != NULL; + stream->oa.interrupt_enabled = interrupt; stream->fd = stream_fd; diff --git a/server/gputop-perf.h b/server/gputop-perf.h index c047f07d..383d9327 100644 --- a/server/gputop-perf.h +++ b/server/gputop-perf.h @@ -155,6 +155,7 @@ struct gputop_perf_stream uint8_t *last; int last_buf_idx; + bool interrupt_enabled; bool header_written; uint32_t total_len; } oa; @@ -240,6 +241,7 @@ struct gputop_perf_stream * gputop_open_i915_perf_oa_stream(struct gputop_metric_set *metric_set, int period_exponent, struct ctx_handle *ctx, + bool interrupt, bool cpu_timestamps, bool gpu_timestamps, void (*ready_cb)(struct gputop_perf_stream *), @@ -288,5 +290,6 @@ void gputop_perf_stream_unref(struct gputop_perf_stream *stream); const struct gputop_devinfo *gputop_perf_get_devinfo(void); +bool gputop_perf_kernel_has_i915_oa_interrupt(void); bool gputop_perf_kernel_has_i915_oa_cpu_timestamps(void); bool gputop_perf_kernel_has_i915_oa_gpu_timestamps(void); diff --git a/server/gputop-server.c b/server/gputop-server.c index 05a02547..3683b644 100644 --- a/server/gputop-server.c +++ b/server/gputop-server.c @@ -613,6 +613,7 @@ handle_open_i915_perf_oa_stream(h2o_websocket_conn_t *conn, stream = gputop_open_i915_perf_oa_stream(metric_set, oa_stream_info->period_exponent, ctx, + oa_stream_info->interrupt, oa_stream_info->cpu_timestamps, oa_stream_info->gpu_timestamps, (open_stream->live_updates ? @@ -1146,6 +1147,7 @@ handle_get_features(h2o_websocket_conn_t *conn, pb_devinfo.topology = &pb_topology; pb_features.fake_mode = gputop_fake_mode; + pb_features.has_i915_oa_interrupt = gputop_perf_kernel_has_i915_oa_interrupt(); pb_features.has_i915_oa_cpu_timestamps = gputop_perf_kernel_has_i915_oa_cpu_timestamps(); pb_features.has_i915_oa_gpu_timestamps = gputop_perf_kernel_has_i915_oa_gpu_timestamps();