mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-11 13:27:06 +09:00
Merge tag 'v4.9.136' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into odroidg12-4.9.y
This is the 4.9.136 stable release
This commit is contained in:
@@ -4336,7 +4336,9 @@ EXPORT_SYMBOL_GPL(perf_event_read_value);
|
||||
static int __perf_read_group_add(struct perf_event *leader,
|
||||
u64 read_format, u64 *values)
|
||||
{
|
||||
struct perf_event_context *ctx = leader->ctx;
|
||||
struct perf_event *sub;
|
||||
unsigned long flags;
|
||||
int n = 1; /* skip @nr */
|
||||
int ret;
|
||||
|
||||
@@ -4366,12 +4368,15 @@ static int __perf_read_group_add(struct perf_event *leader,
|
||||
if (read_format & PERF_FORMAT_ID)
|
||||
values[n++] = primary_event_id(leader);
|
||||
|
||||
raw_spin_lock_irqsave(&ctx->lock, flags);
|
||||
|
||||
list_for_each_entry(sub, &leader->sibling_list, group_entry) {
|
||||
values[n++] += perf_event_count(sub);
|
||||
if (read_format & PERF_FORMAT_ID)
|
||||
values[n++] = primary_event_id(sub);
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&ctx->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -7742,6 +7747,8 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size,
|
||||
goto unlock;
|
||||
|
||||
list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
|
||||
if (event->cpu != smp_processor_id())
|
||||
continue;
|
||||
if (event->attr.type != PERF_TYPE_TRACEPOINT)
|
||||
continue;
|
||||
if (event->attr.config != entry->type)
|
||||
|
||||
@@ -1467,8 +1467,16 @@ static int futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr)
|
||||
int oldval, ret;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) {
|
||||
if (oparg < 0 || oparg > 31)
|
||||
return -EINVAL;
|
||||
if (oparg < 0 || oparg > 31) {
|
||||
char comm[sizeof(current->comm)];
|
||||
/*
|
||||
* kill this print and return -EINVAL when userspace
|
||||
* is sane again
|
||||
*/
|
||||
pr_info_ratelimited("futex_wake_op: %s tries to shift op by %d; fix this program\n",
|
||||
get_task_comm(comm, current), oparg);
|
||||
oparg &= 31;
|
||||
}
|
||||
oparg = 1 << oparg;
|
||||
}
|
||||
|
||||
|
||||
@@ -4234,9 +4234,13 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq)
|
||||
|
||||
/*
|
||||
* Add to the _head_ of the list, so that an already-started
|
||||
* distribute_cfs_runtime will not see us
|
||||
* distribute_cfs_runtime will not see us. If disribute_cfs_runtime is
|
||||
* not running add to the tail so that later runqueues don't get starved.
|
||||
*/
|
||||
list_add_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq);
|
||||
if (cfs_b->distribute_running)
|
||||
list_add_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq);
|
||||
else
|
||||
list_add_tail_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq);
|
||||
|
||||
/*
|
||||
* If we're the first throttled task, make sure the bandwidth
|
||||
@@ -4379,14 +4383,16 @@ static int do_sched_cfs_period_timer(struct cfs_bandwidth *cfs_b, int overrun)
|
||||
* in us over-using our runtime if it is all used during this loop, but
|
||||
* only by limited amounts in that extreme case.
|
||||
*/
|
||||
while (throttled && cfs_b->runtime > 0) {
|
||||
while (throttled && cfs_b->runtime > 0 && !cfs_b->distribute_running) {
|
||||
runtime = cfs_b->runtime;
|
||||
cfs_b->distribute_running = 1;
|
||||
raw_spin_unlock(&cfs_b->lock);
|
||||
/* we can't nest cfs_b->lock while distributing bandwidth */
|
||||
runtime = distribute_cfs_runtime(cfs_b, runtime,
|
||||
runtime_expires);
|
||||
raw_spin_lock(&cfs_b->lock);
|
||||
|
||||
cfs_b->distribute_running = 0;
|
||||
throttled = !list_empty(&cfs_b->throttled_cfs_rq);
|
||||
|
||||
cfs_b->runtime -= min(runtime, cfs_b->runtime);
|
||||
@@ -4497,6 +4503,11 @@ static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b)
|
||||
|
||||
/* confirm we're still not at a refresh boundary */
|
||||
raw_spin_lock(&cfs_b->lock);
|
||||
if (cfs_b->distribute_running) {
|
||||
raw_spin_unlock(&cfs_b->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (runtime_refresh_within(cfs_b, min_bandwidth_expiration)) {
|
||||
raw_spin_unlock(&cfs_b->lock);
|
||||
return;
|
||||
@@ -4506,6 +4517,9 @@ static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b)
|
||||
runtime = cfs_b->runtime;
|
||||
|
||||
expires = cfs_b->runtime_expires;
|
||||
if (runtime)
|
||||
cfs_b->distribute_running = 1;
|
||||
|
||||
raw_spin_unlock(&cfs_b->lock);
|
||||
|
||||
if (!runtime)
|
||||
@@ -4516,6 +4530,7 @@ static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b)
|
||||
raw_spin_lock(&cfs_b->lock);
|
||||
if (expires == cfs_b->runtime_expires)
|
||||
cfs_b->runtime -= min(runtime, cfs_b->runtime);
|
||||
cfs_b->distribute_running = 0;
|
||||
raw_spin_unlock(&cfs_b->lock);
|
||||
}
|
||||
|
||||
@@ -4624,6 +4639,7 @@ void init_cfs_bandwidth(struct cfs_bandwidth *cfs_b)
|
||||
cfs_b->period_timer.function = sched_cfs_period_timer;
|
||||
hrtimer_init(&cfs_b->slack_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
cfs_b->slack_timer.function = sched_cfs_slack_timer;
|
||||
cfs_b->distribute_running = 0;
|
||||
}
|
||||
|
||||
static void init_cfs_rq_runtime(struct cfs_rq *cfs_rq)
|
||||
|
||||
@@ -257,6 +257,8 @@ struct cfs_bandwidth {
|
||||
/* statistics */
|
||||
int nr_periods, nr_throttled;
|
||||
u64 throttled_time;
|
||||
|
||||
bool distribute_running;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ static void bump_cpu_timer(struct k_itimer *timer,
|
||||
continue;
|
||||
|
||||
timer->it.cpu.expires += incr;
|
||||
timer->it_overrun += 1 << i;
|
||||
timer->it_overrun += 1LL << i;
|
||||
delta -= incr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,6 +355,17 @@ static __init int init_posix_timers(void)
|
||||
|
||||
__initcall(init_posix_timers);
|
||||
|
||||
/*
|
||||
* The siginfo si_overrun field and the return value of timer_getoverrun(2)
|
||||
* are of type int. Clamp the overrun value to INT_MAX
|
||||
*/
|
||||
static inline int timer_overrun_to_int(struct k_itimer *timr, int baseval)
|
||||
{
|
||||
s64 sum = timr->it_overrun_last + (s64)baseval;
|
||||
|
||||
return sum > (s64)INT_MAX ? INT_MAX : (int)sum;
|
||||
}
|
||||
|
||||
static void schedule_next_timer(struct k_itimer *timr)
|
||||
{
|
||||
struct hrtimer *timer = &timr->it.real.timer;
|
||||
@@ -362,12 +373,11 @@ static void schedule_next_timer(struct k_itimer *timr)
|
||||
if (timr->it.real.interval.tv64 == 0)
|
||||
return;
|
||||
|
||||
timr->it_overrun += (unsigned int) hrtimer_forward(timer,
|
||||
timer->base->get_time(),
|
||||
timr->it.real.interval);
|
||||
timr->it_overrun += hrtimer_forward(timer, timer->base->get_time(),
|
||||
timr->it.real.interval);
|
||||
|
||||
timr->it_overrun_last = timr->it_overrun;
|
||||
timr->it_overrun = -1;
|
||||
timr->it_overrun = -1LL;
|
||||
++timr->it_requeue_pending;
|
||||
hrtimer_restart(timer);
|
||||
}
|
||||
@@ -396,7 +406,7 @@ void do_schedule_next_timer(struct siginfo *info)
|
||||
else
|
||||
schedule_next_timer(timr);
|
||||
|
||||
info->si_overrun += timr->it_overrun_last;
|
||||
info->si_overrun = timer_overrun_to_int(timr, info->si_overrun);
|
||||
}
|
||||
|
||||
if (timr)
|
||||
@@ -491,8 +501,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
|
||||
now = ktime_add(now, kj);
|
||||
}
|
||||
#endif
|
||||
timr->it_overrun += (unsigned int)
|
||||
hrtimer_forward(timer, now,
|
||||
timr->it_overrun += hrtimer_forward(timer, now,
|
||||
timr->it.real.interval);
|
||||
ret = HRTIMER_RESTART;
|
||||
++timr->it_requeue_pending;
|
||||
@@ -633,7 +642,7 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
|
||||
it_id_set = IT_ID_SET;
|
||||
new_timer->it_id = (timer_t) new_timer_id;
|
||||
new_timer->it_clock = which_clock;
|
||||
new_timer->it_overrun = -1;
|
||||
new_timer->it_overrun = -1LL;
|
||||
|
||||
if (timer_event_spec) {
|
||||
if (copy_from_user(&event, timer_event_spec, sizeof (event))) {
|
||||
@@ -762,7 +771,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
|
||||
*/
|
||||
if (iv.tv64 && (timr->it_requeue_pending & REQUEUE_PENDING ||
|
||||
timr->it_sigev_notify == SIGEV_NONE))
|
||||
timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
|
||||
timr->it_overrun += hrtimer_forward(timer, now, iv);
|
||||
|
||||
remaining = __hrtimer_expires_remaining_adjusted(timer, now);
|
||||
/* Return 0 only, when the timer is expired and not pending */
|
||||
@@ -824,7 +833,7 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)
|
||||
if (!timr)
|
||||
return -EINVAL;
|
||||
|
||||
overrun = timr->it_overrun_last;
|
||||
overrun = timer_overrun_to_int(timr, 0);
|
||||
unlock_timer(timr, flags);
|
||||
|
||||
return overrun;
|
||||
|
||||
Reference in New Issue
Block a user