kbuffer-parse.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  1. /*
  2. * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
  3. *
  4. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation;
  8. * version 2.1 of the License (not later!)
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. *
  19. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  20. */
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include "kbuffer.h"
  25. #define MISSING_EVENTS (1 << 31)
  26. #define MISSING_STORED (1 << 30)
  27. #define COMMIT_MASK ((1 << 27) - 1)
  28. enum {
  29. KBUFFER_FL_HOST_BIG_ENDIAN = (1<<0),
  30. KBUFFER_FL_BIG_ENDIAN = (1<<1),
  31. KBUFFER_FL_LONG_8 = (1<<2),
  32. KBUFFER_FL_OLD_FORMAT = (1<<3),
  33. };
  34. #define ENDIAN_MASK (KBUFFER_FL_HOST_BIG_ENDIAN | KBUFFER_FL_BIG_ENDIAN)
  35. /** kbuffer
  36. * @timestamp - timestamp of current event
  37. * @lost_events - # of lost events between this subbuffer and previous
  38. * @flags - special flags of the kbuffer
  39. * @subbuffer - pointer to the sub-buffer page
  40. * @data - pointer to the start of data on the sub-buffer page
  41. * @index - index from @data to the @curr event data
  42. * @curr - offset from @data to the start of current event
  43. * (includes metadata)
  44. * @next - offset from @data to the start of next event
  45. * @size - The size of data on @data
  46. * @start - The offset from @subbuffer where @data lives
  47. *
  48. * @read_4 - Function to read 4 raw bytes (may swap)
  49. * @read_8 - Function to read 8 raw bytes (may swap)
  50. * @read_long - Function to read a long word (4 or 8 bytes with needed swap)
  51. */
  52. struct kbuffer {
  53. unsigned long long timestamp;
  54. long long lost_events;
  55. unsigned long flags;
  56. void *subbuffer;
  57. void *data;
  58. unsigned int index;
  59. unsigned int curr;
  60. unsigned int next;
  61. unsigned int size;
  62. unsigned int start;
  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. static void *zmalloc(size_t size)
  69. {
  70. return calloc(1, size);
  71. }
  72. static int host_is_bigendian(void)
  73. {
  74. unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 };
  75. unsigned int *ptr;
  76. ptr = (unsigned int *)str;
  77. return *ptr == 0x01020304;
  78. }
  79. static int do_swap(struct kbuffer *kbuf)
  80. {
  81. return ((kbuf->flags & KBUFFER_FL_HOST_BIG_ENDIAN) + kbuf->flags) &
  82. ENDIAN_MASK;
  83. }
  84. static unsigned long long __read_8(void *ptr)
  85. {
  86. unsigned long long data = *(unsigned long long *)ptr;
  87. return data;
  88. }
  89. static unsigned long long __read_8_sw(void *ptr)
  90. {
  91. unsigned long long data = *(unsigned long long *)ptr;
  92. 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);
  101. return swap;
  102. }
  103. static unsigned int __read_4(void *ptr)
  104. {
  105. unsigned int data = *(unsigned int *)ptr;
  106. return data;
  107. }
  108. static unsigned int __read_4_sw(void *ptr)
  109. {
  110. unsigned int data = *(unsigned int *)ptr;
  111. unsigned int swap;
  112. swap = ((data & 0xffULL) << 24) |
  113. ((data & (0xffULL << 8)) << 8) |
  114. ((data & (0xffULL << 16)) >> 8) |
  115. ((data & (0xffULL << 24)) >> 24);
  116. return swap;
  117. }
  118. static unsigned long long read_8(struct kbuffer *kbuf, void *ptr)
  119. {
  120. return kbuf->read_8(ptr);
  121. }
  122. static unsigned int read_4(struct kbuffer *kbuf, void *ptr)
  123. {
  124. return kbuf->read_4(ptr);
  125. }
  126. static unsigned long long __read_long_8(struct kbuffer *kbuf, void *ptr)
  127. {
  128. return kbuf->read_8(ptr);
  129. }
  130. static unsigned long long __read_long_4(struct kbuffer *kbuf, void *ptr)
  131. {
  132. return kbuf->read_4(ptr);
  133. }
  134. static unsigned long long read_long(struct kbuffer *kbuf, void *ptr)
  135. {
  136. return kbuf->read_long(kbuf, ptr);
  137. }
  138. static int calc_index(struct kbuffer *kbuf, void *ptr)
  139. {
  140. return (unsigned long)ptr - (unsigned long)kbuf->data;
  141. }
  142. static int __next_event(struct kbuffer *kbuf);
  143. /**
  144. * kbuffer_alloc - allocat a new kbuffer
  145. * @size; enum to denote size of word
  146. * @endian: enum to denote endianness
  147. *
  148. * Allocates and returns a new kbuffer.
  149. */
  150. struct kbuffer *
  151. kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian)
  152. {
  153. struct kbuffer *kbuf;
  154. int flags = 0;
  155. switch (size) {
  156. case KBUFFER_LSIZE_4:
  157. break;
  158. case KBUFFER_LSIZE_8:
  159. flags |= KBUFFER_FL_LONG_8;
  160. break;
  161. default:
  162. return NULL;
  163. }
  164. switch (endian) {
  165. case KBUFFER_ENDIAN_LITTLE:
  166. break;
  167. case KBUFFER_ENDIAN_BIG:
  168. flags |= KBUFFER_FL_BIG_ENDIAN;
  169. break;
  170. default:
  171. return NULL;
  172. }
  173. kbuf = zmalloc(sizeof(*kbuf));
  174. if (!kbuf)
  175. return NULL;
  176. kbuf->flags = flags;
  177. if (host_is_bigendian())
  178. kbuf->flags |= KBUFFER_FL_HOST_BIG_ENDIAN;
  179. if (do_swap(kbuf)) {
  180. kbuf->read_8 = __read_8_sw;
  181. kbuf->read_4 = __read_4_sw;
  182. } else {
  183. kbuf->read_8 = __read_8;
  184. kbuf->read_4 = __read_4;
  185. }
  186. if (kbuf->flags & KBUFFER_FL_LONG_8)
  187. kbuf->read_long = __read_long_8;
  188. else
  189. kbuf->read_long = __read_long_4;
  190. /* May be changed by kbuffer_set_old_format() */
  191. kbuf->next_event = __next_event;
  192. return kbuf;
  193. }
  194. /** kbuffer_free - free an allocated kbuffer
  195. * @kbuf: The kbuffer to free
  196. *
  197. * Can take NULL as a parameter.
  198. */
  199. void kbuffer_free(struct kbuffer *kbuf)
  200. {
  201. free(kbuf);
  202. }
  203. static unsigned int type4host(struct kbuffer *kbuf,
  204. unsigned int type_len_ts)
  205. {
  206. if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
  207. return (type_len_ts >> 29) & 3;
  208. else
  209. return type_len_ts & 3;
  210. }
  211. static unsigned int len4host(struct kbuffer *kbuf,
  212. unsigned int type_len_ts)
  213. {
  214. if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
  215. return (type_len_ts >> 27) & 7;
  216. else
  217. return (type_len_ts >> 2) & 7;
  218. }
  219. static unsigned int type_len4host(struct kbuffer *kbuf,
  220. unsigned int type_len_ts)
  221. {
  222. if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
  223. return (type_len_ts >> 27) & ((1 << 5) - 1);
  224. else
  225. return type_len_ts & ((1 << 5) - 1);
  226. }
  227. static unsigned int ts4host(struct kbuffer *kbuf,
  228. unsigned int type_len_ts)
  229. {
  230. if (kbuf->flags & KBUFFER_FL_BIG_ENDIAN)
  231. return type_len_ts & ((1 << 27) - 1);
  232. else
  233. return type_len_ts >> 5;
  234. }
  235. /*
  236. * Linux 2.6.30 and earlier (not much ealier) had a different
  237. * ring buffer format. It should be obsolete, but we handle it anyway.
  238. */
  239. enum old_ring_buffer_type {
  240. OLD_RINGBUF_TYPE_PADDING,
  241. OLD_RINGBUF_TYPE_TIME_EXTEND,
  242. OLD_RINGBUF_TYPE_TIME_STAMP,
  243. OLD_RINGBUF_TYPE_DATA,
  244. };
  245. static unsigned int old_update_pointers(struct kbuffer *kbuf)
  246. {
  247. unsigned long long extend;
  248. unsigned int type_len_ts;
  249. unsigned int type;
  250. unsigned int len;
  251. unsigned int delta;
  252. unsigned int length;
  253. void *ptr = kbuf->data + kbuf->curr;
  254. type_len_ts = read_4(kbuf, ptr);
  255. ptr += 4;
  256. type = type4host(kbuf, type_len_ts);
  257. len = len4host(kbuf, type_len_ts);
  258. delta = ts4host(kbuf, type_len_ts);
  259. switch (type) {
  260. case OLD_RINGBUF_TYPE_PADDING:
  261. kbuf->next = kbuf->size;
  262. return 0;
  263. case OLD_RINGBUF_TYPE_TIME_EXTEND:
  264. extend = read_4(kbuf, ptr);
  265. extend <<= TS_SHIFT;
  266. extend += delta;
  267. delta = extend;
  268. ptr += 4;
  269. break;
  270. case OLD_RINGBUF_TYPE_TIME_STAMP:
  271. /* should never happen! */
  272. kbuf->curr = kbuf->size;
  273. kbuf->next = kbuf->size;
  274. kbuf->index = kbuf->size;
  275. return -1;
  276. default:
  277. if (len)
  278. length = len * 4;
  279. else {
  280. length = read_4(kbuf, ptr);
  281. length -= 4;
  282. ptr += 4;
  283. }
  284. break;
  285. }
  286. kbuf->timestamp += delta;
  287. kbuf->index = calc_index(kbuf, ptr);
  288. kbuf->next = kbuf->index + length;
  289. return type;
  290. }
  291. static int __old_next_event(struct kbuffer *kbuf)
  292. {
  293. int type;
  294. do {
  295. kbuf->curr = kbuf->next;
  296. if (kbuf->next >= kbuf->size)
  297. return -1;
  298. type = old_update_pointers(kbuf);
  299. } while (type == OLD_RINGBUF_TYPE_TIME_EXTEND || type == OLD_RINGBUF_TYPE_PADDING);
  300. return 0;
  301. }
  302. static unsigned int
  303. translate_data(struct kbuffer *kbuf, void *data, void **rptr,
  304. unsigned long long *delta, int *length)
  305. {
  306. unsigned long long extend;
  307. unsigned int type_len_ts;
  308. unsigned int type_len;
  309. type_len_ts = read_4(kbuf, data);
  310. data += 4;
  311. type_len = type_len4host(kbuf, type_len_ts);
  312. *delta = ts4host(kbuf, type_len_ts);
  313. switch (type_len) {
  314. case KBUFFER_TYPE_PADDING:
  315. *length = read_4(kbuf, data);
  316. break;
  317. case KBUFFER_TYPE_TIME_EXTEND:
  318. extend = read_4(kbuf, data);
  319. data += 4;
  320. extend <<= TS_SHIFT;
  321. extend += *delta;
  322. *delta = extend;
  323. *length = 0;
  324. break;
  325. case KBUFFER_TYPE_TIME_STAMP:
  326. data += 12;
  327. *length = 0;
  328. break;
  329. case 0:
  330. *length = read_4(kbuf, data) - 4;
  331. *length = (*length + 3) & ~3;
  332. data += 4;
  333. break;
  334. default:
  335. *length = type_len * 4;
  336. break;
  337. }
  338. *rptr = data;
  339. return type_len;
  340. }
  341. static unsigned int update_pointers(struct kbuffer *kbuf)
  342. {
  343. unsigned long long delta;
  344. unsigned int type_len;
  345. int length;
  346. void *ptr = kbuf->data + kbuf->curr;
  347. type_len = translate_data(kbuf, ptr, &ptr, &delta, &length);
  348. kbuf->timestamp += delta;
  349. kbuf->index = calc_index(kbuf, ptr);
  350. kbuf->next = kbuf->index + length;
  351. return type_len;
  352. }
  353. /**
  354. * kbuffer_translate_data - read raw data to get a record
  355. * @swap: Set to 1 if bytes in words need to be swapped when read
  356. * @data: The raw data to read
  357. * @size: Address to store the size of the event data.
  358. *
  359. * Returns a pointer to the event data. To determine the entire
  360. * record size (record metadata + data) just add the difference between
  361. * @data and the returned value to @size.
  362. */
  363. void *kbuffer_translate_data(int swap, void *data, unsigned int *size)
  364. {
  365. unsigned long long delta;
  366. struct kbuffer kbuf;
  367. int type_len;
  368. int length;
  369. void *ptr;
  370. if (swap) {
  371. kbuf.read_8 = __read_8_sw;
  372. kbuf.read_4 = __read_4_sw;
  373. kbuf.flags = host_is_bigendian() ? 0 : KBUFFER_FL_BIG_ENDIAN;
  374. } else {
  375. kbuf.read_8 = __read_8;
  376. kbuf.read_4 = __read_4;
  377. kbuf.flags = host_is_bigendian() ? KBUFFER_FL_BIG_ENDIAN: 0;
  378. }
  379. type_len = translate_data(&kbuf, data, &ptr, &delta, &length);
  380. switch (type_len) {
  381. case KBUFFER_TYPE_PADDING:
  382. case KBUFFER_TYPE_TIME_EXTEND:
  383. case KBUFFER_TYPE_TIME_STAMP:
  384. return NULL;
  385. };
  386. *size = length;
  387. return ptr;
  388. }
  389. static int __next_event(struct kbuffer *kbuf)
  390. {
  391. int type;
  392. do {
  393. kbuf->curr = kbuf->next;
  394. if (kbuf->next >= kbuf->size)
  395. return -1;
  396. type = update_pointers(kbuf);
  397. } while (type == KBUFFER_TYPE_TIME_EXTEND || type == KBUFFER_TYPE_PADDING);
  398. return 0;
  399. }
  400. static int next_event(struct kbuffer *kbuf)
  401. {
  402. return kbuf->next_event(kbuf);
  403. }
  404. /**
  405. * kbuffer_next_event - increment the current pointer
  406. * @kbuf: The kbuffer to read
  407. * @ts: Address to store the next record's timestamp (may be NULL to ignore)
  408. *
  409. * Increments the pointers into the subbuffer of the kbuffer to point to the
  410. * next event so that the next kbuffer_read_event() will return a
  411. * new event.
  412. *
  413. * Returns the data of the next event if a new event exists on the subbuffer,
  414. * NULL otherwise.
  415. */
  416. void *kbuffer_next_event(struct kbuffer *kbuf, unsigned long long *ts)
  417. {
  418. int ret;
  419. if (!kbuf || !kbuf->subbuffer)
  420. return NULL;
  421. ret = next_event(kbuf);
  422. if (ret < 0)
  423. return NULL;
  424. if (ts)
  425. *ts = kbuf->timestamp;
  426. return kbuf->data + kbuf->index;
  427. }
  428. /**
  429. * kbuffer_load_subbuffer - load a new subbuffer into the kbuffer
  430. * @kbuf: The kbuffer to load
  431. * @subbuffer: The subbuffer to load into @kbuf.
  432. *
  433. * Load a new subbuffer (page) into @kbuf. This will reset all
  434. * the pointers and update the @kbuf timestamp. The next read will
  435. * return the first event on @subbuffer.
  436. *
  437. * Returns 0 on succes, -1 otherwise.
  438. */
  439. int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer)
  440. {
  441. unsigned long long flags;
  442. void *ptr = subbuffer;
  443. if (!kbuf || !subbuffer)
  444. return -1;
  445. kbuf->subbuffer = subbuffer;
  446. kbuf->timestamp = read_8(kbuf, ptr);
  447. ptr += 8;
  448. kbuf->curr = 0;
  449. if (kbuf->flags & KBUFFER_FL_LONG_8)
  450. kbuf->start = 16;
  451. else
  452. kbuf->start = 12;
  453. kbuf->data = subbuffer + kbuf->start;
  454. flags = read_long(kbuf, ptr);
  455. kbuf->size = (unsigned int)flags & COMMIT_MASK;
  456. if (flags & MISSING_EVENTS) {
  457. if (flags & MISSING_STORED) {
  458. ptr = kbuf->data + kbuf->size;
  459. kbuf->lost_events = read_long(kbuf, ptr);
  460. } else
  461. kbuf->lost_events = -1;
  462. } else
  463. kbuf->lost_events = 0;
  464. kbuf->index = 0;
  465. kbuf->next = 0;
  466. next_event(kbuf);
  467. return 0;
  468. }
  469. /**
  470. * kbuffer_read_event - read the next event in the kbuffer subbuffer
  471. * @kbuf: The kbuffer to read from
  472. * @ts: The address to store the timestamp of the event (may be NULL to ignore)
  473. *
  474. * Returns a pointer to the data part of the current event.
  475. * NULL if no event is left on the subbuffer.
  476. */
  477. void *kbuffer_read_event(struct kbuffer *kbuf, unsigned long long *ts)
  478. {
  479. if (!kbuf || !kbuf->subbuffer)
  480. return NULL;
  481. if (kbuf->curr >= kbuf->size)
  482. return NULL;
  483. if (ts)
  484. *ts = kbuf->timestamp;
  485. return kbuf->data + kbuf->index;
  486. }
  487. /**
  488. * kbuffer_timestamp - Return the timestamp of the current event
  489. * @kbuf: The kbuffer to read from
  490. *
  491. * Returns the timestamp of the current (next) event.
  492. */
  493. unsigned long long kbuffer_timestamp(struct kbuffer *kbuf)
  494. {
  495. return kbuf->timestamp;
  496. }
  497. /**
  498. * kbuffer_read_at_offset - read the event that is at offset
  499. * @kbuf: The kbuffer to read from
  500. * @offset: The offset into the subbuffer
  501. * @ts: The address to store the timestamp of the event (may be NULL to ignore)
  502. *
  503. * The @offset must be an index from the @kbuf subbuffer beginning.
  504. * If @offset is bigger than the stored subbuffer, NULL will be returned.
  505. *
  506. * Returns the data of the record that is at @offset. Note, @offset does
  507. * not need to be the start of the record, the offset just needs to be
  508. * in the record (or beginning of it).
  509. *
  510. * Note, the kbuf timestamp and pointers are updated to the
  511. * returned record. That is, kbuffer_read_event() will return the same
  512. * data and timestamp, and kbuffer_next_event() will increment from
  513. * this record.
  514. */
  515. void *kbuffer_read_at_offset(struct kbuffer *kbuf, int offset,
  516. unsigned long long *ts)
  517. {
  518. void *data;
  519. if (offset < kbuf->start)
  520. offset = 0;
  521. else
  522. offset -= kbuf->start;
  523. /* Reset the buffer */
  524. kbuffer_load_subbuffer(kbuf, kbuf->subbuffer);
  525. data = kbuffer_read_event(kbuf, ts);
  526. while (kbuf->curr < offset) {
  527. data = kbuffer_next_event(kbuf, ts);
  528. if (!data)
  529. break;
  530. }
  531. return data;
  532. }
  533. /**
  534. * kbuffer_subbuffer_size - the size of the loaded subbuffer
  535. * @kbuf: The kbuffer to read from
  536. *
  537. * Returns the size of the subbuffer. Note, this size is
  538. * where the last event resides. The stored subbuffer may actually be
  539. * bigger due to padding and such.
  540. */
  541. int kbuffer_subbuffer_size(struct kbuffer *kbuf)
  542. {
  543. return kbuf->size;
  544. }
  545. /**
  546. * kbuffer_curr_index - Return the index of the record
  547. * @kbuf: The kbuffer to read from
  548. *
  549. * Returns the index from the start of the data part of
  550. * the subbuffer to the current location. Note this is not
  551. * from the start of the subbuffer. An index of zero will
  552. * point to the first record. Use kbuffer_curr_offset() for
  553. * the actually offset (that can be used by kbuffer_read_at_offset())
  554. */
  555. int kbuffer_curr_index(struct kbuffer *kbuf)
  556. {
  557. return kbuf->curr;
  558. }
  559. /**
  560. * kbuffer_curr_offset - Return the offset of the record
  561. * @kbuf: The kbuffer to read from
  562. *
  563. * Returns the offset from the start of the subbuffer to the
  564. * current location.
  565. */
  566. int kbuffer_curr_offset(struct kbuffer *kbuf)
  567. {
  568. return kbuf->curr + kbuf->start;
  569. }
  570. /**
  571. * kbuffer_event_size - return the size of the event data
  572. * @kbuf: The kbuffer to read
  573. *
  574. * Returns the size of the event data (the payload not counting
  575. * the meta data of the record) of the current event.
  576. */
  577. int kbuffer_event_size(struct kbuffer *kbuf)
  578. {
  579. return kbuf->next - kbuf->index;
  580. }
  581. /**
  582. * kbuffer_curr_size - return the size of the entire record
  583. * @kbuf: The kbuffer to read
  584. *
  585. * Returns the size of the entire record (meta data and payload)
  586. * of the current event.
  587. */
  588. int kbuffer_curr_size(struct kbuffer *kbuf)
  589. {
  590. return kbuf->next - kbuf->curr;
  591. }
  592. /**
  593. * kbuffer_missed_events - return the # of missed events from last event.
  594. * @kbuf: The kbuffer to read from
  595. *
  596. * Returns the # of missed events (if recorded) before the current
  597. * event. Note, only events on the beginning of a subbuffer can
  598. * have missed events, all other events within the buffer will be
  599. * zero.
  600. */
  601. int kbuffer_missed_events(struct kbuffer *kbuf)
  602. {
  603. /* Only the first event can have missed events */
  604. if (kbuf->curr)
  605. return 0;
  606. return kbuf->lost_events;
  607. }
  608. /**
  609. * kbuffer_set_old_forma - set the kbuffer to use the old format parsing
  610. * @kbuf: The kbuffer to set
  611. *
  612. * This is obsolete (or should be). The first kernels to use the
  613. * new ring buffer had a slightly different ring buffer format
  614. * (2.6.30 and earlier). It is still somewhat supported by kbuffer,
  615. * but should not be counted on in the future.
  616. */
  617. void kbuffer_set_old_format(struct kbuffer *kbuf)
  618. {
  619. kbuf->flags |= KBUFFER_FL_OLD_FORMAT;
  620. kbuf->next_event = __old_next_event;
  621. }
  622. /**
  623. * kbuffer_start_of_data - return offset of where data starts on subbuffer
  624. * @kbuf: The kbuffer
  625. *
  626. * Returns the location on the subbuffer where the data starts.
  627. */
  628. int kbuffer_start_of_data(struct kbuffer *kbuf)
  629. {
  630. return kbuf->start;
  631. }