Skip to content

Commit

Permalink
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
 "On the kernel side there's two x86 PMU driver fixes and a uprobes fix,
  plus on the tooling side there's a number of fixes and some late
  updates"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (36 commits)
  perf sched timehist: Fix invalid period calculation
  perf sched timehist: Remove hardcoded 'comm_width' check at print_summary
  perf sched timehist: Enlarge default 'comm_width'
  perf sched timehist: Honour 'comm_width' when aligning the headers
  perf/x86: Fix overlap counter scheduling bug
  perf/x86/pebs: Fix handling of PEBS buffer overflows
  samples/bpf: Move open_raw_sock to separate header
  samples/bpf: Remove perf_event_open() declaration
  samples/bpf: Be consistent with bpf_load_program bpf_insn parameter
  tools lib bpf: Add bpf_prog_{attach,detach}
  samples/bpf: Switch over to libbpf
  perf diff: Do not overwrite valid build id
  perf annotate: Don't throw error for zero length symbols
  perf bench futex: Fix lock-pi help string
  perf trace: Check if MAP_32BIT is defined (again)
  samples/bpf: Make perf_event_read() static
  uprobes: Fix uprobes on MIPS, allow for a cache flush after ixol breakpoint creation
  samples/bpf: Make samples more libbpf-centric
  tools lib bpf: Add flags to bpf_create_map()
  tools lib bpf: use __u32 from linux/types.h
  ...
  • Loading branch information
torvalds committed Dec 24, 2016
2 parents 9004fda + 3705b97 commit 00198da
Show file tree
Hide file tree
Showing 63 changed files with 1,104 additions and 750 deletions.
30 changes: 21 additions & 9 deletions arch/x86/events/intel/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2110,22 +2110,34 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
GLOBAL_STATUS_LBRS_FROZEN);
if (!status)
goto done;
/*
* In case multiple PEBS events are sampled at the same time,
* it is possible to have GLOBAL_STATUS bit 62 set indicating
* PEBS buffer overflow and also seeing at most 3 PEBS counters
* having their bits set in the status register. This is a sign
* that there was at least one PEBS record pending at the time
* of the PMU interrupt. PEBS counters must only be processed
* via the drain_pebs() calls and not via the regular sample
* processing loop coming after that the function, otherwise
* phony regular samples may be generated in the sampling buffer
* not marked with the EXACT tag. Another possibility is to have
* one PEBS event and at least one non-PEBS event whic hoverflows
* while PEBS has armed. In this case, bit 62 of GLOBAL_STATUS will
* not be set, yet the overflow status bit for the PEBS counter will
* be on Skylake.
*
* To avoid this problem, we systematically ignore the PEBS-enabled
* counters from the GLOBAL_STATUS mask and we always process PEBS
* events via drain_pebs().
*/
status &= ~cpuc->pebs_enabled;

/*
* PEBS overflow sets bit 62 in the global status register
*/
if (__test_and_clear_bit(62, (unsigned long *)&status)) {
handled++;
x86_pmu.drain_pebs(regs);
/*
* There are cases where, even though, the PEBS ovfl bit is set
* in GLOBAL_OVF_STATUS, the PEBS events may also have their
* overflow bits set for their counters. We must clear them
* here because they have been processed as exact samples in
* the drain_pebs() routine. They must not be processed again
* in the for_each_bit_set() loop for regular samples below.
*/
status &= ~cpuc->pebs_enabled;
status &= x86_pmu.intel_ctrl | GLOBAL_STATUS_TRACE_TOPAPMI;
}

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/events/intel/uncore_snbep.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ static struct event_constraint snbep_uncore_cbox_constraints[] = {
UNCORE_EVENT_CONSTRAINT(0x1c, 0xc),
UNCORE_EVENT_CONSTRAINT(0x1d, 0xc),
UNCORE_EVENT_CONSTRAINT(0x1e, 0xc),
EVENT_CONSTRAINT_OVERLAP(0x1f, 0xe, 0xff),
UNCORE_EVENT_CONSTRAINT(0x1f, 0xe),
UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
Expand Down
2 changes: 1 addition & 1 deletion kernel/events/uprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1194,7 +1194,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr)
/* Reserve the 1st slot for get_trampoline_vaddr() */
set_bit(0, area->bitmap);
atomic_set(&area->slot_count, 1);
copy_to_page(area->pages[0], 0, &insn, UPROBE_SWBP_INSN_SIZE);
arch_uprobe_copy_ixol(area->pages[0], 0, &insn, UPROBE_SWBP_INSN_SIZE);

