summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2010-03-18 18:54:18 -0700
committerJosh Stone <jistone@redhat.com>2010-03-18 18:54:18 -0700
commit34fe8ec416abfb4355fcb1a9a015de7c9dfc9380 (patch)
tree8bb3556adc361bf8f4604096fa02374f16061518
parent9fab2262961c9cd1ab3efea5d362b8a6a1c0c7c3 (diff)
downloadsystemtap-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.c67
-rw-r--r--runtime/perf.h20
-rw-r--r--tapset-perfmon.cxx28
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
}