lkml.org 
[lkml]   [2015]   [Jan]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
SubjectRe: [PATCH v8 12/14] x86: perf: intel_pt: Intel PT PMU driver
Date
Peter Zijlstra <peterz@infradead.org> writes:

> On Fri, Nov 14, 2014 at 03:43:45PM +0200, Alexander Shishkin wrote:
>> +static void pt_handle_status(struct pt *pt)
>> +{
>> + struct pt_buffer *buf = perf_get_aux(&pt->handle);
>> + int advance = 0;
>> + u64 status;
>> +
>> + rdmsrl(MSR_IA32_RTIT_STATUS, status);
>> +
>> + if (status & RTIT_STATUS_ERROR) {
>> + pr_err_ratelimited("ToPA ERROR encountered, trying to recover\n");
>> + pt_topa_dump(buf);
>> + status &= ~RTIT_STATUS_ERROR;
>> + }
>> +
>> + if (status & RTIT_STATUS_STOPPED) {
>> + status &= ~RTIT_STATUS_STOPPED;
>> +
>> + /*
>> + * On systems that only do single-entry ToPA, hitting STOP
>> + * means we are already losing data; need to let the decoder
>> + * know.
>> + */
>> + if (!pt_cap_get(PT_CAP_topa_multiple_entries) ||
>> + buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
>> + local_inc(&buf->lost);
>> + advance++;
>> + }
>> + }
>> +
>> + /*
>> + * Also on single-entry ToPA implementations, interrupt will come
>> + * before the output reaches its output region's boundary.
>> + */
>
> My understanding was that, while yes it will attempt to generate the
> interrupt early, there is absolutely no guarantee it will in fact arrive
> in time or even it if does, guarantee that there is buffer left by the
> time you're ready to read it.

That's correct. If the PMI didn't arrive on time and the buffer got
filled up, the STOPPED bit will be set in the STATUS register, which is
what we're handling above.

>> + if (!pt_cap_get(PT_CAP_topa_multiple_entries) && !buf->snapshot &&
>> + pt_buffer_region_size(buf) - buf->output_off <= TOPA_PMI_MARGIN) {
>
> Now this check appears to indeed cater for this scenario where the
> buffer is overran, right?

The check above is for the case when the PMI did make it before the end
of the physical buffer was reached.

>
>> + void *head = pt_buffer_region(buf);
>> +
>> + /* everything within this margin needs to be zeroed out */
>> + memset(head + buf->output_off, 0,
>> + pt_buffer_region_size(buf) -
>> + buf->output_off);
>> + advance++;
>> + }
>> +
>> + if (advance)
>> + pt_buffer_advance(buf);
>> +
>> + wrmsrl(MSR_IA32_RTIT_STATUS, status);
>> +}

Regards,
--
Alex


\
 
 \ /
  Last update: 2015-01-12 14:01    [W:0.105 / U:0.088 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site