hc
2024-02-20 e636c8d336489bf3eed5878299e6cc045bbad077
kernel/fs/pstore/ftrace.c
....@@ -1,14 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright 2012 Google, Inc.
3
- *
4
- * This software is licensed under the terms of the GNU General Public
5
- * License version 2, as published by the Free Software Foundation, and
6
- * may be copied, distributed, and modified under those terms.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
124 */
135
146 #include <linux/kernel.h>
....@@ -24,6 +16,7 @@
2416 #include <linux/debugfs.h>
2517 #include <linux/err.h>
2618 #include <linux/cache.h>
19
+#include <linux/slab.h>
2720 #include <asm/barrier.h>
2821 #include "internal.h"
2922
....@@ -120,27 +113,13 @@
120113
121114 void pstore_register_ftrace(void)
122115 {
123
- struct dentry *file;
124
-
125116 if (!psinfo->write)
126117 return;
127118
128119 pstore_ftrace_dir = debugfs_create_dir("pstore", NULL);
129
- if (!pstore_ftrace_dir) {
130
- pr_err("%s: unable to create pstore directory\n", __func__);
131
- return;
132
- }
133120
134
- file = debugfs_create_file("record_ftrace", 0600, pstore_ftrace_dir,
135
- NULL, &pstore_knob_fops);
136
- if (!file) {
137
- pr_err("%s: unable to create record_ftrace file\n", __func__);
138
- goto err_file;
139
- }
140
-
141
- return;
142
-err_file:
143
- debugfs_remove(pstore_ftrace_dir);
121
+ debugfs_create_file("record_ftrace", 0600, pstore_ftrace_dir, NULL,
122
+ &pstore_knob_fops);
144123 }
145124
146125 void pstore_unregister_ftrace(void)
....@@ -148,9 +127,62 @@
148127 mutex_lock(&pstore_ftrace_lock);
149128 if (pstore_ftrace_enabled) {
150129 unregister_ftrace_function(&pstore_ftrace_ops);
151
- pstore_ftrace_enabled = 0;
130
+ pstore_ftrace_enabled = false;
152131 }
153132 mutex_unlock(&pstore_ftrace_lock);
154133
155134 debugfs_remove_recursive(pstore_ftrace_dir);
156135 }
136
+
137
+ssize_t pstore_ftrace_combine_log(char **dest_log, size_t *dest_log_size,
138
+ const char *src_log, size_t src_log_size)
139
+{
140
+ size_t dest_size, src_size, total, dest_off, src_off;
141
+ size_t dest_idx = 0, src_idx = 0, merged_idx = 0;
142
+ void *merged_buf;
143
+ struct pstore_ftrace_record *drec, *srec, *mrec;
144
+ size_t record_size = sizeof(struct pstore_ftrace_record);
145
+
146
+ dest_off = *dest_log_size % record_size;
147
+ dest_size = *dest_log_size - dest_off;
148
+
149
+ src_off = src_log_size % record_size;
150
+ src_size = src_log_size - src_off;
151
+
152
+ total = dest_size + src_size;
153
+ merged_buf = kmalloc(total, GFP_KERNEL);
154
+ if (!merged_buf)
155
+ return -ENOMEM;
156
+
157
+ drec = (struct pstore_ftrace_record *)(*dest_log + dest_off);
158
+ srec = (struct pstore_ftrace_record *)(src_log + src_off);
159
+ mrec = (struct pstore_ftrace_record *)(merged_buf);
160
+
161
+ while (dest_size > 0 && src_size > 0) {
162
+ if (pstore_ftrace_read_timestamp(&drec[dest_idx]) <
163
+ pstore_ftrace_read_timestamp(&srec[src_idx])) {
164
+ mrec[merged_idx++] = drec[dest_idx++];
165
+ dest_size -= record_size;
166
+ } else {
167
+ mrec[merged_idx++] = srec[src_idx++];
168
+ src_size -= record_size;
169
+ }
170
+ }
171
+
172
+ while (dest_size > 0) {
173
+ mrec[merged_idx++] = drec[dest_idx++];
174
+ dest_size -= record_size;
175
+ }
176
+
177
+ while (src_size > 0) {
178
+ mrec[merged_idx++] = srec[src_idx++];
179
+ src_size -= record_size;
180
+ }
181
+
182
+ kfree(*dest_log);
183
+ *dest_log = merged_buf;
184
+ *dest_log_size = total;
185
+
186
+ return 0;
187
+}
188
+EXPORT_SYMBOL_GPL(pstore_ftrace_combine_log);