Commit 1d229d54dbc26971142f61c3d271a68db236d178
Exists in
master
and in
4 other branches
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kerne…
…l/git/tip/linux-2.6-tip * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: perf symbols: Check '/tmp/perf-' symbol file ownership perf sched: Usage leftover from trace -> script rename perf sched: Do not delete session object prematurely perf tools: Check $HOME/.perfconfig ownership perf, x86: Add model 45 SandyBridge support perf tools: Add support to install perf python extension perf tools: do not look at ./config for configuration perf tools: Make clean leaves some files perf lock: Dropping unsupported ':r' modifier perf probe: Fix coredump introduced by probe module option jump label: Reduce the cycle count by changing the link order perf report: Use ui__warning in some more places perf python: Add PERF_RECORD_{LOST,READ,SAMPLE} routine tables perf evlist: Introduce 'disable' method trace events: Update version number reference to new 3.x scheme for EVENT_POWER_TRACING_DEPRECATED perf buildid-cache: Zero out buffer of filenames when adding/removing buildid
Showing 16 changed files Side-by-side Diff
- arch/x86/kernel/cpu/perf_event_intel.c
- kernel/Makefile
- kernel/trace/Kconfig
- tools/perf/Makefile
- tools/perf/builtin-lock.c
- tools/perf/builtin-record.c
- tools/perf/builtin-report.c
- tools/perf/builtin-sched.c
- tools/perf/util/config.c
- tools/perf/util/evlist.c
- tools/perf/util/evlist.h
- tools/perf/util/header.c
- tools/perf/util/probe-event.c
- tools/perf/util/python.c
- tools/perf/util/setup.py
- tools/perf/util/symbol.c
arch/x86/kernel/cpu/perf_event_intel.c
kernel/Makefile
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ |
11 | 11 | hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ |
12 | 12 | notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \ |
13 | - async.o range.o jump_label.o | |
13 | + async.o range.o | |
14 | 14 | obj-y += groups.o |
15 | 15 | |
16 | 16 | ifdef CONFIG_FUNCTION_TRACER |
... | ... | @@ -107,6 +107,7 @@ |
107 | 107 | obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o |
108 | 108 | obj-$(CONFIG_PADATA) += padata.o |
109 | 109 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o |
110 | +obj-$(CONFIG_JUMP_LABEL) += jump_label.o | |
110 | 111 | |
111 | 112 | ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) |
112 | 113 | # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is |
kernel/trace/Kconfig
tools/perf/Makefile
... | ... | @@ -181,9 +181,9 @@ |
181 | 181 | |
182 | 182 | $(OUTPUT)python/perf.so: $(PYRF_OBJS) |
183 | 183 | $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \ |
184 | - --quiet build_ext \ | |
185 | - --build-lib='$(OUTPUT)python' \ | |
186 | - --build-temp='$(OUTPUT)python/temp' | |
184 | + --quiet build_ext; \ | |
185 | + mkdir -p $(OUTPUT)python && \ | |
186 | + cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/ | |
187 | 187 | # |
188 | 188 | # No Perl scripts right now: |
189 | 189 | # |
190 | 190 | |
... | ... | @@ -509,10 +509,14 @@ |
509 | 509 | |
510 | 510 | PYTHON_WORD := $(call shell-wordify,$(PYTHON)) |
511 | 511 | |
512 | - python-clean := $(PYTHON_WORD) util/setup.py clean \ | |
513 | - --build-lib='$(OUTPUT)python' \ | |
514 | - --build-temp='$(OUTPUT)python/temp' | |
512 | + # python extension build directories | |
513 | + PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/ | |
514 | + PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/ | |
515 | + PYTHON_EXTBUILD_TMP := $(PYTHON_EXTBUILD)tmp/ | |
516 | + export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP | |
515 | 517 | |
518 | + python-clean := rm -rf $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so | |
519 | + | |
516 | 520 | ifdef NO_LIBPYTHON |
517 | 521 | $(call disable-python) |
518 | 522 | else |
... | ... | @@ -868,6 +872,9 @@ |
868 | 872 | $(INSTALL) scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python' |
869 | 873 | $(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin' |
870 | 874 | |
875 | +install-python_ext: | |
876 | + $(PYTHON_WORD) util/setup.py --quiet install --root='/$(DESTDIR_SQ)' | |
877 | + | |
871 | 878 | install-doc: |
872 | 879 | $(MAKE) -C Documentation install |
873 | 880 | |
... | ... | @@ -895,7 +902,7 @@ |
895 | 902 | ### Cleaning rules |
896 | 903 | |
897 | 904 | clean: |
898 | - $(RM) $(OUTPUT){*.o,*/*.o,*/*/*.o,*/*/*/*.o,$(LIB_FILE),perf-archive} | |
905 | + $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) | |
899 | 906 | $(RM) $(ALL_PROGRAMS) perf |
900 | 907 | $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* |
901 | 908 | $(MAKE) -C Documentation/ clean |
tools/perf/builtin-lock.c
... | ... | @@ -942,10 +942,10 @@ |
942 | 942 | "-f", |
943 | 943 | "-m", "1024", |
944 | 944 | "-c", "1", |
945 | - "-e", "lock:lock_acquire:r", | |
946 | - "-e", "lock:lock_acquired:r", | |
947 | - "-e", "lock:lock_contended:r", | |
948 | - "-e", "lock:lock_release:r", | |
945 | + "-e", "lock:lock_acquire", | |
946 | + "-e", "lock:lock_acquired", | |
947 | + "-e", "lock:lock_contended", | |
948 | + "-e", "lock:lock_release", | |
949 | 949 | }; |
950 | 950 | |
951 | 951 | static int __cmd_record(int argc, const char **argv) |
tools/perf/builtin-record.c
... | ... | @@ -30,8 +30,6 @@ |
30 | 30 | #include <sched.h> |
31 | 31 | #include <sys/mman.h> |
32 | 32 | |
33 | -#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | |
34 | - | |
35 | 33 | enum write_mode_t { |
36 | 34 | WRITE_FORCE, |
37 | 35 | WRITE_APPEND |
... | ... | @@ -438,7 +436,6 @@ |
438 | 436 | |
439 | 437 | static int __cmd_record(int argc, const char **argv) |
440 | 438 | { |
441 | - int i; | |
442 | 439 | struct stat st; |
443 | 440 | int flags; |
444 | 441 | int err; |
... | ... | @@ -682,7 +679,6 @@ |
682 | 679 | |
683 | 680 | for (;;) { |
684 | 681 | int hits = samples; |
685 | - int thread; | |
686 | 682 | |
687 | 683 | mmap_read_all(); |
688 | 684 | |
... | ... | @@ -693,19 +689,8 @@ |
693 | 689 | waking++; |
694 | 690 | } |
695 | 691 | |
696 | - if (done) { | |
697 | - for (i = 0; i < evsel_list->cpus->nr; i++) { | |
698 | - struct perf_evsel *pos; | |
699 | - | |
700 | - list_for_each_entry(pos, &evsel_list->entries, node) { | |
701 | - for (thread = 0; | |
702 | - thread < evsel_list->threads->nr; | |
703 | - thread++) | |
704 | - ioctl(FD(pos, i, thread), | |
705 | - PERF_EVENT_IOC_DISABLE); | |
706 | - } | |
707 | - } | |
708 | - } | |
692 | + if (done) | |
693 | + perf_evlist__disable(evsel_list); | |
709 | 694 | } |
710 | 695 | |
711 | 696 | if (quiet || signr == SIGUSR1) |
tools/perf/builtin-report.c
... | ... | @@ -162,23 +162,22 @@ |
162 | 162 | { |
163 | 163 | if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { |
164 | 164 | if (sort__has_parent) { |
165 | - fprintf(stderr, "selected --sort parent, but no" | |
166 | - " callchain data. Did you call" | |
167 | - " perf record without -g?\n"); | |
165 | + ui__warning("Selected --sort parent, but no " | |
166 | + "callchain data. Did you call " | |
167 | + "'perf record' without -g?\n"); | |
168 | 168 | return -EINVAL; |
169 | 169 | } |
170 | 170 | if (symbol_conf.use_callchain) { |
171 | - fprintf(stderr, "selected -g but no callchain data." | |
172 | - " Did you call perf record without" | |
173 | - " -g?\n"); | |
171 | + ui__warning("Selected -g but no callchain data. Did " | |
172 | + "you call 'perf record' without -g?\n"); | |
174 | 173 | return -1; |
175 | 174 | } |
176 | 175 | } else if (!dont_use_callchains && callchain_param.mode != CHAIN_NONE && |
177 | 176 | !symbol_conf.use_callchain) { |
178 | 177 | symbol_conf.use_callchain = true; |
179 | 178 | if (callchain_register_param(&callchain_param) < 0) { |
180 | - fprintf(stderr, "Can't register callchain" | |
181 | - " params\n"); | |
179 | + ui__warning("Can't register callchain " | |
180 | + "params.\n"); | |
182 | 181 | return -EINVAL; |
183 | 182 | } |
184 | 183 | } |
tools/perf/builtin-sched.c
... | ... | @@ -1637,23 +1637,29 @@ |
1637 | 1637 | .ordered_samples = true, |
1638 | 1638 | }; |
1639 | 1639 | |
1640 | -static int read_events(void) | |
1640 | +static void read_events(bool destroy, struct perf_session **psession) | |
1641 | 1641 | { |
1642 | 1642 | int err = -EINVAL; |
1643 | 1643 | struct perf_session *session = perf_session__new(input_name, O_RDONLY, |
1644 | 1644 | 0, false, &event_ops); |
1645 | 1645 | if (session == NULL) |
1646 | - return -ENOMEM; | |
1646 | + die("No Memory"); | |
1647 | 1647 | |
1648 | 1648 | if (perf_session__has_traces(session, "record -R")) { |
1649 | 1649 | err = perf_session__process_events(session, &event_ops); |
1650 | + if (err) | |
1651 | + die("Failed to process events, error %d", err); | |
1652 | + | |
1650 | 1653 | nr_events = session->hists.stats.nr_events[0]; |
1651 | 1654 | nr_lost_events = session->hists.stats.total_lost; |
1652 | 1655 | nr_lost_chunks = session->hists.stats.nr_events[PERF_RECORD_LOST]; |
1653 | 1656 | } |
1654 | 1657 | |
1655 | - perf_session__delete(session); | |
1656 | - return err; | |
1658 | + if (destroy) | |
1659 | + perf_session__delete(session); | |
1660 | + | |
1661 | + if (psession) | |
1662 | + *psession = session; | |
1657 | 1663 | } |
1658 | 1664 | |
1659 | 1665 | static void print_bad_events(void) |
1660 | 1666 | |
... | ... | @@ -1689,9 +1695,10 @@ |
1689 | 1695 | static void __cmd_lat(void) |
1690 | 1696 | { |
1691 | 1697 | struct rb_node *next; |
1698 | + struct perf_session *session; | |
1692 | 1699 | |
1693 | 1700 | setup_pager(); |
1694 | - read_events(); | |
1701 | + read_events(false, &session); | |
1695 | 1702 | sort_lat(); |
1696 | 1703 | |
1697 | 1704 | printf("\n ---------------------------------------------------------------------------------------------------------------\n"); |
... | ... | @@ -1717,6 +1724,7 @@ |
1717 | 1724 | print_bad_events(); |
1718 | 1725 | printf("\n"); |
1719 | 1726 | |
1727 | + perf_session__delete(session); | |
1720 | 1728 | } |
1721 | 1729 | |
1722 | 1730 | static struct trace_sched_handler map_ops = { |
... | ... | @@ -1731,7 +1739,7 @@ |
1731 | 1739 | max_cpu = sysconf(_SC_NPROCESSORS_CONF); |
1732 | 1740 | |
1733 | 1741 | setup_pager(); |
1734 | - read_events(); | |
1742 | + read_events(true, NULL); | |
1735 | 1743 | print_bad_events(); |
1736 | 1744 | } |
1737 | 1745 | |
... | ... | @@ -1744,7 +1752,7 @@ |
1744 | 1752 | |
1745 | 1753 | test_calibrations(); |
1746 | 1754 | |
1747 | - read_events(); | |
1755 | + read_events(true, NULL); | |
1748 | 1756 | |
1749 | 1757 | printf("nr_run_events: %ld\n", nr_run_events); |
1750 | 1758 | printf("nr_sleep_events: %ld\n", nr_sleep_events); |
... | ... | @@ -1769,7 +1777,7 @@ |
1769 | 1777 | |
1770 | 1778 | |
1771 | 1779 | static const char * const sched_usage[] = { |
1772 | - "perf sched [<options>] {record|latency|map|replay|trace}", | |
1780 | + "perf sched [<options>] {record|latency|map|replay|script}", | |
1773 | 1781 | NULL |
1774 | 1782 | }; |
1775 | 1783 |
tools/perf/util/config.c
... | ... | @@ -399,7 +399,6 @@ |
399 | 399 | int perf_config(config_fn_t fn, void *data) |
400 | 400 | { |
401 | 401 | int ret = 0, found = 0; |
402 | - char *repo_config = NULL; | |
403 | 402 | const char *home = NULL; |
404 | 403 | |
405 | 404 | /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */ |
406 | 405 | |
407 | 406 | |
408 | 407 | |
409 | 408 | |
... | ... | @@ -414,19 +413,32 @@ |
414 | 413 | home = getenv("HOME"); |
415 | 414 | if (perf_config_global() && home) { |
416 | 415 | char *user_config = strdup(mkpath("%s/.perfconfig", home)); |
417 | - if (!access(user_config, R_OK)) { | |
418 | - ret += perf_config_from_file(fn, user_config, data); | |
419 | - found += 1; | |
416 | + struct stat st; | |
417 | + | |
418 | + if (user_config == NULL) { | |
419 | + warning("Not enough memory to process %s/.perfconfig, " | |
420 | + "ignoring it.", home); | |
421 | + goto out; | |
420 | 422 | } |
421 | - free(user_config); | |
422 | - } | |
423 | 423 | |
424 | - repo_config = perf_pathdup("config"); | |
425 | - if (!access(repo_config, R_OK)) { | |
426 | - ret += perf_config_from_file(fn, repo_config, data); | |
424 | + if (stat(user_config, &st) < 0) | |
425 | + goto out_free; | |
426 | + | |
427 | + if (st.st_uid && (st.st_uid != geteuid())) { | |
428 | + warning("File %s not owned by current user or root, " | |
429 | + "ignoring it.", user_config); | |
430 | + goto out_free; | |
431 | + } | |
432 | + | |
433 | + if (!st.st_size) | |
434 | + goto out_free; | |
435 | + | |
436 | + ret += perf_config_from_file(fn, user_config, data); | |
427 | 437 | found += 1; |
438 | +out_free: | |
439 | + free(user_config); | |
428 | 440 | } |
429 | - free(repo_config); | |
441 | +out: | |
430 | 442 | if (found == 0) |
431 | 443 | return -1; |
432 | 444 | return ret; |
tools/perf/util/evlist.c
... | ... | @@ -91,6 +91,19 @@ |
91 | 91 | return 0; |
92 | 92 | } |
93 | 93 | |
94 | +void perf_evlist__disable(struct perf_evlist *evlist) | |
95 | +{ | |
96 | + int cpu, thread; | |
97 | + struct perf_evsel *pos; | |
98 | + | |
99 | + for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { | |
100 | + list_for_each_entry(pos, &evlist->entries, node) { | |
101 | + for (thread = 0; thread < evlist->threads->nr; thread++) | |
102 | + ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_DISABLE); | |
103 | + } | |
104 | + } | |
105 | +} | |
106 | + | |
94 | 107 | int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) |
95 | 108 | { |
96 | 109 | int nfds = evlist->cpus->nr * evlist->threads->nr * evlist->nr_entries; |
tools/perf/util/evlist.h
... | ... | @@ -53,6 +53,8 @@ |
53 | 53 | int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite); |
54 | 54 | void perf_evlist__munmap(struct perf_evlist *evlist); |
55 | 55 | |
56 | +void perf_evlist__disable(struct perf_evlist *evlist); | |
57 | + | |
56 | 58 | static inline void perf_evlist__set_maps(struct perf_evlist *evlist, |
57 | 59 | struct cpu_map *cpus, |
58 | 60 | struct thread_map *threads) |
tools/perf/util/header.c
... | ... | @@ -189,8 +189,8 @@ |
189 | 189 | const char *name, bool is_kallsyms) |
190 | 190 | { |
191 | 191 | const size_t size = PATH_MAX; |
192 | - char *realname, *filename = malloc(size), | |
193 | - *linkname = malloc(size), *targetname; | |
192 | + char *realname, *filename = zalloc(size), | |
193 | + *linkname = zalloc(size), *targetname; | |
194 | 194 | int len, err = -1; |
195 | 195 | |
196 | 196 | if (is_kallsyms) { |
... | ... | @@ -254,8 +254,8 @@ |
254 | 254 | int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) |
255 | 255 | { |
256 | 256 | const size_t size = PATH_MAX; |
257 | - char *filename = malloc(size), | |
258 | - *linkname = malloc(size); | |
257 | + char *filename = zalloc(size), | |
258 | + *linkname = zalloc(size); | |
259 | 259 | int err = -1; |
260 | 260 | |
261 | 261 | if (filename == NULL || linkname == NULL) |
tools/perf/util/probe-event.c
... | ... | @@ -1820,11 +1820,15 @@ |
1820 | 1820 | ret = -ENOMEM; |
1821 | 1821 | goto error; |
1822 | 1822 | } |
1823 | - tev->point.module = strdup(module); | |
1824 | - if (tev->point.module == NULL) { | |
1825 | - ret = -ENOMEM; | |
1826 | - goto error; | |
1823 | + | |
1824 | + if (module) { | |
1825 | + tev->point.module = strdup(module); | |
1826 | + if (tev->point.module == NULL) { | |
1827 | + ret = -ENOMEM; | |
1828 | + goto error; | |
1829 | + } | |
1827 | 1830 | } |
1831 | + | |
1828 | 1832 | tev->point.offset = pev->point.offset; |
1829 | 1833 | tev->point.retprobe = pev->point.retprobe; |
1830 | 1834 | tev->nargs = pev->nargs; |
tools/perf/util/python.c
... | ... | @@ -187,16 +187,119 @@ |
187 | 187 | .tp_repr = (reprfunc)pyrf_throttle_event__repr, |
188 | 188 | }; |
189 | 189 | |
190 | +static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object."); | |
191 | + | |
192 | +static PyMemberDef pyrf_lost_event__members[] = { | |
193 | + sample_members | |
194 | + member_def(lost_event, id, T_ULONGLONG, "event id"), | |
195 | + member_def(lost_event, lost, T_ULONGLONG, "number of lost events"), | |
196 | + { .name = NULL, }, | |
197 | +}; | |
198 | + | |
199 | +static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent) | |
200 | +{ | |
201 | + PyObject *ret; | |
202 | + char *s; | |
203 | + | |
204 | + if (asprintf(&s, "{ type: lost, id: %#" PRIx64 ", " | |
205 | + "lost: %#" PRIx64 " }", | |
206 | + pevent->event.lost.id, pevent->event.lost.lost) < 0) { | |
207 | + ret = PyErr_NoMemory(); | |
208 | + } else { | |
209 | + ret = PyString_FromString(s); | |
210 | + free(s); | |
211 | + } | |
212 | + return ret; | |
213 | +} | |
214 | + | |
215 | +static PyTypeObject pyrf_lost_event__type = { | |
216 | + PyVarObject_HEAD_INIT(NULL, 0) | |
217 | + .tp_name = "perf.lost_event", | |
218 | + .tp_basicsize = sizeof(struct pyrf_event), | |
219 | + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, | |
220 | + .tp_doc = pyrf_lost_event__doc, | |
221 | + .tp_members = pyrf_lost_event__members, | |
222 | + .tp_repr = (reprfunc)pyrf_lost_event__repr, | |
223 | +}; | |
224 | + | |
225 | +static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object."); | |
226 | + | |
227 | +static PyMemberDef pyrf_read_event__members[] = { | |
228 | + sample_members | |
229 | + member_def(read_event, pid, T_UINT, "event pid"), | |
230 | + member_def(read_event, tid, T_UINT, "event tid"), | |
231 | + { .name = NULL, }, | |
232 | +}; | |
233 | + | |
234 | +static PyObject *pyrf_read_event__repr(struct pyrf_event *pevent) | |
235 | +{ | |
236 | + return PyString_FromFormat("{ type: read, pid: %u, tid: %u }", | |
237 | + pevent->event.read.pid, | |
238 | + pevent->event.read.tid); | |
239 | + /* | |
240 | + * FIXME: return the array of read values, | |
241 | + * making this method useful ;-) | |
242 | + */ | |
243 | +} | |
244 | + | |
245 | +static PyTypeObject pyrf_read_event__type = { | |
246 | + PyVarObject_HEAD_INIT(NULL, 0) | |
247 | + .tp_name = "perf.read_event", | |
248 | + .tp_basicsize = sizeof(struct pyrf_event), | |
249 | + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, | |
250 | + .tp_doc = pyrf_read_event__doc, | |
251 | + .tp_members = pyrf_read_event__members, | |
252 | + .tp_repr = (reprfunc)pyrf_read_event__repr, | |
253 | +}; | |
254 | + | |
255 | +static char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object."); | |
256 | + | |
257 | +static PyMemberDef pyrf_sample_event__members[] = { | |
258 | + sample_members | |
259 | + member_def(perf_event_header, type, T_UINT, "event type"), | |
260 | + { .name = NULL, }, | |
261 | +}; | |
262 | + | |
263 | +static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent) | |
264 | +{ | |
265 | + PyObject *ret; | |
266 | + char *s; | |
267 | + | |
268 | + if (asprintf(&s, "{ type: sample }") < 0) { | |
269 | + ret = PyErr_NoMemory(); | |
270 | + } else { | |
271 | + ret = PyString_FromString(s); | |
272 | + free(s); | |
273 | + } | |
274 | + return ret; | |
275 | +} | |
276 | + | |
277 | +static PyTypeObject pyrf_sample_event__type = { | |
278 | + PyVarObject_HEAD_INIT(NULL, 0) | |
279 | + .tp_name = "perf.sample_event", | |
280 | + .tp_basicsize = sizeof(struct pyrf_event), | |
281 | + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, | |
282 | + .tp_doc = pyrf_sample_event__doc, | |
283 | + .tp_members = pyrf_sample_event__members, | |
284 | + .tp_repr = (reprfunc)pyrf_sample_event__repr, | |
285 | +}; | |
286 | + | |
190 | 287 | static int pyrf_event__setup_types(void) |
191 | 288 | { |
192 | 289 | int err; |
193 | 290 | pyrf_mmap_event__type.tp_new = |
194 | 291 | pyrf_task_event__type.tp_new = |
195 | 292 | pyrf_comm_event__type.tp_new = |
293 | + pyrf_lost_event__type.tp_new = | |
294 | + pyrf_read_event__type.tp_new = | |
295 | + pyrf_sample_event__type.tp_new = | |
196 | 296 | pyrf_throttle_event__type.tp_new = PyType_GenericNew; |
197 | 297 | err = PyType_Ready(&pyrf_mmap_event__type); |
198 | 298 | if (err < 0) |
199 | 299 | goto out; |
300 | + err = PyType_Ready(&pyrf_lost_event__type); | |
301 | + if (err < 0) | |
302 | + goto out; | |
200 | 303 | err = PyType_Ready(&pyrf_task_event__type); |
201 | 304 | if (err < 0) |
202 | 305 | goto out; |
203 | 306 | |
204 | 307 | |
... | ... | @@ -206,20 +309,26 @@ |
206 | 309 | err = PyType_Ready(&pyrf_throttle_event__type); |
207 | 310 | if (err < 0) |
208 | 311 | goto out; |
312 | + err = PyType_Ready(&pyrf_read_event__type); | |
313 | + if (err < 0) | |
314 | + goto out; | |
315 | + err = PyType_Ready(&pyrf_sample_event__type); | |
316 | + if (err < 0) | |
317 | + goto out; | |
209 | 318 | out: |
210 | 319 | return err; |
211 | 320 | } |
212 | 321 | |
213 | 322 | static PyTypeObject *pyrf_event__type[] = { |
214 | 323 | [PERF_RECORD_MMAP] = &pyrf_mmap_event__type, |
215 | - [PERF_RECORD_LOST] = &pyrf_mmap_event__type, | |
324 | + [PERF_RECORD_LOST] = &pyrf_lost_event__type, | |
216 | 325 | [PERF_RECORD_COMM] = &pyrf_comm_event__type, |
217 | 326 | [PERF_RECORD_EXIT] = &pyrf_task_event__type, |
218 | 327 | [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type, |
219 | 328 | [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type, |
220 | 329 | [PERF_RECORD_FORK] = &pyrf_task_event__type, |
221 | - [PERF_RECORD_READ] = &pyrf_mmap_event__type, | |
222 | - [PERF_RECORD_SAMPLE] = &pyrf_mmap_event__type, | |
330 | + [PERF_RECORD_READ] = &pyrf_read_event__type, | |
331 | + [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type, | |
223 | 332 | }; |
224 | 333 | |
225 | 334 | static PyObject *pyrf_event__new(union perf_event *event) |
tools/perf/util/setup.py
... | ... | @@ -3,9 +3,27 @@ |
3 | 3 | from distutils.core import setup, Extension |
4 | 4 | from os import getenv |
5 | 5 | |
6 | +from distutils.command.build_ext import build_ext as _build_ext | |
7 | +from distutils.command.install_lib import install_lib as _install_lib | |
8 | + | |
9 | +class build_ext(_build_ext): | |
10 | + def finalize_options(self): | |
11 | + _build_ext.finalize_options(self) | |
12 | + self.build_lib = build_lib | |
13 | + self.build_temp = build_tmp | |
14 | + | |
15 | +class install_lib(_install_lib): | |
16 | + def finalize_options(self): | |
17 | + _install_lib.finalize_options(self) | |
18 | + self.build_dir = build_lib | |
19 | + | |
20 | + | |
6 | 21 | cflags = ['-fno-strict-aliasing', '-Wno-write-strings'] |
7 | 22 | cflags += getenv('CFLAGS', '').split() |
8 | 23 | |
24 | +build_lib = getenv('PYTHON_EXTBUILD_LIB') | |
25 | +build_tmp = getenv('PYTHON_EXTBUILD_TMP') | |
26 | + | |
9 | 27 | perf = Extension('perf', |
10 | 28 | sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c', |
11 | 29 | 'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c', |
... | ... | @@ -21,5 +39,6 @@ |
21 | 39 | author_email='acme@redhat.com', |
22 | 40 | license='GPLv2', |
23 | 41 | url='http://perf.wiki.kernel.org', |
24 | - ext_modules=[perf]) | |
42 | + ext_modules=[perf], | |
43 | + cmdclass={'build_ext': build_ext, 'install_lib': install_lib}) |
tools/perf/util/symbol.c
... | ... | @@ -1504,6 +1504,17 @@ |
1504 | 1504 | dso->adjust_symbols = 0; |
1505 | 1505 | |
1506 | 1506 | if (strncmp(dso->name, "/tmp/perf-", 10) == 0) { |
1507 | + struct stat st; | |
1508 | + | |
1509 | + if (stat(dso->name, &st) < 0) | |
1510 | + return -1; | |
1511 | + | |
1512 | + if (st.st_uid && (st.st_uid != geteuid())) { | |
1513 | + pr_warning("File %s not owned by current user or root, " | |
1514 | + "ignoring it.\n", dso->name); | |
1515 | + return -1; | |
1516 | + } | |
1517 | + | |
1507 | 1518 | ret = dso__load_perf_map(dso, map, filter); |
1508 | 1519 | dso->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT : |
1509 | 1520 | SYMTAB__NOT_FOUND; |