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