aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/header.c
diff options
context:
space:
mode:
authorTom Zanussi <tzanussi@gmail.com>2010-04-02 00:59:15 -0400
committerIngo Molnar <mingo@elte.hu>2010-04-14 05:56:05 -0400
commit8dc58101f2c838355d44402aa77646649d10dbec (patch)
treed4cc08cccfec56d37dee4c4b2383ffe56d176494 /tools/perf/util/header.c
parentc05556421742eb47f80301767653a4bcb19de9de (diff)
perf: Add pipe-specific header read/write and event processing code
This patch makes several changes to allow the perf event stream to be sent and received over a pipe: - adds pipe-specific versions of the header read/write code - adds pipe-specific version of the event processing code - adds a range of event types to be used for header or other pseudo events, above the range used by the kernel - checks the return value of event handlers, which they can use to skip over large events during event processing rather than actually reading them into event objects. - unifies the multiple do_read() functions and updates its users. Note that none of these changes affect the existing perf data file format or processing - this code only comes into play if perf output is sent to stdout (or is read from stdin). Signed-off-by: Tom Zanussi <tzanussi@gmail.com> Acked-by: Thomas Gleixner <tglx@linutronix.de> Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org Cc: k-keiichi@bx.jp.nec.com Cc: acme@ghostprotocols.net LKML-Reference: <1270184365-8281-2-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/header.c')
-rw-r--r--tools/perf/util/header.c78
1 files changed, 60 insertions, 18 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 6c9aa16ee51f..8d05337d1a59 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -427,6 +427,25 @@ out_free:
427 return err; 427 return err;
428} 428}
429 429
430int perf_header__write_pipe(int fd)
431{
432 struct perf_pipe_file_header f_header;
433 int err;
434
435 f_header = (struct perf_pipe_file_header){
436 .magic = PERF_MAGIC,
437 .size = sizeof(f_header),
438 };
439
440 err = do_write(fd, &f_header, sizeof(f_header));
441 if (err < 0) {
442 pr_debug("failed to write perf pipe header\n");
443 return err;
444 }
445
446 return 0;
447}
448
430int perf_header__write(struct perf_header *self, int fd, bool at_exit) 449int perf_header__write(struct perf_header *self, int fd, bool at_exit)
431{ 450{
432 struct perf_file_header f_header; 451 struct perf_file_header f_header;
@@ -518,25 +537,10 @@ int perf_header__write(struct perf_header *self, int fd, bool at_exit)
518 return 0; 537 return 0;
519} 538}
520 539
521static int do_read(int fd, void *buf, size_t size)
522{
523 while (size) {
524 int ret = read(fd, buf, size);
525
526 if (ret <= 0)
527 return -1;
528
529 size -= ret;
530 buf += ret;
531 }
532
533 return 0;
534}
535
536static int perf_header__getbuffer64(struct perf_header *self, 540static int perf_header__getbuffer64(struct perf_header *self,
537 int fd, void *buf, size_t size) 541 int fd, void *buf, size_t size)
538{ 542{
539 if (do_read(fd, buf, size)) 543 if (do_read(fd, buf, size) <= 0)
540 return -1; 544 return -1;
541 545
542 if (self->needs_swap) 546 if (self->needs_swap)
@@ -592,7 +596,7 @@ int perf_file_header__read(struct perf_file_header *self,
592{ 596{
593 lseek(fd, 0, SEEK_SET); 597 lseek(fd, 0, SEEK_SET);
594 598
595 if (do_read(fd, self, sizeof(*self)) || 599 if (do_read(fd, self, sizeof(*self)) <= 0 ||
596 memcmp(&self->magic, __perf_magic, sizeof(self->magic))) 600 memcmp(&self->magic, __perf_magic, sizeof(self->magic)))
597 return -1; 601 return -1;
598 602
@@ -662,13 +666,51 @@ static int perf_file_section__process(struct perf_file_section *self,
662 return 0; 666 return 0;
663} 667}
664 668
665int perf_header__read(struct perf_header *self, int fd) 669static int perf_file_header__read_pipe(struct perf_pipe_file_header *self,
670 struct perf_header *ph, int fd)
666{ 671{
672 if (do_read(fd, self, sizeof(*self)) <= 0 ||
673 memcmp(&self->magic, __perf_magic, sizeof(self->magic)))
674 return -1;
675
676 if (self->size != sizeof(*self)) {
677 u64 size = bswap_64(self->size);
678
679 if (size != sizeof(*self))
680 return -1;
681
682 ph->needs_swap = true;
683 }
684
685 return 0;
686}
687
688static int perf_header__read_pipe(struct perf_session *session, int fd)
689{
690 struct perf_header *self = &session->header;
691 struct perf_pipe_file_header f_header;
692
693 if (perf_file_header__read_pipe(&f_header, self, fd) < 0) {
694 pr_debug("incompatible file format\n");
695 return -EINVAL;
696 }
697
698 session->fd = fd;
699
700 return 0;
701}
702
703int perf_header__read(struct perf_session *session, int fd)
704{
705 struct perf_header *self = &session->header;
667 struct perf_file_header f_header; 706 struct perf_file_header f_header;
668 struct perf_file_attr f_attr; 707 struct perf_file_attr f_attr;
669 u64 f_id; 708 u64 f_id;
670 int nr_attrs, nr_ids, i, j; 709 int nr_attrs, nr_ids, i, j;
671 710
711 if (session->fd_pipe)
712 return perf_header__read_pipe(session, fd);
713
672 if (perf_file_header__read(&f_header, self, fd) < 0) { 714 if (perf_file_header__read(&f_header, self, fd) < 0) {
673 pr_debug("incompatible file format\n"); 715 pr_debug("incompatible file format\n");
674 return -EINVAL; 716 return -EINVAL;