1 // SPDX-License-Identifier: LGPL-2.1
3 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
12 #define MISSING_EVENTS (1UL << 31)
13 #define MISSING_STORED (1UL << 30)
15 #define COMMIT_MASK ((1 << 27) - 1)
18 KBUFFER_FL_HOST_BIG_ENDIAN = (1<<0),
19 KBUFFER_FL_BIG_ENDIAN = (1<<1),
20 KBUFFER_FL_LONG_8 = (1<<2),
21 KBUFFER_FL_OLD_FORMAT = (1<<3),
24 #define ENDIAN_MASK (KBUFFER_FL_HOST_BIG_ENDIAN | KBUFFER_FL_BIG_ENDIAN)
27 * @timestamp - timestamp of current event
28 * @lost_events - # of lost events between this subbuffer and previous
29 * @flags - special flags of the kbuffer
30 * @subbuffer - pointer to the sub-buffer page
31 * @data - pointer to the start of data on the sub-buffer page
32 * @index - index from @data to the @curr event data
33 * @curr - offset from @data to the start of current event
35 * @next - offset from @data to the start of next event
36 * @size - The size of data on @data
37 * @start - The offset from @subbuffer where @data lives
39 * @read_4 - Function to read 4 raw bytes (may swap)
40 * @read_8 - Function to read 8 raw bytes (may swap)
41 * @read_long - Function to read a long word (4 or 8 bytes with needed swap)
44 unsigned long long timestamp;
45 long long lost_events;
55 unsigned int (*read_4)(void *ptr);
56 unsigned long long (*read_8)(void *ptr);
57 unsigned long long (*read_long)(struct kbuffer *kbuf, void *ptr);
58 int (*next_event)(struct kbuffer *kbuf);
61 static void *zmalloc(size_t size)
63 return calloc(1, size);
66 static int host_is_bigendian(void)
68 unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 };
71 ptr = (unsigned int *)str;
72 return *ptr == 0x01020304;
75 static int do_swap(struct kbuffer *kbuf)
77 return ((kbuf->flags & KBUFFER_FL_HOST_BIG_ENDIAN) + kbuf->flags) &
81 static unsigned long long __read_8(void *ptr)
83 unsigned long long data = *(unsigned long long *)ptr;
88 static unsigned long long __read_8_sw(void *ptr)
90 unsigned long long data = *(unsigned long long *)ptr;
91 unsigned long long swap;
93 swap = ((data & 0xffULL) << 56) |
94 ((data & (0xffULL << 8)) << 40) |
95 ((data & (0xffULL << 16)) << 24) |
96 ((data & (0xffULL << 24)) << 8) |
97 ((data & (0xffULL << 32)) >> 8) |
98 ((data & (0xffULL << 40)) >> 24) |
99 ((data & (0xffULL << 48)) >> 40) |
100 ((data & (0xffULL << 56)) >> 56);
105 static unsigned int __read_4(void *ptr)
107 unsigned int data = *(unsigned int *)ptr;
112 static unsigned int __read_4_sw(void *ptr)
114 unsigned int data = *(unsigned int *)ptr;
117 swap = ((data & 0xffULL) << 24) |
118 ((data & (0xffULL << 8)) << 8) |
119 ((data & (0xffULL << 16)) >> 8) |
120 ((data & (0xffULL << 24)) >> 24);
125 static unsigned long long read_8(struct kbuffer *kbuf, void *ptr)
127 return kbuf->read_8(ptr);
130 static unsigned int read_4(struct kbuffer *kbuf, void *ptr)
132 return kbuf->read_4(ptr);
135 static unsigned long long __read_long_8(struct kbuffer *kbuf, void *ptr)
137 return kbuf->read_8(ptr);
140 static unsigned long long __read_long_4(struct kbuffer *kbuf, void *ptr)
142 return kbuf->read_4(ptr);
145 static unsigned long long read_long(struct kbuffer *kbuf, void *ptr)
147 return kbuf->read_long(kbuf, ptr);
150 static int calc_index(struct kbuffer *kbuf, void *ptr)
152 return (unsigned long)ptr - (unsigned long)kbuf->data;
155 static int __next_event(struct kbuffer *kbuf);
158 * kbuffer_alloc - allocat a new kbuffer
159 * @size; enum to denote size of word
160 * @endian: enum to denote endianness
162 * Allocates and returns a new kbuffer.
165 kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian)
167 struct kbuffer *kbuf;
171 case KBUFFER_LSIZE_4:
173 case KBUFFER_LSIZE_8:
174 flags |= KBUFFER_FL_LONG_8;
181 case KBUFFER_ENDIAN_LITTLE:
183 case KBUFFER_ENDIAN_BIG:
184 flags |= KBUFFER_FL_BIG_ENDIAN;
190 kbuf = zmalloc(sizeof(*kbuf));
196 if (host_is_bigendian())
197 kbuf->flags |= KBUFFER_FL_HOST_BIG_ENDIAN;
200 kbuf->read_8 = __read_8_sw;
201 kbuf->read_4 = __read_4_sw;
203 kbuf->read_8 = __read_8;
204 kbuf->read_4 = __read_4;
207 if (kbuf->flags & KBUFFER_FL_LONG_8)
208 kbuf->read_long = __read_long_8;
210 kbuf->read_long = __read_long_4;
212 /* May be changed by kbuffer_set_old_format() */
213 kbuf->next_event = __next_event;
218 /** kbuffer_free - free an allocated kbuffer
219 * @kbuf: The kbuffer to free
221 * Can take NULL as a parameter.
223 void kbuffer_free(struct kbuffer *kbuf)
228 static unsigned int type4host(struct kbuffer *kbuf,
229 unsigned int type_len_ts)
231 if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
232 return (type_len_ts >> 29) & 3;
234 return type_len_ts & 3;
237 static unsigned int len4host(struct kbuffer *kbuf,
238 unsigned int type_len_ts)
240 if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
241 return (type_len_ts >> 27) & 7;
243 return (type_len_ts >> 2) & 7;
246 static unsigned int type_len4host(struct kbuffer *kbuf,
247 unsigned int type_len_ts)
249 if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
250 return (type_len_ts >> 27) & ((1 << 5) - 1);
252 return type_len_ts & ((1 << 5) - 1);
255 static unsigned int ts4host(struct kbuffer *kbuf,
256 unsigned int type_len_ts)
258 if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
259 return type_len_ts & ((1 << 27) - 1);
261 return type_len_ts >> 5;
265 * Linux 2.6.30 and earlier (not much ealier) had a different
266 * ring buffer format. It should be obsolete, but we handle it anyway.
268 enum old_ring_buffer_type {
269 OLD_RINGBUF_TYPE_PADDING,
270 OLD_RINGBUF_TYPE_TIME_EXTEND,
271 OLD_RINGBUF_TYPE_TIME_STAMP,
272 OLD_RINGBUF_TYPE_DATA,
275 static unsigned int old_update_pointers(struct kbuffer *kbuf)
277 unsigned long long extend;
278 unsigned int type_len_ts;
283 void *ptr = kbuf->data + kbuf->curr;
285 type_len_ts = read_4(kbuf, ptr);
288 type = type4host(kbuf, type_len_ts);
289 len = len4host(kbuf, type_len_ts);
290 delta = ts4host(kbuf, type_len_ts);
293 case OLD_RINGBUF_TYPE_PADDING:
294 kbuf->next = kbuf->size;
297 case OLD_RINGBUF_TYPE_TIME_EXTEND:
298 extend = read_4(kbuf, ptr);
306 case OLD_RINGBUF_TYPE_TIME_STAMP:
307 /* should never happen! */
308 kbuf->curr = kbuf->size;
309 kbuf->next = kbuf->size;
310 kbuf->index = kbuf->size;
316 length = read_4(kbuf, ptr);
323 kbuf->timestamp += delta;
324 kbuf->index = calc_index(kbuf, ptr);
325 kbuf->next = kbuf->index + length;
330 static int __old_next_event(struct kbuffer *kbuf)
335 kbuf->curr = kbuf->next;
336 if (kbuf->next >= kbuf->size)
338 type = old_update_pointers(kbuf);
339 } while (type == OLD_RINGBUF_TYPE_TIME_EXTEND || type == OLD_RINGBUF_TYPE_PADDING);
345 translate_data(struct kbuffer *kbuf, void *data, void **rptr,
346 unsigned long long *delta, int *length)
348 unsigned long long extend;
349 unsigned int type_len_ts;
350 unsigned int type_len;
352 type_len_ts = read_4(kbuf, data);
355 type_len = type_len4host(kbuf, type_len_ts);
356 *delta = ts4host(kbuf, type_len_ts);
359 case KBUFFER_TYPE_PADDING:
360 *length = read_4(kbuf, data);
363 case KBUFFER_TYPE_TIME_EXTEND:
364 case KBUFFER_TYPE_TIME_STAMP:
365 extend = read_4(kbuf, data);
374 *length = read_4(kbuf, data) - 4;
375 *length = (*length + 3) & ~3;
379 *length = type_len * 4;
388 static unsigned int update_pointers(struct kbuffer *kbuf)
390 unsigned long long delta;
391 unsigned int type_len;
393 void *ptr = kbuf->data + kbuf->curr;
395 type_len = translate_data(kbuf, ptr, &ptr, &delta, &length);
397 if (type_len == KBUFFER_TYPE_TIME_STAMP)
398 kbuf->timestamp = delta;
400 kbuf->timestamp += delta;
402 kbuf->index = calc_index(kbuf, ptr);
403 kbuf->next = kbuf->index + length;
409 * kbuffer_translate_data - read raw data to get a record
410 * @swap: Set to 1 if bytes in words need to be swapped when read
411 * @data: The raw data to read
412 * @size: Address to store the size of the event data.
414 * Returns a pointer to the event data. To determine the entire
415 * record size (record metadata + data) just add the difference between
416 * @data and the returned value to @size.
418 void *kbuffer_translate_data(int swap, void *data, unsigned int *size)
420 unsigned long long delta;
427 kbuf.read_8 = __read_8_sw;
428 kbuf.read_4 = __read_4_sw;
429 kbuf.flags = host_is_bigendian() ? 0 : KBUFFER_FL_BIG_ENDIAN;
431 kbuf.read_8 = __read_8;
432 kbuf.read_4 = __read_4;
433 kbuf.flags = host_is_bigendian() ? KBUFFER_FL_BIG_ENDIAN: 0;
436 type_len = translate_data(&kbuf, data, &ptr, &delta, &length);
438 case KBUFFER_TYPE_PADDING:
439 case KBUFFER_TYPE_TIME_EXTEND:
440 case KBUFFER_TYPE_TIME_STAMP:
449 static int __next_event(struct kbuffer *kbuf)
454 kbuf->curr = kbuf->next;
455 if (kbuf->next >= kbuf->size)
457 type = update_pointers(kbuf);
458 } while (type == KBUFFER_TYPE_TIME_EXTEND ||
459 type == KBUFFER_TYPE_TIME_STAMP ||
460 type == KBUFFER_TYPE_PADDING);
465 static int next_event(struct kbuffer *kbuf)
467 return kbuf->next_event(kbuf);
471 * kbuffer_next_event - increment the current pointer
472 * @kbuf: The kbuffer to read
473 * @ts: Address to store the next record's timestamp (may be NULL to ignore)
475 * Increments the pointers into the subbuffer of the kbuffer to point to the
476 * next event so that the next kbuffer_read_event() will return a
479 * Returns the data of the next event if a new event exists on the subbuffer,
482 void *kbuffer_next_event(struct kbuffer *kbuf, unsigned long long *ts)
486 if (!kbuf || !kbuf->subbuffer)
489 ret = next_event(kbuf);
494 *ts = kbuf->timestamp;
496 return kbuf->data + kbuf->index;
500 * kbuffer_load_subbuffer - load a new subbuffer into the kbuffer
501 * @kbuf: The kbuffer to load
502 * @subbuffer: The subbuffer to load into @kbuf.
504 * Load a new subbuffer (page) into @kbuf. This will reset all
505 * the pointers and update the @kbuf timestamp. The next read will
506 * return the first event on @subbuffer.
508 * Returns 0 on succes, -1 otherwise.
510 int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer)
512 unsigned long long flags;
513 void *ptr = subbuffer;
515 if (!kbuf || !subbuffer)
518 kbuf->subbuffer = subbuffer;
520 kbuf->timestamp = read_8(kbuf, ptr);
525 if (kbuf->flags & KBUFFER_FL_LONG_8)
530 kbuf->data = subbuffer + kbuf->start;
532 flags = read_long(kbuf, ptr);
533 kbuf->size = (unsigned int)flags & COMMIT_MASK;
535 if (flags & MISSING_EVENTS) {
536 if (flags & MISSING_STORED) {
537 ptr = kbuf->data + kbuf->size;
538 kbuf->lost_events = read_long(kbuf, ptr);
540 kbuf->lost_events = -1;
542 kbuf->lost_events = 0;
553 * kbuffer_subbuf_timestamp - read the timestamp from a sub buffer
554 * @kbuf: The kbuffer to load
555 * @subbuf: The subbuffer to read from.
557 * Return the timestamp from a subbuffer.
559 unsigned long long kbuffer_subbuf_timestamp(struct kbuffer *kbuf, void *subbuf)
561 return kbuf->read_8(subbuf);
565 * kbuffer_ptr_delta - read the delta field from a record
566 * @kbuf: The kbuffer to load
567 * @ptr: The record in the buffe.
569 * Return the timestamp delta from a record
571 unsigned int kbuffer_ptr_delta(struct kbuffer *kbuf, void *ptr)
573 unsigned int type_len_ts;
575 type_len_ts = read_4(kbuf, ptr);
576 return ts4host(kbuf, type_len_ts);
581 * kbuffer_read_event - read the next event in the kbuffer subbuffer
582 * @kbuf: The kbuffer to read from
583 * @ts: The address to store the timestamp of the event (may be NULL to ignore)
585 * Returns a pointer to the data part of the current event.
586 * NULL if no event is left on the subbuffer.
588 void *kbuffer_read_event(struct kbuffer *kbuf, unsigned long long *ts)
590 if (!kbuf || !kbuf->subbuffer)
593 if (kbuf->curr >= kbuf->size)
597 *ts = kbuf->timestamp;
598 return kbuf->data + kbuf->index;
602 * kbuffer_timestamp - Return the timestamp of the current event
603 * @kbuf: The kbuffer to read from
605 * Returns the timestamp of the current (next) event.
607 unsigned long long kbuffer_timestamp(struct kbuffer *kbuf)
609 return kbuf->timestamp;
613 * kbuffer_read_at_offset - read the event that is at offset
614 * @kbuf: The kbuffer to read from
615 * @offset: The offset into the subbuffer
616 * @ts: The address to store the timestamp of the event (may be NULL to ignore)
618 * The @offset must be an index from the @kbuf subbuffer beginning.
619 * If @offset is bigger than the stored subbuffer, NULL will be returned.
621 * Returns the data of the record that is at @offset. Note, @offset does
622 * not need to be the start of the record, the offset just needs to be
623 * in the record (or beginning of it).
625 * Note, the kbuf timestamp and pointers are updated to the
626 * returned record. That is, kbuffer_read_event() will return the same
627 * data and timestamp, and kbuffer_next_event() will increment from
630 void *kbuffer_read_at_offset(struct kbuffer *kbuf, int offset,
631 unsigned long long *ts)
635 if (offset < kbuf->start)
638 offset -= kbuf->start;
640 /* Reset the buffer */
641 kbuffer_load_subbuffer(kbuf, kbuf->subbuffer);
642 data = kbuffer_read_event(kbuf, ts);
644 while (kbuf->curr < offset) {
645 data = kbuffer_next_event(kbuf, ts);
654 * kbuffer_subbuffer_size - the size of the loaded subbuffer
655 * @kbuf: The kbuffer to read from
657 * Returns the size of the subbuffer. Note, this size is
658 * where the last event resides. The stored subbuffer may actually be
659 * bigger due to padding and such.
661 int kbuffer_subbuffer_size(struct kbuffer *kbuf)
667 * kbuffer_curr_index - Return the index of the record
668 * @kbuf: The kbuffer to read from
670 * Returns the index from the start of the data part of
671 * the subbuffer to the current location. Note this is not
672 * from the start of the subbuffer. An index of zero will
673 * point to the first record. Use kbuffer_curr_offset() for
674 * the actually offset (that can be used by kbuffer_read_at_offset())
676 int kbuffer_curr_index(struct kbuffer *kbuf)
682 * kbuffer_curr_offset - Return the offset of the record
683 * @kbuf: The kbuffer to read from
685 * Returns the offset from the start of the subbuffer to the
688 int kbuffer_curr_offset(struct kbuffer *kbuf)
690 return kbuf->curr + kbuf->start;
694 * kbuffer_event_size - return the size of the event data
695 * @kbuf: The kbuffer to read
697 * Returns the size of the event data (the payload not counting
698 * the meta data of the record) of the current event.
700 int kbuffer_event_size(struct kbuffer *kbuf)
702 return kbuf->next - kbuf->index;
706 * kbuffer_curr_size - return the size of the entire record
707 * @kbuf: The kbuffer to read
709 * Returns the size of the entire record (meta data and payload)
710 * of the current event.
712 int kbuffer_curr_size(struct kbuffer *kbuf)
714 return kbuf->next - kbuf->curr;
718 * kbuffer_missed_events - return the # of missed events from last event.
719 * @kbuf: The kbuffer to read from
721 * Returns the # of missed events (if recorded) before the current
722 * event. Note, only events on the beginning of a subbuffer can
723 * have missed events, all other events within the buffer will be
726 int kbuffer_missed_events(struct kbuffer *kbuf)
728 /* Only the first event can have missed events */
732 return kbuf->lost_events;
736 * kbuffer_set_old_forma - set the kbuffer to use the old format parsing
737 * @kbuf: The kbuffer to set
739 * This is obsolete (or should be). The first kernels to use the
740 * new ring buffer had a slightly different ring buffer format
741 * (2.6.30 and earlier). It is still somewhat supported by kbuffer,
742 * but should not be counted on in the future.
744 void kbuffer_set_old_format(struct kbuffer *kbuf)
746 kbuf->flags |= KBUFFER_FL_OLD_FORMAT;
748 kbuf->next_event = __old_next_event;
752 * kbuffer_start_of_data - return offset of where data starts on subbuffer
755 * Returns the location on the subbuffer where the data starts.
757 int kbuffer_start_of_data(struct kbuffer *kbuf)
763 * kbuffer_raw_get - get raw buffer info
765 * @subbuf: Start of mapped subbuffer
766 * @info: Info descriptor to fill in
768 * For debugging. This can return internals of the ring buffer.
769 * Expects to have info->next set to what it will read.
770 * The type, length and timestamp delta will be filled in, and
771 * @info->next will be updated to the next element.
772 * The @subbuf is used to know if the info is passed the end of
773 * data and NULL will be returned if it is.
775 struct kbuffer_raw_info *
776 kbuffer_raw_get(struct kbuffer *kbuf, void *subbuf, struct kbuffer_raw_info *info)
778 unsigned long long flags;
779 unsigned long long delta;
780 unsigned int type_len;
784 void *ptr = info->next;
786 if (!kbuf || !subbuf)
789 if (kbuf->flags & KBUFFER_FL_LONG_8)
794 flags = read_long(kbuf, subbuf + 8);
795 size = (unsigned int)flags & COMMIT_MASK;
797 if (ptr < subbuf || ptr >= subbuf + start + size)
800 type_len = translate_data(kbuf, ptr, &ptr, &delta, &length);
802 info->next = ptr + length;
804 info->type = type_len;
806 info->length = length;