.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * 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. |
---|
12 | 4 | */ |
---|
13 | 5 | |
---|
14 | 6 | #include <linux/kernel.h> |
---|
.. | .. |
---|
24 | 16 | #include <linux/debugfs.h> |
---|
25 | 17 | #include <linux/err.h> |
---|
26 | 18 | #include <linux/cache.h> |
---|
| 19 | +#include <linux/slab.h> |
---|
27 | 20 | #include <asm/barrier.h> |
---|
28 | 21 | #include "internal.h" |
---|
29 | 22 | |
---|
.. | .. |
---|
120 | 113 | |
---|
121 | 114 | void pstore_register_ftrace(void) |
---|
122 | 115 | { |
---|
123 | | - struct dentry *file; |
---|
124 | | - |
---|
125 | 116 | if (!psinfo->write) |
---|
126 | 117 | return; |
---|
127 | 118 | |
---|
128 | 119 | 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 | | - } |
---|
133 | 120 | |
---|
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); |
---|
144 | 123 | } |
---|
145 | 124 | |
---|
146 | 125 | void pstore_unregister_ftrace(void) |
---|
.. | .. |
---|
148 | 127 | mutex_lock(&pstore_ftrace_lock); |
---|
149 | 128 | if (pstore_ftrace_enabled) { |
---|
150 | 129 | unregister_ftrace_function(&pstore_ftrace_ops); |
---|
151 | | - pstore_ftrace_enabled = 0; |
---|
| 130 | + pstore_ftrace_enabled = false; |
---|
152 | 131 | } |
---|
153 | 132 | mutex_unlock(&pstore_ftrace_lock); |
---|
154 | 133 | |
---|
155 | 134 | debugfs_remove_recursive(pstore_ftrace_dir); |
---|
156 | 135 | } |
---|
| 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); |
---|