if (!xol_add_vma(mm, area))
return area;
Expand Down
70 changes: 38 additions & 32 deletions samples/bpf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,40 +35,43 @@ hostprogs-y += tc_l2_redirect
hostprogs-y += lwt_len_hist
hostprogs-y += xdp_tx_iptunnel

test_lru_dist-objs := test_lru_dist.o libbpf.o
sock_example-objs := sock_example.o libbpf.o
fds_example-objs := bpf_load.o libbpf.o fds_example.o
sockex1-objs := bpf_load.o libbpf.o sockex1_user.o
sockex2-objs := bpf_load.o libbpf.o sockex2_user.o
sockex3-objs := bpf_load.o libbpf.o sockex3_user.o
tracex1-objs := bpf_load.o libbpf.o tracex1_user.o
tracex2-objs := bpf_load.o libbpf.o tracex2_user.o
tracex3-objs := bpf_load.o libbpf.o tracex3_user.o
tracex4-objs := bpf_load.o libbpf.o tracex4_user.o
tracex5-objs := bpf_load.o libbpf.o tracex5_user.o
tracex6-objs := bpf_load.o libbpf.o tracex6_user.o
test_probe_write_user-objs := bpf_load.o libbpf.o test_probe_write_user_user.o
trace_output-objs := bpf_load.o libbpf.o trace_output_user.o
lathist-objs := bpf_load.o libbpf.o lathist_user.o
offwaketime-objs := bpf_load.o libbpf.o offwaketime_user.o
spintest-objs := bpf_load.o libbpf.o spintest_user.o
map_perf_test-objs := bpf_load.o libbpf.o map_perf_test_user.o
test_overhead-objs := bpf_load.o libbpf.o test_overhead_user.o
test_cgrp2_array_pin-objs := libbpf.o test_cgrp2_array_pin.o
test_cgrp2_attach-objs := libbpf.o test_cgrp2_attach.o
test_cgrp2_attach2-objs := libbpf.o test_cgrp2_attach2.o cgroup_helpers.o
test_cgrp2_sock-objs := libbpf.o test_cgrp2_sock.o
test_cgrp2_sock2-objs := bpf_load.o libbpf.o test_cgrp2_sock2.o
xdp1-objs := bpf_load.o libbpf.o xdp1_user.o
# Libbpf dependencies
LIBBPF := ../../tools/lib/bpf/bpf.o

