/* * Collect the trace on the current cpu and write it into the ftrace buffer. * * pre: bts_tracer_lock must be locked */ static void trace_bts_cpu(void *arg) { struct trace_array *tr = (struct trace_array *) arg; const struct bts_trace *trace; unsigned char *at; if (unlikely(!tr)) return; if (unlikely(atomic_read(&tr->data[raw_smp_processor_id()]->disabled))) return; if (unlikely(!this_tracer)) return; ds_suspend_bts(this_tracer); trace = ds_read_bts(this_tracer); if (!trace) goto out; for (at = trace->ds.top; (void *)at < trace->ds.end; at += trace->ds.size) trace_bts_at(trace, at); for (at = trace->ds.begin; (void *)at < trace->ds.top; at += trace->ds.size) trace_bts_at(trace, at); out: ds_resume_bts(this_tracer); }
static void trace_bts_cpu(void *arg) { struct trace_array *tr = (struct trace_array *) arg; const struct bts_trace *trace; unsigned char *at; if (!this_tracer) return; ds_suspend_bts(this_tracer); trace = ds_read_bts(this_tracer); if (!trace) goto out; for (at = trace->ds.top; (void *)at < trace->ds.end; at += trace->ds.size) trace_bts_at(tr, trace, at); for (at = trace->ds.begin; (void *)at < trace->ds.top; at += trace->ds.size) trace_bts_at(tr, trace, at); out: ds_resume_bts(this_tracer); }
static void ds_selftest_bts_cpu(void *arg) { struct ds_selftest_bts_conf *conf = arg; const struct bts_trace *trace; void *top; if (IS_ERR(conf->tracer)) { conf->error = PTR_ERR(conf->tracer); conf->tracer = NULL; printk(KERN_CONT "initialization failed (err: %d)...", conf->error); return; } /* We should meanwhile have enough trace. */ conf->error = conf->suspend(conf->tracer); if (conf->error < 0) return; /* Let's see if we can access the trace. */ trace = ds_read_bts(conf->tracer); conf->error = ds_selftest_bts_consistency(trace); if (conf->error < 0) return; /* If everything went well, we should have a few trace entries. */ if (trace->ds.top == trace->ds.begin) { /* * It is possible but highly unlikely that we got a * buffer overflow and end up at exactly the same * position we started from. * Let's issue a warning, but continue. */ printk(KERN_CONT "no trace/overflow..."); } /* Let's try to read the trace we collected. */ conf->error = ds_selftest_bts_read(conf->tracer, trace, trace->ds.begin, trace->ds.top); if (conf->error < 0) return; /* * Let's read the trace again. * Since we suspended tracing, we should get the same result. */ top = trace->ds.top; trace = ds_read_bts(conf->tracer); conf->error = ds_selftest_bts_consistency(trace); if (conf->error < 0) return; if (top != trace->ds.top) { printk(KERN_CONT "suspend not working..."); conf->error = -1; return; } /* Let's collect some more trace - see if resume is working. */ conf->error = conf->resume(conf->tracer); if (conf->error < 0) return; conf->error = conf->suspend(conf->tracer); if (conf->error < 0) return; trace = ds_read_bts(conf->tracer); conf->error = ds_selftest_bts_consistency(trace); if (conf->error < 0) return; if (trace->ds.top == top) { /* * It is possible but highly unlikely that we got a * buffer overflow and end up at exactly the same * position we started from. * Let's issue a warning and check the full trace. */ printk(KERN_CONT "no resume progress/overflow..."); conf->error = ds_selftest_bts_read(conf->tracer, trace, trace->ds.begin, trace->ds.end); } else if (trace->ds.top < top) { /* * We had a buffer overflow - the entire buffer should * contain trace records. */ conf->error = ds_selftest_bts_read(conf->tracer, trace, trace->ds.begin, trace->ds.end); } else { /* * It is quite likely that the buffer did not overflow. * Let's just check the delta trace. */ conf->error = ds_selftest_bts_read(conf->tracer, trace, top, trace->ds.top); } if (conf->error < 0) return; conf->error = 0; }