From ce5cddc50edd07aeb34e5f7ea6ee4b5e229f6ea2 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Fri, 21 Nov 2008 10:47:02 -0500 Subject: stability: fix shutdown synchronization with possibly pending/running probes --- ChangeLog | 6 ++++++ translate.cxx | 22 +++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index cf4f4611..20f5706a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-11-21 Frank Ch. Eigler + + * translate.cxx (emit_module_exit): Perform shutdown probe + synchronization after all unregistrations and end/error probe + runs. + 2008-11-20 Frank Ch. Eigler PR 5689 diff --git a/translate.cxx b/translate.cxx index 0d4cc266..8bae5275 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1256,6 +1256,17 @@ 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. + vector g = all_session_groups (*session); + for (vector::reverse_iterator i = g.rbegin(); + i != g.rend(); i++) + (*i)->emit_module_exit (*session); // NB: runs "end" probes + + // But some other probes may have launched too during unregistration. + // Let's wait a while to make sure they're all done, done, done. + // NB: systemtap_module_exit is assumed to be called from ordinary // user context, say during module unload. Among other things, this // means we can sleep a while. @@ -1266,20 +1277,13 @@ c_unparser::emit_module_exit () o->newline(1) << "if (cpu_possible (i) && " << "atomic_read (& ((struct context *)per_cpu_ptr(contexts, i))->busy)) " << "holdon = 1;"; - o->newline () << "schedule ();"; + // NB: we run at least one of these during the shutdown sequence: + o->newline () << "yield ();"; // aka schedule() and then some o->newline(-2) << "} while (holdon);"; // XXX: might like to have an escape hatch, in case some probe is // genuinely stuck somehow - // Notice 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. - vector g = all_session_groups (*session); - for (vector::reverse_iterator i = g.rbegin(); - i != g.rend(); i++) - (*i)->emit_module_exit (*session); // NB: runs "end" probes - for (unsigned i=0; iglobals.size(); i++) { vardecl* v = session->globals[i]; -- cgit