summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--tapsets.cxx8
-rw-r--r--translate.cxx23
3 files changed, 30 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 9062e793..f7b43b69 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-11-24 Frank Ch. Eigler <fche@redhat.com>
+
+ PR 1917
+ * translate.cxx (emit_common_header, emit_module_init,
+ emit_module_exit): Switch context array to per-cpu kmalloc variant.
+ * tapsets (*::emit_probe_entires): Use per_cpu_ptr() for my context.
+
2005-11-23 Graydon Hoare <graydon@redhat.com>
* elaborate.h (get_symbol_within_expression): Make visible.
diff --git a/tapsets.cxx b/tapsets.cxx
index fdf1b999..415bc31a 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -146,7 +146,7 @@ be_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
// While begin/end probes are executed single-threaded, we
// still code defensively and use a per-cpu context.
- o->newline(1) << "struct context* c = & contexts [smp_processor_id()];";
+ o->newline(1) << "struct context* c = per_cpu_ptr (contexts, smp_processor_id());";
o->newline() << "const char* probe_point = "
<< lex_cast_qstring(*l) << ";";
@@ -2754,7 +2754,7 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o,
{
o->newline() << "int stap_kprobe_fault_handler (struct kprobe* kp, "
<< "struct pt_regs* regs, int trapnr) {";
- o->newline(1) << "struct context *c = & contexts [smp_processor_id()];";
+ o->newline(1) << "struct context* c = per_cpu_ptr (contexts, smp_processor_id());";
o->newline() << "_stp_warn (\"systemtap probe fault\\n\");";
o->newline() << "_stp_warn (\"cpu %d, probe %s, near %s\\n\", ";
o->newline(1) << "smp_processor_id(), ";
@@ -2851,7 +2851,7 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o,
else
o->line() << "struct kprobe *probe_instance";
o->line() << ", struct pt_regs *regs) {";
- o->newline(1) << "struct context *c = & contexts [smp_processor_id()];";
+ o->newline(1) << "struct context* c = per_cpu_ptr (contexts, smp_processor_id());";
// Calculate the name of the current probe by finding its index in the probe array.
if (has_return)
@@ -3017,7 +3017,7 @@ timer_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
o->newline() << "static struct timer_list timer_" << j << ";";
o->newline() << "void enter_" << j << " (unsigned long val) {";
- o->newline(1) << "struct context* c = & contexts [smp_processor_id()];";
+ o->newline(1) << "struct context* c = per_cpu_ptr (contexts, smp_processor_id());";
o->newline() << "const char* probe_point = "
<< lex_cast_qstring(*locations[0]) << ";";
o->newline() << "(void) val;";
diff --git a/translate.cxx b/translate.cxx
index 31899120..e47f2856 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -856,7 +856,8 @@ c_unparser::emit_common_header ()
o->newline(-1) << "} function_" << c_varname (fd->name) << ";";
}
o->newline(-1) << "} locals [MAXNESTING];";
- o->newline(-1) << "} contexts [NR_CPUS];" << endl;
+ o->newline(-1) << "};" << endl;
+ o->newline() << "void *contexts; /* alloc_percpu */" << endl;
emit_map_type_instantiations ();
@@ -903,8 +904,17 @@ c_unparser::emit_module_init ()
// while to abort right away. Currently running probes are allowed to
// terminate. These may set STAP_SESSION_ERROR!
+ // per-cpu context
+ o->newline() << "contexts = alloc_percpu (struct context);";
+ o->newline() << "if (contexts == NULL) {";
+ o->newline() << "_stp_error (\"percpu context (size %lu) allocation failed\", sizeof (struct context));";
+ o->newline(1) << "rc = -ENOMEM;";
+ o->newline() << "goto out;";
+ o->newline(-1) << "}";
+
for (unsigned i=0; i<session->globals.size(); i++)
{
+ // XXX: handle failure!
vardecl* v = session->globals[i];
if (v->index_types.size() > 0)
o->newline() << getmap (v).init();
@@ -1013,8 +1023,10 @@ c_unparser::emit_module_exit ()
o->newline() << "do {";
o->newline(1) << "int i;";
o->newline() << "holdon = 0;";
- o->newline() << "for (i=0; i<NR_CPUS; i++)";
- o->newline(1) << "if (atomic_read (&contexts[i].busy)) holdon = 1;";
+ o->newline() << "for (i=0; i < NR_CPUS; i++)";
+ o->newline(1) << "if (cpu_possible (i) && "
+ << "atomic_read (& ((struct context *)per_cpu_ptr(contexts, i))->busy)) "
+ << "holdon = 1;";
// o->newline(-1) << "if (holdon) msleep (5);";
o->newline(-1) << "} while (holdon);";
o->newline(-1);
@@ -1022,7 +1034,7 @@ c_unparser::emit_module_exit ()
// genuinely stuck somehow
for (int i=session->probes.size()-1; i>=0; i--)
- session->probes[i]->emit_deregistrations (o, i);
+ session->probes[i]->emit_deregistrations (o, i); // NB: runs "end" probes
for (unsigned i=0; i<session->globals.size(); i++)
{
@@ -1030,6 +1042,9 @@ c_unparser::emit_module_exit ()
if (v->index_types.size() > 0)
o->newline() << getmap (v).fini();
}
+
+ o->newline() << "free_percpu (contexts);";
+
o->newline(-1) << "}" << endl;
}