• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3  * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
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 
__read_8(void * ptr)89 static unsigned long long __read_8(void *ptr)
90 {
91 	unsigned long long data = *(unsigned long long *)ptr;
92 
93 	return data;
94 }
95 
__read_8_sw(void * ptr)96 static unsigned long long __read_8_sw(void *ptr)
97 {
98 	unsigned long long data = *(unsigned long long *)ptr;
99 	unsigned long long swap;
100 
101 	swap = ((data & 0xffULL) << 56) |
102 		((data & (0xffULL << 8)) << 40) |
103 		((data & (0xffULL << 16)) << 24) |
104 		((data & (0xffULL << 24)) << 8) |
105 		((data & (0xffULL << 32)) >> 8) |
106 		((data & (0xffULL << 40)) >> 24) |
107 		((data & (0xffULL << 48)) >> 40) |
108 		((data & (0xffULL << 56)) >> 56);
109 
110 	return swap;
111 }
112 
__read_4(void * ptr)113 static unsigned int __read_4(void *ptr)
114 {
115 	unsigned int data = *(unsigned int *)ptr;
116 
117 	return data;
118 }
119 
__read_4_sw(void * ptr)120 static unsigned int __read_4_sw(void *ptr)
121 {
122 	unsigned int data = *(unsigned int *)ptr;
123 	unsigned int swap;
124 
125 	swap = ((data & 0xffULL) << 24) |
126 		((data & (0xffULL << 8)) << 8) |
127 		((data & (0xffULL << 16)) >> 8) |
128 		((data & (0xffULL << 24)) >> 24);
129 
130 	return swap;
131 }
132 
read_8(struct kbuffer * kbuf,void * ptr)133 static unsigned long long read_8(struct kbuffer *kbuf, void *ptr)
134 {
135 	return kbuf->read_8(ptr);
136 }
137 
read_4(struct kbuffer * kbuf,void * ptr)138 static unsigned int read_4(struct kbuffer *kbuf, void *ptr)
139 {
140 	return kbuf->read_4(ptr);
141 }
142 
__read_long_8(struct kbuffer * kbuf,void * ptr)143 static unsigned long long __read_long_8(struct kbuffer *kbuf, void *ptr)
144 {
145 	return kbuf->read_8(ptr);
146 }
147 
__read_long_4(struct kbuffer * kbuf,void * ptr)148 static unsigned long long __read_long_4(struct kbuffer *kbuf, void *ptr)
149 {
150 	return kbuf->read_4(ptr);
151 }
152 
read_long(struct kbuffer * kbuf,void * ptr)153 static unsigned long long read_long(struct kbuffer *kbuf, void *ptr)
154 {
155 	return kbuf->read_long(kbuf, ptr);
156 }
157 
calc_index(struct kbuffer * kbuf,void * ptr)158 static int calc_index(struct kbuffer *kbuf, void *ptr)
159 {
160 	return (unsigned long)ptr - (unsigned long)kbuf->data;
161 }
162 
163 static int __next_event(struct kbuffer *kbuf);
164 
165 /*
166  * Just because sizeof(long) is 4 bytes, doesn't mean the OS isn't
167  * 64bits
168  */
host_is_32bit(void)169 static bool host_is_32bit(void)
170 {
171 	struct utsname buf;
172 	int ret;
173 
174 	ret = uname(&buf);
175 	if (ret < 0) {
176 		/* Oh well, just assume it is 32 bit */
177 		return true;
178 	}
179 	/* If the uname machine value contains 64, assume the kernel is 64 bit */
180 	return strstr(buf.machine, "64") == NULL;
181 }
182 
183 /**
184  * kbuffer_alloc - allocat a new kbuffer
185  * @size;	enum to denote size of word
186  * @endian:	enum to denote endianness
187  *
188  * Allocates and returns a new kbuffer.
189  */
190 struct kbuffer *
kbuffer_alloc(enum kbuffer_long_size size,enum kbuffer_endian endian)191 kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian)
192 {
193 	struct kbuffer *kbuf;
194 	int flags = 0;
195 
196 	switch (size) {
197 	case KBUFFER_LSIZE_4:
198 		break;
199 	case KBUFFER_LSIZE_SAME_AS_HOST:
200 		if (sizeof(long) != 8 && host_is_32bit())
201 			break;
202 		/* fallthrough */
203 	case KBUFFER_LSIZE_8:
204 		flags |= KBUFFER_FL_LONG_8;
205 		break;
206 	default:
207 		return NULL;
208 	}
209 
210 	switch (endian) {
211 	case KBUFFER_ENDIAN_LITTLE:
212 	case KBUFFER_ENDIAN_SAME_AS_HOST:
213 		break;
214 	case KBUFFER_ENDIAN_BIG:
215 		flags |= KBUFFER_FL_BIG_ENDIAN;
216 		break;
217 	default:
218 		return NULL;
219 	}
220 
221 	kbuf = zmalloc(sizeof(*kbuf));
222 	if (!kbuf)
223 		return NULL;
224 
225 	kbuf->flags = flags;
226 
227 	if (host_is_bigendian()) {
228 		if (endian == KBUFFER_ENDIAN_SAME_AS_HOST)
229 			flags |= KBUFFER_FL_BIG_ENDIAN;
230 		kbuf->flags |= KBUFFER_FL_HOST_BIG_ENDIAN;
231 	}
232 
233 	if (do_swap(kbuf)) {
234 		kbuf->read_8 = __read_8_sw;
235 		kbuf->read_4 = __read_4_sw;
236 	} else {
237 		kbuf->read_8 = __read_8;
238 		kbuf->read_4 = __read_4;
239 	}
240 
241 	if (kbuf->flags & KBUFFER_FL_LONG_8)
242 		kbuf->read_long = __read_long_8;
243 	else
244 		kbuf->read_long = __read_long_4;
245 
246 	/* May be changed by kbuffer_set_old_format() */
247 	kbuf->next_event = __next_event;
248 
249 	return kbuf;
250 }
251 
252 /** kbuffer_free - free an allocated kbuffer
253  * @kbuf:	The kbuffer to free
254  *
255  * Can take NULL as a parameter.
256  */
kbuffer_free(struct kbuffer * kbuf)257 void kbuffer_free(struct kbuffer *kbuf)
258 {
259 	free(kbuf);
260 }
261 
type4host(struct kbuffer * kbuf,unsigned int type_len_ts)262 static unsigned int type4host(struct kbuffer *kbuf,
263 			      unsigned int type_len_ts)
264 {
265 	if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
266 		return (type_len_ts >> 29) & 3;
267 	else
268 		return type_len_ts & 3;
269 }
270 
len4host(struct kbuffer * kbuf,unsigned int type_len_ts)271 static unsigned int len4host(struct kbuffer *kbuf,
272 			     unsigned int type_len_ts)
273 {
274 	if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
275 		return (type_len_ts >> 27) & 7;
276 	else
277 		return (type_len_ts >> 2) & 7;
278 }
279 
type_len4host(struct kbuffer * kbuf,unsigned int type_len_ts)280 static unsigned int type_len4host(struct kbuffer *kbuf,
281 				  unsigned int type_len_ts)
282 {
283 	if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
284 		return (type_len_ts >> 27) & ((1 << 5) - 1);
285 	else
286 		return type_len_ts & ((1 << 5) - 1);
287 }
288 
ts4host(struct kbuffer * kbuf,unsigned int type_len_ts)289 static unsigned int ts4host(struct kbuffer *kbuf,
290 			    unsigned int type_len_ts)
291 {
292 	if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
293 		return type_len_ts & ((1 << 27) - 1);
294 	else
295 		return type_len_ts >> 5;
296 }
297 
298 /*
299  * Linux 2.6.30 and earlier (not much ealier) had a different
300  * ring buffer format. It should be obsolete, but we handle it anyway.
301  */
302 enum old_ring_buffer_type {
303 	OLD_RINGBUF_TYPE_PADDING,
304 	OLD_RINGBUF_TYPE_TIME_EXTEND,
305 	OLD_RINGBUF_TYPE_TIME_STAMP,
306 	OLD_RINGBUF_TYPE_DATA,
307 };
308 
old_update_pointers(struct kbuffer * kbuf)309 static unsigned int old_update_pointers(struct kbuffer *kbuf)
310 {
311 	unsigned long long extend;
312 	unsigned int type_len_ts;
313 	unsigned int type;
314 	unsigned int len;
315 	unsigned int delta;
316 	unsigned int length;
317 	void *ptr = kbuf->data + kbuf->curr;
318 
319 	type_len_ts = read_4(kbuf, ptr);
320 	ptr += 4;
321 
322 	type = type4host(kbuf, type_len_ts);
323 	len = len4host(kbuf, type_len_ts);
324 	delta = ts4host(kbuf, type_len_ts);
325 
326 	switch (type) {
327 	case OLD_RINGBUF_TYPE_PADDING:
328 		kbuf->next = kbuf->size;
329 		return 0;
330 
331 	case OLD_RINGBUF_TYPE_TIME_EXTEND:
332 		extend = read_4(kbuf, ptr);
333 		extend <<= TS_SHIFT;
334 		extend += delta;
335 		delta = extend;
336 		ptr += 4;
337 		length = 0;
338 		break;
339 
340 	case OLD_RINGBUF_TYPE_TIME_STAMP:
341 		/* should never happen! */
342 		kbuf->curr = kbuf->size;
343 		kbuf->next = kbuf->size;
344 		kbuf->index = kbuf->size;
345 		return -1;
346 	default:
347 		if (len)
348 			length = len * 4;
349 		else {
350 			length = read_4(kbuf, ptr);
351 			length -= 4;
352 			ptr += 4;
353 		}
354 		break;
355 	}
356 
357 	kbuf->timestamp += delta;
358 	kbuf->index = calc_index(kbuf, ptr);
359 	kbuf->next = kbuf->index + length;
360 
361 	return type;
362 }
363 
__old_next_event(struct kbuffer * kbuf)364 static int __old_next_event(struct kbuffer *kbuf)
365 {
366 	int type;
367 
368 	do {
369 		kbuf->curr = kbuf->next;
370 		if (kbuf->next >= kbuf->size)
371 			return -1;
372 		type = old_update_pointers(kbuf);
373 	} while (type == OLD_RINGBUF_TYPE_TIME_EXTEND || type == OLD_RINGBUF_TYPE_PADDING);
374 
375 	return 0;
376 }
377 
378 static unsigned int
translate_data(struct kbuffer * kbuf,void * data,void ** rptr,unsigned long long * delta,int * length)379 translate_data(struct kbuffer *kbuf, void *data, void **rptr,
380 	       unsigned long long *delta, int *length)
381 {
382 	unsigned long long extend, msb = 0;
383 	unsigned int type_len_ts;
384 	unsigned int type_len;
385 
386 	type_len_ts = read_4(kbuf, data);
387 	data += 4;
388 
389 	type_len = type_len4host(kbuf, type_len_ts);
390 	*delta = ts4host(kbuf, type_len_ts);
391 
392 	switch (type_len) {
393 	case KBUFFER_TYPE_PADDING:
394 		*length = read_4(kbuf, data);
395 		break;
396 
397 	case KBUFFER_TYPE_TIME_STAMP:
398 		msb = kbuf->timestamp & TS_MSB;
399 		/* fall through */
400 	case KBUFFER_TYPE_TIME_EXTEND:
401 		extend = read_4(kbuf, data);
402 		data += 4;
403 		extend <<= TS_SHIFT;
404 		extend += *delta;
405 		*delta = extend | msb;
406 		*length = 0;
407 		break;
408 
409 	case 0:
410 		*length = read_4(kbuf, data) - 4;
411 		*length = (*length + 3) & ~3;
412 		data += 4;
413 		break;
414 	default:
415 		*length = type_len * 4;
416 		break;
417 	}
418 
419 	*rptr = data;
420 
421 	return type_len;
422 }
423 
update_pointers(struct kbuffer * kbuf)424 static unsigned int update_pointers(struct kbuffer *kbuf)
425 {
426 	unsigned long long delta;
427 	unsigned int type_len;
428 	int length;
429 	void *ptr = kbuf->data + kbuf->curr;
430 
431 	type_len = translate_data(kbuf, ptr, &ptr, &delta, &length);
432 
433 	if (type_len == KBUFFER_TYPE_TIME_STAMP)
434 		kbuf->timestamp = delta;
435 	else
436 		kbuf->timestamp += delta;
437 
438 	kbuf->index = calc_index(kbuf, ptr);
439 	kbuf->next = kbuf->index + length;
440 
441 	return type_len;
442 }
443 
444 /**
445  * kbuffer_translate_data - read raw data to get a record
446  * @swap:	Set to 1 if bytes in words need to be swapped when read
447  * @data:	The raw data to read
448  * @size:	Address to store the size of the event data.
449  *
450  * Returns a pointer to the event data. To determine the entire
451  * record size (record metadata + data) just add the difference between
452  * @data and the returned value to @size.
453  */
kbuffer_translate_data(int swap,void * data,unsigned int * size)454 void *kbuffer_translate_data(int swap, void *data, unsigned int *size)
455 {
456 	unsigned long long delta;
457 	struct kbuffer kbuf;
458 	int type_len;
459 	int length;
460 	void *ptr;
461 
462 	if (swap) {
463 		kbuf.read_8 = __read_8_sw;
464 		kbuf.read_4 = __read_4_sw;
465 		kbuf.flags = host_is_bigendian() ? 0 : KBUFFER_FL_BIG_ENDIAN;
466 	} else {
467 		kbuf.read_8 = __read_8;
468 		kbuf.read_4 = __read_4;
469 		kbuf.flags = host_is_bigendian() ? KBUFFER_FL_BIG_ENDIAN: 0;
470 	}
471 
472 	type_len = translate_data(&kbuf, data, &ptr, &delta, &length);
473 	switch (type_len) {
474 	case KBUFFER_TYPE_PADDING:
475 	case KBUFFER_TYPE_TIME_EXTEND:
476 	case KBUFFER_TYPE_TIME_STAMP:
477 		return NULL;
478 	}
479 
480 	*size = length;
481 
482 	return ptr;
483 }
484 
__next_event(struct kbuffer * kbuf)485 static int __next_event(struct kbuffer *kbuf)
486 {
487 	int type;
488 
489 	do {
490 		kbuf->curr = kbuf->next;
491 		if (kbuf->next >= kbuf->size)
492 			return -1;
493 		type = update_pointers(kbuf);
494 	} while (type == KBUFFER_TYPE_TIME_EXTEND ||
495 		 type == KBUFFER_TYPE_TIME_STAMP ||
496 		 type == KBUFFER_TYPE_PADDING);
497 
498 	return 0;
499 }
500 
next_event(struct kbuffer * kbuf)501 static int next_event(struct kbuffer *kbuf)
502 {
503 	return kbuf->next_event(kbuf);
504 }
505 
506 /**
507  * kbuffer_next_event - increment the current pointer
508  * @kbuf:	The kbuffer to read
509  * @ts:		Address to store the next record's timestamp (may be NULL to ignore)
510  *
511  * Increments the pointers into the subbuffer of the kbuffer to point to the
512  * next event so that the next kbuffer_read_event() will return a
513  * new event.
514  *
515  * Returns the data of the next event if a new event exists on the subbuffer,
516  * NULL otherwise.
517  */
kbuffer_next_event(struct kbuffer * kbuf,unsigned long long * ts)518 void *kbuffer_next_event(struct kbuffer *kbuf, unsigned long long *ts)
519 {
520 	int ret;
521 
522 	if (!kbuf || !kbuf->subbuffer)
523 		return NULL;
524 
525 	ret = next_event(kbuf);
526 	if (ret < 0)
527 		return NULL;
528 
529 	if (ts)
530 		*ts = kbuf->timestamp;
531 
532 	return kbuf->data + kbuf->index;
533 }
534 
535 /**
536  * kbuffer_load_subbuffer - load a new subbuffer into the kbuffer
537  * @kbuf:	The kbuffer to load
538  * @subbuffer:	The subbuffer to load into @kbuf.
539  *
540  * Load a new subbuffer (page) into @kbuf. This will reset all
541  * the pointers and update the @kbuf timestamp. The next read will
542  * return the first event on @subbuffer.
543  *
544  * Returns 0 on succes, -1 otherwise.
545  */
kbuffer_load_subbuffer(struct kbuffer * kbuf,void * subbuffer)546 int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer)
547 {
548 	unsigned long long flags;
549 	void *ptr = subbuffer;
550 
551 	if (!kbuf || !subbuffer)
552 		return -1;
553 
554 	kbuf->subbuffer = subbuffer;
555 
556 	kbuf->timestamp = read_8(kbuf, ptr);
557 	ptr += 8;
558 
559 	kbuf->curr = 0;
560 
561 	if (kbuf->flags & KBUFFER_FL_LONG_8)
562 		kbuf->start = 16;
563 	else
564 		kbuf->start = 12;
565 
566 	kbuf->data = subbuffer + kbuf->start;
567 
568 	flags = read_long(kbuf, ptr);
569 	kbuf->size = (unsigned int)flags & COMMIT_MASK;
570 
571 	if (flags & MISSING_EVENTS) {
572 		if (flags & MISSING_STORED) {
573 			ptr = kbuf->data + kbuf->size;
574 			kbuf->lost_events = read_long(kbuf, ptr);
575 		} else
576 			kbuf->lost_events = -1;
577 	} else
578 		kbuf->lost_events = 0;
579 
580 	kbuf->index = 0;
581 	kbuf->next = 0;
582 
583 	next_event(kbuf);
584 
585 	/* save the first record from the page */
586 	kbuf->first = kbuf->curr;
587 
588 	return 0;
589 }
590 
591 /**
592  * kbuffer_subbuf_timestamp - read the timestamp from a sub buffer
593  * @kbuf:      The kbuffer to load
594  * @subbuf:    The subbuffer to read from.
595  *
596  * Return the timestamp from a subbuffer.
597  */
kbuffer_subbuf_timestamp(struct kbuffer * kbuf,void * subbuf)598 unsigned long long kbuffer_subbuf_timestamp(struct kbuffer *kbuf, void *subbuf)
599 {
600 	return kbuf->read_8(subbuf);
601 }
602 
603 /**
604  * kbuffer_ptr_delta - read the delta field from a record
605  * @kbuf:      The kbuffer to load
606  * @ptr:       The record in the buffe.
607  *
608  * Return the timestamp delta from a record
609  */
kbuffer_ptr_delta(struct kbuffer * kbuf,void * ptr)610 unsigned int kbuffer_ptr_delta(struct kbuffer *kbuf, void *ptr)
611 {
612 	unsigned int type_len_ts;
613 
614 	type_len_ts = read_4(kbuf, ptr);
615 	return ts4host(kbuf, type_len_ts);
616 }
617 
618 
619 /**
620  * kbuffer_read_event - read the next event in the kbuffer subbuffer
621  * @kbuf:	The kbuffer to read from
622  * @ts:		The address to store the timestamp of the event (may be NULL to ignore)
623  *
624  * Returns a pointer to the data part of the current event.
625  * NULL if no event is left on the subbuffer.
626  */
kbuffer_read_event(struct kbuffer * kbuf,unsigned long long * ts)627 void *kbuffer_read_event(struct kbuffer *kbuf, unsigned long long *ts)
628 {
629 	if (!kbuf || !kbuf->subbuffer)
630 		return NULL;
631 
632 	if (kbuf->curr >= kbuf->size)
633 		return NULL;
634 
635 	if (ts)
636 		*ts = kbuf->timestamp;
637 	return kbuf->data + kbuf->index;
638 }
639 
640 /**
641  * kbuffer_timestamp - Return the timestamp of the current event
642  * @kbuf:	The kbuffer to read from
643  *
644  * Returns the timestamp of the current (next) event.
645  */
kbuffer_timestamp(struct kbuffer * kbuf)646 unsigned long long kbuffer_timestamp(struct kbuffer *kbuf)
647 {
648 	return kbuf->timestamp;
649 }
650 
651 /**
652  * kbuffer_read_at_offset - read the event that is at offset
653  * @kbuf:	The kbuffer to read from
654  * @offset:	The offset into the subbuffer
655  * @ts:		The address to store the timestamp of the event (may be NULL to ignore)
656  *
657  * The @offset must be an index from the @kbuf subbuffer beginning.
658  * If @offset is bigger than the stored subbuffer, NULL will be returned.
659  *
660  * Returns the data of the record that is at @offset. Note, @offset does
661  * not need to be the start of the record, the offset just needs to be
662  * in the record (or beginning of it).
663  *
664  * Note, the kbuf timestamp and pointers are updated to the
665  * returned record. That is, kbuffer_read_event() will return the same
666  * data and timestamp, and kbuffer_next_event() will increment from
667  * this record.
668  */
kbuffer_read_at_offset(struct kbuffer * kbuf,int offset,unsigned long long * ts)669 void *kbuffer_read_at_offset(struct kbuffer *kbuf, int offset,
670 			     unsigned long long *ts)
671 {
672 	void *data;
673 
674 	if (offset < kbuf->start)
675 		offset = 0;
676 	else
677 		offset -= kbuf->start;
678 
679 	/* Reset the buffer */
680 	kbuffer_load_subbuffer(kbuf, kbuf->subbuffer);
681 	data = kbuffer_read_event(kbuf, ts);
682 
683 	while (kbuf->curr < offset) {
684 		data = kbuffer_next_event(kbuf, ts);
685 		if (!data)
686 			break;
687 	}
688 
689 	return data;
690 }
691 
692 /**
693  * kbuffer_subbuffer_size - the size of the loaded subbuffer
694  * @kbuf:	The kbuffer to read from
695  *
696  * Returns the size of the subbuffer. Note, this size is
697  * where the last event resides. The stored subbuffer may actually be
698  * bigger due to padding and such.
699  */
kbuffer_subbuffer_size(struct kbuffer * kbuf)700 int kbuffer_subbuffer_size(struct kbuffer *kbuf)
701 {
702 	return kbuf->size;
703 }
704 
705 /**
706  * kbuffer_curr_index - Return the index of the record
707  * @kbuf:	The kbuffer to read from
708  *
709  * Returns the index from the start of the data part of
710  * the subbuffer to the current location. Note this is not
711  * from the start of the subbuffer. An index of zero will
712  * point to the first record. Use kbuffer_curr_offset() for
713  * the actually offset (that can be used by kbuffer_read_at_offset())
714  */
kbuffer_curr_index(struct kbuffer * kbuf)715 int kbuffer_curr_index(struct kbuffer *kbuf)
716 {
717 	return kbuf->curr;
718 }
719 
720 /**
721  * kbuffer_curr_offset - Return the offset of the record
722  * @kbuf:	The kbuffer to read from
723  *
724  * Returns the offset from the start of the subbuffer to the
725  * current location.
726  */
kbuffer_curr_offset(struct kbuffer * kbuf)727 int kbuffer_curr_offset(struct kbuffer *kbuf)
728 {
729 	return kbuf->curr + kbuf->start;
730 }
731 
732 /**
733  * kbuffer_event_size - return the size of the event data
734  * @kbuf:	The kbuffer to read
735  *
736  * Returns the size of the event data (the payload not counting
737  * the meta data of the record) of the current event.
738  */
kbuffer_event_size(struct kbuffer * kbuf)739 int kbuffer_event_size(struct kbuffer *kbuf)
740 {
741 	return kbuf->next - kbuf->index;
742 }
743 
744 /**
745  * kbuffer_curr_size - return the size of the entire record
746  * @kbuf:	The kbuffer to read
747  *
748  * Returns the size of the entire record (meta data and payload)
749  * of the current event.
750  */
kbuffer_curr_size(struct kbuffer * kbuf)751 int kbuffer_curr_size(struct kbuffer *kbuf)
752 {
753 	return kbuf->next - kbuf->curr;
754 }
755 
756 /**
757  * kbuffer_missed_events - return the # of missed events from last event.
758  * @kbuf: 	The kbuffer to read from
759  *
760  * Returns the # of missed events (if recorded) before the current
761  * event. Note, only events on the beginning of a subbuffer can
762  * have missed events, all other events within the buffer will be
763  * zero.
764  */
kbuffer_missed_events(struct kbuffer * kbuf)765 int kbuffer_missed_events(struct kbuffer *kbuf)
766 {
767 	/* Only the first event can have missed events */
768 	if (kbuf->curr)
769 		return 0;
770 
771 	return kbuf->lost_events;
772 }
773 
774 /**
775  * kbuffer_set_old_forma - set the kbuffer to use the old format parsing
776  * @kbuf:	The kbuffer to set
777  *
778  * This is obsolete (or should be). The first kernels to use the
779  * new ring buffer had a slightly different ring buffer format
780  * (2.6.30 and earlier). It is still somewhat supported by kbuffer,
781  * but should not be counted on in the future.
782  */
kbuffer_set_old_format(struct kbuffer * kbuf)783 void kbuffer_set_old_format(struct kbuffer *kbuf)
784 {
785 	kbuf->flags |= KBUFFER_FL_OLD_FORMAT;
786 
787 	kbuf->next_event = __old_next_event;
788 }
789 
790 /**
791  * kbuffer_start_of_data - return offset of where data starts on subbuffer
792  * @kbuf:	The kbuffer
793  *
794  * Returns the location on the subbuffer where the data starts.
795  */
kbuffer_start_of_data(struct kbuffer * kbuf)796 int kbuffer_start_of_data(struct kbuffer *kbuf)
797 {
798 	return kbuf->first + kbuf->start;
799 }
800 
801 /**
802  * kbuffer_raw_get - get raw buffer info
803  * @kbuf:	The kbuffer
804  * @subbuf:	Start of mapped subbuffer
805  * @info:	Info descriptor to fill in
806  *
807  * For debugging. This can return internals of the ring buffer.
808  * Expects to have info->next set to what it will read.
809  * The type, length and timestamp delta will be filled in, and
810  * @info->next will be updated to the next element.
811  * The @subbuf is used to know if the info is passed the end of
812  * data and NULL will be returned if it is.
813  */
814 struct kbuffer_raw_info *
kbuffer_raw_get(struct kbuffer * kbuf,void * subbuf,struct kbuffer_raw_info * info)815 kbuffer_raw_get(struct kbuffer *kbuf, void *subbuf, struct kbuffer_raw_info *info)
816 {
817 	unsigned long long flags;
818 	unsigned long long delta;
819 	unsigned int type_len;
820 	unsigned int size;
821 	int start;
822 	int length;
823 	void *ptr = info->next;
824 
825 	if (!kbuf || !subbuf)
826 		return NULL;
827 
828 	if (kbuf->flags & KBUFFER_FL_LONG_8)
829 		start = 16;
830 	else
831 		start = 12;
832 
833 	flags = read_long(kbuf, subbuf + 8);
834 	size = (unsigned int)flags & COMMIT_MASK;
835 
836 	if (ptr < subbuf || ptr >= subbuf + start + size)
837 		return NULL;
838 
839 	type_len = translate_data(kbuf, ptr, &ptr, &delta, &length);
840 
841 	info->next = ptr + length;
842 
843 	info->type = type_len;
844 	info->delta = delta;
845 	info->length = length;
846 
847 	return info;
848 }
849