diff options
Diffstat (limited to 'meta')
9 files changed, 1148 insertions, 1 deletions
diff --git a/meta/recipes-kernel/lttng/lttng-modules/0001-Fix-handle-missing-ftrace-header-on-v4.12.patch b/meta/recipes-kernel/lttng/lttng-modules/0001-Fix-handle-missing-ftrace-header-on-v4.12.patch new file mode 100644 index 0000000000..37c1f9af49 --- /dev/null +++ b/meta/recipes-kernel/lttng/lttng-modules/0001-Fix-handle-missing-ftrace-header-on-v4.12.patch | |||
@@ -0,0 +1,96 @@ | |||
1 | From fea65d0c097a42cf163bf7035985a6da330b9a1f Mon Sep 17 00:00:00 2001 | ||
2 | From: Michael Jeanson <mjeanson@efficios.com> | ||
3 | Date: Fri, 23 Jun 2017 14:29:42 -0400 | ||
4 | Subject: [PATCH 1/8] Fix: handle missing ftrace header on v4.12 | ||
5 | Organization: O.S. Systems Software LTDA. | ||
6 | |||
7 | Properly handle the case where we build against the distro headers of a | ||
8 | kernel >= 4.12 and ftrace is enabled but the private header is | ||
9 | unavailable. | ||
10 | |||
11 | Upstream-Status: Backport [2.9.4] | ||
12 | |||
13 | Signed-off-by: Michael Jeanson <mjeanson@efficios.com> | ||
14 | Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | ||
15 | --- | ||
16 | Makefile.ABI.workarounds | 21 +++++++++++++++++++++ | ||
17 | lttng-events.h | 2 +- | ||
18 | probes/Kbuild | 19 ++++--------------- | ||
19 | 3 files changed, 26 insertions(+), 16 deletions(-) | ||
20 | |||
21 | diff --git a/Makefile.ABI.workarounds b/Makefile.ABI.workarounds | ||
22 | index c3717f8..2e6c4aa 100644 | ||
23 | --- a/Makefile.ABI.workarounds | ||
24 | +++ b/Makefile.ABI.workarounds | ||
25 | @@ -27,3 +27,24 @@ RT_PATCH_VERSION:=$(shell $(TOP_LTTNG_MODULES_DIR)/rt-patch-version.sh $(CURDIR) | ||
26 | ifneq ($(RT_PATCH_VERSION), 0) | ||
27 | ccflags-y += -DRT_PATCH_VERSION=$(RT_PATCH_VERSION) | ||
28 | endif | ||
29 | + | ||
30 | +# Starting with kernel 4.12, the ftrace header was moved to private headers | ||
31 | +# and as such is not available when building against distro headers instead | ||
32 | +# of the full kernel sources. In the situation, define LTTNG_FTRACE_MISSING_HEADER | ||
33 | +# so we can enable the compat code even if CONFIG_DYNAMIC_FTRACE is enabled. | ||
34 | +ifneq ($(CONFIG_DYNAMIC_FTRACE),) | ||
35 | + ftrace_dep = $(srctree)/kernel/trace/trace.h | ||
36 | + ftrace_dep_check = $(wildcard $(ftrace_dep)) | ||
37 | + have_ftrace_header = $(shell \ | ||
38 | + if [ $(VERSION) -ge 5 -o \( $(VERSION) -eq 4 -a $(PATCHLEVEL) -ge 12 \) ] ; then \ | ||
39 | + if [ -z "$(ftrace_dep_check)" ] ; then \ | ||
40 | + echo "no" ; \ | ||
41 | + exit ; \ | ||
42 | + fi; \ | ||
43 | + fi; \ | ||
44 | + echo "yes" ; \ | ||
45 | + ) | ||
46 | + ifeq ($(have_ftrace_header), no) | ||
47 | + ccflags-y += -DLTTNG_FTRACE_MISSING_HEADER | ||
48 | + endif | ||
49 | +endif | ||
50 | diff --git a/lttng-events.h b/lttng-events.h | ||
51 | index 173f369..5a96bf3 100644 | ||
52 | --- a/lttng-events.h | ||
53 | +++ b/lttng-events.h | ||
54 | @@ -810,7 +810,7 @@ int lttng_kretprobes_event_enable_state(struct lttng_event *event, | ||
55 | } | ||
56 | #endif | ||
57 | |||
58 | -#ifdef CONFIG_DYNAMIC_FTRACE | ||
59 | +#if defined(CONFIG_DYNAMIC_FTRACE) && !defined(LTTNG_FTRACE_MISSING_HEADER) | ||
60 | int lttng_ftrace_register(const char *name, | ||
61 | const char *symbol_name, | ||
62 | struct lttng_event *event); | ||
63 | diff --git a/probes/Kbuild b/probes/Kbuild | ||
64 | index 78bf3fb..cc1c065 100644 | ||
65 | --- a/probes/Kbuild | ||
66 | +++ b/probes/Kbuild | ||
67 | @@ -259,22 +259,11 @@ ifneq ($(CONFIG_KRETPROBES),) | ||
68 | endif # CONFIG_KRETPROBES | ||
69 | |||
70 | ifneq ($(CONFIG_DYNAMIC_FTRACE),) | ||
71 | - ftrace_dep = $(srctree)/kernel/trace/trace.h | ||
72 | - ftrace_dep_check = $(wildcard $(ftrace_dep)) | ||
73 | - ftrace = $(shell \ | ||
74 | - if [ $(VERSION) -ge 5 -o \( $(VERSION) -eq 4 -a $(PATCHLEVEL) -ge 12 \) ] ; then \ | ||
75 | - if [ -z "$(ftrace_dep_check)" ] ; then \ | ||
76 | - echo "warn" ; \ | ||
77 | - exit ; \ | ||
78 | - fi; \ | ||
79 | - fi; \ | ||
80 | - echo "lttng-ftrace.o" ; \ | ||
81 | - ) | ||
82 | - ifeq ($(ftrace),warn) | ||
83 | + ifeq ($(have_ftrace_header),yes) | ||
84 | + obj-$(CONFIG_LTTNG) += lttng-ftrace.o | ||
85 | + else | ||
86 | $(warning Files $(ftrace_dep) not found. Probe "ftrace" is disabled. Use full kernel source tree to enable it.) | ||
87 | - ftrace = | ||
88 | - endif # $(ftrace),warn | ||
89 | - obj-$(CONFIG_LTTNG) += $(ftrace) | ||
90 | + endif | ||
91 | endif # CONFIG_DYNAMIC_FTRACE | ||
92 | |||
93 | # vim:syntax=make | ||
94 | -- | ||
95 | 2.14.1 | ||
96 | |||
diff --git a/meta/recipes-kernel/lttng/lttng-modules/0002-Fix-sched-for-v4.11.5-rt1.patch b/meta/recipes-kernel/lttng/lttng-modules/0002-Fix-sched-for-v4.11.5-rt1.patch new file mode 100644 index 0000000000..d85630565a --- /dev/null +++ b/meta/recipes-kernel/lttng/lttng-modules/0002-Fix-sched-for-v4.11.5-rt1.patch | |||
@@ -0,0 +1,31 @@ | |||
1 | From 8db274f8dda050c4f2ee3dbd0f36a5ad8f8bd993 Mon Sep 17 00:00:00 2001 | ||
2 | From: Michael Jeanson <mjeanson@efficios.com> | ||
3 | Date: Mon, 10 Jul 2017 18:13:11 -0400 | ||
4 | Subject: [PATCH 2/8] Fix: sched for v4.11.5-rt1 | ||
5 | Organization: O.S. Systems Software LTDA. | ||
6 | |||
7 | Upstream-Status: Backport [2.9.4] | ||
8 | |||
9 | Signed-off-by: Michael Jeanson <mjeanson@efficios.com> | ||
10 | Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | ||
11 | --- | ||
12 | instrumentation/events/lttng-module/sched.h | 3 ++- | ||
13 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
14 | |||
15 | diff --git a/instrumentation/events/lttng-module/sched.h b/instrumentation/events/lttng-module/sched.h | ||
16 | index e6f36b1..cb5b5b2 100644 | ||
17 | --- a/instrumentation/events/lttng-module/sched.h | ||
18 | +++ b/instrumentation/events/lttng-module/sched.h | ||
19 | @@ -541,7 +541,8 @@ LTTNG_TRACEPOINT_EVENT(sched_stat_runtime, | ||
20 | #endif | ||
21 | |||
22 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) || \ | ||
23 | - LTTNG_RT_KERNEL_RANGE(4,9,27,18, 4,10,0,0)) | ||
24 | + LTTNG_RT_KERNEL_RANGE(4,9,27,18, 4,10,0,0) || \ | ||
25 | + LTTNG_RT_KERNEL_RANGE(4,11,5,1, 4,12,0,0)) | ||
26 | /* | ||
27 | * Tracepoint for showing priority inheritance modifying a tasks | ||
28 | * priority. | ||
29 | -- | ||
30 | 2.14.1 | ||
31 | |||
diff --git a/meta/recipes-kernel/lttng/lttng-modules/0003-Fix-Sleeping-function-called-from-invalid-context.patch b/meta/recipes-kernel/lttng/lttng-modules/0003-Fix-Sleeping-function-called-from-invalid-context.patch new file mode 100644 index 0000000000..d444a0728a --- /dev/null +++ b/meta/recipes-kernel/lttng/lttng-modules/0003-Fix-Sleeping-function-called-from-invalid-context.patch | |||
@@ -0,0 +1,133 @@ | |||
1 | From c1af5643e0df56b92481f7a7bc4110a58e4e5abb Mon Sep 17 00:00:00 2001 | ||
2 | From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | ||
3 | Date: Fri, 21 Jul 2017 08:22:04 -0400 | ||
4 | Subject: [PATCH 3/8] Fix: Sleeping function called from invalid context | ||
5 | Organization: O.S. Systems Software LTDA. | ||
6 | |||
7 | It affects system call instrumentation for accept, accept4 and connect, | ||
8 | only on the x86-64 architecture. | ||
9 | |||
10 | We need to use the LTTng accessing functions to touch user-space memory, | ||
11 | which take care of disabling the page fault handler, so we don't preempt | ||
12 | while in preempt-off context (tracepoints disable preemption). | ||
13 | |||
14 | Fixes #1111 | ||
15 | |||
16 | Upstream-Status: Backport [2.9.4] | ||
17 | |||
18 | Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | ||
19 | --- | ||
20 | .../x86-64-syscalls-3.10.0-rc7_pointers_override.h | 47 ++++++++++++++-------- | ||
21 | 1 file changed, 31 insertions(+), 16 deletions(-) | ||
22 | |||
23 | diff --git a/instrumentation/syscalls/headers/x86-64-syscalls-3.10.0-rc7_pointers_override.h b/instrumentation/syscalls/headers/x86-64-syscalls-3.10.0-rc7_pointers_override.h | ||
24 | index 5e91004..6bf5291 100644 | ||
25 | --- a/instrumentation/syscalls/headers/x86-64-syscalls-3.10.0-rc7_pointers_override.h | ||
26 | +++ b/instrumentation/syscalls/headers/x86-64-syscalls-3.10.0-rc7_pointers_override.h | ||
27 | @@ -2,7 +2,7 @@ | ||
28 | |||
29 | #define OVERRIDE_64_connect | ||
30 | SC_LTTNG_TRACEPOINT_EVENT_CODE(connect, | ||
31 | - TP_PROTO(sc_exit(long ret,) int fd, struct sockaddr * uservaddr, int addrlen), | ||
32 | + TP_PROTO(sc_exit(long ret,) int fd, struct sockaddr __user * uservaddr, int addrlen), | ||
33 | TP_ARGS(sc_exit(ret,) fd, uservaddr, addrlen), | ||
34 | TP_locvar( | ||
35 | __typeof__(uservaddr->sa_family) sa_family; | ||
36 | @@ -16,21 +16,28 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(connect, | ||
37 | memset(tp_locvar, 0, sizeof(*tp_locvar)); | ||
38 | if (addrlen < sizeof(tp_locvar->sa_family)) | ||
39 | goto skip_code; | ||
40 | - (void) get_user(tp_locvar->sa_family, &uservaddr->sa_family); | ||
41 | + (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->sa_family, | ||
42 | + &uservaddr->sa_family, sizeof(tp_locvar->sa_family)); | ||
43 | switch (tp_locvar->sa_family) { | ||
44 | case AF_INET: | ||
45 | if (addrlen < sizeof(struct sockaddr_in)) | ||
46 | goto skip_code; | ||
47 | - (void) get_user(tp_locvar->dport, &((struct sockaddr_in *) uservaddr)->sin_port); | ||
48 | - (void) get_user(tp_locvar->v4addr, &((struct sockaddr_in *) uservaddr)->sin_addr.s_addr); | ||
49 | + (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->dport, | ||
50 | + &((struct sockaddr_in __user *) uservaddr)->sin_port, | ||
51 | + sizeof(tp_locvar->dport)); | ||
52 | + (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->v4addr, | ||
53 | + &((struct sockaddr_in __user *) uservaddr)->sin_addr.s_addr, | ||
54 | + sizeof(tp_locvar->v4addr)); | ||
55 | tp_locvar->v4addr_len = 4; | ||
56 | break; | ||
57 | case AF_INET6: | ||
58 | if (addrlen < sizeof(struct sockaddr_in6)) | ||
59 | goto skip_code; | ||
60 | - (void) get_user(tp_locvar->dport, &((struct sockaddr_in6 *) uservaddr)->sin6_port); | ||
61 | - if (copy_from_user(tp_locvar->v6addr, | ||
62 | - &((struct sockaddr_in6 *) uservaddr)->sin6_addr.in6_u.u6_addr8, | ||
63 | + (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->dport, | ||
64 | + &((struct sockaddr_in6 __user *) uservaddr)->sin6_port, | ||
65 | + sizeof(tp_locvar->dport)); | ||
66 | + if (lib_ring_buffer_copy_from_user_check_nofault(tp_locvar->v6addr, | ||
67 | + &((struct sockaddr_in6 __user *) uservaddr)->sin6_addr.in6_u.u6_addr8, | ||
68 | sizeof(tp_locvar->v6addr))) | ||
69 | memset(tp_locvar->v6addr, 0, sizeof(tp_locvar->v6addr)); | ||
70 | tp_locvar->v6addr_len = 8; | ||
71 | @@ -63,26 +70,34 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(connect, | ||
72 | #define LTTNG_SYSCALL_ACCEPT_code_pre \ | ||
73 | sc_inout( \ | ||
74 | memset(tp_locvar, 0, sizeof(*tp_locvar)); \ | ||
75 | - (void) get_user(tp_locvar->uaddr_len, upeer_addrlen); \ | ||
76 | + (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->uaddr_len, \ | ||
77 | + upeer_addrlen, sizeof(tp_locvar->uaddr_len)); \ | ||
78 | ) \ | ||
79 | sc_out( \ | ||
80 | if (tp_locvar->uaddr_len < sizeof(tp_locvar->sa_family)) \ | ||
81 | goto skip_code; \ | ||
82 | - (void) get_user(tp_locvar->sa_family, &upeer_sockaddr->sa_family); \ | ||
83 | + (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->sa_family, \ | ||
84 | + &upeer_sockaddr->sa_family, sizeof(tp_locvar->sa_family)); \ | ||
85 | switch (tp_locvar->sa_family) { \ | ||
86 | case AF_INET: \ | ||
87 | if (tp_locvar->uaddr_len < sizeof(struct sockaddr_in)) \ | ||
88 | goto skip_code; \ | ||
89 | - (void) get_user(tp_locvar->sport, &((struct sockaddr_in *) upeer_sockaddr)->sin_port); \ | ||
90 | - (void) get_user(tp_locvar->v4addr, &((struct sockaddr_in *) upeer_sockaddr)->sin_addr.s_addr); \ | ||
91 | + (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->sport, \ | ||
92 | + &((struct sockaddr_in __user *) upeer_sockaddr)->sin_port, \ | ||
93 | + sizeof(tp_locvar->sport)); \ | ||
94 | + (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->v4addr, \ | ||
95 | + &((struct sockaddr_in __user *) upeer_sockaddr)->sin_addr.s_addr, \ | ||
96 | + sizeof(tp_locvar->v4addr)); \ | ||
97 | tp_locvar->v4addr_len = 4; \ | ||
98 | break; \ | ||
99 | case AF_INET6: \ | ||
100 | if (tp_locvar->uaddr_len < sizeof(struct sockaddr_in6)) \ | ||
101 | goto skip_code; \ | ||
102 | - (void) get_user(tp_locvar->sport, &((struct sockaddr_in6 *) upeer_sockaddr)->sin6_port); \ | ||
103 | - if (copy_from_user(tp_locvar->v6addr, \ | ||
104 | - &((struct sockaddr_in6 *) upeer_sockaddr)->sin6_addr.in6_u.u6_addr8, \ | ||
105 | + (void) lib_ring_buffer_copy_from_user_check_nofault(&tp_locvar->sport, \ | ||
106 | + &((struct sockaddr_in6 __user *) upeer_sockaddr)->sin6_port, \ | ||
107 | + sizeof(tp_locvar->sport)); \ | ||
108 | + if (lib_ring_buffer_copy_from_user_check_nofault(tp_locvar->v6addr, \ | ||
109 | + &((struct sockaddr_in6 __user *) upeer_sockaddr)->sin6_addr.in6_u.u6_addr8, \ | ||
110 | sizeof(tp_locvar->v6addr))) \ | ||
111 | memset(tp_locvar->v6addr, 0, sizeof(tp_locvar->v6addr)); \ | ||
112 | tp_locvar->v6addr_len = 8; \ | ||
113 | @@ -93,7 +108,7 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(connect, | ||
114 | |||
115 | #define OVERRIDE_64_accept | ||
116 | SC_LTTNG_TRACEPOINT_EVENT_CODE(accept, | ||
117 | - TP_PROTO(sc_exit(long ret,) int fd, struct sockaddr * upeer_sockaddr, int * upeer_addrlen), | ||
118 | + TP_PROTO(sc_exit(long ret,) int fd, struct sockaddr __user * upeer_sockaddr, int __user * upeer_addrlen), | ||
119 | TP_ARGS(sc_exit(ret,) fd, upeer_sockaddr, upeer_addrlen), | ||
120 | TP_locvar( | ||
121 | LTTNG_SYSCALL_ACCEPT_locvar | ||
122 | @@ -116,7 +131,7 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(accept, | ||
123 | |||
124 | #define OVERRIDE_64_accept4 | ||
125 | SC_LTTNG_TRACEPOINT_EVENT_CODE(accept4, | ||
126 | - TP_PROTO(sc_exit(long ret,) int fd, struct sockaddr * upeer_sockaddr, int * upeer_addrlen, int flags), | ||
127 | + TP_PROTO(sc_exit(long ret,) int fd, struct sockaddr __user * upeer_sockaddr, int __user * upeer_addrlen, int flags), | ||
128 | TP_ARGS(sc_exit(ret,) fd, upeer_sockaddr, upeer_addrlen, flags), | ||
129 | TP_locvar( | ||
130 | LTTNG_SYSCALL_ACCEPT_locvar | ||
131 | -- | ||
132 | 2.14.1 | ||
133 | |||
diff --git a/meta/recipes-kernel/lttng/lttng-modules/0004-Fix-update-ext4-instrumentation-for-kernel-4.13.patch b/meta/recipes-kernel/lttng/lttng-modules/0004-Fix-update-ext4-instrumentation-for-kernel-4.13.patch new file mode 100644 index 0000000000..c835d06cf5 --- /dev/null +++ b/meta/recipes-kernel/lttng/lttng-modules/0004-Fix-update-ext4-instrumentation-for-kernel-4.13.patch | |||
@@ -0,0 +1,189 @@ | |||
1 | From 500c99a45fc0da09d1dc7b9e62bf58d562856a9a Mon Sep 17 00:00:00 2001 | ||
2 | From: Michael Jeanson <mjeanson@efficios.com> | ||
3 | Date: Mon, 21 Aug 2017 14:47:08 -0400 | ||
4 | Subject: [PATCH 4/8] Fix: update ext4 instrumentation for kernel 4.13 | ||
5 | Organization: O.S. Systems Software LTDA. | ||
6 | |||
7 | See this upstream commit : | ||
8 | |||
9 | commit a627b0a7c15ee4d2c87a86d5be5c8167382e8d0d | ||
10 | Author: Eric Whitney <enwlinux@gmail.com> | ||
11 | Date: Sun Jul 30 22:30:11 2017 -0400 | ||
12 | |||
13 | ext4: remove unused metadata accounting variables | ||
14 | |||
15 | Two variables in ext4_inode_info, i_reserved_meta_blocks and | ||
16 | i_allocated_meta_blocks, are unused. Removing them saves a little | ||
17 | memory per in-memory inode and cleans up clutter in several tracepoints. | ||
18 | Adjust tracepoint output from ext4_alloc_da_blocks() for consistency | ||
19 | and fix a typo and whitespace near these changes. | ||
20 | |||
21 | Upstream-Status: Backport [2.9.4] | ||
22 | |||
23 | Signed-off-by: Eric Whitney <enwlinux@gmail.com> | ||
24 | Signed-off-by: Theodore Ts'o <tytso@mit.edu> | ||
25 | Reviewed-by: Jan Kara <jack@suse.cz> | ||
26 | |||
27 | Signed-off-by: Michael Jeanson <mjeanson@efficios.com> | ||
28 | Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | ||
29 | --- | ||
30 | instrumentation/events/lttng-module/ext4.h | 96 ++++++++++++++++++++++++++---- | ||
31 | 1 file changed, 86 insertions(+), 10 deletions(-) | ||
32 | |||
33 | diff --git a/instrumentation/events/lttng-module/ext4.h b/instrumentation/events/lttng-module/ext4.h | ||
34 | index e87b534..fe6f802 100644 | ||
35 | --- a/instrumentation/events/lttng-module/ext4.h | ||
36 | +++ b/instrumentation/events/lttng-module/ext4.h | ||
37 | @@ -689,6 +689,19 @@ LTTNG_TRACEPOINT_EVENT(ext4_sync_fs, | ||
38 | ) | ||
39 | ) | ||
40 | |||
41 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)) | ||
42 | +LTTNG_TRACEPOINT_EVENT(ext4_alloc_da_blocks, | ||
43 | + TP_PROTO(struct inode *inode), | ||
44 | + | ||
45 | + TP_ARGS(inode), | ||
46 | + | ||
47 | + TP_FIELDS( | ||
48 | + ctf_integer(dev_t, dev, inode->i_sb->s_dev) | ||
49 | + ctf_integer(ino_t, ino, inode->i_ino) | ||
50 | + ctf_integer(unsigned int, data_blocks, EXT4_I(inode)->i_reserved_data_blocks) | ||
51 | + ) | ||
52 | +) | ||
53 | +#else | ||
54 | LTTNG_TRACEPOINT_EVENT(ext4_alloc_da_blocks, | ||
55 | TP_PROTO(struct inode *inode), | ||
56 | |||
57 | @@ -701,6 +714,7 @@ LTTNG_TRACEPOINT_EVENT(ext4_alloc_da_blocks, | ||
58 | ctf_integer(unsigned int, meta_blocks, EXT4_I(inode)->i_reserved_meta_blocks) | ||
59 | ) | ||
60 | ) | ||
61 | +#endif | ||
62 | |||
63 | LTTNG_TRACEPOINT_EVENT(ext4_mballoc_alloc, | ||
64 | TP_PROTO(struct ext4_allocation_context *ac), | ||
65 | @@ -833,17 +847,49 @@ LTTNG_TRACEPOINT_EVENT(ext4_forget, | ||
66 | ) | ||
67 | #endif | ||
68 | |||
69 | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) | ||
70 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)) | ||
71 | LTTNG_TRACEPOINT_EVENT(ext4_da_update_reserve_space, | ||
72 | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) | ||
73 | TP_PROTO(struct inode *inode, int used_blocks, int quota_claim), | ||
74 | |||
75 | TP_ARGS(inode, used_blocks, quota_claim), | ||
76 | -#else | ||
77 | + | ||
78 | + TP_FIELDS( | ||
79 | + ctf_integer(dev_t, dev, inode->i_sb->s_dev) | ||
80 | + ctf_integer(ino_t, ino, inode->i_ino) | ||
81 | + ctf_integer(__u64, i_blocks, inode->i_blocks) | ||
82 | + ctf_integer(int, used_blocks, used_blocks) | ||
83 | + ctf_integer(int, reserved_data_blocks, | ||
84 | + EXT4_I(inode)->i_reserved_data_blocks) | ||
85 | + ctf_integer(int, quota_claim, quota_claim) | ||
86 | + ctf_integer(TP_MODE_T, mode, inode->i_mode) | ||
87 | + ) | ||
88 | +) | ||
89 | +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) | ||
90 | +LTTNG_TRACEPOINT_EVENT(ext4_da_update_reserve_space, | ||
91 | + TP_PROTO(struct inode *inode, int used_blocks, int quota_claim), | ||
92 | + | ||
93 | + TP_ARGS(inode, used_blocks, quota_claim), | ||
94 | + | ||
95 | + TP_FIELDS( | ||
96 | + ctf_integer(dev_t, dev, inode->i_sb->s_dev) | ||
97 | + ctf_integer(ino_t, ino, inode->i_ino) | ||
98 | + ctf_integer(__u64, i_blocks, inode->i_blocks) | ||
99 | + ctf_integer(int, used_blocks, used_blocks) | ||
100 | + ctf_integer(int, reserved_data_blocks, | ||
101 | + EXT4_I(inode)->i_reserved_data_blocks) | ||
102 | + ctf_integer(int, reserved_meta_blocks, | ||
103 | + EXT4_I(inode)->i_reserved_meta_blocks) | ||
104 | + ctf_integer(int, allocated_meta_blocks, | ||
105 | + EXT4_I(inode)->i_allocated_meta_blocks) | ||
106 | + ctf_integer(int, quota_claim, quota_claim) | ||
107 | + ctf_integer(TP_MODE_T, mode, inode->i_mode) | ||
108 | + ) | ||
109 | +) | ||
110 | +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) | ||
111 | +LTTNG_TRACEPOINT_EVENT(ext4_da_update_reserve_space, | ||
112 | TP_PROTO(struct inode *inode, int used_blocks), | ||
113 | |||
114 | TP_ARGS(inode, used_blocks), | ||
115 | -#endif | ||
116 | |||
117 | TP_FIELDS( | ||
118 | ctf_integer(dev_t, dev, inode->i_sb->s_dev) | ||
119 | @@ -856,14 +902,27 @@ LTTNG_TRACEPOINT_EVENT(ext4_da_update_reserve_space, | ||
120 | EXT4_I(inode)->i_reserved_meta_blocks) | ||
121 | ctf_integer(int, allocated_meta_blocks, | ||
122 | EXT4_I(inode)->i_allocated_meta_blocks) | ||
123 | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) | ||
124 | - ctf_integer(int, quota_claim, quota_claim) | ||
125 | -#endif | ||
126 | ctf_integer(TP_MODE_T, mode, inode->i_mode) | ||
127 | ) | ||
128 | ) | ||
129 | +#endif | ||
130 | |||
131 | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0)) | ||
132 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)) | ||
133 | +LTTNG_TRACEPOINT_EVENT(ext4_da_reserve_space, | ||
134 | + TP_PROTO(struct inode *inode), | ||
135 | + | ||
136 | + TP_ARGS(inode), | ||
137 | + | ||
138 | + TP_FIELDS( | ||
139 | + ctf_integer(dev_t, dev, inode->i_sb->s_dev) | ||
140 | + ctf_integer(ino_t, ino, inode->i_ino) | ||
141 | + ctf_integer(__u64, i_blocks, inode->i_blocks) | ||
142 | + ctf_integer(int, reserved_data_blocks, | ||
143 | + EXT4_I(inode)->i_reserved_data_blocks) | ||
144 | + ctf_integer(TP_MODE_T, mode, inode->i_mode) | ||
145 | + ) | ||
146 | +) | ||
147 | +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0)) | ||
148 | LTTNG_TRACEPOINT_EVENT(ext4_da_reserve_space, | ||
149 | TP_PROTO(struct inode *inode), | ||
150 | |||
151 | @@ -880,7 +939,7 @@ LTTNG_TRACEPOINT_EVENT(ext4_da_reserve_space, | ||
152 | ctf_integer(TP_MODE_T, mode, inode->i_mode) | ||
153 | ) | ||
154 | ) | ||
155 | -#else /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0)) */ | ||
156 | +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) | ||
157 | LTTNG_TRACEPOINT_EVENT(ext4_da_reserve_space, | ||
158 | TP_PROTO(struct inode *inode, int md_needed), | ||
159 | |||
160 | @@ -898,8 +957,25 @@ LTTNG_TRACEPOINT_EVENT(ext4_da_reserve_space, | ||
161 | ctf_integer(TP_MODE_T, mode, inode->i_mode) | ||
162 | ) | ||
163 | ) | ||
164 | -#endif /* #else #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0)) */ | ||
165 | +#endif | ||
166 | + | ||
167 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)) | ||
168 | +LTTNG_TRACEPOINT_EVENT(ext4_da_release_space, | ||
169 | + TP_PROTO(struct inode *inode, int freed_blocks), | ||
170 | + | ||
171 | + TP_ARGS(inode, freed_blocks), | ||
172 | |||
173 | + TP_FIELDS( | ||
174 | + ctf_integer(dev_t, dev, inode->i_sb->s_dev) | ||
175 | + ctf_integer(ino_t, ino, inode->i_ino) | ||
176 | + ctf_integer(__u64, i_blocks, inode->i_blocks) | ||
177 | + ctf_integer(int, freed_blocks, freed_blocks) | ||
178 | + ctf_integer(int, reserved_data_blocks, | ||
179 | + EXT4_I(inode)->i_reserved_data_blocks) | ||
180 | + ctf_integer(TP_MODE_T, mode, inode->i_mode) | ||
181 | + ) | ||
182 | +) | ||
183 | +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) | ||
184 | LTTNG_TRACEPOINT_EVENT(ext4_da_release_space, | ||
185 | TP_PROTO(struct inode *inode, int freed_blocks), | ||
186 | |||
187 | -- | ||
188 | 2.14.1 | ||
189 | |||
diff --git a/meta/recipes-kernel/lttng/lttng-modules/0005-Fix-mmap-caches-aliased-on-virtual-addresses.patch b/meta/recipes-kernel/lttng/lttng-modules/0005-Fix-mmap-caches-aliased-on-virtual-addresses.patch new file mode 100644 index 0000000000..7f25c6a709 --- /dev/null +++ b/meta/recipes-kernel/lttng/lttng-modules/0005-Fix-mmap-caches-aliased-on-virtual-addresses.patch | |||
@@ -0,0 +1,100 @@ | |||
1 | From 90715ba61e3fa66c1bb438138c8716c6e72356f9 Mon Sep 17 00:00:00 2001 | ||
2 | From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | ||
3 | Date: Tue, 19 Sep 2017 12:16:58 -0400 | ||
4 | Subject: [PATCH 5/8] Fix: mmap: caches aliased on virtual addresses | ||
5 | Organization: O.S. Systems Software LTDA. | ||
6 | |||
7 | Some architectures (e.g. implementations of arm64) implement their | ||
8 | caches based on the virtual addresses (rather than physical address). | ||
9 | It has the upside of making the cache access faster (no TLB lookup | ||
10 | required to access the cache line), but the downside of requiring | ||
11 | virtual mappings (e.g. kernel vs user-space) to be aligned on the number | ||
12 | of bits used for cache aliasing. | ||
13 | |||
14 | Perform dcache flushing for the entire sub-buffer in the get_subbuf | ||
15 | operation on those architectures, thus ensuring we don't end up with | ||
16 | cache aliasing issues. | ||
17 | |||
18 | An alternative approach we could eventually take would be to create a | ||
19 | kernel mapping for the ring buffer that is aligned with the user-space | ||
20 | mapping. | ||
21 | |||
22 | Upstream-Status: Backport [2.9.4] | ||
23 | |||
24 | Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | ||
25 | --- | ||
26 | lib/ringbuffer/ring_buffer_frontend.c | 44 +++++++++++++++++++++++++++++++++++ | ||
27 | 1 file changed, 44 insertions(+) | ||
28 | |||
29 | diff --git a/lib/ringbuffer/ring_buffer_frontend.c b/lib/ringbuffer/ring_buffer_frontend.c | ||
30 | index dc1ee45..e77d789 100644 | ||
31 | --- a/lib/ringbuffer/ring_buffer_frontend.c | ||
32 | +++ b/lib/ringbuffer/ring_buffer_frontend.c | ||
33 | @@ -54,6 +54,7 @@ | ||
34 | #include <linux/delay.h> | ||
35 | #include <linux/module.h> | ||
36 | #include <linux/percpu.h> | ||
37 | +#include <asm/cacheflush.h> | ||
38 | |||
39 | #include <wrapper/ringbuffer/config.h> | ||
40 | #include <wrapper/ringbuffer/backend.h> | ||
41 | @@ -1149,6 +1150,47 @@ void lib_ring_buffer_move_consumer(struct lib_ring_buffer *buf, | ||
42 | } | ||
43 | EXPORT_SYMBOL_GPL(lib_ring_buffer_move_consumer); | ||
44 | |||
45 | +#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE | ||
46 | +static void lib_ring_buffer_flush_read_subbuf_dcache( | ||
47 | + const struct lib_ring_buffer_config *config, | ||
48 | + struct channel *chan, | ||
49 | + struct lib_ring_buffer *buf) | ||
50 | +{ | ||
51 | + struct lib_ring_buffer_backend_pages *pages; | ||
52 | + unsigned long sb_bindex, id, i, nr_pages; | ||
53 | + | ||
54 | + if (config->output != RING_BUFFER_MMAP) | ||
55 | + return; | ||
56 | + | ||
57 | + /* | ||
58 | + * Architectures with caches aliased on virtual addresses may | ||
59 | + * use different cache lines for the linear mapping vs | ||
60 | + * user-space memory mapping. Given that the ring buffer is | ||
61 | + * based on the kernel linear mapping, aligning it with the | ||
62 | + * user-space mapping is not straightforward, and would require | ||
63 | + * extra TLB entries. Therefore, simply flush the dcache for the | ||
64 | + * entire sub-buffer before reading it. | ||
65 | + */ | ||
66 | + id = buf->backend.buf_rsb.id; | ||
67 | + sb_bindex = subbuffer_id_get_index(config, id); | ||
68 | + pages = buf->backend.array[sb_bindex]; | ||
69 | + nr_pages = buf->backend.num_pages_per_subbuf; | ||
70 | + for (i = 0; i < nr_pages; i++) { | ||
71 | + struct lib_ring_buffer_backend_page *backend_page; | ||
72 | + | ||
73 | + backend_page = &pages->p[i]; | ||
74 | + flush_dcache_page(pfn_to_page(backend_page->pfn)); | ||
75 | + } | ||
76 | +} | ||
77 | +#else | ||
78 | +static void lib_ring_buffer_flush_read_subbuf_dcache( | ||
79 | + const struct lib_ring_buffer_config *config, | ||
80 | + struct channel *chan, | ||
81 | + struct lib_ring_buffer *buf) | ||
82 | +{ | ||
83 | +} | ||
84 | +#endif | ||
85 | + | ||
86 | /** | ||
87 | * lib_ring_buffer_get_subbuf - get exclusive access to subbuffer for reading | ||
88 | * @buf: ring buffer | ||
89 | @@ -1291,6 +1333,8 @@ retry: | ||
90 | buf->get_subbuf_consumed = consumed; | ||
91 | buf->get_subbuf = 1; | ||
92 | |||
93 | + lib_ring_buffer_flush_read_subbuf_dcache(config, chan, buf); | ||
94 | + | ||
95 | return 0; | ||
96 | |||
97 | nodata: | ||
98 | -- | ||
99 | 2.14.1 | ||
100 | |||
diff --git a/meta/recipes-kernel/lttng/lttng-modules/0006-Add-kmalloc-failover-to-vmalloc.patch b/meta/recipes-kernel/lttng/lttng-modules/0006-Add-kmalloc-failover-to-vmalloc.patch new file mode 100644 index 0000000000..82007691a6 --- /dev/null +++ b/meta/recipes-kernel/lttng/lttng-modules/0006-Add-kmalloc-failover-to-vmalloc.patch | |||
@@ -0,0 +1,519 @@ | |||
1 | From df57c35ddc8772652d8daa1e53da07f4c7819d8d Mon Sep 17 00:00:00 2001 | ||
2 | From: Michael Jeanson <mjeanson@efficios.com> | ||
3 | Date: Mon, 25 Sep 2017 10:56:20 -0400 | ||
4 | Subject: [PATCH 6/8] Add kmalloc failover to vmalloc | ||
5 | Organization: O.S. Systems Software LTDA. | ||
6 | |||
7 | This patch is based on the kvmalloc helpers introduced in kernel 4.12. | ||
8 | |||
9 | It will gracefully failover memory allocations of more than one page to | ||
10 | vmalloc for systems under high memory pressure or fragmentation. | ||
11 | |||
12 | See Linux kernel commit: | ||
13 | commit a7c3e901a46ff54c016d040847eda598a9e3e653 | ||
14 | Author: Michal Hocko <mhocko@suse.com> | ||
15 | Date: Mon May 8 15:57:09 2017 -0700 | ||
16 | |||
17 | mm: introduce kv[mz]alloc helpers | ||
18 | |||
19 | Patch series "kvmalloc", v5. | ||
20 | |||
21 | There are many open coded kmalloc with vmalloc fallback instances in the | ||
22 | tree. Most of them are not careful enough or simply do not care about | ||
23 | the underlying semantic of the kmalloc/page allocator which means that | ||
24 | a) some vmalloc fallbacks are basically unreachable because the kmalloc | ||
25 | part will keep retrying until it succeeds b) the page allocator can | ||
26 | invoke a really disruptive steps like the OOM killer to move forward | ||
27 | which doesn't sound appropriate when we consider that the vmalloc | ||
28 | fallback is available. | ||
29 | |||
30 | As it can be seen implementing kvmalloc requires quite an intimate | ||
31 | knowledge if the page allocator and the memory reclaim internals which | ||
32 | strongly suggests that a helper should be implemented in the memory | ||
33 | subsystem proper. | ||
34 | |||
35 | Most callers, I could find, have been converted to use the helper | ||
36 | instead. This is patch 6. There are some more relying on __GFP_REPEAT | ||
37 | in the networking stack which I have converted as well and Eric Dumazet | ||
38 | was not opposed [2] to convert them as well. | ||
39 | |||
40 | [1] http://lkml.kernel.org/r/20170130094940.13546-1-mhocko@kernel.org | ||
41 | [2] http://lkml.kernel.org/r/1485273626.16328.301.camel@edumazet-glaptop3.roam.corp.google.com | ||
42 | |||
43 | This patch (of 9): | ||
44 | |||
45 | Using kmalloc with the vmalloc fallback for larger allocations is a | ||
46 | common pattern in the kernel code. Yet we do not have any common helper | ||
47 | for that and so users have invented their own helpers. Some of them are | ||
48 | really creative when doing so. Let's just add kv[mz]alloc and make sure | ||
49 | it is implemented properly. This implementation makes sure to not make | ||
50 | a large memory pressure for > PAGE_SZE requests (__GFP_NORETRY) and also | ||
51 | to not warn about allocation failures. This also rules out the OOM | ||
52 | killer as the vmalloc is a more approapriate fallback than a disruptive | ||
53 | user visible action. | ||
54 | |||
55 | Upstream-Status: Backport [2.9.4] | ||
56 | |||
57 | Signed-off-by: Michael Jeanson <mjeanson@efficios.com> | ||
58 | Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | ||
59 | --- | ||
60 | lib/prio_heap/lttng_prio_heap.c | 7 +- | ||
61 | lib/ringbuffer/ring_buffer_backend.c | 22 ++--- | ||
62 | lib/ringbuffer/ring_buffer_frontend.c | 13 +-- | ||
63 | lttng-context-perf-counters.c | 6 +- | ||
64 | lttng-context.c | 6 +- | ||
65 | lttng-events.c | 6 +- | ||
66 | wrapper/vmalloc.h | 169 +++++++++++++++++++++++++++++++++- | ||
67 | 7 files changed, 198 insertions(+), 31 deletions(-) | ||
68 | |||
69 | diff --git a/lib/prio_heap/lttng_prio_heap.c b/lib/prio_heap/lttng_prio_heap.c | ||
70 | index 6db7f52..01ed69f 100644 | ||
71 | --- a/lib/prio_heap/lttng_prio_heap.c | ||
72 | +++ b/lib/prio_heap/lttng_prio_heap.c | ||
73 | @@ -26,6 +26,7 @@ | ||
74 | |||
75 | #include <linux/slab.h> | ||
76 | #include <lib/prio_heap/lttng_prio_heap.h> | ||
77 | +#include <wrapper/vmalloc.h> | ||
78 | |||
79 | #ifdef DEBUG_HEAP | ||
80 | void lttng_check_heap(const struct lttng_ptr_heap *heap) | ||
81 | @@ -70,12 +71,12 @@ int heap_grow(struct lttng_ptr_heap *heap, size_t new_len) | ||
82 | return 0; | ||
83 | |||
84 | heap->alloc_len = max_t(size_t, new_len, heap->alloc_len << 1); | ||
85 | - new_ptrs = kmalloc(heap->alloc_len * sizeof(void *), heap->gfpmask); | ||
86 | + new_ptrs = lttng_kvmalloc(heap->alloc_len * sizeof(void *), heap->gfpmask); | ||
87 | if (!new_ptrs) | ||
88 | return -ENOMEM; | ||
89 | if (heap->ptrs) | ||
90 | memcpy(new_ptrs, heap->ptrs, heap->len * sizeof(void *)); | ||
91 | - kfree(heap->ptrs); | ||
92 | + lttng_kvfree(heap->ptrs); | ||
93 | heap->ptrs = new_ptrs; | ||
94 | return 0; | ||
95 | } | ||
96 | @@ -109,7 +110,7 @@ int lttng_heap_init(struct lttng_ptr_heap *heap, size_t alloc_len, | ||
97 | |||
98 | void lttng_heap_free(struct lttng_ptr_heap *heap) | ||
99 | { | ||
100 | - kfree(heap->ptrs); | ||
101 | + lttng_kvfree(heap->ptrs); | ||
102 | } | ||
103 | |||
104 | static void heapify(struct lttng_ptr_heap *heap, size_t i) | ||
105 | diff --git a/lib/ringbuffer/ring_buffer_backend.c b/lib/ringbuffer/ring_buffer_backend.c | ||
106 | index f760836..3efa1d1 100644 | ||
107 | --- a/lib/ringbuffer/ring_buffer_backend.c | ||
108 | +++ b/lib/ringbuffer/ring_buffer_backend.c | ||
109 | @@ -71,7 +71,7 @@ int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config | ||
110 | if (unlikely(!pages)) | ||
111 | goto pages_error; | ||
112 | |||
113 | - bufb->array = kmalloc_node(ALIGN(sizeof(*bufb->array) | ||
114 | + bufb->array = lttng_kvmalloc_node(ALIGN(sizeof(*bufb->array) | ||
115 | * num_subbuf_alloc, | ||
116 | 1 << INTERNODE_CACHE_SHIFT), | ||
117 | GFP_KERNEL | __GFP_NOWARN, | ||
118 | @@ -90,7 +90,7 @@ int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config | ||
119 | /* Allocate backend pages array elements */ | ||
120 | for (i = 0; i < num_subbuf_alloc; i++) { | ||
121 | bufb->array[i] = | ||
122 | - kzalloc_node(ALIGN( | ||
123 | + lttng_kvzalloc_node(ALIGN( | ||
124 | sizeof(struct lib_ring_buffer_backend_pages) + | ||
125 | sizeof(struct lib_ring_buffer_backend_page) | ||
126 | * num_pages_per_subbuf, | ||
127 | @@ -102,7 +102,7 @@ int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config | ||
128 | } | ||
129 | |||
130 | /* Allocate write-side subbuffer table */ | ||
131 | - bufb->buf_wsb = kzalloc_node(ALIGN( | ||
132 | + bufb->buf_wsb = lttng_kvzalloc_node(ALIGN( | ||
133 | sizeof(struct lib_ring_buffer_backend_subbuffer) | ||
134 | * num_subbuf, | ||
135 | 1 << INTERNODE_CACHE_SHIFT), | ||
136 | @@ -122,7 +122,7 @@ int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config | ||
137 | bufb->buf_rsb.id = subbuffer_id(config, 0, 1, 0); | ||
138 | |||
139 | /* Allocate subbuffer packet counter table */ | ||
140 | - bufb->buf_cnt = kzalloc_node(ALIGN( | ||
141 | + bufb->buf_cnt = lttng_kvzalloc_node(ALIGN( | ||
142 | sizeof(struct lib_ring_buffer_backend_counts) | ||
143 | * num_subbuf, | ||
144 | 1 << INTERNODE_CACHE_SHIFT), | ||
145 | @@ -154,15 +154,15 @@ int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config | ||
146 | return 0; | ||
147 | |||
148 | free_wsb: | ||
149 | - kfree(bufb->buf_wsb); | ||
150 | + lttng_kvfree(bufb->buf_wsb); | ||
151 | free_array: | ||
152 | for (i = 0; (i < num_subbuf_alloc && bufb->array[i]); i++) | ||
153 | - kfree(bufb->array[i]); | ||
154 | + lttng_kvfree(bufb->array[i]); | ||
155 | depopulate: | ||
156 | /* Free all allocated pages */ | ||
157 | for (i = 0; (i < num_pages && pages[i]); i++) | ||
158 | __free_page(pages[i]); | ||
159 | - kfree(bufb->array); | ||
160 | + lttng_kvfree(bufb->array); | ||
161 | array_error: | ||
162 | vfree(pages); | ||
163 | pages_error: | ||
164 | @@ -191,14 +191,14 @@ void lib_ring_buffer_backend_free(struct lib_ring_buffer_backend *bufb) | ||
165 | if (chanb->extra_reader_sb) | ||
166 | num_subbuf_alloc++; | ||
167 | |||
168 | - kfree(bufb->buf_wsb); | ||
169 | - kfree(bufb->buf_cnt); | ||
170 | + lttng_kvfree(bufb->buf_wsb); | ||
171 | + lttng_kvfree(bufb->buf_cnt); | ||
172 | for (i = 0; i < num_subbuf_alloc; i++) { | ||
173 | for (j = 0; j < bufb->num_pages_per_subbuf; j++) | ||
174 | __free_page(pfn_to_page(bufb->array[i]->p[j].pfn)); | ||
175 | - kfree(bufb->array[i]); | ||
176 | + lttng_kvfree(bufb->array[i]); | ||
177 | } | ||
178 | - kfree(bufb->array); | ||
179 | + lttng_kvfree(bufb->array); | ||
180 | bufb->allocated = 0; | ||
181 | } | ||
182 | |||
183 | diff --git a/lib/ringbuffer/ring_buffer_frontend.c b/lib/ringbuffer/ring_buffer_frontend.c | ||
184 | index e77d789..1e43980 100644 | ||
185 | --- a/lib/ringbuffer/ring_buffer_frontend.c | ||
186 | +++ b/lib/ringbuffer/ring_buffer_frontend.c | ||
187 | @@ -65,6 +65,7 @@ | ||
188 | #include <wrapper/kref.h> | ||
189 | #include <wrapper/percpu-defs.h> | ||
190 | #include <wrapper/timer.h> | ||
191 | +#include <wrapper/vmalloc.h> | ||
192 | |||
193 | /* | ||
194 | * Internal structure representing offsets to use at a sub-buffer switch. | ||
195 | @@ -147,8 +148,8 @@ void lib_ring_buffer_free(struct lib_ring_buffer *buf) | ||
196 | struct channel *chan = buf->backend.chan; | ||
197 | |||
198 | lib_ring_buffer_print_errors(chan, buf, buf->backend.cpu); | ||
199 | - kfree(buf->commit_hot); | ||
200 | - kfree(buf->commit_cold); | ||
201 | + lttng_kvfree(buf->commit_hot); | ||
202 | + lttng_kvfree(buf->commit_cold); | ||
203 | |||
204 | lib_ring_buffer_backend_free(&buf->backend); | ||
205 | } | ||
206 | @@ -245,7 +246,7 @@ int lib_ring_buffer_create(struct lib_ring_buffer *buf, | ||
207 | return ret; | ||
208 | |||
209 | buf->commit_hot = | ||
210 | - kzalloc_node(ALIGN(sizeof(*buf->commit_hot) | ||
211 | + lttng_kvzalloc_node(ALIGN(sizeof(*buf->commit_hot) | ||
212 | * chan->backend.num_subbuf, | ||
213 | 1 << INTERNODE_CACHE_SHIFT), | ||
214 | GFP_KERNEL | __GFP_NOWARN, | ||
215 | @@ -256,7 +257,7 @@ int lib_ring_buffer_create(struct lib_ring_buffer *buf, | ||
216 | } | ||
217 | |||
218 | buf->commit_cold = | ||
219 | - kzalloc_node(ALIGN(sizeof(*buf->commit_cold) | ||
220 | + lttng_kvzalloc_node(ALIGN(sizeof(*buf->commit_cold) | ||
221 | * chan->backend.num_subbuf, | ||
222 | 1 << INTERNODE_CACHE_SHIFT), | ||
223 | GFP_KERNEL | __GFP_NOWARN, | ||
224 | @@ -305,9 +306,9 @@ int lib_ring_buffer_create(struct lib_ring_buffer *buf, | ||
225 | |||
226 | /* Error handling */ | ||
227 | free_init: | ||
228 | - kfree(buf->commit_cold); | ||
229 | + lttng_kvfree(buf->commit_cold); | ||
230 | free_commit: | ||
231 | - kfree(buf->commit_hot); | ||
232 | + lttng_kvfree(buf->commit_hot); | ||
233 | free_chanbuf: | ||
234 | lib_ring_buffer_backend_free(&buf->backend); | ||
235 | return ret; | ||
236 | diff --git a/lttng-context-perf-counters.c b/lttng-context-perf-counters.c | ||
237 | index 8afc11f..260e5d0 100644 | ||
238 | --- a/lttng-context-perf-counters.c | ||
239 | +++ b/lttng-context-perf-counters.c | ||
240 | @@ -119,7 +119,7 @@ void lttng_destroy_perf_counter_field(struct lttng_ctx_field *field) | ||
241 | #endif /* #else #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) */ | ||
242 | kfree(field->event_field.name); | ||
243 | kfree(field->u.perf_counter->attr); | ||
244 | - kfree(events); | ||
245 | + lttng_kvfree(events); | ||
246 | kfree(field->u.perf_counter); | ||
247 | } | ||
248 | |||
249 | @@ -237,7 +237,7 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, | ||
250 | int ret; | ||
251 | char *name_alloc; | ||
252 | |||
253 | - events = kzalloc(num_possible_cpus() * sizeof(*events), GFP_KERNEL); | ||
254 | + events = lttng_kvzalloc(num_possible_cpus() * sizeof(*events), GFP_KERNEL); | ||
255 | if (!events) | ||
256 | return -ENOMEM; | ||
257 | |||
258 | @@ -372,6 +372,6 @@ name_alloc_error: | ||
259 | error_alloc_perf_field: | ||
260 | kfree(attr); | ||
261 | error_attr: | ||
262 | - kfree(events); | ||
263 | + lttng_kvfree(events); | ||
264 | return ret; | ||
265 | } | ||
266 | diff --git a/lttng-context.c b/lttng-context.c | ||
267 | index 406f479..544e95f 100644 | ||
268 | --- a/lttng-context.c | ||
269 | +++ b/lttng-context.c | ||
270 | @@ -95,12 +95,12 @@ struct lttng_ctx_field *lttng_append_context(struct lttng_ctx **ctx_p) | ||
271 | struct lttng_ctx_field *new_fields; | ||
272 | |||
273 | ctx->allocated_fields = max_t(size_t, 1, 2 * ctx->allocated_fields); | ||
274 | - new_fields = kzalloc(ctx->allocated_fields * sizeof(struct lttng_ctx_field), GFP_KERNEL); | ||
275 | + new_fields = lttng_kvzalloc(ctx->allocated_fields * sizeof(struct lttng_ctx_field), GFP_KERNEL); | ||
276 | if (!new_fields) | ||
277 | return NULL; | ||
278 | if (ctx->fields) | ||
279 | memcpy(new_fields, ctx->fields, sizeof(*ctx->fields) * ctx->nr_fields); | ||
280 | - kfree(ctx->fields); | ||
281 | + lttng_kvfree(ctx->fields); | ||
282 | ctx->fields = new_fields; | ||
283 | } | ||
284 | field = &ctx->fields[ctx->nr_fields]; | ||
285 | @@ -240,7 +240,7 @@ void lttng_destroy_context(struct lttng_ctx *ctx) | ||
286 | if (ctx->fields[i].destroy) | ||
287 | ctx->fields[i].destroy(&ctx->fields[i]); | ||
288 | } | ||
289 | - kfree(ctx->fields); | ||
290 | + lttng_kvfree(ctx->fields); | ||
291 | kfree(ctx); | ||
292 | } | ||
293 | |||
294 | diff --git a/lttng-events.c b/lttng-events.c | ||
295 | index c86a756..7132485 100644 | ||
296 | --- a/lttng-events.c | ||
297 | +++ b/lttng-events.c | ||
298 | @@ -130,7 +130,7 @@ struct lttng_session *lttng_session_create(void) | ||
299 | int i; | ||
300 | |||
301 | mutex_lock(&sessions_mutex); | ||
302 | - session = kzalloc(sizeof(struct lttng_session), GFP_KERNEL); | ||
303 | + session = lttng_kvzalloc(sizeof(struct lttng_session), GFP_KERNEL); | ||
304 | if (!session) | ||
305 | goto err; | ||
306 | INIT_LIST_HEAD(&session->chan); | ||
307 | @@ -161,7 +161,7 @@ struct lttng_session *lttng_session_create(void) | ||
308 | err_free_cache: | ||
309 | kfree(metadata_cache); | ||
310 | err_free_session: | ||
311 | - kfree(session); | ||
312 | + lttng_kvfree(session); | ||
313 | err: | ||
314 | mutex_unlock(&sessions_mutex); | ||
315 | return NULL; | ||
316 | @@ -210,7 +210,7 @@ void lttng_session_destroy(struct lttng_session *session) | ||
317 | kref_put(&session->metadata_cache->refcount, metadata_cache_destroy); | ||
318 | list_del(&session->list); | ||
319 | mutex_unlock(&sessions_mutex); | ||
320 | - kfree(session); | ||
321 | + lttng_kvfree(session); | ||
322 | } | ||
323 | |||
324 | int lttng_session_statedump(struct lttng_session *session) | ||
325 | diff --git a/wrapper/vmalloc.h b/wrapper/vmalloc.h | ||
326 | index 2332439..2dd06cb 100644 | ||
327 | --- a/wrapper/vmalloc.h | ||
328 | +++ b/wrapper/vmalloc.h | ||
329 | @@ -25,6 +25,9 @@ | ||
330 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
331 | */ | ||
332 | |||
333 | +#include <linux/version.h> | ||
334 | +#include <linux/vmalloc.h> | ||
335 | + | ||
336 | #ifdef CONFIG_KALLSYMS | ||
337 | |||
338 | #include <linux/kallsyms.h> | ||
339 | @@ -51,8 +54,6 @@ void wrapper_vmalloc_sync_all(void) | ||
340 | } | ||
341 | #else | ||
342 | |||
343 | -#include <linux/vmalloc.h> | ||
344 | - | ||
345 | static inline | ||
346 | void wrapper_vmalloc_sync_all(void) | ||
347 | { | ||
348 | @@ -60,4 +61,168 @@ void wrapper_vmalloc_sync_all(void) | ||
349 | } | ||
350 | #endif | ||
351 | |||
352 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)) | ||
353 | +static inline | ||
354 | +void *lttng_kvmalloc_node(unsigned long size, gfp_t flags, int node) | ||
355 | +{ | ||
356 | + void *ret; | ||
357 | + | ||
358 | + ret = kvmalloc_node(size, flags, node); | ||
359 | + if (is_vmalloc_addr(ret)) { | ||
360 | + /* | ||
361 | + * Make sure we don't trigger recursive page faults in the | ||
362 | + * tracing fast path. | ||
363 | + */ | ||
364 | + wrapper_vmalloc_sync_all(); | ||
365 | + } | ||
366 | + return ret; | ||
367 | +} | ||
368 | + | ||
369 | +static inline | ||
370 | +void *lttng_kvzalloc_node(unsigned long size, gfp_t flags, int node) | ||
371 | +{ | ||
372 | + return lttng_kvmalloc_node(size, flags | __GFP_ZERO, node); | ||
373 | +} | ||
374 | + | ||
375 | +static inline | ||
376 | +void *lttng_kvmalloc(unsigned long size, gfp_t flags) | ||
377 | +{ | ||
378 | + return lttng_kvmalloc_node(size, flags, NUMA_NO_NODE); | ||
379 | +} | ||
380 | + | ||
381 | +static inline | ||
382 | +void *lttng_kvzalloc(unsigned long size, gfp_t flags) | ||
383 | +{ | ||
384 | + return lttng_kvzalloc_node(size, flags, NUMA_NO_NODE); | ||
385 | +} | ||
386 | + | ||
387 | +static inline | ||
388 | +void lttng_kvfree(const void *addr) | ||
389 | +{ | ||
390 | + kvfree(addr); | ||
391 | +} | ||
392 | + | ||
393 | +#else | ||
394 | + | ||
395 | +#include <linux/slab.h> | ||
396 | +#include <linux/mm.h> | ||
397 | + | ||
398 | +/* | ||
399 | + * kallsyms wrapper of __vmalloc_node with a fallback to kmalloc_node. | ||
400 | + */ | ||
401 | +static inline | ||
402 | +void *__lttng_vmalloc_node_fallback(unsigned long size, unsigned long align, | ||
403 | + gfp_t gfp_mask, pgprot_t prot, int node, void *caller) | ||
404 | +{ | ||
405 | + void *ret; | ||
406 | + | ||
407 | +#ifdef CONFIG_KALLSYMS | ||
408 | + /* | ||
409 | + * If we have KALLSYMS, get * __vmalloc_node which is not exported. | ||
410 | + */ | ||
411 | + void *(*lttng__vmalloc_node)(unsigned long size, unsigned long align, | ||
412 | + gfp_t gfp_mask, pgprot_t prot, int node, void *caller); | ||
413 | + | ||
414 | + lttng__vmalloc_node = (void *) kallsyms_lookup_funcptr("__vmalloc_node"); | ||
415 | + ret = lttng__vmalloc_node(size, align, gfp_mask, prot, node, caller); | ||
416 | +#else | ||
417 | + /* | ||
418 | + * If we don't have KALLSYMS, fallback to kmalloc_node. | ||
419 | + */ | ||
420 | + ret = kmalloc_node(size, flags, node); | ||
421 | +#endif | ||
422 | + | ||
423 | + return ret; | ||
424 | +} | ||
425 | + | ||
426 | +/** | ||
427 | + * lttng_kvmalloc_node - attempt to allocate physically contiguous memory, but upon | ||
428 | + * failure, fall back to non-contiguous (vmalloc) allocation. | ||
429 | + * @size: size of the request. | ||
430 | + * @flags: gfp mask for the allocation - must be compatible with GFP_KERNEL. | ||
431 | + * | ||
432 | + * Uses kmalloc to get the memory but if the allocation fails then falls back | ||
433 | + * to the vmalloc allocator. Use lttng_kvfree to free the memory. | ||
434 | + * | ||
435 | + * Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported | ||
436 | + */ | ||
437 | +static inline | ||
438 | +void *lttng_kvmalloc_node(unsigned long size, gfp_t flags, int node) | ||
439 | +{ | ||
440 | + void *ret; | ||
441 | + | ||
442 | + /* | ||
443 | + * vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables) | ||
444 | + * so the given set of flags has to be compatible. | ||
445 | + */ | ||
446 | + WARN_ON_ONCE((flags & GFP_KERNEL) != GFP_KERNEL); | ||
447 | + | ||
448 | + /* | ||
449 | + * If the allocation fits in a single page, do not fallback. | ||
450 | + */ | ||
451 | + if (size <= PAGE_SIZE) { | ||
452 | + return kmalloc_node(size, flags, node); | ||
453 | + } | ||
454 | + | ||
455 | + /* | ||
456 | + * Make sure that larger requests are not too disruptive - no OOM | ||
457 | + * killer and no allocation failure warnings as we have a fallback | ||
458 | + */ | ||
459 | + ret = kmalloc_node(size, flags | __GFP_NOWARN | __GFP_NORETRY, node); | ||
460 | + if (!ret) { | ||
461 | + if (node == NUMA_NO_NODE) { | ||
462 | + /* | ||
463 | + * If no node was specified, use __vmalloc which is | ||
464 | + * always exported. | ||
465 | + */ | ||
466 | + ret = __vmalloc(size, flags | __GFP_HIGHMEM, PAGE_KERNEL); | ||
467 | + } else { | ||
468 | + /* | ||
469 | + * Otherwise, we need to select a node but __vmalloc_node | ||
470 | + * is not exported, use this fallback wrapper which uses | ||
471 | + * kallsyms if available or falls back to kmalloc_node. | ||
472 | + */ | ||
473 | + ret = __lttng_vmalloc_node_fallback(size, 1, | ||
474 | + flags | __GFP_HIGHMEM, PAGE_KERNEL, node, | ||
475 | + __builtin_return_address(0)); | ||
476 | + } | ||
477 | + | ||
478 | + /* | ||
479 | + * Make sure we don't trigger recursive page faults in the | ||
480 | + * tracing fast path. | ||
481 | + */ | ||
482 | + wrapper_vmalloc_sync_all(); | ||
483 | + } | ||
484 | + return ret; | ||
485 | +} | ||
486 | + | ||
487 | +static inline | ||
488 | +void *lttng_kvzalloc_node(unsigned long size, gfp_t flags, int node) | ||
489 | +{ | ||
490 | + return lttng_kvmalloc_node(size, flags | __GFP_ZERO, node); | ||
491 | +} | ||
492 | + | ||
493 | +static inline | ||
494 | +void *lttng_kvmalloc(unsigned long size, gfp_t flags) | ||
495 | +{ | ||
496 | + return lttng_kvmalloc_node(size, flags, NUMA_NO_NODE); | ||
497 | +} | ||
498 | + | ||
499 | +static inline | ||
500 | +void *lttng_kvzalloc(unsigned long size, gfp_t flags) | ||
501 | +{ | ||
502 | + return lttng_kvzalloc_node(size, flags, NUMA_NO_NODE); | ||
503 | +} | ||
504 | + | ||
505 | +static inline | ||
506 | +void lttng_kvfree(const void *addr) | ||
507 | +{ | ||
508 | + if (is_vmalloc_addr(addr)) { | ||
509 | + vfree(addr); | ||
510 | + } else { | ||
511 | + kfree(addr); | ||
512 | + } | ||
513 | +} | ||
514 | +#endif | ||
515 | + | ||
516 | #endif /* _LTTNG_WRAPPER_VMALLOC_H */ | ||
517 | -- | ||
518 | 2.14.1 | ||
519 | |||
diff --git a/meta/recipes-kernel/lttng/lttng-modules/0007-Fix-vmalloc-wrapper-on-kernel-4.12.patch b/meta/recipes-kernel/lttng/lttng-modules/0007-Fix-vmalloc-wrapper-on-kernel-4.12.patch new file mode 100644 index 0000000000..1412db35d6 --- /dev/null +++ b/meta/recipes-kernel/lttng/lttng-modules/0007-Fix-vmalloc-wrapper-on-kernel-4.12.patch | |||
@@ -0,0 +1,37 @@ | |||
1 | From ecda9325cd5ad6b69600fd4d88c46095d22f95e1 Mon Sep 17 00:00:00 2001 | ||
2 | From: Michael Jeanson <mjeanson@efficios.com> | ||
3 | Date: Tue, 26 Sep 2017 13:46:30 -0400 | ||
4 | Subject: [PATCH 7/8] Fix: vmalloc wrapper on kernel >= 4.12 | ||
5 | Organization: O.S. Systems Software LTDA. | ||
6 | |||
7 | Upstream-Status: Backport [2.9.4] | ||
8 | |||
9 | Signed-off-by: Michael Jeanson <mjeanson@efficios.com> | ||
10 | Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | ||
11 | --- | ||
12 | wrapper/vmalloc.h | 2 +- | ||
13 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
14 | |||
15 | diff --git a/wrapper/vmalloc.h b/wrapper/vmalloc.h | ||
16 | index 2dd06cb..e117584 100644 | ||
17 | --- a/wrapper/vmalloc.h | ||
18 | +++ b/wrapper/vmalloc.h | ||
19 | @@ -27,6 +27,7 @@ | ||
20 | |||
21 | #include <linux/version.h> | ||
22 | #include <linux/vmalloc.h> | ||
23 | +#include <linux/mm.h> | ||
24 | |||
25 | #ifdef CONFIG_KALLSYMS | ||
26 | |||
27 | @@ -105,7 +106,6 @@ void lttng_kvfree(const void *addr) | ||
28 | #else | ||
29 | |||
30 | #include <linux/slab.h> | ||
31 | -#include <linux/mm.h> | ||
32 | |||
33 | /* | ||
34 | * kallsyms wrapper of __vmalloc_node with a fallback to kmalloc_node. | ||
35 | -- | ||
36 | 2.14.1 | ||
37 | |||
diff --git a/meta/recipes-kernel/lttng/lttng-modules/0008-Fix-vmalloc-wrapper-on-kernel-2.6.38.patch b/meta/recipes-kernel/lttng/lttng-modules/0008-Fix-vmalloc-wrapper-on-kernel-2.6.38.patch new file mode 100644 index 0000000000..e7a79c67f1 --- /dev/null +++ b/meta/recipes-kernel/lttng/lttng-modules/0008-Fix-vmalloc-wrapper-on-kernel-2.6.38.patch | |||
@@ -0,0 +1,34 @@ | |||
1 | From a919317a3e3352038c8285a41055b370adc79478 Mon Sep 17 00:00:00 2001 | ||
2 | From: Michael Jeanson <mjeanson@efficios.com> | ||
3 | Date: Tue, 26 Sep 2017 14:16:47 -0400 | ||
4 | Subject: [PATCH 8/8] Fix: vmalloc wrapper on kernel < 2.6.38 | ||
5 | Organization: O.S. Systems Software LTDA. | ||
6 | |||
7 | Ensure that all probes end up including the vmalloc wrapper through the | ||
8 | lttng-tracer.h header so the trace_*() static inlines are generated | ||
9 | through inclusion of include/trace/events/kmem.h before we define | ||
10 | CREATE_TRACE_POINTS. | ||
11 | |||
12 | Upstream-Status: Backport [2.9.4] | ||
13 | |||
14 | Signed-off-by: Michael Jeanson <mjeanson@efficios.com> | ||
15 | Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | ||
16 | --- | ||
17 | lttng-tracer.h | 1 + | ||
18 | 1 file changed, 1 insertion(+) | ||
19 | |||
20 | diff --git a/lttng-tracer.h b/lttng-tracer.h | ||
21 | index 58a7a26..5da882b 100644 | ||
22 | --- a/lttng-tracer.h | ||
23 | +++ b/lttng-tracer.h | ||
24 | @@ -36,6 +36,7 @@ | ||
25 | |||
26 | #include <wrapper/trace-clock.h> | ||
27 | #include <wrapper/compiler.h> | ||
28 | +#include <wrapper/vmalloc.h> | ||
29 | #include <lttng-tracer-core.h> | ||
30 | #include <lttng-events.h> | ||
31 | |||
32 | -- | ||
33 | 2.14.1 | ||
34 | |||
diff --git a/meta/recipes-kernel/lttng/lttng-modules_2.9.3.bb b/meta/recipes-kernel/lttng/lttng-modules_2.9.3.bb index acd76b54b3..f3c04886e1 100644 --- a/meta/recipes-kernel/lttng/lttng-modules_2.9.3.bb +++ b/meta/recipes-kernel/lttng/lttng-modules_2.9.3.bb | |||
@@ -12,7 +12,15 @@ COMPATIBLE_HOST = '(x86_64|i.86|powerpc|aarch64|mips|nios2|arm).*-linux' | |||
12 | 12 | ||
13 | SRC_URI = "https://lttng.org/files/${BPN}/${BPN}-${PV}.tar.bz2 \ | 13 | SRC_URI = "https://lttng.org/files/${BPN}/${BPN}-${PV}.tar.bz2 \ |
14 | file://Makefile-Do-not-fail-if-CONFIG_TRACEPOINTS-is-not-en.patch \ | 14 | file://Makefile-Do-not-fail-if-CONFIG_TRACEPOINTS-is-not-en.patch \ |
15 | file://BUILD_RUNTIME_BUG_ON-vs-gcc7.patch" | 15 | file://BUILD_RUNTIME_BUG_ON-vs-gcc7.patch \ |
16 | file://0001-Fix-handle-missing-ftrace-header-on-v4.12.patch \ | ||
17 | file://0002-Fix-sched-for-v4.11.5-rt1.patch \ | ||
18 | file://0003-Fix-Sleeping-function-called-from-invalid-context.patch \ | ||
19 | file://0004-Fix-update-ext4-instrumentation-for-kernel-4.13.patch \ | ||
20 | file://0005-Fix-mmap-caches-aliased-on-virtual-addresses.patch \ | ||
21 | file://0006-Add-kmalloc-failover-to-vmalloc.patch \ | ||
22 | file://0007-Fix-vmalloc-wrapper-on-kernel-4.12.patch \ | ||
23 | file://0008-Fix-vmalloc-wrapper-on-kernel-2.6.38.patch" | ||
16 | 24 | ||
17 | SRC_URI[md5sum] = "9abf694dddcc197988189ef65b496f4c" | 25 | SRC_URI[md5sum] = "9abf694dddcc197988189ef65b496f4c" |
18 | SRC_URI[sha256sum] = "f911bca81b02a787474f3d100390dad7447f952525e6d041f50991940246bafe" | 26 | SRC_URI[sha256sum] = "f911bca81b02a787474f3d100390dad7447f952525e6d041f50991940246bafe" |