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 extend
= read_4(kbuf
, data
);
372 case KBUFFER_TYPE_TIME_STAMP
:
377 *length
= read_4(kbuf
, data
) - 4;
378 *length
= (*length
+ 3) & ~3;
382 *length
= type_len
* 4;
391 static unsigned int update_pointers(struct kbuffer
*kbuf
)
393 unsigned long long delta
;
394 unsigned int type_len
;
396 void *ptr
= kbuf
->data
+ kbuf
->curr
;
398 type_len
= translate_data(kbuf
, ptr
, &ptr
, &delta
, &length
);
400 kbuf
->timestamp
+= delta
;
401 kbuf
->index
= calc_index(kbuf
, ptr
);
402 kbuf
->next
= kbuf
->index
+ length
;
408 * kbuffer_translate_data - read raw data to get a record
409 * @swap: Set to 1 if bytes in words need to be swapped when read
410 * @data: The raw data to read
411 * @size: Address to store the size of the event data.
413 * Returns a pointer to the event data. To determine the entire
414 * record size (record metadata + data) just add the difference between
415 * @data and the returned value to @size.
417 void *kbuffer_translate_data(int swap
, void *data
, unsigned int *size
)
419 unsigned long long delta
;
426 kbuf
.read_8
= __read_8_sw
;
427 kbuf
.read_4
= __read_4_sw
;
428 kbuf
.flags
= host_is_bigendian() ? 0 : KBUFFER_FL_BIG_ENDIAN
;
430 kbuf
.read_8
= __read_8
;
431 kbuf
.read_4
= __read_4
;
432 kbuf
.flags
= host_is_bigendian() ? KBUFFER_FL_BIG_ENDIAN
: 0;
435 type_len
= translate_data(&kbuf
, data
, &ptr
, &delta
, &length
);
437 case KBUFFER_TYPE_PADDING
:
438 case KBUFFER_TYPE_TIME_EXTEND
:
439 case KBUFFER_TYPE_TIME_STAMP
:
448 static int __next_event(struct kbuffer
*kbuf
)
453 kbuf
->curr
= kbuf
->next
;
454 if (kbuf
->next
>= kbuf
->size
)
456 type
= update_pointers(kbuf
);
457 } while (type
== KBUFFER_TYPE_TIME_EXTEND
|| type
== KBUFFER_TYPE_PADDING
);
462 static int next_event(struct kbuffer
*kbuf
)
464 return kbuf
->next_event(kbuf
);
468 * kbuffer_next_event - increment the current pointer
469 * @kbuf: The kbuffer to read
470 * @ts: Address to store the next record's timestamp (may be NULL to ignore)
472 * Increments the pointers into the subbuffer of the kbuffer to point to the
473 * next event so that the next kbuffer_read_event() will return a
476 * Returns the data of the next event if a new event exists on the subbuffer,
479 void *kbuffer_next_event(struct kbuffer
*kbuf
, unsigned long long *ts
)
483 if (!kbuf
|| !kbuf
->subbuffer
)
486 ret
= next_event(kbuf
);
491 *ts
= kbuf
->timestamp
;
493 return kbuf
->data
+ kbuf
->index
;
497 * kbuffer_load_subbuffer - load a new subbuffer into the kbuffer
498 * @kbuf: The kbuffer to load
499 * @subbuffer: The subbuffer to load into @kbuf.
501 * Load a new subbuffer (page) into @kbuf. This will reset all
502 * the pointers and update the @kbuf timestamp. The next read will
503 * return the first event on @subbuffer.
505 * Returns 0 on succes, -1 otherwise.
507 int kbuffer_load_subbuffer(struct kbuffer
*kbuf
, void *subbuffer
)
509 unsigned long long flags
;
510 void *ptr
= subbuffer
;
512 if (!kbuf
|| !subbuffer
)
515 kbuf
->subbuffer
= subbuffer
;
517 kbuf
->timestamp
= read_8(kbuf
, ptr
);
522 if (kbuf
->flags
& KBUFFER_FL_LONG_8
)
527 kbuf
->data
= subbuffer
+ kbuf
->start
;
529 flags
= read_long(kbuf
, ptr
);
530 kbuf
->size
= (unsigned int)flags
& COMMIT_MASK
;
532 if (flags
& MISSING_EVENTS
) {
533 if (flags
& MISSING_STORED
) {
534 ptr
= kbuf
->data
+ kbuf
->size
;
535 kbuf
->lost_events
= read_long(kbuf
, ptr
);
537 kbuf
->lost_events
= -1;
539 kbuf
->lost_events
= 0;
550 * kbuffer_read_event - read the next event in the kbuffer subbuffer
551 * @kbuf: The kbuffer to read from
552 * @ts: The address to store the timestamp of the event (may be NULL to ignore)
554 * Returns a pointer to the data part of the current event.
555 * NULL if no event is left on the subbuffer.
557 void *kbuffer_read_event(struct kbuffer
*kbuf
, unsigned long long *ts
)
559 if (!kbuf
|| !kbuf
->subbuffer
)
562 if (kbuf
->curr
>= kbuf
->size
)
566 *ts
= kbuf
->timestamp
;
567 return kbuf
->data
+ kbuf
->index
;
571 * kbuffer_timestamp - Return the timestamp of the current event
572 * @kbuf: The kbuffer to read from
574 * Returns the timestamp of the current (next) event.
576 unsigned long long kbuffer_timestamp(struct kbuffer
*kbuf
)
578 return kbuf
->timestamp
;
582 * kbuffer_read_at_offset - read the event that is at offset
583 * @kbuf: The kbuffer to read from
584 * @offset: The offset into the subbuffer
585 * @ts: The address to store the timestamp of the event (may be NULL to ignore)
587 * The @offset must be an index from the @kbuf subbuffer beginning.
588 * If @offset is bigger than the stored subbuffer, NULL will be returned.
590 * Returns the data of the record that is at @offset. Note, @offset does
591 * not need to be the start of the record, the offset just needs to be
592 * in the record (or beginning of it).
594 * Note, the kbuf timestamp and pointers are updated to the
595 * returned record. That is, kbuffer_read_event() will return the same
596 * data and timestamp, and kbuffer_next_event() will increment from
599 void *kbuffer_read_at_offset(struct kbuffer
*kbuf
, int offset
,
600 unsigned long long *ts
)
604 if (offset
< kbuf
->start
)
607 offset
-= kbuf
->start
;
609 /* Reset the buffer */
610 kbuffer_load_subbuffer(kbuf
, kbuf
->subbuffer
);
611 data
= kbuffer_read_event(kbuf
, ts
);
613 while (kbuf
->curr
< offset
) {
614 data
= kbuffer_next_event(kbuf
, ts
);
623 * kbuffer_subbuffer_size - the size of the loaded subbuffer
624 * @kbuf: The kbuffer to read from
626 * Returns the size of the subbuffer. Note, this size is
627 * where the last event resides. The stored subbuffer may actually be
628 * bigger due to padding and such.
630 int kbuffer_subbuffer_size(struct kbuffer
*kbuf
)
636 * kbuffer_curr_index - Return the index of the record
637 * @kbuf: The kbuffer to read from
639 * Returns the index from the start of the data part of
640 * the subbuffer to the current location. Note this is not
641 * from the start of the subbuffer. An index of zero will
642 * point to the first record. Use kbuffer_curr_offset() for
643 * the actually offset (that can be used by kbuffer_read_at_offset())
645 int kbuffer_curr_index(struct kbuffer
*kbuf
)
651 * kbuffer_curr_offset - Return the offset of the record
652 * @kbuf: The kbuffer to read from
654 * Returns the offset from the start of the subbuffer to the
657 int kbuffer_curr_offset(struct kbuffer
*kbuf
)
659 return kbuf
->curr
+ kbuf
->start
;
663 * kbuffer_event_size - return the size of the event data
664 * @kbuf: The kbuffer to read
666 * Returns the size of the event data (the payload not counting
667 * the meta data of the record) of the current event.
669 int kbuffer_event_size(struct kbuffer
*kbuf
)
671 return kbuf
->next
- kbuf
->index
;
675 * kbuffer_curr_size - return the size of the entire record
676 * @kbuf: The kbuffer to read
678 * Returns the size of the entire record (meta data and payload)
679 * of the current event.
681 int kbuffer_curr_size(struct kbuffer
*kbuf
)
683 return kbuf
->next
- kbuf
->curr
;
687 * kbuffer_missed_events - return the # of missed events from last event.
688 * @kbuf: The kbuffer to read from
690 * Returns the # of missed events (if recorded) before the current
691 * event. Note, only events on the beginning of a subbuffer can
692 * have missed events, all other events within the buffer will be
695 int kbuffer_missed_events(struct kbuffer
*kbuf
)
697 /* Only the first event can have missed events */
701 return kbuf
->lost_events
;
705 * kbuffer_set_old_forma - set the kbuffer to use the old format parsing
706 * @kbuf: The kbuffer to set
708 * This is obsolete (or should be). The first kernels to use the
709 * new ring buffer had a slightly different ring buffer format
710 * (2.6.30 and earlier). It is still somewhat supported by kbuffer,
711 * but should not be counted on in the future.
713 void kbuffer_set_old_format(struct kbuffer
*kbuf
)
715 kbuf
->flags
|= KBUFFER_FL_OLD_FORMAT
;
717 kbuf
->next_event
= __old_next_event
;
721 * kbuffer_start_of_data - return offset of where data starts on subbuffer
724 * Returns the location on the subbuffer where the data starts.
726 int kbuffer_start_of_data(struct kbuffer
*kbuf
)