diff options
author | Josh Stone <jistone@redhat.com> | 2010-03-18 18:54:18 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2010-03-18 18:54:18 -0700 |
commit | 34fe8ec416abfb4355fcb1a9a015de7c9dfc9380 (patch) | |
tree | 8bb3556adc361bf8f4604096fa02374f16061518 | |
parent | 9fab2262961c9cd1ab3efea5d362b8a6a1c0c7c3 (diff) | |
download | systemtap-steved-34fe8ec416abfb4355fcb1a9a015de7c9dfc9380.tar.gz systemtap-steved-34fe8ec416abfb4355fcb1a9a015de7c9dfc9380.tar.xz systemtap-steved-34fe8ec416abfb4355fcb1a9a015de7c9dfc9380.zip |
Create one perf structure to rule them all
* perf.h (stap_perf_probe): Define one structure for all our needs.
* perf.c (_stp_perf_init): Use the new struct, return errors directly.
(_stp_perf_exit): Use the new struct.
* tapset-perfmon.cxx (perf_derived_probe_group::emit_module_decls): Use
the stap_perf_probe definition from perf.h now.
(perf_derived_probe_group::emit_module_init): Adapt.
(perf_derived_probe_group::emit_module_exit): Adapt.
-rw-r--r-- | runtime/perf.c | 67 | ||||
-rw-r--r-- | runtime/perf.h | 20 | ||||
-rw-r--r-- | tapset-perfmon.cxx | 28 |
3 files changed, 38 insertions, 77 deletions
diff --git a/runtime/perf.c b/runtime/perf.c index 12bf220a..bf31cdaa 100644 --- a/runtime/perf.c +++ b/runtime/perf.c @@ -22,84 +22,59 @@ /** Initialize performance sampling * Call this during probe initialization to set up performance event sampling - * for all online cpus. Returns ERR_PTR on error. + * for all online cpus. Returns non-zero on error. * - * @param attr description of event to sample - * @param callback function to call when perf event overflows - * @param pp associated probe point - * @param ph probe handler + * @param stp Handle for the event to be registered. */ -static Perf *_stp_perf_init (struct perf_event_attr *attr, - perf_overflow_handler_t callback, - const char *pp, void (*ph) (struct context *) ) +static long _stp_perf_init (struct stap_perf_probe *stp) { - long rc = -EINVAL; int cpu; - Perf *pe; - - pe = (Perf *) _stp_kmalloc (sizeof(Perf)); - if (pe == NULL) - return ERR_PTR(-ENOMEM); /* allocate space for the event descriptor for each cpu */ - pe->pd = (perfcpu *) _stp_alloc_percpu (sizeof(perfcpu)); - if (pe->pd == NULL) { - rc = -ENOMEM; - goto exit1; + stp->events = _stp_alloc_percpu (sizeof(struct perf_event*)); + if (stp->events == NULL) { + return -ENOMEM; } /* initialize event on each processor */ stp_for_each_cpu(cpu) { - perfcpu *pd = per_cpu_ptr (pe->pd, cpu); - struct perf_event **event = &(pd->event); + struct perf_event **event = per_cpu_ptr (stp->events, cpu); if (cpu_is_offline(cpu)) { - *event = NULL; + *event = NULL; continue; } - *event = perf_event_create_kernel_counter(attr, cpu, -1, - callback); + *event = perf_event_create_kernel_counter(&stp->attr, + cpu, -1, + stp->callback); if (IS_ERR(*event)) { - rc = PTR_ERR(*event); + long rc = PTR_ERR(*event); *event = NULL; - goto exit2; + _stp_perf_del(stp); + return rc; } - pd->pp = pp; - pd->ph = ph; - } - return pe; - -exit2: - stp_for_each_cpu(cpu) { - perfcpu *pd = per_cpu_ptr (pe->pd, cpu); - struct perf_event **event = &(pd->event); - if (*event) perf_event_release_kernel(*event); } - _stp_free_percpu(pe->pd); -exit1: - _stp_kfree(pe); - return ERR_PTR(rc); + return 0; } /** Delete performance event. * Call this to shutdown performance event sampling * - * @param pe + * @param stp Handle for the event to be unregistered. */ -static void _stp_perf_del (Perf *pe) +static void _stp_perf_del (struct stap_perf_probe *stp) { - if (pe) { + if (stp && stp->events) { int cpu; /* shut down performance event sampling */ stp_for_each_cpu(cpu) { - perfcpu *pd = per_cpu_ptr (pe->pd, cpu); - struct perf_event **event = &(pd->event); + struct perf_event **event = per_cpu_ptr (stp->events, cpu); if (*event) { perf_event_release_kernel(*event); } } - _stp_free_percpu (pe->pd); - _stp_kfree (pe); + _stp_free_percpu (stp->events); + stp->events = NULL; } } diff --git a/runtime/perf.h b/runtime/perf.h index 19f89fe7..bdc79ade 100644 --- a/runtime/perf.h +++ b/runtime/perf.h @@ -16,22 +16,18 @@ * @brief Header file for performance monitoring hardware support */ -typedef struct { - struct perf_event *event; +struct stap_perf_probe { + struct perf_event_attr attr; + perf_overflow_handler_t callback; const char *pp; - void (*ph) (struct context *); -} perfcpu; + void (*ph) (struct context*); -typedef struct { /* per-cpu data. allocated with _stp_alloc_percpu() */ - perfcpu *pd; -} Perf; + struct perf_event **events; +}; -static Perf *_stp_perf_init (struct perf_event_attr *attr, - perf_overflow_handler_t callback, - const char *pp, - void (*ph) (struct context *) ); +static long _stp_perf_init (struct stap_perf_probe *stp); -static void _stp_perf_del (Perf *pe); +static void _stp_perf_del (struct stap_perf_probe *stp); #endif /* _PERF_H_ */ diff --git a/tapset-perfmon.cxx b/tapset-perfmon.cxx index 9078dfd9..98bc8fe6 100644 --- a/tapset-perfmon.cxx +++ b/tapset-perfmon.cxx @@ -94,13 +94,8 @@ perf_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(); /* data structures */ - s.op->newline() << "static struct stap_perf_probe {"; - s.op->newline(1) << "struct perf_event_attr attr;"; - s.op->newline() << "perf_overflow_handler_t cb;"; - s.op->newline() << "const char *pp;"; - s.op->newline() << "void (*ph) (struct context*);"; - s.op->newline() << "Perf *perf;"; - s.op->newline(-1) << "} stap_perf_probes [" << probes.size() << "] = {"; + s.op->newline() << "static struct stap_perf_probe stap_perf_probes [" + << probes.size() << "] = {"; s.op->indent(1); for (unsigned i=0; i < probes.size(); i++) { @@ -109,7 +104,7 @@ perf_derived_probe_group::emit_module_decls (systemtap_session& s) << ".type=" << probes[i]->event_type << "ULL, " << ".config=" << probes[i]->event_config << "ULL, " << "{ .sample_period=" << probes[i]->interval << "ULL }},"; - s.op->newline() << ".cb=enter_perf_probe_" << i << ", "; + s.op->newline() << ".callback=enter_perf_probe_" << i << ", "; s.op->newline() << ".pp=" << lex_cast_qstring (*probes[i]->sole_location()) << ","; s.op->newline() << ".ph=" << probes[i]->name << ","; s.op->newline(-1) << "},"; @@ -150,17 +145,14 @@ perf_derived_probe_group::emit_module_init (systemtap_session& s) s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {"; s.op->newline(1) << "struct stap_perf_probe* stp = & stap_perf_probes [i];"; - s.op->newline() << "stp->perf = _stp_perf_init(&stp->attr, stp->cb, stp->pp, stp->ph);"; - s.op->newline() << "if (IS_ERR(stp->perf)) {"; - s.op->newline(1) << "rc = PTR_ERR(stp->perf);"; - s.op->newline() << "stp->perf = NULL;"; - s.op->newline() << "probe_point = stp->pp;"; + s.op->newline() << "rc = _stp_perf_init(stp);"; + s.op->newline() << "if (rc) {"; + s.op->newline(1) << "probe_point = stp->pp;"; s.op->newline() << "for (j=0; j<i; j++) {"; - s.op->newline(1) << "stp = & stap_perf_probes [j];"; - s.op->newline() << "_stp_perf_del(stp->perf);"; - s.op->newline() << "stp->perf = NULL;"; + s.op->newline(1) << "_stp_perf_del(& stap_perf_probes [j]);"; s.op->newline(-1) << "}"; // for unwind loop s.op->newline(-1) << "}"; // if-error + s.op->newline() << "break;"; s.op->newline(-1) << "}"; // for loop } @@ -171,9 +163,7 @@ perf_derived_probe_group::emit_module_exit (systemtap_session& s) if (probes.empty()) return; s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {"; - s.op->newline(1) << "struct stap_perf_probe* stp = & stap_perf_probes [i];"; - s.op->newline() << "_stp_perf_del(stp->perf);"; - s.op->newline() << "stp->perf = NULL;"; + s.op->newline(1) << "_stp_perf_del(& stap_perf_probes [i]);"; s.op->newline(-1) << "}"; // for loop } |