perf/core improvements and fixes
Subsystems (2)
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling, there is some more stuff in queue to be
processed, but better send in smaller batches,
- Arnaldo
The following changes since commit b3890e4704594fa23abe1395d1fafc97d3214be8:
Merge branch 'perf/hw_breakpoints' into perf/core (2015-01-28 15:48:59 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo
for you to fetch changes up to c52686f9f888d23ca72f1309e86af8e91d075697:
perf symbols: Convert lseek + read to pread (2015-01-29 17:02:01 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
User visible:
- Show precise number of samples in at the end of a 'record' session, if processing build ids, since we will then traverse the whole perf.data file and see all the PERF_RECORD_SAMPLE records, otherwise stop showing the previous off-base heuristicly counted number of "samples" (Namhyung Kim).
- Support to read compressed module from build-id cache (Namhyung Kim)
Infrastructure:
- Cache eh/debug frame offset for dwarf unwind (Namhyung Kim)
- Set header version correctly in all cases (Namhyung Kim)
- Set attr.task bit for a tracking event, to be consistent (Namhyung Kim) perf tools: Use perf_data_file__fd() consistently
perf symbols: Convert lseek + read to pread
- Don't rely on malloc working for sz 0, fixing another problem when using uClibc (Vineet Gupta)
- Provide stub for missing pthread_attr_setaffinity_np for libcs where this is not available, such as uClibc (Vineet Gupta)
----------------------------------------------------------------
Namhyung Kim (8):
perf callchain: Cache eh/debug frame offset for dwarf unwind perf tools: Do not use __perf_session__process_events() directly perf record: Show precise number of samples
perf header: Set header version correctly
perf evsel: Set attr.task bit for a tracking event
perf symbols: Support to read compressed module from build-id cache perf tools: Use perf_data_file__fd() consistently
perf symbols: Convert lseek + read to pread
Vineet Gupta (2):
perf evsel: Don't rely on malloc working for sz 0 perf tools: Provide stub for missing pthread_attr_setaffinity_np
tools/perf/bench/futex.h | 13 ++++ tools/perf/builtin-inject.c | 5 +- tools/perf/builtin-record.c | 70 +++++++++++++++------- tools/perf/config/Makefile | 6 ++ tools/perf/config/feature-checks/Makefile | 4 ++ tools/perf/config/feature-checks/test-all.c | 5 ++ .../test-pthread-attr-setaffinity-np.c | 14 +++++ tools/perf/util/dso.c | 6 +- tools/perf/util/dso.h | 1 + tools/perf/util/evsel.c | 4 ++ tools/perf/util/header.c | 2 +- tools/perf/util/session.c | 6 +- tools/perf/util/session.h | 3 - tools/perf/util/symbol-elf.c | 13 ++-- tools/perf/util/unwind-libunwind.c | 31 ++++++---- 15 files changed, 131 insertions(+), 52 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-pthread-attr-setaffinity-np.c
Arnaldo Carvalho de Melo
maintainerPATCH 1/10 perf evsel: Don't rely on malloc working for sz 0
From: Vineet Gupta <[email protected]>
When running perf on ARC (uClibc based userspace), ran into this issue
------------->8----------------
[ARCLinux]$ ./perf record ls
bin etc perf sys
debug init perf.data tmp
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data (~24 samples) ]
[ARCLinux]$ ./perf report
incompatible file format (rerun with -v to learn more)
------------->8----------------
The problem happens in the following call stack when zalloc is called with size zero
glibc default / uClibc with MALLOC_GLIBC_COMPAT are OK, but not if that config option is not enabled.
cmd_report
perf_session__new perf_session__open perf_session__read_header read_attr(fd, header, &f_attr) nr_ids = f_attr.ids.size / sizeof(u64); <-- 0 perf_evsel__alloc_id(vsel, 1, nr_ids) zalloc(ncpus * nthreads * sizeof(u64)) <-- 0
header.c: read_attr()
(gdb) p *f_attr
$17 = {
attr = {
type = 0,
size = 96,
config = 0,
{
sample_period = 4000,
sample_freq = 4000
},
...
ids = {
offset = 104,
size = 0 <------ }
}
--- tools/perf/util/evsel.c | 3 +++ 1 file changed, 3 insertions(+)
tools/perf/util/evsel.c +3 -0
@@ -797,6 +797,9 @@ int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads)int perf_evsel__alloc_id (struct perf_evsel *evsel,int ncpus,int nthreads) { +if (ncpus ==0 || nthreads ==0 ) +return 0 ; +if (evsel->system_wide) nthreads =1 ;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 2/10 perf tools: Provide stub for missing pthread_attr_setaffinity_np
In reply to Arnaldo Carvalho de MeloFrom: Vineet Gupta <[email protected]>
uClibc Linuxthreads.old doesn't support the pthread_attr_setaffinity_np() functioo:
----------------->8-----------------------
CC bench/futex-hash.o
CC bench/futex-wake.obench/futex-hash.c: In function 'bench_futex_hash':bench/futex-hash.c:161:3: error: implicit declaration of function 'pthread_attr_setaffinity_np' [-Werror=implicit-function-declaration]
ret = pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t),
&cpu);
^bench/futex-hash.c:161:3: error: nested extern declaration of 'pthread_attr_setaffinity_np' [-Werror=nested-externs]
----------------->8-----------------------
So introduce a test to check that and if not available provide a stub.
--- tools/perf/bench/futex.h | 13 +++++++++++++ tools/perf/config/Makefile | 6 ++++++ tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-all.c | 5 +++++ .../feature-checks/test-pthread-attr-setaffinity-np.c | 14 ++++++++++++++ 5 files changed, 42 insertions(+) create mode 100644 tools/perf/config/feature-checks/test-pthread-attr-setaffinity-np.c
tools/perf/bench/futex.h +13 -0
@@ -68,4 +68,17 @@ futex_cmp_requeue(u_int32_t *uaddr, u_int32_t val, u_int32_t *uaddr2, int nr_wak val, opflags); } +#ifndef HAVE_PTHREAD_ATTR_SETAFFINITY_NP +#include <pthread.h> +static inline int pthread_attr_setaffinity_np (pthread_attr_t *attr, +size_t cpusetsize, +cpu_set_t *cpuset) +{ + attr = attr; + cpusetsize = cpusetsize; + cpuset = cpuset; +return 0 ; +} +#endif +#endif /* _FUTEX_H */
tools/perf/config/Makefile +6 -0
@@ -198,6 +198,7 @@ CORE_FEATURE_TESTS = \ libpython-version \ libslang \ libunwind \ + pthread-attr-setaffinity-np \ stackprotector-all \ timerfd \ libdw-dwarf-unwind \
@@ -226,6 +227,7 @@ VF_FEATURE_TESTS = \ libelf-getphdrnum \ libelf-mmap \ libpython-version \ + pthread-attr-setaffinity-np \ stackprotector-all \ timerfd \ libunwind-debug-frame \
@@ -301,6 +303,10 @@ ifeq ($(feature-sync-compare-and-swap), 1) CFLAGS += -DHAVE_SYNC_COMPARE_AND_SWAP_SUPPORT endif +ifeq ($(feature-pthread-attr-setaffinity-np), 1) + CFLAGS += -DHAVE_PTHREAD_ATTR_SETAFFINITY_NP +endif + ifndef NO_BIONIC $(call feature_check,bionic) ifeq ($(feature-bionic), 1)
tools/perf/config/feature-checks/Makefile +4 -0
@@ -25,6 +25,7 @@ FILES= \ test-libslang.bin \ test-libunwind.bin \ test-libunwind-debug-frame.bin \ + test-pthread-attr-setaffinity-np.bin \ test-stackprotector-all.bin \ test-timerfd.bin \ test-libdw-dwarf-unwind.bin \
@@ -47,6 +48,9 @@ test-all.bin: test-hello.bin: $(BUILD) +test-pthread-attr-setaffinity-np.bin: + $(BUILD) -Werror -lpthread + test-stackprotector-all.bin: $(BUILD) -Werror -fstack-protector-all
tools/perf/config/feature-checks/test-all.c +5 -0
@@ -97,6 +97,10 @@# include "test-zlib.c" #undef main +#define main main_test_pthread_attr_setaffinity_np +# include "test-pthread_attr_setaffinity_np.c" +#undef main +int main (int argc,char *argv[]) {main_test_libpython ();
@@ -121,6 +125,7 @@ int main(int argc, char *argv[])main_test_libdw_dwarf_unwind ();main_test_sync_compare_and_swap (argc, argv);main_test_zlib (); +main_test_pthread_attr_setaffinity_np ();return 0 ; }
tools/perf/config/feature-checks/test-pthread-attr-setaffinity-np.c new file +14 -0
@@ -0,0 +1,14 @@ +#include <stdint.h> +#include <pthread.h> + +int main (void ) +{ +int ret =0 ; +pthread_attr_t thread_attr; + +pthread_attr_init (&thread_attr); +/* don't care abt exact args, just the API itself in libpthread */ + ret =pthread_attr_setaffinity_np (&thread_attr,0 ,NULL ); + +return ret; +}
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 3/10 perf callchain: Cache eh/debug frame offset for dwarf unwind
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
When libunwind tries to resolve callchains it needs to know the offset of .eh_frame_hdr or .debug_frame to access the dso.
Since it will always return the same result for a given DSO, just cache the result as an optimization.
--- tools/perf/util/dso.h | 1 + tools/perf/util/unwind-libunwind.c | 31 ++++++++++++++++++++----------- 2 files changed, 21 insertions(+), 11 deletions(-)
tools/perf/util/dso.h +1 -0
@@ -139,6 +139,7 @@ struct dso {u32 status_seen;size_t file_size;struct list_head open_entry; +u64 frame_offset; } data;union {/* Tool specific area */
tools/perf/util/unwind-libunwind.c +20 -11
@@ -266,14 +266,17 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine, u64 *fde_count) {int ret = -EINVAL , fd; -u64 offset; +u64 offset = dso->data.frame_offset; - fd =dso__data_fd (dso, machine); -if (fd <0 ) -return -EINVAL ; +if (offset ==0 ) { + fd =dso__data_fd (dso, machine); +if (fd <0 ) +return -EINVAL ; -/* Check the .eh_frame section for unwinding info */ - offset =elf_section_offset (fd,".eh_frame_hdr" ); +/* Check the .eh_frame section for unwinding info */ + offset =elf_section_offset (fd,".eh_frame_hdr" ); + dso->data.frame_offset = offset; + }if (offset) ret = unwind_spec_ehframe(dso, machine, offset,
@@ -287,14 +290,20 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,static int read_unwind_spec_debug_frame (struct dso *dso,struct machine *machine,u64 *offset) { -int fd =dso__data_fd (dso, machine); +int fd; +u64 ofs = dso->data.frame_offset; -if (fd <0 ) -return -EINVAL ; +if (ofs ==0 ) { + fd =dso__data_fd (dso, machine); +if (fd <0 ) +return -EINVAL ; -/* Check the .debug_frame section for unwinding info */ - *offset =elf_section_offset (fd,".debug_frame" ); +/* Check the .debug_frame section for unwinding info */ + ofs =elf_section_offset (fd,".debug_frame" ); + dso->data.frame_offset = ofs; + } + *offset = ofs;if (*offset)return 0 ;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 4/10 perf tools: Do not use __perf_session__process_events() directly
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
It's only used for perf record to process build-id because its file size it's not fixed at this time due to remaining header features.
However data offset and size is available so that we can use the perf_session__process_events() once we set the file size as the current offset like for now.
--- tools/perf/builtin-record.c | 7 +++---- tools/perf/util/session.c | 6 +++--- tools/perf/util/session.h | 3 --- 3 files changed, 6 insertions(+), 10 deletions(-)
tools/perf/builtin-record.c +3 -4
@@ -194,12 +194,13 @@ static int process_buildids(struct record *rec) {struct perf_data_file *file = &rec->file;struct perf_session *session = rec->session; -u64 start = session->header.data_offset;u64 size =lseek (file->fd,0 ,SEEK_CUR );if (size ==0 )return 0 ; + file->size = size; +/* * During this process, it'll load kernel map and replace the * dso->long_name to a real pathname it found. In this case
@@ -211,9 +212,7 @@ static int process_buildids(struct record *rec)*/ symbol_conf.ignore_vmlinux_buildid = true; -return __perf_session__process_events (session, start, - size - start, - size, &build_id__mark_dso_hit_ops); +return perf_session__process_events (session, &build_id__mark_dso_hit_ops); }static void perf_event__synthesize_guest_os (struct machine *machine,void *data)
tools/perf/util/session.c +3 -3
@@ -1251,9 +1251,9 @@ fetch_mmaped_event(struct perf_session *session,#define NUM_MMAPS 128#endif -int __perf_session__process_events (struct perf_session *session, -u64 data_offset,u64 data_size, -u64 file_size,struct perf_tool *tool) +static int __perf_session__process_events (struct perf_session *session, +u64 data_offset,u64 data_size, +u64 file_size,struct perf_tool *tool) {int fd =perf_data_file__fd (session->file);u64 head, page_offset, file_offset, file_pos, size;
tools/perf/util/session.h +0 -3
@@ -49,9 +49,6 @@ int perf_session__peek_event(struct perf_session *session, off_t file_offset,union perf_event **event_ptr, struct perf_sample *sample); -int __perf_session__process_events (struct perf_session *session, -u64 data_offset,u64 data_size,u64 size, -struct perf_tool *tool);int perf_session__process_events (struct perf_session *session,struct perf_tool *tool);
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 5/10 perf record: Show precise number of samples
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
After perf record finishes, it prints file size and number of samples in the file but this info is wrong since it assumes typical sample size of 24 bytes and divides file size by the value.
However as we post-process recorded samples for build-id, it can show correct number like below. If build-id post-processing is not requested just omit the wrong number of samples.
$ perf record noploop 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.159 MB perf.data (3989 samples) ] $ perf report --stdio -n
# To display the perf.data header info, please use --header/--header-only options.
#
# Samples: 3K of event 'cycles'
# Event count (approx.): 3771330663
#
# Overhead Samples Command Shared Object Symbol
# ........ ............ ....... ................ ..........................
#
99.90% 3982 noploop noploop [.] main
0.09% 1 noploop ld-2.17.so [.] _dl_check_map_versions
0.01% 1 noploop [kernel.vmlinux] [k] setup_arg_pages
0.00% 5 noploop [kernel.vmlinux] [k] intel_pmu_enable_all--- tools/perf/builtin-record.c | 51 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 12 deletions(-)
tools/perf/builtin-record.c +39 -12
@@ -190,6 +190,19 @@ out:return rc; } +static int process_sample_event (struct perf_tool *tool, +union perf_event *event, +struct perf_sample *sample, +struct perf_evsel *evsel, +struct machine *machine) +{ + struct record *rec = container_of(tool, struct record, tool); + + rec->samples++; + +return build_id__mark_dso_hit (tool, event, sample, evsel, machine); +} +static int process_buildids (struct record *rec) {struct perf_data_file *file = &rec->file;
@@ -212,7 +225,7 @@ static int process_buildids(struct record *rec)*/ symbol_conf.ignore_vmlinux_buildid = true; -return perf_session__process_events (session, &build_id__mark_dso_hit_ops); +return perf_session__process_events (session, &rec->tool); }static void perf_event__synthesize_guest_os (struct machine *machine,void *data)
@@ -503,19 +516,9 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) goto out_child; } -if (!quiet) { +if (!quiet)fprintf (stderr,"[ perf record: Woken up %ld times to write data ]\n" , waking); -/* -* Approximate RIP event size: 24 bytes. -*/ -fprintf (stderr, -"[ perf record: Captured and wrote %.3f MB %s (~%" PRIu64" samples) ]\n" , - (double )rec->bytes_written /1024.0 /1024.0 , - file->path, - rec->bytes_written /24 ); - } - out_child:if (forks) {int exit_status;
@@ -534,6 +537,9 @@ out_child: }else status = err; +/* this will be recalculated during process_buildids() */ + rec->samples =0 ; +if (!err && !file->is_pipe) { rec->session->header.data_size += rec->bytes_written;
@@ -543,6 +549,20 @@ out_child: file->fd, true); } +if (!err && !quiet) { +char samples[128 ]; + +if (rec->samples) +scnprintf (samples,sizeof (samples), +" (%" PRIu64" samples)" , rec->samples); +else + samples[0 ] ='\0' ; + +fprintf (stderr,"[ perf record: Captured and wrote %.3f MB %s%s ]\n" , +perf_data_file__size (file) /1024.0 /1024.0 , + file->path, samples); + } + out_delete_session:perf_session__delete (session);return status;
@@ -719,6 +739,13 @@ static struct record record = { .default_per_cpu = true, }, }, + .tool = { + .sample = process_sample_event, + .fork = perf_event__process_fork, + .comm = perf_event__process_comm, + .mmap = perf_event__process_mmap, + .mmap2 = perf_event__process_mmap2, + }, };#define CALLCHAIN_HELP "setup and enables call-graph (stack chain/backtrace) recording: "
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 6/10 perf header: Set header version correctly
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
When check_magic_endian() is called, it checks the magic number in the perf data file to determine version and endianness. But if it uses a same endian the verison number wasn't updated and makes confusion.
--- tools/perf/util/header.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/header.c +1 -1
@@ -2237,6 +2237,7 @@ static int check_magic_endian(u64 magic, uint64_t hdr_sz,* - unique number to identify actual perf.data files * - encode endianness of file */ + ph->version =PERF_HEADER_VERSION_2 ;/* check magic number with one endianness */ if (magic == __perf_magic2)
@@ -2247,7 +2248,6 @@ static int check_magic_endian(u64 magic, uint64_t hdr_sz,return -1 ; ph->needs_swap = true; - ph->version =PERF_HEADER_VERSION_2 ;return 0 ; }
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 7/10 perf evsel: Set attr.task bit for a tracking event
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
The perf_event_attr.task bit is to track task (fork and exit) events but it missed to be set by perf_evsel__config(). While it was not a problem in practice since setting other bits (comm/mmap) ended up being in same result, it'd be good to set it explicitly anyway.
The attr->task is to track task related events (fork/exit) only but other meta events like comm and mmap[2] also needs the task events. So setting attr->comm and/or attr->mmap causes the kernel emits the task events anyway. So the attr->task is only meaningful when other bits are off but I'd like to set it for completeness.
--- tools/perf/util/evsel.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/util/evsel.c +1 -0
@@ -709,6 +709,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)if (opts->sample_weight)perf_evsel__set_sample_bit (evsel,WEIGHT ); + attr->task = track; attr->mmap = track; attr->mmap2 = track && !perf_missing_features.mmap2; attr->comm = track;
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 8/10 perf symbols: Support to read compressed module from build-id cache
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
The commit c00c48fc6e6e ("perf symbols: Preparation for compressed kernel module support") added support for compressed kernel modules but it only supports system path DSOs. When a dso is read from build-id cache, its filename doesn't end with ".gz" but has build-id. In this case, we should fallback to the original dso->name.
--- tools/perf/util/symbol-elf.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
tools/perf/util/symbol-elf.c +8 -5
@@ -574,13 +574,16 @@ static int decompress_kmodule(struct dso *dso, const char *name,const char *ext =strrchr (name,'.' );char tmpbuf[] ="/tmp/perf-kmod-XXXXXX" ; -if ((type !=DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP && - type !=DSO_BINARY_TYPE__GUEST_KMODULE_COMP ) || - type != dso->symtab_type) +if (type !=DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP && + type !=DSO_BINARY_TYPE__GUEST_KMODULE_COMP && + type !=DSO_BINARY_TYPE__BUILD_ID_CACHE )return -1 ; -if (!ext || !is_supported_compression (ext +1 )) -return -1 ; +if (!ext || !is_supported_compression (ext +1 )) { + ext =strrchr (dso->name,'.' ); +if (!ext || !is_supported_compression (ext +1 )) +return -1 ; + } fd =mkstemp (tmpbuf);if (fd <0 )
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 9/10 perf tools: Use perf_data_file__fd() consistently
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
Do not reference file->fd directly since we want hide the implementation details from outside for possible future changes.
--- tools/perf/builtin-inject.c | 5 +++-- tools/perf/builtin-record.c | 14 +++++++------- 2 files changed, 10 insertions(+), 9 deletions(-)
tools/perf/builtin-inject.c +3 -2
@@ -343,6 +343,7 @@ static int __cmd_inject(struct perf_inject *inject)int ret = -EINVAL ;struct perf_session *session = inject->session;struct perf_data_file *file_out = &inject->output; +int fd =perf_data_file__fd (file_out);signal (SIGINT , sig_handler);
@@ -376,7 +377,7 @@ static int __cmd_inject(struct perf_inject *inject) }if (!file_out->is_pipe) -lseek (file_out->fd, session->header.data_offset,SEEK_SET ); +lseek (fd, session->header.data_offset,SEEK_SET ); ret =perf_session__process_events (session, &inject->tool);
@@ -385,7 +386,7 @@ static int __cmd_inject(struct perf_inject *inject)perf_header__set_feat (&session->header,HEADER_BUILD_ID ); session->header.data_size = inject->bytes_written; -perf_session__write_header (session, session->evlist, file_out->fd, true); +perf_session__write_header (session, session->evlist, fd, true); }return ret;
tools/perf/builtin-record.c +7 -7
@@ -208,7 +208,7 @@ static int process_buildids(struct record *rec)struct perf_data_file *file = &rec->file;struct perf_session *session = rec->session; -u64 size =lseek (file->fd,0 ,SEEK_CUR ); +u64 size =lseek (perf_data_file__fd (file),0 ,SEEK_CUR );if (size ==0 )return 0 ;
@@ -334,6 +334,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)struct perf_data_file *file = &rec->file;struct perf_session *session;bool disabled = false, draining = false; +int fd; rec->progname = argv[0 ];
@@ -348,6 +349,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)return -1 ; } + fd =perf_data_file__fd (file); rec->session = session;record__init_features (rec);
@@ -372,12 +374,11 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)perf_header__clear_feat (&session->header,HEADER_GROUP_DESC );if (file->is_pipe) { - err =perf_header__write_pipe (file->fd); + err =perf_header__write_pipe (fd);if (err <0 ) goto out_child; }else { - err =perf_session__write_header (session, rec->evlist, - file->fd, false); + err =perf_session__write_header (session, rec->evlist, fd, false);if (err <0 ) goto out_child; }
@@ -409,7 +410,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)* return this more properly and also * propagate errors that now are calling die() */ - err =perf_event__synthesize_tracing_data (tool, file->fd, rec->evlist, + err =perf_event__synthesize_tracing_data (tool, fd, rec->evlist, process_synthesized_event);if (err <=0 ) {pr_err ("Couldn't record tracing data.\n" );
@@ -545,8 +546,7 @@ out_child:if (!rec->no_buildid)process_buildids (rec); -perf_session__write_header (rec->session, rec->evlist, - file->fd, true); +perf_session__write_header (rec->session, rec->evlist, fd, true); }if (!err && !quiet) {
Signature · 1 line
1.9.3
Arnaldo Carvalho de Melo
maintainerPATCH 10/10 perf symbols: Convert lseek + read to pread
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
When dso_cache__read() is called, it reads data from the given offset using lseek + normal read syscall. It can be combined to a single pread syscall.
--- tools/perf/util/dso.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
tools/perf/util/dso.c +1 -5
@@ -532,12 +532,8 @@ dso_cache__read(struct dso *dso, u64 offset, u8 *data, ssize_t size)break ; cache_offset = offset &DSO__DATA_CACHE_MASK ; - ret = -EINVAL ; -if (-1 ==lseek (dso->data.fd, cache_offset,SEEK_SET )) -break ; - - ret =read (dso->data.fd, cache->data,DSO__DATA_CACHE_SIZE ); + ret =pread (dso->data.fd, cache->data,DSO__DATA_CACHE_SIZE , cache_offset);if (ret <=0 )break ;
Signature · 1 line
1.9.3
Quoted 74 lines · Arnaldo Carvalho de Melo
Hi Ingo,
Please consider pulling, there is some more stuff in queue to be
processed, but better send in smaller batches,- Arnaldo
The following changes since commit
b3890e4704594fa23abe1395d1fafc97d3214be8:Merge branch 'perf/hw_breakpoints' into perf/core (2015-01-28 15:48:59 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.gittags/perf-core-for-mingofor you to fetch changes up to
c52686f9f888d23ca72f1309e86af8e91d075697:perf symbols: Convert lseek + read to pread (2015-01-29 17:02:01 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:User visible:
- Show precise number of samples in at the end of a 'record' session, if processing build ids, since we will then traverse the whole perf.data file and see all the
PERF_RECORD_SAMPLErecords, otherwise stop showing the previous off-base heuristicly counted number of "samples" (Namhyung Kim).- Support to read compressed module from build-id cache (Namhyung Kim)
Infrastructure:
- Cache eh/debug frame offset for dwarf unwind (Namhyung Kim)
- Set header version correctly in all cases (Namhyung Kim)
- Set attr.task bit for a tracking event, to be consistent (Namhyung Kim) perf tools: Use
perf_data_file__fd()consistently
perf symbols: Convert lseek + read to pread- Don't rely on malloc working for sz 0, fixing another problem when using uClibc (Vineet Gupta)
- Provide stub for missing
pthread_attr_setaffinity_npfor libcs where this is not available, such as uClibc (Vineet Gupta)Signed-off-by Arnaldo Carvalho de Melo <[email protected]>----------------------------------------------------------------
Namhyung Kim (8):
perf callchain: Cache eh/debug frame offset for dwarf unwind perf tools: Do not use__perf_session__process_events()directly perf record: Show precise number of samples
perf header: Set header version correctly
perf evsel: Set attr.task bit for a tracking event
perf symbols: Support to read compressed module from build-id cache perf tools: Useperf_data_file__fd()consistently
perf symbols: Convert lseek + read to preadVineet Gupta (2):
perf evsel: Don't rely on malloc working for sz 0 perf tools: Provide stub for missingpthread_attr_setaffinity_nptools/perf/bench/futex.h | 13 ++++ tools/perf/builtin-inject.c | 5 +- tools/perf/builtin-record.c | 70 +++++++++++++++------- tools/perf/config/Makefile | 6 ++ tools/perf/config/feature-checks/Makefile | 4 ++ tools/perf/config/feature-checks/test-all.c | 5 ++ .../test-pthread-attr-setaffinity-np.c | 14 +++++ tools/perf/util/dso.c | 6 +- tools/perf/util/dso.h | 1 +
Quoted 8 lines
tools/perf/util/evsel.c | 4 ++ tools/perf/util/header.c | 2 +- tools/perf/util/session.c | 6 +- tools/perf/util/session.h | 3 - tools/perf/util/symbol-elf.c | 13 ++-- tools/perf/util/unwind-libunwind.c | 31 ++++++---- 15 files changed, 131 insertions(+), 52 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-pthread-attr-setaffinity-np.c
Pulled into tip:perf/core, thanks a lot Arnaldo!
Ingo