test_lru_dist-objs := test_lru_dist.o $(LIBBPF)
sock_example-objs := sock_example.o $(LIBBPF)
fds_example-objs := bpf_load.o $(LIBBPF) fds_example.o
sockex1-objs := bpf_load.o $(LIBBPF) sockex1_user.o
sockex2-objs := bpf_load.o $(LIBBPF) sockex2_user.o
sockex3-objs := bpf_load.o $(LIBBPF) sockex3_user.o
tracex1-objs := bpf_load.o $(LIBBPF) tracex1_user.o
tracex2-objs := bpf_load.o $(LIBBPF) tracex2_user.o
tracex3-objs := bpf_load.o $(LIBBPF) tracex3_user.o
tracex4-objs := bpf_load.o $(LIBBPF) tracex4_user.o
tracex5-objs := bpf_load.o $(LIBBPF) tracex5_user.o
tracex6-objs := bpf_load.o $(LIBBPF) tracex6_user.o
test_probe_write_user-objs := bpf_load.o $(LIBBPF) test_probe_write_user_user.o
trace_output-objs := bpf_load.o $(LIBBPF) trace_output_user.o
lathist-objs := bpf_load.o $(LIBBPF) lathist_user.o
offwaketime-objs := bpf_load.o $(LIBBPF) offwaketime_user.o
spintest-objs := bpf_load.o $(LIBBPF) spintest_user.o
map_perf_test-objs := bpf_load.o $(LIBBPF) map_perf_test_user.o
test_overhead-objs := bpf_load.o $(LIBBPF) test_overhead_user.o
test_cgrp2_array_pin-objs := $(LIBBPF) test_cgrp2_array_pin.o
test_cgrp2_attach-objs := $(LIBBPF) test_cgrp2_attach.o
test_cgrp2_attach2-objs := $(LIBBPF) test_cgrp2_attach2.o cgroup_helpers.o
test_cgrp2_sock-objs := $(LIBBPF) test_cgrp2_sock.o
test_cgrp2_sock2-objs := bpf_load.o $(LIBBPF) test_cgrp2_sock2.o
xdp1-objs := bpf_load.o $(LIBBPF) xdp1_user.o
# reuse xdp1 source intentionally
xdp2-objs := bpf_load.o libbpf.o xdp1_user.o
test_current_task_under_cgroup-objs := bpf_load.o libbpf.o cgroup_helpers.o \
xdp2-objs := bpf_load.o $(LIBBPF) xdp1_user.o
test_current_task_under_cgroup-objs := bpf_load.o $(LIBBPF) cgroup_helpers.o \
test_current_task_under_cgroup_user.o
trace_event-objs := bpf_load.o libbpf.o trace_event_user.o
sampleip-objs := bpf_load.o libbpf.o sampleip_user.o
tc_l2_redirect-objs := bpf_load.o libbpf.o tc_l2_redirect_user.o
lwt_len_hist-objs := bpf_load.o libbpf.o lwt_len_hist_user.o
xdp_tx_iptunnel-objs := bpf_load.o libbpf.o xdp_tx_iptunnel_user.o
trace_event-objs := bpf_load.o $(LIBBPF) trace_event_user.o
sampleip-objs := bpf_load.o $(LIBBPF) sampleip_user.o
tc_l2_redirect-objs := bpf_load.o $(LIBBPF) tc_l2_redirect_user.o
lwt_len_hist-objs := bpf_load.o $(LIBBPF) lwt_len_hist_user.o
xdp_tx_iptunnel-objs := bpf_load.o $(LIBBPF) xdp_tx_iptunnel_user.o

# Tell kbuild to always build the programs
always := $(hostprogs-y)
Expand Down Expand Up @@ -104,7 +107,10 @@ always += lwt_len_hist_kern.o
always += xdp_tx_iptunnel_kern.o

HOSTCFLAGS += -I$(objtree)/usr/include
HOSTCFLAGS += -I$(srctree)/tools/lib/
HOSTCFLAGS += -I$(srctree)/tools/testing/selftests/bpf/
HOSTCFLAGS += -I$(srctree)/tools/lib/ -I$(srctree)/tools/include
HOSTCFLAGS += -I$(srctree)/tools/perf

HOSTCFLAGS_bpf_load.o += -I$(objtree)/usr/include -Wno-unused-variable
HOSTLOADLIBES_fds_example += -lelf
Expand Down
4 changes: 2 additions & 2 deletions samples/bpf/README.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
eBPF sample programs
====================

This directory contains a mini eBPF library, test stubs, verifier
test-suite and examples for using eBPF.
This directory contains a test stubs, verifier test-suite and examples
for using eBPF. The examples use libbpf from tools/lib/bpf.

Build dependencies
==================
Expand Down
21 changes: 16 additions & 5 deletions samples/bpf/bpf_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,34 @@
#include <poll.h>
#include <ctype.h>
#include "libbpf.h"
#include "bpf_helpers.h"
#include "bpf_load.h"
#include "perf-sys.h"

#define DEBUGFS "/sys/kernel/debug/tracing/"

static char license[128];
static int kern_version;
static bool processed_sec[128];
char bpf_log_buf[BPF_LOG_BUF_SIZE];
int map_fd[MAX_MAPS];
int prog_fd[MAX_PROGS];
int event_fd[MAX_PROGS];
int prog_cnt;
int prog_array_fd = -1;

struct bpf_map_def {
unsigned int type;
unsigned int key_size;
unsigned int value_size;
unsigned int max_entries;
unsigned int map_flags;
};

