Commit d184b31c0e403580aafb3f8955ecc185a3d04801

Authored by Johannes Berg
Committed by Steven Rostedt
1 parent a63ce5b306

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>

Showing 2 changed files with 52 additions and 11 deletions Side-by-side Diff

include/linux/trace_seq.h
... ... @@ -14,6 +14,7 @@
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
... ... @@ -21,6 +22,7 @@
21 22 {
22 23 s->len = 0;
23 24 s->readpos = 0;
  25 + s->full = 0;
24 26 }
25 27  
26 28 /*
kernel/trace/trace_output.c
... ... @@ -93,7 +93,7 @@
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);
100 100  
... ... @@ -101,8 +101,10 @@
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  
109 111  
110 112  
... ... @@ -127,14 +129,16 @@
127 129 int len = (PAGE_SIZE - 1) - s->len;
128 130 int ret;
129 131  
130   - if (!len)
  132 + if (s->full || !len)
131 133 return 0;
132 134  
133 135 ret = vsnprintf(s->buffer + s->len, len, fmt, args);
134 136  
135 137 /* If we can't write it all, don't bother writing anything */
136   - if (ret >= len)
  138 + if (ret >= len) {
  139 + s->full = 1;
137 140 return 0;
  141 + }
138 142  
139 143 s->len += ret;
140 144  
141 145  
142 146  
... ... @@ -147,14 +151,16 @@
147 151 int len = (PAGE_SIZE - 1) - s->len;
148 152 int ret;
149 153  
150   - if (!len)
  154 + if (s->full || !len)
151 155 return 0;
152 156  
153 157 ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
154 158  
155 159 /* If we can't write it all, don't bother writing anything */
156   - if (ret >= len)
  160 + if (ret >= len) {
  161 + s->full = 1;
157 162 return 0;
  163 + }
158 164  
159 165 s->len += ret;
160 166  
161 167  
... ... @@ -175,9 +181,14 @@
175 181 {
176 182 int len = strlen(str);
177 183  
178   - if (len > ((PAGE_SIZE - 1) - s->len))
  184 + if (s->full)
179 185 return 0;
180 186  
  187 + if (len > ((PAGE_SIZE - 1) - s->len)) {
  188 + s->full = 1;
  189 + return 0;
  190 + }
  191 +
181 192 memcpy(s->buffer + s->len, str, len);
182 193 s->len += len;
183 194  
184 195  
... ... @@ -186,9 +197,14 @@
186 197  
187 198 int trace_seq_putc(struct trace_seq *s, unsigned char c)
188 199 {
189   - if (s->len >= (PAGE_SIZE - 1))
  200 + if (s->full)
190 201 return 0;
191 202  
  203 + if (s->len >= (PAGE_SIZE - 1)) {
  204 + s->full = 1;
  205 + return 0;
  206 + }
  207 +
192 208 s->buffer[s->len++] = c;
193 209  
194 210 return 1;
195 211  
... ... @@ -196,9 +212,14 @@
196 212  
197 213 int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
198 214 {
199   - if (len > ((PAGE_SIZE - 1) - s->len))
  215 + if (s->full)
200 216 return 0;
201 217  
  218 + if (len > ((PAGE_SIZE - 1) - s->len)) {
  219 + s->full = 1;
  220 + return 0;
  221 + }
  222 +
202 223 memcpy(s->buffer + s->len, mem, len);
203 224 s->len += len;
204 225  
... ... @@ -211,6 +232,9 @@
211 232 const unsigned char *data = mem;
212 233 int i, j;
213 234  
  235 + if (s->full)
  236 + return 0;
  237 +
214 238 #ifdef __BIG_ENDIAN
215 239 for (i = 0, j = 0; i < len; i++) {
216 240 #else
217 241  
... ... @@ -228,8 +252,13 @@
228 252 {
229 253 void *ret;
230 254  
231   - 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;
232 260 return NULL;
  261 + }
233 262  
234 263 ret = s->buffer + s->len;
235 264 s->len += len;
236 265  
... ... @@ -241,8 +270,14 @@
241 270 {
242 271 unsigned char *p;
243 272  
244   - if (s->len >= (PAGE_SIZE - 1))
  273 + if (s->full)
245 274 return 0;
  275 +
  276 + if (s->len >= (PAGE_SIZE - 1)) {
  277 + s->full = 1;
  278 + return 0;
  279 + }
  280 +
246 281 p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
247 282 if (!IS_ERR(p)) {
248 283 p = mangle_path(s->buffer + s->len, p, "\n");
... ... @@ -255,6 +290,7 @@
255 290 return 1;
256 291 }
257 292  
  293 + s->full = 1;
258 294 return 0;
259 295 }
260 296  
... ... @@ -380,6 +416,9 @@
380 416 struct file *file = NULL;
381 417 unsigned long vmstart = 0;
382 418 int ret = 1;
  419 +
  420 + if (s->full)
  421 + return 0;
383 422  
384 423 if (mm) {
385 424 const struct vm_area_struct *vma;