Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tracing: Add full state to trace_seq

The trace_seq buffer might fill up, and right now one needs to check the
return value of each printf into the buffer to check for that.

Instead, have the buffer keep track of whether it is full or not, and
reject more input if it is full or would have overflowed with an input
that wasn't added.

Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>

authored by

Johannes Berg and committed by
Steven Rostedt
d184b31c a63ce5b3

+52 -11
+2
include/linux/trace_seq.h
··· 14 14 unsigned char buffer[PAGE_SIZE]; 15 15 unsigned int len; 16 16 unsigned int readpos; 17 + int full; 17 18 }; 18 19 19 20 static inline void ··· 22 21 { 23 22 s->len = 0; 24 23 s->readpos = 0; 24 + s->full = 0; 25 25 } 26 26 27 27 /*
+50 -11
kernel/trace/trace_output.c
··· 93 93 va_list ap; 94 94 int ret; 95 95 96 - if (!len) 96 + if (s->full || !len) 97 97 return 0; 98 98 99 99 va_start(ap, fmt); ··· 101 101 va_end(ap); 102 102 103 103 /* If we can't write it all, don't bother writing anything */ 104 - if (ret >= len) 104 + if (ret >= len) { 105 + s->full = 1; 105 106 return 0; 107 + } 106 108 107 109 s->len += ret; 108 110 ··· 129 127 int len = (PAGE_SIZE - 1) - s->len; 130 128 int ret; 131 129 132 - if (!len) 130 + if (s->full || !len) 133 131 return 0; 134 132 135 133 ret = vsnprintf(s->buffer + s->len, len, fmt, args); 136 134 137 135 /* If we can't write it all, don't bother writing anything */ 138 - if (ret >= len) 136 + if (ret >= len) { 137 + s->full = 1; 139 138 return 0; 139 + } 140 140 141 141 s->len += ret; 142 142 ··· 151 147 int len = (PAGE_SIZE - 1) - s->len; 152 148 int ret; 153 149 154 - if (!len) 150 + if (s->full || !len) 155 151 return 0; 156 152 157 153 ret = bstr_printf(s->buffer + s->len, len, fmt, binary); 158 154 159 155 /* If we can't write it all, don't bother writing anything */ 160 - if (ret >= len) 156 + if (ret >= len) { 157 + s->full = 1; 161 158 return 0; 159 + } 162 160 163 161 s->len += ret; 164 162 ··· 181 175 { 182 176 int len = strlen(str); 183 177 184 - if (len > ((PAGE_SIZE - 1) - s->len)) 178 + if (s->full) 185 179 return 0; 180 + 181 + if (len > ((PAGE_SIZE - 1) - s->len)) { 182 + s->full = 1; 183 + return 0; 184 + } 186 185 187 186 memcpy(s->buffer + s->len, str, len); 188 187 s->len += len; ··· 197 186 198 187 int trace_seq_putc(struct trace_seq *s, unsigned char c) 199 188 { 200 - if (s->len >= (PAGE_SIZE - 1)) 189 + if (s->full) 201 190 return 0; 191 + 192 + if (s->len >= (PAGE_SIZE - 1)) { 193 + s->full = 1; 194 + return 0; 195 + } 202 196 203 197 s->buffer[s->len++] = c; 204 198 ··· 212 196 213 197 int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len) 214 198 { 215 - if (len > ((PAGE_SIZE - 1) - s->len)) 199 + if (s->full) 216 200 return 0; 201 + 202 + if (len > ((PAGE_SIZE - 1) - s->len)) { 203 + s->full = 1; 204 + return 0; 205 + } 217 206 218 207 memcpy(s->buffer + s->len, mem, len); 219 208 s->len += len; ··· 231 210 unsigned char hex[HEX_CHARS]; 232 211 const unsigned char *data = mem; 233 212 int i, j; 213 + 214 + if (s->full) 215 + return 0; 234 216 235 217 #ifdef __BIG_ENDIAN 236 218 for (i = 0, j = 0; i < len; i++) { ··· 252 228 { 253 229 void *ret; 254 230 255 - if (len > ((PAGE_SIZE - 1) - s->len)) 231 + if (s->full) 232 + return 0; 233 + 234 + if (len > ((PAGE_SIZE - 1) - s->len)) { 235 + s->full = 1; 256 236 return NULL; 237 + } 257 238 258 239 ret = s->buffer + s->len; 259 240 s->len += len; ··· 270 241 { 271 242 unsigned char *p; 272 243 273 - if (s->len >= (PAGE_SIZE - 1)) 244 + if (s->full) 274 245 return 0; 246 + 247 + if (s->len >= (PAGE_SIZE - 1)) { 248 + s->full = 1; 249 + return 0; 250 + } 251 + 275 252 p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len); 276 253 if (!IS_ERR(p)) { 277 254 p = mangle_path(s->buffer + s->len, p, "\n"); ··· 290 255 return 1; 291 256 } 292 257 258 + s->full = 1; 293 259 return 0; 294 260 } 295 261 ··· 416 380 struct file *file = NULL; 417 381 unsigned long vmstart = 0; 418 382 int ret = 1; 383 + 384 + if (s->full) 385 + return 0; 419 386 420 387 if (mm) { 421 388 const struct vm_area_struct *vma;