output_exportconf(s, o, "vmalloc_node", "STAPCONF_VMALLOC_NODE");
// RHBZ1233912 - s390 temporary workaround for non-atomic udelay()
- output_exportconf(s, o, "udelay_simple", "STAPCONF_UDELAY_SIMPLE");
+ output_exportconf(s, o, "udelay_simple", "STAPCONF_UDELAY_SIMPLE_EXPORTED");
+ output_autoconf(s, o, "autoconf-udelay_simple.c", "STAPCONF_UDELAY_SIMPLE",
+ NULL);
output_autoconf(s, o, "autoconf-tracepoint-strings.c", "STAPCONF_TRACEPOINT_STRINGS", NULL);
output_autoconf(s, o, "autoconf-timerfd.c", "STAPCONF_TIMERFD_H", NULL);
--- /dev/null
+#include <asm/delay.h>
+
+void foo (unsigned long long usecs)
+{
+ udelay_simple(usecs);
+}
g_refresh_timing = _stp_stat_init(STAT_OP_MIN, STAT_OP_MAX, STAT_OP_AVG, STAT_OP_VARIANCE, 0, NULL);
#endif
+#if defined(STAPCONF_UDELAY_SIMPLE) && !defined(STAPCONF_UDELAY_SIMPLE_EXPORTED)
+ // PR20516: Some s390 kernels that have udelay_simple() don't
+ // have it exported. Note that we have to do this early since
+ // other init routines could call udelay().
+ kallsyms_udelay_simple = (void *)kallsyms_lookup_name("udelay_simple");
+ if (kallsyms_udelay_simple == NULL) {
+ _stp_error("couldn't find udelay_simple");
+ return 1;
+ }
+#endif
return 0;
}
#define STP_TRANSPORT_VERSION 1
#endif
-#ifdef STAPCONF_UDELAY_SIMPLE
+#if defined(STAPCONF_UDELAY_SIMPLE_EXPORTED)
#undef udelay
#define udelay(x) udelay_simple(x)
+#elif defined(STAPCONF_UDELAY_SIMPLE)
+#undef udelay
+static void *kallsyms_udelay_simple;
+typedef typeof(&udelay_simple) udelay_simple_fn;
+#define udelay(x) ((* (udelay_simple_fn)(kallsyms_udelay_simple))((x)))
#endif
#ifndef clamp