aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_output.c')
-rw-r--r--kernel/trace/trace_output.c80
1 files changed, 65 insertions, 15 deletions
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index ed17565826b0..8e46b3323cdc 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -23,13 +23,21 @@ static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
23 23
24static int next_event_type = __TRACE_LAST_TYPE + 1; 24static int next_event_type = __TRACE_LAST_TYPE + 1;
25 25
26void trace_print_seq(struct seq_file *m, struct trace_seq *s) 26int trace_print_seq(struct seq_file *m, struct trace_seq *s)
27{ 27{
28 int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len; 28 int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len;
29 int ret;
30
31 ret = seq_write(m, s->buffer, len);
29 32
30 seq_write(m, s->buffer, len); 33 /*
34 * Only reset this buffer if we successfully wrote to the
35 * seq_file buffer.
36 */
37 if (!ret)
38 trace_seq_init(s);
31 39
32 trace_seq_init(s); 40 return ret;
33} 41}
34 42
35enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter) 43enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter)
@@ -69,6 +77,9 @@ enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter)
69 * @s: trace sequence descriptor 77 * @s: trace sequence descriptor
70 * @fmt: printf format string 78 * @fmt: printf format string
71 * 79 *
80 * It returns 0 if the trace oversizes the buffer's free
81 * space, 1 otherwise.
82 *
72 * The tracer may use either sequence operations or its own 83 * The tracer may use either sequence operations or its own
73 * copy to user routines. To simplify formating of a trace 84 * copy to user routines. To simplify formating of a trace
74 * trace_seq_printf is used to store strings into a special 85 * trace_seq_printf is used to store strings into a special
@@ -82,7 +93,7 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
82 va_list ap; 93 va_list ap;
83 int ret; 94 int ret;
84 95
85 if (!len) 96 if (s->full || !len)
86 return 0; 97 return 0;
87 98
88 va_start(ap, fmt); 99 va_start(ap, fmt);
@@ -90,12 +101,14 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
90 va_end(ap); 101 va_end(ap);
91 102
92 /* If we can't write it all, don't bother writing anything */ 103 /* If we can't write it all, don't bother writing anything */
93 if (ret >= len) 104 if (ret >= len) {
105 s->full = 1;
94 return 0; 106 return 0;
107 }
95 108
96 s->len += ret; 109 s->len += ret;
97 110
98 return len; 111 return 1;
99} 112}
100EXPORT_SYMBOL_GPL(trace_seq_printf); 113EXPORT_SYMBOL_GPL(trace_seq_printf);
101 114
@@ -116,14 +129,16 @@ trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
116 int len = (PAGE_SIZE - 1) - s->len; 129 int len = (PAGE_SIZE - 1) - s->len;
117 int ret; 130 int ret;
118 131
119 if (!len) 132 if (s->full || !len)
120 return 0; 133 return 0;
121 134
122 ret = vsnprintf(s->buffer + s->len, len, fmt, args); 135 ret = vsnprintf(s->buffer + s->len, len, fmt, args);
123 136
124 /* If we can't write it all, don't bother writing anything */ 137 /* If we can't write it all, don't bother writing anything */
125 if (ret >= len) 138 if (ret >= len) {
139 s->full = 1;
126 return 0; 140 return 0;
141 }
127 142
128 s->len += ret; 143 s->len += ret;
129 144
@@ -136,14 +151,16 @@ int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
136 int len = (PAGE_SIZE - 1) - s->len; 151 int len = (PAGE_SIZE - 1) - s->len;
137 int ret; 152 int ret;
138 153
139 if (!len) 154 if (s->full || !len)
140 return 0; 155 return 0;
141 156
142 ret = bstr_printf(s->buffer + s->len, len, fmt, binary); 157 ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
143 158
144 /* If we can't write it all, don't bother writing anything */ 159 /* If we can't write it all, don't bother writing anything */
145 if (ret >= len) 160 if (ret >= len) {
161 s->full = 1;
146 return 0; 162 return 0;
163 }
147 164
148 s->len += ret; 165 s->len += ret;
149 166
@@ -164,9 +181,14 @@ int trace_seq_puts(struct trace_seq *s, const char *str)
164{ 181{
165 int len = strlen(str); 182 int len = strlen(str);
166 183
167 if (len > ((PAGE_SIZE - 1) - s->len)) 184 if (s->full)
168 return 0; 185 return 0;
169 186
187 if (len > ((PAGE_SIZE - 1) - s->len)) {
188 s->full = 1;
189 return 0;
190 }
191
170 memcpy(s->buffer + s->len, str, len); 192 memcpy(s->buffer + s->len, str, len);
171 s->len += len; 193 s->len += len;
172 194
@@ -175,8 +197,13 @@ int trace_seq_puts(struct trace_seq *s, const char *str)
175 197
176int trace_seq_putc(struct trace_seq *s, unsigned char c) 198int trace_seq_putc(struct trace_seq *s, unsigned char c)
177{ 199{
178 if (s->len >= (PAGE_SIZE - 1)) 200 if (s->full)
201 return 0;
202
203 if (s->len >= (PAGE_SIZE - 1)) {
204 s->full = 1;
179 return 0; 205 return 0;
206 }
180 207
181 s->buffer[s->len++] = c; 208 s->buffer[s->len++] = c;
182 209
@@ -185,8 +212,13 @@ int trace_seq_putc(struct trace_seq *s, unsigned char c)
185 212
186int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len) 213int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
187{ 214{
188 if (len > ((PAGE_SIZE - 1) - s->len)) 215 if (s->full)
216 return 0;
217
218 if (len > ((PAGE_SIZE - 1) - s->len)) {
219 s->full = 1;
189 return 0; 220 return 0;
221 }
190 222
191 memcpy(s->buffer + s->len, mem, len); 223 memcpy(s->buffer + s->len, mem, len);
192 s->len += len; 224 s->len += len;
@@ -200,6 +232,9 @@ int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len)
200 const unsigned char *data = mem; 232 const unsigned char *data = mem;
201 int i, j; 233 int i, j;
202 234
235 if (s->full)
236 return 0;
237
203#ifdef __BIG_ENDIAN 238#ifdef __BIG_ENDIAN
204 for (i = 0, j = 0; i < len; i++) { 239 for (i = 0, j = 0; i < len; i++) {
205#else 240#else
@@ -217,8 +252,13 @@ void *trace_seq_reserve(struct trace_seq *s, size_t len)
217{ 252{
218 void *ret; 253 void *ret;
219 254
220 if (len > ((PAGE_SIZE - 1) - s->len)) 255 if (s->full)
256 return 0;
257
258 if (len > ((PAGE_SIZE - 1) - s->len)) {
259 s->full = 1;
221 return NULL; 260 return NULL;
261 }
222 262
223 ret = s->buffer + s->len; 263 ret = s->buffer + s->len;
224 s->len += len; 264 s->len += len;
@@ -230,8 +270,14 @@ int trace_seq_path(struct trace_seq *s, struct path *path)
230{ 270{
231 unsigned char *p; 271 unsigned char *p;
232 272
233 if (s->len >= (PAGE_SIZE - 1)) 273 if (s->full)
274 return 0;
275
276 if (s->len >= (PAGE_SIZE - 1)) {
277 s->full = 1;
234 return 0; 278 return 0;
279 }
280
235 p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len); 281 p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
236 if (!IS_ERR(p)) { 282 if (!IS_ERR(p)) {
237 p = mangle_path(s->buffer + s->len, p, "\n"); 283 p = mangle_path(s->buffer + s->len, p, "\n");
@@ -244,6 +290,7 @@ int trace_seq_path(struct trace_seq *s, struct path *path)
244 return 1; 290 return 1;
245 } 291 }
246 292
293 s->full = 1;
247 return 0; 294 return 0;
248} 295}
249 296
@@ -370,6 +417,9 @@ int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
370 unsigned long vmstart = 0; 417 unsigned long vmstart = 0;
371 int ret = 1; 418 int ret = 1;
372 419
420 if (s->full)
421 return 0;
422
373 if (mm) { 423 if (mm) {
374 const struct vm_area_struct *vma; 424 const struct vm_area_struct *vma;
375 425