Merge tag 'v4.9-rc4' into sound

Bring in -rc4 patches so I can successfully merge the sound doc changes.
This commit is contained in:
Jonathan Corbet
2016-11-18 16:13:41 -07:00
993 changed files with 11222 additions and 6749 deletions

View File

@@ -194,6 +194,8 @@
#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
#define X86_FEATURE_AVX512_4VNNIW (7*32+16) /* AVX-512 Neural Network Instructions */
#define X86_FEATURE_AVX512_4FMAPS (7*32+17) /* AVX-512 Multiply Accumulation Single precision */
/* Virtualization flags: Linux defined, word 8 */
#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */

View File

@@ -98,6 +98,15 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
*type = INSN_FP_SETUP;
break;
case 0x8d:
if (insn.rex_prefix.bytes &&
insn.rex_prefix.bytes[0] == 0x48 &&
insn.modrm.nbytes && insn.modrm.bytes[0] == 0x2c &&
insn.sib.nbytes && insn.sib.bytes[0] == 0x24)
/* lea %(rsp), %rbp */
*type = INSN_FP_SETUP;
break;
case 0x90:
*type = INSN_NOP;
break;

View File

@@ -97,6 +97,19 @@ static struct instruction *next_insn_same_sec(struct objtool_file *file,
return next;
}
static bool gcov_enabled(struct objtool_file *file)
{
struct section *sec;
struct symbol *sym;
list_for_each_entry(sec, &file->elf->sections, list)
list_for_each_entry(sym, &sec->symbol_list, list)
if (!strncmp(sym->name, "__gcov_.", 8))
return true;
return false;
}
#define for_each_insn(file, insn) \
list_for_each_entry(insn, &file->insn_list, list)
@@ -713,6 +726,7 @@ static struct rela *find_switch_table(struct objtool_file *file,
struct instruction *insn)
{
struct rela *text_rela, *rodata_rela;
struct instruction *orig_insn = insn;
text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
if (text_rela && text_rela->sym == file->rodata->sym) {
@@ -733,10 +747,16 @@ static struct rela *find_switch_table(struct objtool_file *file,
/* case 3 */
func_for_each_insn_continue_reverse(file, func, insn) {
if (insn->type == INSN_JUMP_UNCONDITIONAL ||
insn->type == INSN_JUMP_DYNAMIC)
if (insn->type == INSN_JUMP_DYNAMIC)
break;
/* allow small jumps within the range */
if (insn->type == INSN_JUMP_UNCONDITIONAL &&
insn->jump_dest &&
(insn->jump_dest->offset <= insn->offset ||
insn->jump_dest->offset > orig_insn->offset))
break;
text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
insn->len);
if (text_rela && text_rela->sym == file->rodata->sym)
@@ -1034,34 +1054,6 @@ static int validate_branch(struct objtool_file *file,
return 0;
}
static bool is_gcov_insn(struct instruction *insn)
{
struct rela *rela;
struct section *sec;
struct symbol *sym;
unsigned long offset;
rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
if (!rela)
return false;
if (rela->sym->type != STT_SECTION)
return false;
sec = rela->sym->sec;
offset = rela->addend + insn->offset + insn->len - rela->offset;
list_for_each_entry(sym, &sec->symbol_list, list) {
if (sym->type != STT_OBJECT)
continue;
if (offset >= sym->offset && offset < sym->offset + sym->len)
return (!memcmp(sym->name, "__gcov0.", 8));
}
return false;
}
static bool is_kasan_insn(struct instruction *insn)
{
return (insn->type == INSN_CALL &&
@@ -1083,9 +1075,6 @@ static bool ignore_unreachable_insn(struct symbol *func,
if (insn->type == INSN_NOP)
return true;
if (is_gcov_insn(insn))
return true;
/*
* Check if this (or a subsequent) instruction is related to
* CONFIG_UBSAN or CONFIG_KASAN.
@@ -1146,6 +1135,19 @@ static int validate_functions(struct objtool_file *file)
ignore_unreachable_insn(func, insn))
continue;
/*
* gcov produces a lot of unreachable
* instructions. If we get an unreachable
* warning and the file has gcov enabled, just
* ignore it, and all other such warnings for
* the file.
*/
if (!file->ignore_unreachables &&
gcov_enabled(file)) {
file->ignore_unreachables = true;
continue;
}
WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset);
warnings++;
}

View File

@@ -36,7 +36,7 @@ SOLIBEXT=so
# The following works at least on fedora 23, you may need the next
# line for other distros.
ifneq (,$(wildcard /usr/sbin/update-java-alternatives))
JDIR=$(shell /usr/sbin/update-java-alternatives -l | head -1 | cut -d ' ' -f 3)
JDIR=$(shell /usr/sbin/update-java-alternatives -l | head -1 | awk '{print $$3}')
else
ifneq (,$(wildcard /usr/sbin/alternatives))
JDIR=$(shell alternatives --display java | tail -1 | cut -d' ' -f 5 | sed 's%/jre/bin/java.%%g')

View File

@@ -601,7 +601,8 @@ int hist_browser__run(struct hist_browser *browser, const char *help)
u64 nr_entries;
hbt->timer(hbt->arg);
if (hist_browser__has_filter(browser))
if (hist_browser__has_filter(browser) ||
symbol_conf.report_hierarchy)
hist_browser__update_nr_entries(browser);
nr_entries = hist_browser__nr_entries(browser);

View File

@@ -1895,7 +1895,6 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse
if (ph->needs_swap)
nr = bswap_32(nr);
ph->env.nr_numa_nodes = nr;
nodes = zalloc(sizeof(*nodes) * nr);
if (!nodes)
return -ENOMEM;
@@ -1932,6 +1931,7 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse
free(str);
}
ph->env.nr_numa_nodes = nr;
ph->env.numa_nodes = nodes;
return 0;

View File

@@ -136,8 +136,8 @@ do { \
group [^,{}/]*[{][^}]*[}][^,{}/]*
event_pmu [^,{}/]+[/][^/]*[/][^,{}/]*
event [^,{}/]+
bpf_object .*\.(o|bpf)
bpf_source .*\.c
bpf_object [^,{}]+\.(o|bpf)
bpf_source [^,{}]+\.c
num_dec [0-9]+
num_hex 0x[a-fA-F0-9]+

View File

@@ -3,8 +3,8 @@ all:
all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder ptr_ring noring
CFLAGS += -Wall
CFLAGS += -pthread -O2 -ggdb
LDFLAGS += -pthread -O2 -ggdb
CFLAGS += -pthread -O2 -ggdb -flto -fwhole-program
LDFLAGS += -pthread -O2 -ggdb -flto -fwhole-program
main.o: main.c main.h
ring.o: ring.c main.h

View File

@@ -96,7 +96,13 @@ void set_affinity(const char *arg)
assert(!ret);
}
static void run_guest(void)
void poll_used(void)
{
while (used_empty())
busy_wait();
}
static void __attribute__((__flatten__)) run_guest(void)
{
int completed_before;
int completed = 0;
@@ -141,7 +147,7 @@ static void run_guest(void)
assert(completed <= bufs);
assert(started <= bufs);
if (do_sleep) {
if (enable_call())
if (used_empty() && enable_call())
wait_for_call();
} else {
poll_used();
@@ -149,7 +155,13 @@ static void run_guest(void)
}
}
static void run_host(void)
void poll_avail(void)
{
while (avail_empty())
busy_wait();
}
static void __attribute__((__flatten__)) run_host(void)
{
int completed_before;
int completed = 0;
@@ -160,7 +172,7 @@ static void run_host(void)
for (;;) {
if (do_sleep) {
if (enable_kick())
if (avail_empty() && enable_kick())
wait_for_kick();
} else {
poll_avail();

View File

@@ -56,15 +56,15 @@ void alloc_ring(void);
int add_inbuf(unsigned, void *, void *);
void *get_buf(unsigned *, void **);
void disable_call();
bool used_empty();
bool enable_call();
void kick_available();
void poll_used();
/* host side */
void disable_kick();
bool avail_empty();
bool enable_kick();
bool use_buf(unsigned *, void **);
void call_used();
void poll_avail();
/* implemented by main */
extern bool do_sleep;

View File

@@ -24,8 +24,9 @@ void *get_buf(unsigned *lenp, void **bufp)
return "Buffer";
}
void poll_used(void)
bool used_empty()
{
return false;
}
void disable_call()
@@ -54,8 +55,9 @@ bool enable_kick()
assert(0);
}
void poll_avail(void)
bool avail_empty()
{
return false;
}
bool use_buf(unsigned *lenp, void **bufp)

View File

@@ -133,18 +133,9 @@ void *get_buf(unsigned *lenp, void **bufp)
return datap;
}
void poll_used(void)
bool used_empty()
{
void *b;
do {
if (tailcnt == headcnt || __ptr_ring_full(&array)) {
b = NULL;
barrier();
} else {
b = "Buffer\n";
}
} while (!b);
return (tailcnt == headcnt || __ptr_ring_full(&array));
}
void disable_call()
@@ -173,14 +164,9 @@ bool enable_kick()
assert(0);
}
void poll_avail(void)
bool avail_empty()
{
void *b;
do {
barrier();
b = __ptr_ring_peek(&array);
} while (!b);
return !__ptr_ring_peek(&array);
}
bool use_buf(unsigned *lenp, void **bufp)

View File

@@ -163,12 +163,11 @@ void *get_buf(unsigned *lenp, void **bufp)
return datap;
}
void poll_used(void)
bool used_empty()
{
unsigned head = (ring_size - 1) & guest.last_used_idx;
while (ring[head].flags & DESC_HW)
busy_wait();
return (ring[head].flags & DESC_HW);
}
void disable_call()
@@ -180,13 +179,11 @@ void disable_call()
bool enable_call()
{
unsigned head = (ring_size - 1) & guest.last_used_idx;
event->call_index = guest.last_used_idx;
/* Flush call index write */
/* Barrier D (for pairing) */
smp_mb();
return ring[head].flags & DESC_HW;
return used_empty();
}
void kick_available(void)
@@ -213,20 +210,17 @@ void disable_kick()
bool enable_kick()
{
unsigned head = (ring_size - 1) & host.used_idx;
event->kick_index = host.used_idx;
/* Barrier C (for pairing) */
smp_mb();
return !(ring[head].flags & DESC_HW);
return avail_empty();
}
void poll_avail(void)
bool avail_empty()
{
unsigned head = (ring_size - 1) & host.used_idx;
while (!(ring[head].flags & DESC_HW))
busy_wait();
return !(ring[head].flags & DESC_HW);
}
bool use_buf(unsigned *lenp, void **bufp)