static int populate_prog_array(const char *event, int prog_fd)
{
int ind = atoi(event), err;

err = bpf_update_elem(prog_array_fd, &ind, &prog_fd, BPF_ANY);
err = bpf_map_update_elem(prog_array_fd, &ind, &prog_fd, BPF_ANY);
if (err < 0) {
printf("failed to store prog_fd in prog_array\n");
return -1;
Expand All @@ -58,6 +67,7 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
bool is_perf_event = strncmp(event, "perf_event", 10) == 0;
bool is_cgroup_skb = strncmp(event, "cgroup/skb", 10) == 0;
bool is_cgroup_sk = strncmp(event, "cgroup/sock", 11) == 0;
size_t insns_cnt = size / sizeof(struct bpf_insn);
enum bpf_prog_type prog_type;
char buf[256];
int fd, efd, err, id;
Expand Down Expand Up @@ -87,9 +97,10 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
return -1;
}

fd = bpf_prog_load(prog_type, prog, size, license, kern_version);
fd = bpf_load_program(prog_type, prog, insns_cnt, license, kern_version,
bpf_log_buf, BPF_LOG_BUF_SIZE);
if (fd < 0) {
printf("bpf_prog_load() err=%d\n%s", errno, bpf_log_buf);
printf("bpf_load_program() err=%d\n%s", errno, bpf_log_buf);
return -1;
}

Expand Down Expand Up @@ -169,7 +180,7 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
id = atoi(buf);
attr.config = id;

efd = perf_event_open(&attr, -1/*pid*/, 0/*cpu*/, -1/*group_fd*/, 0);
efd = sys_perf_event_open(&attr, -1/*pid*/, 0/*cpu*/, -1/*group_fd*/, 0);
if (efd < 0) {
printf("event %d fd %d err %s\n", id, efd, strerror(errno));
return -1;
Expand Down
3 changes: 3 additions & 0 deletions samples/bpf/bpf_load.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#ifndef __BPF_LOAD_H
#define __BPF_LOAD_H

#include "libbpf.h"

#define MAX_MAPS 32
#define MAX_PROGS 32

extern int map_fd[MAX_MAPS];
extern int prog_fd[MAX_PROGS];
extern int event_fd[MAX_PROGS];
extern char bpf_log_buf[BPF_LOG_BUF_SIZE];
extern int prog_cnt;

/* parses elf file compiled by llvm .c->.o
Expand Down
13 changes: 8 additions & 5 deletions samples/bpf/fds_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "bpf_load.h"
#include "libbpf.h"
#include "sock_example.h"

#define BPF_F_PIN (1 << 0)
#define BPF_F_GET (1 << 1)
Expand Down Expand Up @@ -49,17 +50,19 @@ static int bpf_map_create(void)

static int bpf_prog_create(const char *object)
{
static const struct bpf_insn insns[] = {
static struct bpf_insn insns[] = {
BPF_MOV64_IMM(BPF_REG_0, 1),
BPF_EXIT_INSN(),
};
size_t insns_cnt = sizeof(insns) / sizeof(struct bpf_insn);

if (object) {
assert(!load_bpf_file((char *)object));
return prog_fd[0];
} else {
return bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER,
insns, sizeof(insns), "GPL", 0);
return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER,
insns, insns_cnt, "GPL", 0,
bpf_log_buf, BPF_LOG_BUF_SIZE);
}
}

Expand All @@ -83,12 +86,12 @@ static int bpf_do_map(const char *file, uint32_t flags, uint32_t key,
}

if ((flags & BPF_F_KEY_VAL) == BPF_F_KEY_VAL) {
ret = bpf_update_elem(fd, &key, &value, 0);
ret = bpf_map_update_elem(fd, &key, &value, 0);
printf("bpf: fd:%d u->(%u:%u) ret:(%d,%s)\n", fd, key, value,
ret, strerror(errno));
assert(ret == 0);
} else if (flags & BPF_F_KEY) {
ret = bpf_lookup_elem(fd, &key, &value);
ret = bpf_map_lookup_elem(fd, &key, &value);
printf("bpf: fd:%d l->(%u):%u ret:(%d,%s)\n", fd, key, value,
ret, strerror(errno));
assert(ret == 0);
Expand Down
2 changes: 1 addition & 1 deletion samples/bpf/lathist_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static void get_data(int fd)
for (c = 0; c < MAX_CPU; c++) {
for (i = 0; i < MAX_ENTRIES; i++) {
key = c * MAX_ENTRIES + i;
bpf_lookup_elem(fd, &key, &value);
bpf_map_lookup_elem(fd, &key, &value);

cpu_hist[c].data[i] = value;
if (value > cpu_hist[c].max)
Expand Down
Loading

0 comments on commit 00198da

Please sign in to comment.