1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <[email protected]>
4 *
5 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <stdbool.h>
10
11 #include <sys/utsname.h>
12
13 #include "kbuffer.h"
14
15 #define MISSING_EVENTS (1UL << 31)
16 #define MISSING_STORED (1UL << 30)
17
18 #define COMMIT_MASK ((1 << 27) - 1)
19
20 /* Absolute time stamps do not have the 5 MSB, take from the real time stamp */
21 #define TS_MSB (0xf8ULL << 56)
22
23 enum {
24 KBUFFER_FL_HOST_BIG_ENDIAN = (1<<0),
25 KBUFFER_FL_BIG_ENDIAN = (1<<1),
26 KBUFFER_FL_LONG_8 = (1<<2),
27 KBUFFER_FL_OLD_FORMAT = (1<<3),
28 };
29
30 #define ENDIAN_MASK (KBUFFER_FL_HOST_BIG_ENDIAN | KBUFFER_FL_BIG_ENDIAN)
31
32 /** kbuffer
33 * @timestamp - timestamp of current event
34 * @lost_events - # of lost events between this subbuffer and previous
35 * @flags - special flags of the kbuffer
36 * @subbuffer - pointer to the sub-buffer page
37 * @data - pointer to the start of data on the sub-buffer page
38 * @index - index from @data to the @curr event data
39 * @curr - offset from @data to the start of current event
40 * (includes metadata)
41 * @next - offset from @data to the start of next event
42 * @size - The size of data on @data
43 * @start - The offset from @subbuffer where @data lives
44 * @first - The offset from @subbuffer where the first non time stamp event lives
45 *
46 * @read_4 - Function to read 4 raw bytes (may swap)
47 * @read_8 - Function to read 8 raw bytes (may swap)
48 * @read_long - Function to read a long word (4 or 8 bytes with needed swap)
49 */
50 struct kbuffer {
51 unsigned long long timestamp;
52 long long lost_events;
53 unsigned long flags;
54 void *subbuffer;
55 void *data;
56 unsigned int index;
57 unsigned int curr;
58 unsigned int next;
59 unsigned int size;
60 unsigned int start;
61 unsigned int first;
62
63 unsigned int (*read_4)(void *ptr);
64 unsigned long long (*read_8)(void *ptr);
65 unsigned long long (*read_long)(struct kbuffer *kbuf, void *ptr);
66 int (*next_event)(struct kbuffer *kbuf);
67 };
68
zmalloc(size_t size)69 static void *zmalloc(size_t size)
70 {
71 return calloc(1, size);
72 }
73
host_is_bigendian(void)74 static int host_is_bigendian(void)
75 {
76 unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 };
77 unsigned int *ptr;
78
79 ptr = (unsigned int *)str;
80 return *ptr == 0x01020304;
81 }
82
do_swap(struct kbuffer * kbuf)83 static int do_swap(struct kbuffer *kbuf)
84 {
85 return ((kbuf->flags & KBUFFER_FL_HOST_BIG_ENDIAN) + kbuf->flags) &
86 ENDIAN_MASK;
87 }
88
swap_8(unsigned long data)89 static unsigned long long swap_8(unsigned long data)
90 {
91 return ((data & 0xffULL) << 56) |
92 ((data & (0xffULL << 8)) << 40) |
93 ((data & (0xffULL << 16)) << 24) |
94 ((data & (0xffULL << 24)) << 8) |
95 ((data & (0xffULL << 32)) >> 8) |
96 ((data & (0xffULL << 40)) >> 24) |
97 ((data & (0xffULL << 48)) >> 40) |
98 ((data & (0xffULL << 56)) >> 56);
99 }
100
swap_4(unsigned int data)101 static unsigned int swap_4(unsigned int data)
102 {
103 return ((data & 0xffULL) << 24) |
104 ((data & (0xffULL << 8)) << 8) |
105 ((data & (0xffULL << 16)) >> 8) |
106 ((data & (0xffULL << 24)) >> 24);
107 }
108
write_8(bool do_swap,void * ptr,unsigned long long data)109 static void write_8(bool do_swap, void *ptr, unsigned long long data)
110 {
111 if (do_swap)
112 *(unsigned long long *)ptr = swap_8(data);
113 else
114 *(unsigned long long *)ptr = data;
115 }
116
write_4(bool do_swap,void * ptr,unsigned int data)117 static void write_4(bool do_swap, void *ptr, unsigned int data)
118 {
119 if (do_swap)
120 *(unsigned int *)ptr = swap_4(data);
121 else
122 *(unsigned int *)ptr = data;
123 }
124
__read_8(void * ptr)125 static unsigned long long __read_8(void *ptr)
126 {
127 unsigned long long data = *(unsigned long long *)ptr;
128
129 return data;
130 }
131
__read_8_sw(void * ptr)132 static unsigned long long __read_8_sw(void *ptr)
133 {
134 unsigned long long data = *(unsigned long long *)ptr;
135
136 return swap_8(data);
137 }
138
__read_4(void * ptr)139 static unsigned int __read_4(void *ptr)
140 {
141 unsigned int data = *(unsigned int *)ptr;
142
143 return data;
144 }
145
__read_4_sw(void * ptr)146 static unsigned int __read_4_sw(void *ptr)
147 {
148 unsigned int data = *(unsigned int *)ptr;
149
150 return swap_4(data);
151 }
152
read_8(struct kbuffer * kbuf,void * ptr)153 static unsigned long long read_8(struct kbuffer *kbuf, void *ptr)
154 {
155 return kbuf->read_8(ptr);
156 }
157
read_4(struct kbuffer * kbuf,void * ptr)158 static unsigned int read_4(struct kbuffer *kbuf, void *ptr)
159 {
160 return kbuf->read_4(ptr);
161 }
162
__read_long_8(struct kbuffer * kbuf,void * ptr)163 static unsigned long long __read_long_8(struct kbuffer *kbuf, void *ptr)
164 {
165 return kbuf->read_8(ptr);
166 }
167
__read_long_4(struct kbuffer * kbuf,void * ptr)168 static unsigned long long __read_long_4(struct kbuffer *kbuf, void *ptr)
169 {
170 return kbuf->read_4(ptr);
171 }
172
read_long(struct kbuffer * kbuf,void * ptr)173 static unsigned long long read_long(struct kbuffer *kbuf, void *ptr)
174 {
175 return kbuf->read_long(kbuf, ptr);
176 }
177
calc_index(struct kbuffer * kbuf,void * ptr)178 static int calc_index(struct kbuffer *kbuf, void *ptr)
179 {
180 return (unsigned long)ptr - (unsigned long)kbuf->data;
181 }
182
183 static int next_event(struct kbuffer *kbuf);
184 static int __next_event(struct kbuffer *kbuf);
185
186 /*
187 * Just because sizeof(long) is 4 bytes, doesn't mean the OS isn't
188 * 64bits
189 */
host_is_32bit(void)190 static bool host_is_32bit(void)
191 {
192 struct utsname buf;
193 int ret;
194
195 ret = uname(&buf);
196 if (ret < 0) {
197 /* Oh well, just assume it is 32 bit */
198 return true;
199 }
200 /* If the uname machine value contains 64, assume the kernel is 64 bit */
201 return strstr(buf.machine, "64") == NULL;
202 }
203
204 /**
205 * kbuffer_alloc - allocat a new kbuffer
206 * @size; enum to denote size of word
207 * @endian: enum to denote endianness
208 *
209 * Allocates and returns a new kbuffer.
210 */
211 struct kbuffer *
kbuffer_alloc(enum kbuffer_long_size size,enum kbuffer_endian endian)212 kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian)
213 {
214 struct kbuffer *kbuf;
215 int flags = 0;
216
217 switch (size) {
218 case KBUFFER_LSIZE_4:
219 break;
220 case KBUFFER_LSIZE_SAME_AS_HOST:
221 if (sizeof(long) != 8 && host_is_32bit())
222 break;
223 /* fallthrough */
224 case KBUFFER_LSIZE_8:
225 flags |= KBUFFER_FL_LONG_8;
226 break;
227 default:
228 return NULL;
229 }
230
231 switch (endian) {
232 case KBUFFER_ENDIAN_LITTLE:
233 case KBUFFER_ENDIAN_SAME_AS_HOST:
234 break;
235 case KBUFFER_ENDIAN_BIG:
236 flags |= KBUFFER_FL_BIG_ENDIAN;
237 break;
238 default:
239 return NULL;
240 }
241
242 kbuf = zmalloc(sizeof(*kbuf));
243 if (!kbuf)
244 return NULL;
245
246 kbuf->flags = flags;
247
248 if (host_is_bigendian()) {
249 if (endian == KBUFFER_ENDIAN_SAME_AS_HOST)
250 flags |= KBUFFER_FL_BIG_ENDIAN;
251 kbuf->flags |= KBUFFER_FL_HOST_BIG_ENDIAN;
252 }
253
254 if (do_swap(kbuf)) {
255 kbuf->read_8 = __read_8_sw;
256 kbuf->read_4 = __read_4_sw;
257 } else {
258 kbuf->read_8 = __read_8;
259 kbuf->read_4 = __read_4;
260 }
261
262 if (kbuf->flags & KBUFFER_FL_LONG_8)
263 kbuf->read_long = __read_long_8;
264 else
265 kbuf->read_long = __read_long_4;
266
267 /* May be changed by kbuffer_set_old_format() */
268 kbuf->next_event = __next_event;
269
270 return kbuf;
271 }
272
273 /**
274 * kbuffer_dup - duplicate a given kbuffer
275 * @kbuf_orig; The kbuffer to duplicate
276 *
277 * Allocates a new kbuffer based off of anothe kbuffer.
278 * Returns the duplicate on success or NULL on error.
279 */
kbuffer_dup(struct kbuffer * kbuf_orig)280 struct kbuffer *kbuffer_dup(struct kbuffer *kbuf_orig)
281 {
282 struct kbuffer *kbuf;
283
284 kbuf = malloc(sizeof(*kbuf));
285 if (!kbuf)
286 return NULL;
287
288 *kbuf = *kbuf_orig;
289
290 return kbuf;
291 }
292
293 /** kbuffer_free - free an allocated kbuffer
294 * @kbuf: The kbuffer to free
295 *
296 * Can take NULL as a parameter.
297 */
kbuffer_free(struct kbuffer * kbuf)298 void kbuffer_free(struct kbuffer *kbuf)
299 {
300 free(kbuf);
301 }
302
303 /**
304 * kbuffer_refresh - update the meta data from the subbuffer
305 * @kbuf; The kbuffer to update
306 *
307 * If the loaded subbuffer changed its meta data (the commit)
308 * then update the pointers for it.
309 */
kbuffer_refresh(struct kbuffer * kbuf)310 int kbuffer_refresh(struct kbuffer *kbuf)
311 {
312 unsigned long long flags;
313 unsigned int old_size;
314
315 if (!kbuf || !kbuf->subbuffer)
316 return -1;
317
318 old_size = kbuf->size;
319
320 flags = read_long(kbuf, kbuf->subbuffer + 8);
321 kbuf->size = (unsigned int)flags & COMMIT_MASK;
322
323 /* Update next to be the next element */
324 if (kbuf->size != old_size && kbuf->curr == kbuf->next)
325 next_event(kbuf);
326
327 return 0;
328 }
329
type4host(struct kbuffer * kbuf,unsigned int type_len_ts)330 static unsigned int type4host(struct kbuffer *kbuf,
331 unsigned int type_len_ts)
332 {
333 if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
334 return (type_len_ts >> 29) & 3;
335 else
336 return type_len_ts & 3;
337 }
338
len4host(struct kbuffer * kbuf,unsigned int type_len_ts)339 static unsigned int len4host(struct kbuffer *kbuf,
340 unsigned int type_len_ts)
341 {
342 if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
343 return (type_len_ts >> 27) & 7;
344 else
345 return (type_len_ts >> 2) & 7;
346 }
347
type_len4host(struct kbuffer * kbuf,unsigned int type_len_ts)348 static unsigned int type_len4host(struct kbuffer *kbuf,
349 unsigned int type_len_ts)
350 {
351 if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
352 return (type_len_ts >> 27) & ((1 << 5) - 1);
353 else
354 return type_len_ts & ((1 << 5) - 1);
355 }
356
ts4host(struct kbuffer * kbuf,unsigned int type_len_ts)357 static unsigned int ts4host(struct kbuffer *kbuf,
358 unsigned int type_len_ts)
359 {
360 if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
361 return type_len_ts & ((1 << 27) - 1);
362 else
363 return type_len_ts >> 5;
364 }
365
set_curr_to_end(struct kbuffer * kbuf)366 static void set_curr_to_end(struct kbuffer *kbuf)
367 {
368 kbuf->curr = kbuf->size;
369 kbuf->next = kbuf->size;
370 kbuf->index = kbuf->size;
371 }
372
373 /*
374 * Linux 2.6.30 and earlier (not much ealier) had a different
375 * ring buffer format. It should be obsolete, but we handle it anyway.
376 */
377 enum old_ring_buffer_type {
378 OLD_RINGBUF_TYPE_PADDING,
379 OLD_RINGBUF_TYPE_TIME_EXTEND,
380 OLD_RINGBUF_TYPE_TIME_STAMP,
381 OLD_RINGBUF_TYPE_DATA,
382 };
383
old_update_pointers(struct kbuffer * kbuf)384 static unsigned int old_update_pointers(struct kbuffer *kbuf)
385 {
386 unsigned long long extend;
387 unsigned int type_len_ts;
388 unsigned int type;
389 unsigned int len;
390 unsigned int delta;
391 unsigned int length;
392 void *ptr = kbuf->data + kbuf->curr;
393
394 type_len_ts = read_4(kbuf, ptr);
395 ptr += 4;
396
397 type = type4host(kbuf, type_len_ts);
398 len = len4host(kbuf, type_len_ts);
399 delta = ts4host(kbuf, type_len_ts);
400
401 switch (type) {
402 case OLD_RINGBUF_TYPE_PADDING:
403 kbuf->next = kbuf->size;
404 return 0;
405
406 case OLD_RINGBUF_TYPE_TIME_EXTEND:
407 extend = read_4(kbuf, ptr);
408 extend <<= TS_SHIFT;
409 extend += delta;
410 delta = extend;
411 ptr += 4;
412 length = 0;
413 break;
414
415 case OLD_RINGBUF_TYPE_TIME_STAMP:
416 /* should never happen! */
417 set_curr_to_end(kbuf);
418 return -1;
419 default:
420 if (len)
421 length = len * 4;
422 else {
423 length = read_4(kbuf, ptr);
424 length -= 4;
425 ptr += 4;
426 }
427 break;
428 }
429
430 kbuf->timestamp += delta;
431 kbuf->index = calc_index(kbuf, ptr);
432 kbuf->next = kbuf->index + length;
433
434 return type;
435 }
436
__old_next_event(struct kbuffer * kbuf)437 static int __old_next_event(struct kbuffer *kbuf)
438 {
439 int type;
440
441 do {
442 kbuf->curr = kbuf->next;
443 if (kbuf->next >= kbuf->size)
444 return -1;
445 type = old_update_pointers(kbuf);
446 } while (type == OLD_RINGBUF_TYPE_TIME_EXTEND || type == OLD_RINGBUF_TYPE_PADDING);
447
448 return 0;
449 }
450
451 static unsigned int
translate_data(struct kbuffer * kbuf,void * data,void ** rptr,unsigned long long * delta,int * length)452 translate_data(struct kbuffer *kbuf, void *data, void **rptr,
453 unsigned long long *delta, int *length)
454 {
455 unsigned long long extend, msb = 0;
456 unsigned int type_len_ts;
457 unsigned int type_len;
458
459 type_len_ts = read_4(kbuf, data);
460 data += 4;
461
462 type_len = type_len4host(kbuf, type_len_ts);
463 *delta = ts4host(kbuf, type_len_ts);
464
465 switch (type_len) {
466 case KBUFFER_TYPE_PADDING:
467 *length = read_4(kbuf, data);
468 break;
469
470 case KBUFFER_TYPE_TIME_STAMP:
471 msb = kbuf->timestamp & TS_MSB;
472 /* fall through */
473 case KBUFFER_TYPE_TIME_EXTEND:
474 extend = read_4(kbuf, data);
475 data += 4;
476 extend <<= TS_SHIFT;
477 extend += *delta;
478 *delta = extend | msb;
479 *length = 0;
480 break;
481
482 case 0:
483 *length = read_4(kbuf, data) - 4;
484 *length = (*length + 3) & ~3;
485 data += 4;
486 break;
487 default:
488 *length = type_len * 4;
489 break;
490 }
491
492 *rptr = data;
493
494 return type_len;
495 }
496
update_pointers(struct kbuffer * kbuf)497 static unsigned int update_pointers(struct kbuffer *kbuf)
498 {
499 unsigned long long delta;
500 unsigned int type_len;
501 int length;
502 void *ptr = kbuf->data + kbuf->curr;
503
504 type_len = translate_data(kbuf, ptr, &ptr, &delta, &length);
505
506 if (type_len == KBUFFER_TYPE_TIME_STAMP)
507 kbuf->timestamp = delta;
508 else
509 kbuf->timestamp += delta;
510
511 kbuf->index = calc_index(kbuf, ptr);
512 kbuf->next = kbuf->index + length;
513
514 return type_len;
515 }
516
517 /**
518 * kbuffer_translate_data - read raw data to get a record
519 * @swap: Set to 1 if bytes in words need to be swapped when read
520 * @data: The raw data to read
521 * @size: Address to store the size of the event data.
522 *
523 * Returns a pointer to the event data. To determine the entire
524 * record size (record metadata + data) just add the difference between
525 * @data and the returned value to @size.
526 */
kbuffer_translate_data(int swap,void * data,unsigned int * size)527 void *kbuffer_translate_data(int swap, void *data, unsigned int *size)
528 {
529 unsigned long long delta;
530 struct kbuffer kbuf;
531 int type_len;
532 int length;
533 void *ptr;
534
535 if (swap) {
536 kbuf.read_8 = __read_8_sw;
537 kbuf.read_4 = __read_4_sw;
538 kbuf.flags = host_is_bigendian() ? 0 : KBUFFER_FL_BIG_ENDIAN;
539 } else {
540 kbuf.read_8 = __read_8;
541 kbuf.read_4 = __read_4;
542 kbuf.flags = host_is_bigendian() ? KBUFFER_FL_BIG_ENDIAN: 0;
543 }
544
545 type_len = translate_data(&kbuf, data, &ptr, &delta, &length);
546 switch (type_len) {
547 case KBUFFER_TYPE_PADDING:
548 case KBUFFER_TYPE_TIME_EXTEND:
549 case KBUFFER_TYPE_TIME_STAMP:
550 return NULL;
551 }
552
553 *size = length;
554
555 return ptr;
556 }
557
__next_event(struct kbuffer * kbuf)558 static int __next_event(struct kbuffer *kbuf)
559 {
560 int type;
561
562 do {
563 kbuf->curr = kbuf->next;
564 if (kbuf->next >= kbuf->size)
565 return -1;
566 type = update_pointers(kbuf);
567 } while (type == KBUFFER_TYPE_TIME_EXTEND ||
568 type == KBUFFER_TYPE_TIME_STAMP ||
569 type == KBUFFER_TYPE_PADDING);
570
571 return 0;
572 }
573
next_event(struct kbuffer * kbuf)574 static int next_event(struct kbuffer *kbuf)
575 {
576 return kbuf->next_event(kbuf);
577 }
578
579 /**
580 * kbuffer_next_event - increment the current pointer
581 * @kbuf: The kbuffer to read
582 * @ts: Address to store the next record's timestamp (may be NULL to ignore)
583 *
584 * Increments the pointers into the subbuffer of the kbuffer to point to the
585 * next event so that the next kbuffer_read_event() will return a
586 * new event.
587 *
588 * Returns the data of the next event if a new event exists on the subbuffer,
589 * NULL otherwise.
590 */
kbuffer_next_event(struct kbuffer * kbuf,unsigned long long * ts)591 void *kbuffer_next_event(struct kbuffer *kbuf, unsigned long long *ts)
592 {
593 int ret;
594
595 if (!kbuf || !kbuf->subbuffer)
596 return NULL;
597
598 ret = next_event(kbuf);
599 if (ret < 0)
600 return NULL;
601
602 if (ts)
603 *ts = kbuf->timestamp;
604
605 return kbuf->data + kbuf->index;
606 }
607
608 /**
609 * kbuffer_load_subbuffer - load a new subbuffer into the kbuffer
610 * @kbuf: The kbuffer to load
611 * @subbuffer: The subbuffer to load into @kbuf.
612 *
613 * Load a new subbuffer (page) into @kbuf. This will reset all
614 * the pointers and update the @kbuf timestamp. The next read will
615 * return the first event on @subbuffer.
616 *
617 * Returns 0 on succes, -1 otherwise.
618 */
kbuffer_load_subbuffer(struct kbuffer * kbuf,void * subbuffer)619 int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer)
620 {
621 unsigned long long flags;
622 void *ptr = subbuffer;
623
624 if (!kbuf || !subbuffer)
625 return -1;
626
627 kbuf->subbuffer = subbuffer;
628
629 kbuf->timestamp = read_8(kbuf, ptr);
630 ptr += 8;
631
632 kbuf->curr = 0;
633
634 if (kbuf->flags & KBUFFER_FL_LONG_8)
635 kbuf->start = 16;
636 else
637 kbuf->start = 12;
638
639 kbuf->data = subbuffer + kbuf->start;
640
641 flags = read_long(kbuf, ptr);
642 kbuf->size = (unsigned int)flags & COMMIT_MASK;
643
644 if (flags & MISSING_EVENTS) {
645 if (flags & MISSING_STORED) {
646 ptr = kbuf->data + kbuf->size;
647 kbuf->lost_events = read_long(kbuf, ptr);
648 } else
649 kbuf->lost_events = -1;
650 } else
651 kbuf->lost_events = 0;
652
653 kbuf->index = 0;
654 kbuf->next = 0;
655
656 next_event(kbuf);
657
658 /* save the first record from the page */
659 kbuf->first = kbuf->curr;
660
661 return 0;
662 }
663
664 /**
665 * kbuffer_subbuf_timestamp - read the timestamp from a sub buffer
666 * @kbuf: The kbuffer to load
667 * @subbuf: The subbuffer to read from.
668 *
669 * Return the timestamp from a subbuffer.
670 */
kbuffer_subbuf_timestamp(struct kbuffer * kbuf,void * subbuf)671 unsigned long long kbuffer_subbuf_timestamp(struct kbuffer *kbuf, void *subbuf)
672 {
673 return kbuf->read_8(subbuf);
674 }
675
676 /**
677 * kbuffer_ptr_delta - read the delta field from a record
678 * @kbuf: The kbuffer to load
679 * @ptr: The record in the buffe.
680 *
681 * Return the timestamp delta from a record
682 */
kbuffer_ptr_delta(struct kbuffer * kbuf,void * ptr)683 unsigned int kbuffer_ptr_delta(struct kbuffer *kbuf, void *ptr)
684 {
685 unsigned int type_len_ts;
686
687 type_len_ts = read_4(kbuf, ptr);
688 return ts4host(kbuf, type_len_ts);
689 }
690
691
692 /**
693 * kbuffer_read_event - read the next event in the kbuffer subbuffer
694 * @kbuf: The kbuffer to read from
695 * @ts: The address to store the timestamp of the event (may be NULL to ignore)
696 *
697 * Returns a pointer to the data part of the current event.
698 * NULL if no event is left on the subbuffer.
699 */
kbuffer_read_event(struct kbuffer * kbuf,unsigned long long * ts)700 void *kbuffer_read_event(struct kbuffer *kbuf, unsigned long long *ts)
701 {
702 if (!kbuf || !kbuf->subbuffer)
703 return NULL;
704
705 if (kbuf->curr >= kbuf->size)
706 return NULL;
707
708 if (ts)
709 *ts = kbuf->timestamp;
710 return kbuf->data + kbuf->index;
711 }
712
713 /**
714 * kbuffer_timestamp - Return the timestamp of the current event
715 * @kbuf: The kbuffer to read from
716 *
717 * Returns the timestamp of the current (next) event.
718 */
kbuffer_timestamp(struct kbuffer * kbuf)719 unsigned long long kbuffer_timestamp(struct kbuffer *kbuf)
720 {
721 return kbuf->timestamp;
722 }
723
724 /**
725 * kbuffer_read_at_offset - read the event that is at offset
726 * @kbuf: The kbuffer to read from
727 * @offset: The offset into the subbuffer
728 * @ts: The address to store the timestamp of the event (may be NULL to ignore)
729 *
730 * The @offset must be an index from the @kbuf subbuffer beginning.
731 * If @offset is bigger than the stored subbuffer, NULL will be returned.
732 *
733 * Returns the data of the record that is at @offset. Note, @offset does
734 * not need to be the start of the record, the offset just needs to be
735 * in the record (or beginning of it).
736 *
737 * Note, the kbuf timestamp and pointers are updated to the
738 * returned record. That is, kbuffer_read_event() will return the same
739 * data and timestamp, and kbuffer_next_event() will increment from
740 * this record.
741 */
kbuffer_read_at_offset(struct kbuffer * kbuf,int offset,unsigned long long * ts)742 void *kbuffer_read_at_offset(struct kbuffer *kbuf, int offset,
743 unsigned long long *ts)
744 {
745 void *data;
746
747 if (offset < kbuf->start)
748 offset = 0;
749 else
750 offset -= kbuf->start;
751
752 /* Reset the buffer */
753 kbuffer_load_subbuffer(kbuf, kbuf->subbuffer);
754 data = kbuffer_read_event(kbuf, ts);
755
756 while (kbuf->curr < offset) {
757 data = kbuffer_next_event(kbuf, ts);
758 if (!data)
759 break;
760 }
761
762 return data;
763 }
764
765 /**
766 * kbuffer_subbuffer_size - the size of the loaded subbuffer
767 * @kbuf: The kbuffer to read from
768 *
769 * Returns the size of the subbuffer. Note, this size is
770 * where the last event resides. The stored subbuffer may actually be
771 * bigger due to padding and such.
772 */
kbuffer_subbuffer_size(struct kbuffer * kbuf)773 int kbuffer_subbuffer_size(struct kbuffer *kbuf)
774 {
775 return kbuf->size;
776 }
777
778 /**
779 * kbuffer_subbuffer - the currently loaded subbuffer
780 * @kbuf: The kbuffer to read from
781 *
782 * Returns the currently loaded subbuffer.
783 */
kbuffer_subbuffer(struct kbuffer * kbuf)784 void *kbuffer_subbuffer(struct kbuffer *kbuf)
785 {
786 return kbuf->subbuffer;
787 }
788
789 /**
790 * kbuffer_curr_index - Return the index of the record
791 * @kbuf: The kbuffer to read from
792 *
793 * Returns the index from the start of the data part of
794 * the subbuffer to the current location. Note this is not
795 * from the start of the subbuffer. An index of zero will
796 * point to the first record. Use kbuffer_curr_offset() for
797 * the actually offset (that can be used by kbuffer_read_at_offset())
798 */
kbuffer_curr_index(struct kbuffer * kbuf)799 int kbuffer_curr_index(struct kbuffer *kbuf)
800 {
801 return kbuf->curr;
802 }
803
804 /**
805 * kbuffer_curr_offset - Return the offset of the record
806 * @kbuf: The kbuffer to read from
807 *
808 * Returns the offset from the start of the subbuffer to the
809 * current location.
810 */
kbuffer_curr_offset(struct kbuffer * kbuf)811 int kbuffer_curr_offset(struct kbuffer *kbuf)
812 {
813 return kbuf->curr + kbuf->start;
814 }
815
816 /**
817 * kbuffer_event_size - return the size of the event data
818 * @kbuf: The kbuffer to read
819 *
820 * Returns the size of the event data (the payload not counting
821 * the meta data of the record) of the current event.
822 */
kbuffer_event_size(struct kbuffer * kbuf)823 int kbuffer_event_size(struct kbuffer *kbuf)
824 {
825 return kbuf->next - kbuf->index;
826 }
827
828 /**
829 * kbuffer_curr_size - return the size of the entire record
830 * @kbuf: The kbuffer to read
831 *
832 * Returns the size of the entire record (meta data and payload)
833 * of the current event.
834 */
kbuffer_curr_size(struct kbuffer * kbuf)835 int kbuffer_curr_size(struct kbuffer *kbuf)
836 {
837 return kbuf->next - kbuf->curr;
838 }
839
840 /**
841 * kbuffer_missed_events - return the # of missed events from last event.
842 * @kbuf: The kbuffer to read from
843 *
844 * Returns the # of missed events (if recorded) before the current
845 * event. Note, only events on the beginning of a subbuffer can
846 * have missed events, all other events within the buffer will be
847 * zero.
848 */
kbuffer_missed_events(struct kbuffer * kbuf)849 int kbuffer_missed_events(struct kbuffer *kbuf)
850 {
851 /* Only the first event can have missed events */
852 if (kbuf->curr)
853 return 0;
854
855 return kbuf->lost_events;
856 }
857
858 /**
859 * kbuffer_set_old_forma - set the kbuffer to use the old format parsing
860 * @kbuf: The kbuffer to set
861 *
862 * This is obsolete (or should be). The first kernels to use the
863 * new ring buffer had a slightly different ring buffer format
864 * (2.6.30 and earlier). It is still somewhat supported by kbuffer,
865 * but should not be counted on in the future.
866 */
kbuffer_set_old_format(struct kbuffer * kbuf)867 void kbuffer_set_old_format(struct kbuffer *kbuf)
868 {
869 kbuf->flags |= KBUFFER_FL_OLD_FORMAT;
870
871 kbuf->next_event = __old_next_event;
872 }
873
874 /**
875 * kbuffer_start_of_data - return offset of where data starts on subbuffer
876 * @kbuf: The kbuffer
877 *
878 * Returns the location on the subbuffer where the data starts.
879 */
kbuffer_start_of_data(struct kbuffer * kbuf)880 int kbuffer_start_of_data(struct kbuffer *kbuf)
881 {
882 return kbuf->first + kbuf->start;
883 }
884
885 /**
886 * kbuffer_raw_get - get raw buffer info
887 * @kbuf: The kbuffer
888 * @subbuf: Start of mapped subbuffer
889 * @info: Info descriptor to fill in
890 *
891 * For debugging. This can return internals of the ring buffer.
892 * Expects to have info->next set to what it will read.
893 * The type, length and timestamp delta will be filled in, and
894 * @info->next will be updated to the next element.
895 * The @subbuf is used to know if the info is passed the end of
896 * data and NULL will be returned if it is.
897 */
898 struct kbuffer_raw_info *
kbuffer_raw_get(struct kbuffer * kbuf,void * subbuf,struct kbuffer_raw_info * info)899 kbuffer_raw_get(struct kbuffer *kbuf, void *subbuf, struct kbuffer_raw_info *info)
900 {
901 unsigned long long flags;
902 unsigned long long delta;
903 unsigned int type_len;
904 unsigned int size;
905 int start;
906 int length;
907 void *ptr = info->next;
908
909 if (!kbuf || !subbuf)
910 return NULL;
911
912 if (kbuf->flags & KBUFFER_FL_LONG_8)
913 start = 16;
914 else
915 start = 12;
916
917 flags = read_long(kbuf, subbuf + 8);
918 size = (unsigned int)flags & COMMIT_MASK;
919
920 if (ptr < subbuf || ptr >= subbuf + start + size)
921 return NULL;
922
923 type_len = translate_data(kbuf, ptr, &ptr, &delta, &length);
924
925 info->next = ptr + length;
926
927 info->type = type_len;
928 info->delta = delta;
929 info->length = length;
930
931 return info;
932 }
933
934 /**
935 * kbuffer_read_buffer - read a buffer like the kernel would perform a read
936 * @kbuf: the kbuffer handle
937 * @buffer: where to write the data into
938 * @len; The length of @buffer
939 *
940 * This will read the saved sub buffer within @kbuf like the systemcall
941 * of read() to the trace_pipe_raw would do. That is, if either @len
942 * can not fit the entire buffer, or if the current index in @kbuf
943 * is non-zero, it will write to @buffer a new subbuffer that could be
944 * loaded into kbuffer_load_subbuffer(). That is, it will write into
945 * @buffer a legitimate sub-buffer with a header and all that has the
946 * proper timestamp and commit fields.
947 *
948 * Returns the index after the last element written.
949 * 0 if nothing was copied.
950 * -1 on error (which includes not having enough space in len to
951 * copy the subbuffer header or any of its content. In otherwords,
952 * do not try again!
953 *
954 * @kbuf current index will be set to the next element to read.
955 */
kbuffer_read_buffer(struct kbuffer * kbuf,void * buffer,int len)956 int kbuffer_read_buffer(struct kbuffer *kbuf, void *buffer, int len)
957 {
958 unsigned long long ts;
959 unsigned int type_len_ts;
960 bool do_swap = false;
961 int last_next;
962 int save_curr;
963
964 /* Are we at the end of the buffer */
965 if (kbuf->curr >= kbuf->size)
966 return 0;
967
968 /* If we can not copy anyting, return -1 */
969 if (len < kbuf->start)
970 return -1;
971
972 /* Check if the first event can fit */
973 if (len < (kbuf->next - kbuf->curr) + kbuf->start)
974 return -1;
975
976 if (kbuf->read_8 == __read_8_sw)
977 do_swap = true;
978
979 /* Have this subbuffer timestamp be the current timestamp */
980 write_8(do_swap, buffer, kbuf->timestamp);
981
982 len -= kbuf->start;
983
984 save_curr = kbuf->curr;
985
986 /* Due to timestamps, we must save the current next to use */
987 last_next = kbuf->next;
988
989 while (len >= kbuf->next - save_curr) {
990 last_next = kbuf->next;
991 if (!kbuffer_next_event(kbuf, &ts))
992 break;
993 }
994
995 len = last_next - save_curr;
996 /* No event was found? */
997 if (!len)
998 return 0;
999
1000 memcpy(buffer + kbuf->start, kbuf->data + save_curr, len);
1001
1002 /* Zero out the delta, as the sub-buffer has the timestamp */
1003 type_len_ts = read_4(kbuf, buffer + kbuf->start);
1004
1005 if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
1006 type_len_ts &= ~(((1 << 27) - 1));
1007 else
1008 type_len_ts &= ((1 << 5) - 1);
1009
1010 write_4(do_swap, buffer + kbuf->start, type_len_ts);
1011
1012 /* Update the size */
1013 if (kbuf->read_long == __read_long_8)
1014 write_8(do_swap, buffer + 8, len);
1015 else
1016 write_4(do_swap, buffer + 8, len);
1017
1018 return last_next;
1019 }
1020