Merge tag 'v4.10-rc8' into perf/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -3538,14 +3538,15 @@ struct perf_read_data {
|
||||
int ret;
|
||||
};
|
||||
|
||||
static int find_cpu_to_read(struct perf_event *event, int local_cpu)
|
||||
static int __perf_event_read_cpu(struct perf_event *event, int event_cpu)
|
||||
{
|
||||
int event_cpu = event->oncpu;
|
||||
u16 local_pkg, event_pkg;
|
||||
|
||||
if (event->group_caps & PERF_EV_CAP_READ_ACTIVE_PKG) {
|
||||
event_pkg = topology_physical_package_id(event_cpu);
|
||||
local_pkg = topology_physical_package_id(local_cpu);
|
||||
int local_cpu = smp_processor_id();
|
||||
|
||||
event_pkg = topology_physical_package_id(event_cpu);
|
||||
local_pkg = topology_physical_package_id(local_cpu);
|
||||
|
||||
if (event_pkg == local_pkg)
|
||||
return local_cpu;
|
||||
@@ -3675,7 +3676,7 @@ u64 perf_event_read_local(struct perf_event *event)
|
||||
|
||||
static int perf_event_read(struct perf_event *event, bool group)
|
||||
{
|
||||
int ret = 0, cpu_to_read, local_cpu;
|
||||
int event_cpu, ret = 0;
|
||||
|
||||
/*
|
||||
* If event is enabled and currently active on a CPU, update the
|
||||
@@ -3688,21 +3689,25 @@ static int perf_event_read(struct perf_event *event, bool group)
|
||||
.ret = 0,
|
||||
};
|
||||
|
||||
local_cpu = get_cpu();
|
||||
cpu_to_read = find_cpu_to_read(event, local_cpu);
|
||||
put_cpu();
|
||||
event_cpu = READ_ONCE(event->oncpu);
|
||||
if ((unsigned)event_cpu >= nr_cpu_ids)
|
||||
return 0;
|
||||
|
||||
preempt_disable();
|
||||
event_cpu = __perf_event_read_cpu(event, event_cpu);
|
||||
|
||||
/*
|
||||
* Purposely ignore the smp_call_function_single() return
|
||||
* value.
|
||||
*
|
||||
* If event->oncpu isn't a valid CPU it means the event got
|
||||
* If event_cpu isn't a valid CPU it means the event got
|
||||
* scheduled out and that will have updated the event count.
|
||||
*
|
||||
* Therefore, either way, we'll have an up-to-date event count
|
||||
* after this.
|
||||
*/
|
||||
(void)smp_call_function_single(cpu_to_read, __perf_event_read, &data, 1);
|
||||
(void)smp_call_function_single(event_cpu, __perf_event_read, &data, 1);
|
||||
preempt_enable();
|
||||
ret = data.ret;
|
||||
} else if (event->state == PERF_EVENT_STATE_INACTIVE) {
|
||||
struct perf_event_context *ctx = event->ctx;
|
||||
|
||||
@@ -1346,6 +1346,30 @@ void irq_domain_free_irqs_parent(struct irq_domain *domain,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(irq_domain_free_irqs_parent);
|
||||
|
||||
static void __irq_domain_activate_irq(struct irq_data *irq_data)
|
||||
{
|
||||
if (irq_data && irq_data->domain) {
|
||||
struct irq_domain *domain = irq_data->domain;
|
||||
|
||||
if (irq_data->parent_data)
|
||||
__irq_domain_activate_irq(irq_data->parent_data);
|
||||
if (domain->ops->activate)
|
||||
domain->ops->activate(domain, irq_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void __irq_domain_deactivate_irq(struct irq_data *irq_data)
|
||||
{
|
||||
if (irq_data && irq_data->domain) {
|
||||
struct irq_domain *domain = irq_data->domain;
|
||||
|
||||
if (domain->ops->deactivate)
|
||||
domain->ops->deactivate(domain, irq_data);
|
||||
if (irq_data->parent_data)
|
||||
__irq_domain_deactivate_irq(irq_data->parent_data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* irq_domain_activate_irq - Call domain_ops->activate recursively to activate
|
||||
* interrupt
|
||||
@@ -1356,13 +1380,9 @@ EXPORT_SYMBOL_GPL(irq_domain_free_irqs_parent);
|
||||
*/
|
||||
void irq_domain_activate_irq(struct irq_data *irq_data)
|
||||
{
|
||||
if (irq_data && irq_data->domain) {
|
||||
struct irq_domain *domain = irq_data->domain;
|
||||
|
||||
if (irq_data->parent_data)
|
||||
irq_domain_activate_irq(irq_data->parent_data);
|
||||
if (domain->ops->activate)
|
||||
domain->ops->activate(domain, irq_data);
|
||||
if (!irqd_is_activated(irq_data)) {
|
||||
__irq_domain_activate_irq(irq_data);
|
||||
irqd_set_activated(irq_data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1376,13 +1396,9 @@ void irq_domain_activate_irq(struct irq_data *irq_data)
|
||||
*/
|
||||
void irq_domain_deactivate_irq(struct irq_data *irq_data)
|
||||
{
|
||||
if (irq_data && irq_data->domain) {
|
||||
struct irq_domain *domain = irq_data->domain;
|
||||
|
||||
if (domain->ops->deactivate)
|
||||
domain->ops->deactivate(domain, irq_data);
|
||||
if (irq_data->parent_data)
|
||||
irq_domain_deactivate_irq(irq_data->parent_data);
|
||||
if (irqd_is_activated(irq_data)) {
|
||||
__irq_domain_deactivate_irq(irq_data);
|
||||
irqd_clr_activated(irq_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -389,16 +389,16 @@ extern const struct kernel_symbol __start___ksymtab_gpl[];
|
||||
extern const struct kernel_symbol __stop___ksymtab_gpl[];
|
||||
extern const struct kernel_symbol __start___ksymtab_gpl_future[];
|
||||
extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
|
||||
extern const unsigned long __start___kcrctab[];
|
||||
extern const unsigned long __start___kcrctab_gpl[];
|
||||
extern const unsigned long __start___kcrctab_gpl_future[];
|
||||
extern const s32 __start___kcrctab[];
|
||||
extern const s32 __start___kcrctab_gpl[];
|
||||
extern const s32 __start___kcrctab_gpl_future[];
|
||||
#ifdef CONFIG_UNUSED_SYMBOLS
|
||||
extern const struct kernel_symbol __start___ksymtab_unused[];
|
||||
extern const struct kernel_symbol __stop___ksymtab_unused[];
|
||||
extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
|
||||
extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
|
||||
extern const unsigned long __start___kcrctab_unused[];
|
||||
extern const unsigned long __start___kcrctab_unused_gpl[];
|
||||
extern const s32 __start___kcrctab_unused[];
|
||||
extern const s32 __start___kcrctab_unused_gpl[];
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_MODVERSIONS
|
||||
@@ -497,7 +497,7 @@ struct find_symbol_arg {
|
||||
|
||||
/* Output */
|
||||
struct module *owner;
|
||||
const unsigned long *crc;
|
||||
const s32 *crc;
|
||||
const struct kernel_symbol *sym;
|
||||
};
|
||||
|
||||
@@ -563,7 +563,7 @@ static bool find_symbol_in_section(const struct symsearch *syms,
|
||||
* (optional) module which owns it. Needs preempt disabled or module_mutex. */
|
||||
const struct kernel_symbol *find_symbol(const char *name,
|
||||
struct module **owner,
|
||||
const unsigned long **crc,
|
||||
const s32 **crc,
|
||||
bool gplok,
|
||||
bool warn)
|
||||
{
|
||||
@@ -1249,23 +1249,17 @@ static int try_to_force_load(struct module *mod, const char *reason)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MODVERSIONS
|
||||
/* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */
|
||||
static unsigned long maybe_relocated(unsigned long crc,
|
||||
const struct module *crc_owner)
|
||||
|
||||
static u32 resolve_rel_crc(const s32 *crc)
|
||||
{
|
||||
#ifdef ARCH_RELOCATES_KCRCTAB
|
||||
if (crc_owner == NULL)
|
||||
return crc - (unsigned long)reloc_start;
|
||||
#endif
|
||||
return crc;
|
||||
return *(u32 *)((void *)crc + *crc);
|
||||
}
|
||||
|
||||
static int check_version(Elf_Shdr *sechdrs,
|
||||
unsigned int versindex,
|
||||
const char *symname,
|
||||
struct module *mod,
|
||||
const unsigned long *crc,
|
||||
const struct module *crc_owner)
|
||||
const s32 *crc)
|
||||
{
|
||||
unsigned int i, num_versions;
|
||||
struct modversion_info *versions;
|
||||
@@ -1283,13 +1277,19 @@ static int check_version(Elf_Shdr *sechdrs,
|
||||
/ sizeof(struct modversion_info);
|
||||
|
||||
for (i = 0; i < num_versions; i++) {
|
||||
u32 crcval;
|
||||
|
||||
if (strcmp(versions[i].name, symname) != 0)
|
||||
continue;
|
||||
|
||||
if (versions[i].crc == maybe_relocated(*crc, crc_owner))
|
||||
if (IS_ENABLED(CONFIG_MODULE_REL_CRCS))
|
||||
crcval = resolve_rel_crc(crc);
|
||||
else
|
||||
crcval = *crc;
|
||||
if (versions[i].crc == crcval)
|
||||
return 1;
|
||||
pr_debug("Found checksum %lX vs module %lX\n",
|
||||
maybe_relocated(*crc, crc_owner), versions[i].crc);
|
||||
pr_debug("Found checksum %X vs module %lX\n",
|
||||
crcval, versions[i].crc);
|
||||
goto bad_version;
|
||||
}
|
||||
|
||||
@@ -1307,7 +1307,7 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
|
||||
unsigned int versindex,
|
||||
struct module *mod)
|
||||
{
|
||||
const unsigned long *crc;
|
||||
const s32 *crc;
|
||||
|
||||
/*
|
||||
* Since this should be found in kernel (which can't be removed), no
|
||||
@@ -1321,8 +1321,7 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
|
||||
}
|
||||
preempt_enable();
|
||||
return check_version(sechdrs, versindex,
|
||||
VMLINUX_SYMBOL_STR(module_layout), mod, crc,
|
||||
NULL);
|
||||
VMLINUX_SYMBOL_STR(module_layout), mod, crc);
|
||||
}
|
||||
|
||||
/* First part is kernel version, which we ignore if module has crcs. */
|
||||
@@ -1340,8 +1339,7 @@ static inline int check_version(Elf_Shdr *sechdrs,
|
||||
unsigned int versindex,
|
||||
const char *symname,
|
||||
struct module *mod,
|
||||
const unsigned long *crc,
|
||||
const struct module *crc_owner)
|
||||
const s32 *crc)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -1368,7 +1366,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
|
||||
{
|
||||
struct module *owner;
|
||||
const struct kernel_symbol *sym;
|
||||
const unsigned long *crc;
|
||||
const s32 *crc;
|
||||
int err;
|
||||
|
||||
/*
|
||||
@@ -1383,8 +1381,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
|
||||
if (!sym)
|
||||
goto unlock;
|
||||
|
||||
if (!check_version(info->sechdrs, info->index.vers, name, mod, crc,
|
||||
owner)) {
|
||||
if (!check_version(info->sechdrs, info->index.vers, name, mod, crc)) {
|
||||
sym = ERR_PTR(-EINVAL);
|
||||
goto getname;
|
||||
}
|
||||
|
||||
@@ -18,10 +18,8 @@ void print_stack_trace(struct stack_trace *trace, int spaces)
|
||||
if (WARN_ON(!trace->entries))
|
||||
return;
|
||||
|
||||
for (i = 0; i < trace->nr_entries; i++) {
|
||||
printk("%*c", 1 + spaces, ' ');
|
||||
print_ip_sym(trace->entries[i]);
|
||||
}
|
||||
for (i = 0; i < trace->nr_entries; i++)
|
||||
printk("%*c%pS\n", 1 + spaces, ' ', (void *)trace->entries[i]);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(print_stack_trace);
|
||||
|
||||
@@ -29,7 +27,6 @@ int snprint_stack_trace(char *buf, size_t size,
|
||||
struct stack_trace *trace, int spaces)
|
||||
{
|
||||
int i;
|
||||
unsigned long ip;
|
||||
int generated;
|
||||
int total = 0;
|
||||
|
||||
@@ -37,9 +34,8 @@ int snprint_stack_trace(char *buf, size_t size,
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < trace->nr_entries; i++) {
|
||||
ip = trace->entries[i];
|
||||
generated = snprintf(buf, size, "%*c[<%p>] %pS\n",
|
||||
1 + spaces, ' ', (void *) ip, (void *) ip);
|
||||
generated = snprintf(buf, size, "%*c%pS\n", 1 + spaces, ' ',
|
||||
(void *)trace->entries[i]);
|
||||
|
||||
total += generated;
|
||||
|
||||
|
||||
@@ -725,6 +725,11 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
|
||||
*/
|
||||
if (delta == 0) {
|
||||
tick_nohz_restart(ts, now);
|
||||
/*
|
||||
* Make sure next tick stop doesn't get fooled by past
|
||||
* clock deadline
|
||||
*/
|
||||
ts->next_tick = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1372,7 +1372,7 @@ kprobe_trace_selftest_target(int a1, int a2, int a3, int a4, int a5, int a6)
|
||||
return a1 + a2 + a3 + a4 + a5 + a6;
|
||||
}
|
||||
|
||||
static struct __init trace_event_file *
|
||||
static __init struct trace_event_file *
|
||||
find_trace_probe_file(struct trace_kprobe *tk, struct trace_array *tr)
|
||||
{
|
||||
struct trace_event_file *file;
|
||||
|
||||
@@ -227,11 +227,10 @@ static __init int user_namespace_sysctl_init(void)
|
||||
* properly.
|
||||
*/
|
||||
user_header = register_sysctl("user", empty);
|
||||
kmemleak_ignore(user_header);
|
||||
BUG_ON(!user_header);
|
||||
BUG_ON(!setup_userns_sysctls(&init_user_ns));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(user_namespace_sysctl_init);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user