Skip to content

Commit be0bdd6

Browse files
unerligellandwerlin-intel
authored andcommitted
i915/perf: Start hrtimer only if sampling the OA buffer
SAMPLE_OA parameter enables sampling of OA buffer and results in a call to init the OA buffer which initializes the OA unit head/tail pointers. The OA_EXPONENT parameter controls the periodicity of the OA reports in the OA buffer and results in starting a hrtimer. Before gen12, all use cases required the use of the OA buffer and i915 enforced this setting when vetting out the parameters passed. In these platforms the hrtimer was enabled if OA_EXPONENT was passed. This worked fine since it was implied that SAMPLE_OA is always passed. With gen12, this changed. Users can use perf without enabling the OA buffer as in OAR use cases. While an OAR use case should ideally not start the hrtimer, we see that passing an OA_EXPONENT parameter will start the hrtimer even though SAMPLE_OA is not specified. This results in an uninitialized OA buffer, so the head/tail pointers used to track the buffer are zero. This itself does not fail, but if we ran a use-case that SAMPLED the OA buffer previously, then the OA_TAIL register is still pointing to an old value. When the timer callback runs, it ends up calculating a wrong/large number of available reports. Since we do a spinlock_irq_save and start processing a large number of reports, NMI watchdog fires and causes a crash. Start the timer only if SAMPLE_OA is specified. v2: - Drop SAMPLE OA check when appending samples (Ashutosh) - Prevent read if OA buffer is not being sampled Fixes: 00a7f0d ("drm/i915/tgl: Add perf support on TGL") Signed-off-by: Umesh Nerlige Ramappa <[email protected]> Reviewed-by: Ashutosh Dixit <[email protected]> Signed-off-by: Lionel Landwerlin <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 5dac808 commit be0bdd6

File tree

1 file changed

+5
-8
lines changed

1 file changed

+5
-8
lines changed

drivers/gpu/drm/i915/i915_perf.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,6 @@ static int append_oa_sample(struct i915_perf_stream *stream,
595595
{
596596
int report_size = stream->oa_buffer.format_size;
597597
struct drm_i915_perf_record_header header;
598-
u32 sample_flags = stream->sample_flags;
599598

600599
header.type = DRM_I915_PERF_RECORD_SAMPLE;
601600
header.pad = 0;
@@ -609,10 +608,8 @@ static int append_oa_sample(struct i915_perf_stream *stream,
609608
return -EFAULT;
610609
buf += sizeof(header);
611610

612-
if (sample_flags & SAMPLE_OA_REPORT) {
613-
if (copy_to_user(buf, report, report_size))
614-
return -EFAULT;
615-
}
611+
if (copy_to_user(buf, report, report_size))
612+
return -EFAULT;
616613

617614
(*offset) += header.size;
618615

@@ -2669,7 +2666,7 @@ static void i915_oa_stream_enable(struct i915_perf_stream *stream)
26692666

26702667
stream->perf->ops.oa_enable(stream);
26712668

2672-
if (stream->periodic)
2669+
if (stream->sample_flags & SAMPLE_OA_REPORT)
26732670
hrtimer_start(&stream->poll_check_timer,
26742671
ns_to_ktime(stream->poll_oa_period),
26752672
HRTIMER_MODE_REL_PINNED);
@@ -2732,7 +2729,7 @@ static void i915_oa_stream_disable(struct i915_perf_stream *stream)
27322729
{
27332730
stream->perf->ops.oa_disable(stream);
27342731

2735-
if (stream->periodic)
2732+
if (stream->sample_flags & SAMPLE_OA_REPORT)
27362733
hrtimer_cancel(&stream->poll_check_timer);
27372734
}
27382735

@@ -3015,7 +3012,7 @@ static ssize_t i915_perf_read(struct file *file,
30153012
* disabled stream as an error. In particular it might otherwise lead
30163013
* to a deadlock for blocking file descriptors...
30173014
*/
3018-
if (!stream->enabled)
3015+
if (!stream->enabled || !(stream->sample_flags & SAMPLE_OA_REPORT))
30193016
return -EIO;
30203017

30213018
if (!(file->f_flags & O_NONBLOCK)) {

0 commit comments

Comments
 (0)