output_autoconf(s, o, "autoconf-uaccess.c", "STAPCONF_LINUX_UACCESS_H", NULL);
output_autoconf(s, o, "autoconf-oneachcpu-retry.c", "STAPCONF_ONEACHCPU_RETRY", NULL);
output_autoconf(s, o, "autoconf-dpath-path.c", "STAPCONF_DPATH_PATH", NULL);
+ output_exportconf(s, o, "synchronize_kernel", "STAPCONF_SYNCHRONIZE_KERNEL");
+ output_exportconf(s, o, "synchronize_rcu", "STAPCONF_SYNCHRONIZE_RCU");
output_exportconf(s, o, "synchronize_sched", "STAPCONF_SYNCHRONIZE_SCHED");
output_autoconf(s, o, "autoconf-task-uid.c", "STAPCONF_TASK_UID", NULL);
output_autoconf(s, o, "autoconf-from_kuid_munged.c", "STAPCONF_FROM_KUID_MUNGED", NULL);
return rc;
}
+static inline void stp_synchronize_sched(void) { }
+
/*
* For stapdyn to work in a multiprocess environment, the module must be
* prepared to be loaded multiple times in different processes. Thus, we have
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/profile.h>
+#include <linux/rcupdate.h>
//#include <linux/utsrelease.h> // newer kernels only
//#include <linux/compile.h>
#ifdef STAPCONF_GENERATED_COMPILE
#endif
#undef _STP_KERNEL_PARAM_ARG
+
+static inline void stp_synchronize_sched(void)
+{
+#if defined(STAPCONF_SYNCHRONIZE_SCHED)
+ synchronize_sched();
+#elif defined(STAPCONF_SYNCHRONIZE_RCU)
+ synchronize_rcu();
+#elif defined(STAPCONF_SYNCHRONIZE_KERNEL)
+ synchronize_kernel();
+#else
+#error "No implementation for stp_synchronize_sched!"
+#endif
+}
+
/************* Module Stuff ********************/
}
/* Sync to make sure existing readers are done. */
-#ifdef STAPCONF_SYNCHRONIZE_SCHED
- synchronize_sched();
-#else
- synchronize_kernel();
-#endif
+ stp_synchronize_sched();
/* Now we can actually free the contexts. */
for_each_possible_cpu(cpu) {
// For any partially registered/unregistered kernel facilities.
o->newline() << "atomic_set (session_state(), STAP_SESSION_STOPPED);";
- o->newline() << "#ifdef STAPCONF_SYNCHRONIZE_SCHED";
- o->newline() << "synchronize_sched();";
- o->newline() << "#endif";
+ o->newline() << "stp_synchronize_sched();";
// In case tracepoints were started, they need to be cleaned up
o->newline() << "#ifdef STAP_NEED_TRACEPOINTS";
// Let's wait a while to make sure they're all done, done, done.
// cargo cult prologue
- o->newline() << "#ifdef STAPCONF_SYNCHRONIZE_SCHED";
- o->newline() << "synchronize_sched();";
- o->newline() << "#endif";
+ o->newline() << "stp_synchronize_sched();";
// NB: systemtap_module_exit is assumed to be called from ordinary
// user context, say during module unload. Among other things, this
// cargo cult epilogue
o->newline() << "atomic_set (session_state(), STAP_SESSION_STOPPED);";
- o->newline() << "#ifdef STAPCONF_SYNCHRONIZE_SCHED";
- o->newline() << "synchronize_sched();";
- o->newline() << "#endif";
+ o->newline() << "stp_synchronize_sched();";
// XXX: might like to have an escape hatch, in case some probe is
// genuinely stuck somehow