Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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