]> sourceware.org Git - systemtap.git/commitdiff
runtime: use workqueue to schedule systemtap_module_refresh()
authorJonathan Lebon <jlebon@redhat.com>
Mon, 2 Jun 2014 15:51:38 +0000 (11:51 -0400)
committerJonathan Lebon <jlebon@redhat.com>
Mon, 11 Aug 2014 19:40:00 +0000 (15:40 -0400)
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
tapsets.cxx
translate.cxx

index 2a85823dbf62773a0f29afe6c83c6c62e3a9aed6..d00a7a10a8c646d2a632ee93298fe0e6292ca1c3 100644 (file)
@@ -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 */
index 11118c04f185e8f1cd08e4cf64a690b3393a2a21..3b6cafdd3487b79c8a2e20868bc1ac7d520252aa 100644 (file)
@@ -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
index 2b29f42d80e526168bb819a92d787c56bbb378d3..b25526d6a1e548f9bcb5c14cf0dddf6d3b275ed6 100644 (file)
@@ -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 <linux/workqueue.h>";
+  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; i<session->probes.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
This page took 0.060578 seconds and 5 git commands to generate.