Merge branch 'perf/urgent' into perf/core
Conflicts: tools/perf/builtin-record.c tools/perf/builtin-top.c tools/perf/perf.h tools/perf/util/top.h Merge reason: resolve these cherry-picking conflicts. Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
+14
-5
@@ -2303,7 +2303,7 @@ do { \
|
||||
static DEFINE_PER_CPU(int, perf_throttled_count);
|
||||
static DEFINE_PER_CPU(u64, perf_throttled_seq);
|
||||
|
||||
static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count)
|
||||
static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count, bool disable)
|
||||
{
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
s64 period, sample_period;
|
||||
@@ -2322,9 +2322,13 @@ static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count)
|
||||
hwc->sample_period = sample_period;
|
||||
|
||||
if (local64_read(&hwc->period_left) > 8*sample_period) {
|
||||
event->pmu->stop(event, PERF_EF_UPDATE);
|
||||
if (disable)
|
||||
event->pmu->stop(event, PERF_EF_UPDATE);
|
||||
|
||||
local64_set(&hwc->period_left, 0);
|
||||
event->pmu->start(event, PERF_EF_RELOAD);
|
||||
|
||||
if (disable)
|
||||
event->pmu->start(event, PERF_EF_RELOAD);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2350,6 +2354,7 @@ static void perf_adjust_freq_unthr_context(struct perf_event_context *ctx,
|
||||
return;
|
||||
|
||||
raw_spin_lock(&ctx->lock);
|
||||
perf_pmu_disable(ctx->pmu);
|
||||
|
||||
list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
|
||||
if (event->state != PERF_EVENT_STATE_ACTIVE)
|
||||
@@ -2381,13 +2386,17 @@ static void perf_adjust_freq_unthr_context(struct perf_event_context *ctx,
|
||||
/*
|
||||
* restart the event
|
||||
* reload only if value has changed
|
||||
* we have stopped the event so tell that
|
||||
* to perf_adjust_period() to avoid stopping it
|
||||
* twice.
|
||||
*/
|
||||
if (delta > 0)
|
||||
perf_adjust_period(event, period, delta);
|
||||
perf_adjust_period(event, period, delta, false);
|
||||
|
||||
event->pmu->start(event, delta > 0 ? PERF_EF_RELOAD : 0);
|
||||
}
|
||||
|
||||
perf_pmu_enable(ctx->pmu);
|
||||
raw_spin_unlock(&ctx->lock);
|
||||
}
|
||||
|
||||
@@ -4567,7 +4576,7 @@ static int __perf_event_overflow(struct perf_event *event,
|
||||
hwc->freq_time_stamp = now;
|
||||
|
||||
if (delta > 0 && delta < 2*TICK_NSEC)
|
||||
perf_adjust_period(event, delta, hwc->last_period);
|
||||
perf_adjust_period(event, delta, hwc->last_period, true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -658,10 +658,10 @@ int __init init_hw_breakpoint(void)
|
||||
|
||||
err_alloc:
|
||||
for_each_possible_cpu(err_cpu) {
|
||||
if (err_cpu == cpu)
|
||||
break;
|
||||
for (i = 0; i < TYPE_MAX; i++)
|
||||
kfree(per_cpu(nr_task_bp_pinned[i], cpu));
|
||||
if (err_cpu == cpu)
|
||||
break;
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
|
||||
+5
-2
@@ -66,6 +66,7 @@
|
||||
#include <linux/user-return-notifier.h>
|
||||
#include <linux/oom.h>
|
||||
#include <linux/khugepaged.h>
|
||||
#include <linux/signalfd.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
@@ -910,7 +911,7 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk)
|
||||
return -ENOMEM;
|
||||
|
||||
new_ioc->ioprio = ioc->ioprio;
|
||||
put_io_context(new_ioc, NULL);
|
||||
put_io_context(new_ioc);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
@@ -935,8 +936,10 @@ static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
|
||||
|
||||
void __cleanup_sighand(struct sighand_struct *sighand)
|
||||
{
|
||||
if (atomic_dec_and_test(&sighand->count))
|
||||
if (atomic_dec_and_test(&sighand->count)) {
|
||||
signalfd_cleanup(sighand);
|
||||
kmem_cache_free(sighand_cachep, sighand);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ unsigned long probe_irq_on(void)
|
||||
if (desc->irq_data.chip->irq_set_type)
|
||||
desc->irq_data.chip->irq_set_type(&desc->irq_data,
|
||||
IRQ_TYPE_PROBE);
|
||||
irq_startup(desc);
|
||||
irq_startup(desc, false);
|
||||
}
|
||||
raw_spin_unlock_irq(&desc->lock);
|
||||
}
|
||||
@@ -70,7 +70,7 @@ unsigned long probe_irq_on(void)
|
||||
raw_spin_lock_irq(&desc->lock);
|
||||
if (!desc->action && irq_settings_can_probe(desc)) {
|
||||
desc->istate |= IRQS_AUTODETECT | IRQS_WAITING;
|
||||
if (irq_startup(desc))
|
||||
if (irq_startup(desc, false))
|
||||
desc->istate |= IRQS_PENDING;
|
||||
}
|
||||
raw_spin_unlock_irq(&desc->lock);
|
||||
|
||||
+33
-9
@@ -159,19 +159,22 @@ static void irq_state_set_masked(struct irq_desc *desc)
|
||||
irqd_set(&desc->irq_data, IRQD_IRQ_MASKED);
|
||||
}
|
||||
|
||||
int irq_startup(struct irq_desc *desc)
|
||||
int irq_startup(struct irq_desc *desc, bool resend)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
irq_state_clr_disabled(desc);
|
||||
desc->depth = 0;
|
||||
|
||||
if (desc->irq_data.chip->irq_startup) {
|
||||
int ret = desc->irq_data.chip->irq_startup(&desc->irq_data);
|
||||
ret = desc->irq_data.chip->irq_startup(&desc->irq_data);
|
||||
irq_state_clr_masked(desc);
|
||||
return ret;
|
||||
} else {
|
||||
irq_enable(desc);
|
||||
}
|
||||
|
||||
irq_enable(desc);
|
||||
return 0;
|
||||
if (resend)
|
||||
check_irq_resend(desc, desc->irq_data.irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void irq_shutdown(struct irq_desc *desc)
|
||||
@@ -332,6 +335,24 @@ out_unlock:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(handle_simple_irq);
|
||||
|
||||
/*
|
||||
* Called unconditionally from handle_level_irq() and only for oneshot
|
||||
* interrupts from handle_fasteoi_irq()
|
||||
*/
|
||||
static void cond_unmask_irq(struct irq_desc *desc)
|
||||
{
|
||||
/*
|
||||
* We need to unmask in the following cases:
|
||||
* - Standard level irq (IRQF_ONESHOT is not set)
|
||||
* - Oneshot irq which did not wake the thread (caused by a
|
||||
* spurious interrupt or a primary handler handling it
|
||||
* completely).
|
||||
*/
|
||||
if (!irqd_irq_disabled(&desc->irq_data) &&
|
||||
irqd_irq_masked(&desc->irq_data) && !desc->threads_oneshot)
|
||||
unmask_irq(desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* handle_level_irq - Level type irq handler
|
||||
* @irq: the interrupt number
|
||||
@@ -364,8 +385,8 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
|
||||
|
||||
handle_irq_event(desc);
|
||||
|
||||
if (!irqd_irq_disabled(&desc->irq_data) && !(desc->istate & IRQS_ONESHOT))
|
||||
unmask_irq(desc);
|
||||
cond_unmask_irq(desc);
|
||||
|
||||
out_unlock:
|
||||
raw_spin_unlock(&desc->lock);
|
||||
}
|
||||
@@ -419,6 +440,9 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
|
||||
preflow_handler(desc);
|
||||
handle_irq_event(desc);
|
||||
|
||||
if (desc->istate & IRQS_ONESHOT)
|
||||
cond_unmask_irq(desc);
|
||||
|
||||
out_eoi:
|
||||
desc->irq_data.chip->irq_eoi(&desc->irq_data);
|
||||
out_unlock:
|
||||
@@ -627,7 +651,7 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
|
||||
irq_settings_set_noprobe(desc);
|
||||
irq_settings_set_norequest(desc);
|
||||
irq_settings_set_nothread(desc);
|
||||
irq_startup(desc);
|
||||
irq_startup(desc, true);
|
||||
}
|
||||
out:
|
||||
irq_put_desc_busunlock(desc, flags);
|
||||
|
||||
@@ -67,7 +67,7 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
|
||||
extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
|
||||
extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
|
||||
|
||||
extern int irq_startup(struct irq_desc *desc);
|
||||
extern int irq_startup(struct irq_desc *desc, bool resend);
|
||||
extern void irq_shutdown(struct irq_desc *desc);
|
||||
extern void irq_enable(struct irq_desc *desc);
|
||||
extern void irq_disable(struct irq_desc *desc);
|
||||
|
||||
+1
-1
@@ -1027,7 +1027,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
|
||||
desc->istate |= IRQS_ONESHOT;
|
||||
|
||||
if (irq_settings_can_autoenable(desc))
|
||||
irq_startup(desc);
|
||||
irq_startup(desc, true);
|
||||
else
|
||||
/* Undo nested disables: */
|
||||
desc->depth = 1;
|
||||
|
||||
+5
-1
@@ -1673,8 +1673,12 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p,
|
||||
ri->rp = rp;
|
||||
ri->task = current;
|
||||
|
||||
if (rp->entry_handler && rp->entry_handler(ri, regs))
|
||||
if (rp->entry_handler && rp->entry_handler(ri, regs)) {
|
||||
raw_spin_lock_irqsave(&rp->lock, flags);
|
||||
hlist_add_head(&ri->hlist, &rp->free_instances);
|
||||
raw_spin_unlock_irqrestore(&rp->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_prepare_kretprobe(ri, regs);
|
||||
|
||||
|
||||
+2
-1
@@ -97,7 +97,8 @@ static int parse_one(char *param,
|
||||
for (i = 0; i < num_params; i++) {
|
||||
if (parameq(param, params[i].name)) {
|
||||
/* No one handled NULL, so do it here. */
|
||||
if (!val && params[i].ops->set != param_set_bool)
|
||||
if (!val && params[i].ops->set != param_set_bool
|
||||
&& params[i].ops->set != param_set_bint)
|
||||
return -EINVAL;
|
||||
pr_debug("They are equal! Calling %p\n",
|
||||
params[i].ops->set);
|
||||
|
||||
+2
-2
@@ -543,12 +543,12 @@ struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
|
||||
*/
|
||||
void __init pidhash_init(void)
|
||||
{
|
||||
int i, pidhash_size;
|
||||
unsigned int i, pidhash_size;
|
||||
|
||||
pid_hash = alloc_large_system_hash("PID", sizeof(*pid_hash), 0, 18,
|
||||
HASH_EARLY | HASH_SMALL,
|
||||
&pidhash_shift, NULL, 4096);
|
||||
pidhash_size = 1 << pidhash_shift;
|
||||
pidhash_size = 1U << pidhash_shift;
|
||||
|
||||
for (i = 0; i < pidhash_size; i++)
|
||||
INIT_HLIST_HEAD(&pid_hash[i]);
|
||||
|
||||
+22
-2
@@ -231,8 +231,28 @@ extern int pm_test_level;
|
||||
#ifdef CONFIG_SUSPEND_FREEZER
|
||||
static inline int suspend_freeze_processes(void)
|
||||
{
|
||||
int error = freeze_processes();
|
||||
return error ? : freeze_kernel_threads();
|
||||
int error;
|
||||
|
||||
error = freeze_processes();
|
||||
|
||||
/*
|
||||
* freeze_processes() automatically thaws every task if freezing
|
||||
* fails. So we need not do anything extra upon error.
|
||||
*/
|
||||
if (error)
|
||||
goto Finish;
|
||||
|
||||
error = freeze_kernel_threads();
|
||||
|
||||
/*
|
||||
* freeze_kernel_threads() thaws only kernel threads upon freezing
|
||||
* failure. So we have to thaw the userspace tasks ourselves.
|
||||
*/
|
||||
if (error)
|
||||
thaw_processes();
|
||||
|
||||
Finish:
|
||||
return error;
|
||||
}
|
||||
|
||||
static inline void suspend_thaw_processes(void)
|
||||
|
||||
@@ -143,7 +143,10 @@ int freeze_processes(void)
|
||||
/**
|
||||
* freeze_kernel_threads - Make freezable kernel threads go to the refrigerator.
|
||||
*
|
||||
* On success, returns 0. On failure, -errno and system is fully thawed.
|
||||
* On success, returns 0. On failure, -errno and only the kernel threads are
|
||||
* thawed, so as to give a chance to the caller to do additional cleanups
|
||||
* (if any) before thawing the userspace tasks. So, it is the responsibility
|
||||
* of the caller to thaw the userspace tasks, when the time is right.
|
||||
*/
|
||||
int freeze_kernel_threads(void)
|
||||
{
|
||||
@@ -159,7 +162,7 @@ int freeze_kernel_threads(void)
|
||||
BUG_ON(in_atomic());
|
||||
|
||||
if (error)
|
||||
thaw_processes();
|
||||
thaw_kernel_threads();
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -249,13 +249,15 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
|
||||
}
|
||||
pm_restore_gfp_mask();
|
||||
error = hibernation_snapshot(data->platform_support);
|
||||
if (!error) {
|
||||
if (error) {
|
||||
thaw_kernel_threads();
|
||||
} else {
|
||||
error = put_user(in_suspend, (int __user *)arg);
|
||||
if (!error && !freezer_test_done)
|
||||
data->ready = 1;
|
||||
if (freezer_test_done) {
|
||||
freezer_test_done = false;
|
||||
thaw_processes();
|
||||
thaw_kernel_threads();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
+8
-2
@@ -164,10 +164,14 @@ depopulate:
|
||||
*/
|
||||
static struct rchan_buf *relay_create_buf(struct rchan *chan)
|
||||
{
|
||||
struct rchan_buf *buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
|
||||
if (!buf)
|
||||
struct rchan_buf *buf;
|
||||
|
||||
if (chan->n_subbufs > UINT_MAX / sizeof(size_t *))
|
||||
return NULL;
|
||||
|
||||
buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
buf->padding = kmalloc(chan->n_subbufs * sizeof(size_t *), GFP_KERNEL);
|
||||
if (!buf->padding)
|
||||
goto free_buf;
|
||||
@@ -574,6 +578,8 @@ struct rchan *relay_open(const char *base_filename,
|
||||
|
||||
if (!(subbuf_size && n_subbufs))
|
||||
return NULL;
|
||||
if (subbuf_size > UINT_MAX / n_subbufs)
|
||||
return NULL;
|
||||
|
||||
chan = kzalloc(sizeof(struct rchan), GFP_KERNEL);
|
||||
if (!chan)
|
||||
|
||||
@@ -1932,7 +1932,6 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev)
|
||||
local_irq_enable();
|
||||
#endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */
|
||||
finish_lock_switch(rq, prev);
|
||||
trace_sched_stat_sleeptime(current, rq->clock);
|
||||
|
||||
fire_sched_in_preempt_notifiers(current);
|
||||
if (mm)
|
||||
|
||||
@@ -1003,6 +1003,7 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
if (unlikely(delta > se->statistics.sleep_max))
|
||||
se->statistics.sleep_max = delta;
|
||||
|
||||
se->statistics.sleep_start = 0;
|
||||
se->statistics.sum_sleep_runtime += delta;
|
||||
|
||||
if (tsk) {
|
||||
@@ -1019,6 +1020,7 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
if (unlikely(delta > se->statistics.block_max))
|
||||
se->statistics.block_max = delta;
|
||||
|
||||
se->statistics.block_start = 0;
|
||||
se->statistics.sum_sleep_runtime += delta;
|
||||
|
||||
if (tsk) {
|
||||
|
||||
Reference in New Issue
Block a user