View File

@@ -194,24 +194,16 @@ void *get_buf(unsigned *lenp, void **bufp)
return datap;
}
void poll_used(void)
bool used_empty()
{
unsigned short last_used_idx = guest.last_used_idx;
#ifdef RING_POLL
unsigned head = (ring_size - 1) & guest.last_used_idx;
unsigned short head = last_used_idx & (ring_size - 1);
unsigned index = ring.used->ring[head].id;
for (;;) {
unsigned index = ring.used->ring[head].id;
if ((index ^ guest.last_used_idx ^ 0x8000) & ~(ring_size - 1))
busy_wait();
else
break;
}
return (index ^ last_used_idx ^ 0x8000) & ~(ring_size - 1);
#else
unsigned head = guest.last_used_idx;
while (ring.used->idx == head)
busy_wait();
return ring.used->idx == last_used_idx;
#endif
}
@@ -224,22 +216,11 @@ void disable_call()
bool enable_call()
{
unsigned short last_used_idx;
vring_used_event(&ring) = (last_used_idx = guest.last_used_idx);
vring_used_event(&ring) = guest.last_used_idx;
/* Flush call index write */
/* Barrier D (for pairing) */
smp_mb();
#ifdef RING_POLL
{
unsigned short head = last_used_idx & (ring_size - 1);
unsigned index = ring.used->ring[head].id;
return (index ^ last_used_idx ^ 0x8000) & ~(ring_size - 1);
}
#else
return ring.used->idx == last_used_idx;
#endif
return used_empty();
}
void kick_available(void)
@@ -266,36 +247,21 @@ void disable_kick()
bool enable_kick()
{
unsigned head = host.used_idx;
vring_avail_event(&ring) = head;
vring_avail_event(&ring) = host.used_idx;
/* Barrier C (for pairing) */
smp_mb();
#ifdef RING_POLL
{
unsigned index = ring.avail->ring[head & (ring_size - 1)];
return (index ^ head ^ 0x8000) & ~(ring_size - 1);
}
#else
return head == ring.avail->idx;
#endif
return avail_empty();
}
void poll_avail(void)
bool avail_empty()
{
unsigned head = host.used_idx;
#ifdef RING_POLL
for (;;) {
unsigned index = ring.avail->ring[head & (ring_size - 1)];
if ((index ^ head ^ 0x8000) & ~(ring_size - 1))
busy_wait();
else
break;
}
unsigned index = ring.avail->ring[head & (ring_size - 1)];
return ((index ^ head ^ 0x8000) & ~(ring_size - 1));
#else
while (ring.avail->idx == head)
busy_wait();
return head == ring.avail->idx;
#endif
}