From ba7276fa26711e1e822144f4dc1da8126076bc75 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Mon, 2 Jun 2014 11:51:38 -0400 Subject: [PATCH] runtime: use workqueue to schedule systemtap_module_refresh() In this patch, we check in the probe handler common epilogue whether a module refresh is needed as determined by the probe handlers. If so, we schedule_work() so that systemtap_module_refresh() is eventually called to update the necessary probes. --- runtime/transport/symbols.c | 1 - tapsets.cxx | 10 ++++++++++ translate.cxx | 30 +++++++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c index 2a85823db..d00a7a10a 100644 --- a/runtime/transport/symbols.c +++ b/runtime/transport/symbols.c @@ -17,7 +17,6 @@ #define KERN_CONT "" #endif -static void systemtap_module_refresh (void); static int _stp_kmodule_check (const char*); /* PR12612: pre-commit-3abb860f values */ diff --git a/tapsets.cxx b/tapsets.cxx index 11118c04f..3b6cafdd3 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -214,6 +214,16 @@ void common_probe_entryfn_epilogue (systemtap_session& s, bool overload_processing) { + // Check if we need to enable/disable probes based on the latest values of + // probes_condition_enabled[]. + + s.op->newline( 0) << "#ifdef STP_ON_THE_FLY"; + s.op->newline( 0) << "if (need_module_refresh) {"; + s.op->newline(+1) << "need_module_refresh = 0;"; + s.op->newline( 0) << "schedule_work(&module_refresher_work);"; + s.op->newline(-1) << "}"; + s.op->newline( 0) << "#endif"; + if (overload_processing && !s.runtime_usermode_p()) s.op->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)"; else diff --git a/translate.cxx b/translate.cxx index 2b29f42d8..b25526d6a 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1087,10 +1087,27 @@ c_unparser::emit_common_header () emit_compiled_printfs(); - // Updated in probe handlers to signal that a module refresh is needed. o->newline( 0) << "#ifdef STP_ON_THE_FLY"; + + // Updated in probe handlers to signal that a module refresh is needed. + // Checked and cleared by common epilogue after scheduling refresh work. o->newline( 0) << "static unsigned need_module_refresh = 0;"; + + // We will use a workqueue to schedule module_refresh work when we need + // to enable/disable probes. + o->newline( 0) << "#include "; + o->newline( 0) << "static struct work_struct module_refresher_work;"; + o->newline( 0) << "#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)"; + o->newline( 0) << "static void module_refresher(void *data) {"; + o->newline( 0) << "#else"; + o->newline( 0) << "static void module_refresher(struct work_struct *work) {"; o->newline( 0) << "#endif"; + o->newline( 1) << "systemtap_module_refresh();"; + o->newline(-1) << "}"; + + o->newline( 0) << "#endif"; // STP_ON_THE_FLY + + o->newline(); } @@ -1828,6 +1845,13 @@ c_unparser::emit_module_init () o->newline() << "#ifdef STP_ON_THE_FLY"; + // Initialize workqueue needed for on-the-fly arming/disarming + o->newline() << "#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)"; + o->newline() << "INIT_WORK(&module_refresher_work, module_refresher, NULL);"; + o->newline() << "#else"; + o->newline() << "INIT_WORK(&module_refresher_work, module_refresher);"; + o->newline() << "#endif"; + // Initialize probe conditions for (unsigned i=0; iprobes.size(); i++) emit_probe_condition_initialize(session->probes[i]); @@ -1959,6 +1983,7 @@ c_unparser::emit_module_exit () // while to abort right away. Currently running probes are allowed to // terminate. These may set STAP_SESSION_ERROR! + // We're processing the derived_probe_group list in reverse // order. This ensures that probes get unregistered in reverse // order of the way they were registered. @@ -7014,6 +7039,9 @@ translate_pass (systemtap_session& s) s.op->newline() << "#undef STP_ON_THE_FLY"; s.op->newline() << "#endif"; + // Emit systemtap_module_refresh() prototype so we can reference it + s.op->newline() << "static void systemtap_module_refresh (void);"; + s.op->newline() << "#include \"runtime.h\""; // Emit embeds ahead of time, in case they affect context layout -- 2.43.5