diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | tapsets.cxx | 8 | ||||
-rw-r--r-- | translate.cxx | 23 |
3 files changed, 30 insertions, 8 deletions
@@ -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; } |