From a208676d5d136b1d52cc598f85374750e368587c Mon Sep 17 00:00:00 2001 From: Kienan Stewart Date: Mon, 15 Apr 2024 09:25:26 -0400 Subject: [PATCH 1/2] Fix: timer_expire_entry changed in 4.19.312 See upstream commit: commit bbb5b1c060d73ca96ccc8cceaa81f5e1a96e8fa4 Author: Anna-Maria Gleixner Date: Thu Mar 21 13:09:21 2019 +0100 timer/trace: Improve timer tracing [ Upstream commit f28d3d5346e97e60c81f933ac89ccf015430e5cf ] Timers are added to the timer wheel off by one. This is required in case a timer is queued directly before incrementing jiffies to prevent early timer expiry. When reading a timer trace and relying only on the expiry time of the timer in the timer_start trace point and on the now in the timer_expiry_entry trace point, it seems that the timer fires late. With the current timer_expiry_entry trace point information only now=jiffies is printed but not the value of base->clk. This makes it impossible to draw a conclusion to the index of base->clk and makes it impossible to examine timer problems without additional trace points. Therefore add the base->clk value to the timer_expire_entry trace point, to be able to calculate the index the timer base is located at during collecting expired timers. Change-Id: I2ebdbb637db0966ff51f45bf66916a59a496b50c Signed-off-by: Kienan Stewart Signed-off-by: Mathieu Desnoyers --- instrumentation/events/lttng-module/timer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/events/lttng-module/timer.h b/instrumentation/events/lttng-module/timer.h index 1d69758c..d92e9b98 100644 --- a/instrumentation/events/lttng-module/timer.h +++ b/instrumentation/events/lttng-module/timer.h @@ -90,6 +90,7 @@ LTTNG_TRACEPOINT_EVENT(timer_start, #endif /* #else #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,2,0)) */ #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,2,0) || \ + LTTNG_KERNEL_RANGE(4,19,312, 4,20,0) || \ LTTNG_RHEL_KERNEL_RANGE(4,18,0,193,0,0, 4,19,0,0,0,0)) /** * timer_expire_entry - called immediately before the timer callback -- 2.34.1 From 7a03a49a221efa744ef2de0562dcd24cde911603 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 9 May 2024 14:43:05 -0400 Subject: [PATCH 2/2] page alloc wrapper: Fix get_pfnblock_flags_mask prototype The canary __canary__get_pfnblock_flags_mask has never done its job of detecting changes to the prototype of get_pfnblock_flags_mask because it was actually calling the wrapper, because the wrapper/page_alloc.h header maps get_pfnblock_flags_mask to wrapper_get_pfnblock_flags_mask. Unfortunately, this wrapper is included by page_alloc.c only _after_ the linux/pageblock-flags.h header is included, which means the get_pfnblock_flags_mask prototype does _not_ have the wrapper prefix, which prevents it from being useful for any kind of type validation. This has been detected by a compiler warning stating that wrapper_get_pfnblock_flags_mask() does not have a prior declaration. Move the wrapper/page_alloc.h include _before_ including pageblock-flags.h. This ensures the declaration has the wrapper_ prefix, and therefore the compiler compares the declaration with the definition of wrapper_get_pfnblock_flags_mask within page_alloc.c. The canary function can be removed because it is redundant with this type check. With this proper type check in place, we notice the following two changes upstream: commit 535b81e209219 ("mm/page_alloc.c: remove unnecessary end_bitidx for [set|get]_pfnblock_flags_mask()") introduced in v5.9 removes the end_bitidx argument. commit ca891f41c4c79 ("mm: constify get_pfnblock_flags_mask and get_pfnblock_migratetype") introduced in v5.14 adds a const qualifier to the struct page pointer. Adapt the code to match the evolution of this prototype. Signed-off-by: Mathieu Desnoyers Change-Id: I51b7871edfbff0f74ba1cf4d0ad988eb8d642b4e --- wrapper/page_alloc.c | 62 ++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/wrapper/page_alloc.c b/wrapper/page_alloc.c index b464f4d1..3353eed7 100644 --- a/wrapper/page_alloc.c +++ b/wrapper/page_alloc.c @@ -18,12 +18,51 @@ || LTTNG_DEBIAN_KERNEL_RANGE(3,16,7,9,0,0, 3,17,0,0,0,0) \ || LTTNG_UBUNTU_KERNEL_RANGE(3,16,7,34, 3,17,0,0))) +/* Include page_alloc wrapper before pageblock-flags.h. */ +#include + +#include #include #include #include #include -#include +#include + +#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,14,0)) +static +unsigned long (*get_pfnblock_flags_mask_sym)(const struct page *page, + unsigned long pfn, + unsigned long mask); + +unsigned long wrapper_get_pfnblock_flags_mask(const struct page *page, + unsigned long pfn, + unsigned long mask) +{ + WARN_ON_ONCE(!get_pfnblock_flags_mask_sym); + if (get_pfnblock_flags_mask_sym) { + return get_pfnblock_flags_mask_sym(page, pfn, mask); + } else { + return -ENOSYS; + } +} +#elif (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,9,0)) +static +unsigned long (*get_pfnblock_flags_mask_sym)(struct page *page, + unsigned long pfn, + unsigned long mask); +unsigned long wrapper_get_pfnblock_flags_mask(struct page *page, + unsigned long pfn, + unsigned long mask) +{ + WARN_ON_ONCE(!get_pfnblock_flags_mask_sym); + if (get_pfnblock_flags_mask_sym) { + return get_pfnblock_flags_mask_sym(page, pfn, mask); + } else { + return -ENOSYS; + } +} +#else /* #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,9,0)) */ static unsigned long (*get_pfnblock_flags_mask_sym)(struct page *page, unsigned long pfn, @@ -42,6 +81,8 @@ unsigned long wrapper_get_pfnblock_flags_mask(struct page *page, return -ENOSYS; } } +#endif /* #else #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,9,0)) */ + EXPORT_SYMBOL_GPL(wrapper_get_pfnblock_flags_mask); int wrapper_get_pfnblock_flags_mask_init(void) @@ -54,25 +95,6 @@ int wrapper_get_pfnblock_flags_mask_init(void) } EXPORT_SYMBOL_GPL(wrapper_get_pfnblock_flags_mask_init); -/* - * Canary function to check for 'get_pfnblock_flags_mask()' at compile time. - * - * From 'include/linux/pageblock-flags.h': - * - * unsigned long get_pfnblock_flags_mask(struct page *page, - * unsigned long pfn, - * unsigned long end_bitidx, - * unsigned long mask); - */ -__attribute__((unused)) static -unsigned long __canary__get_pfnblock_flags_mask(struct page *page, - unsigned long pfn, - unsigned long end_bitidx, - unsigned long mask) -{ - return get_pfnblock_flags_mask(page, pfn, end_bitidx, mask); -} - #else #include -- 2.34.1