diff options
Diffstat (limited to 'kernel/sched/core.c')
| -rw-r--r-- | kernel/sched/core.c | 63 | 
1 files changed, 34 insertions, 29 deletions
| diff --git a/kernel/sched/core.c b/kernel/sched/core.c index fc1dfc007604..1a9983da4408 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -552,27 +552,32 @@ void resched_cpu(int cpu)   */  int get_nohz_timer_target(void)  { -	int i, cpu = smp_processor_id(); +	int i, cpu = smp_processor_id(), default_cpu = -1;  	struct sched_domain *sd; -	if (!idle_cpu(cpu) && housekeeping_cpu(cpu, HK_FLAG_TIMER)) -		return cpu; +	if (housekeeping_cpu(cpu, HK_FLAG_TIMER)) { +		if (!idle_cpu(cpu)) +			return cpu; +		default_cpu = cpu; +	}  	rcu_read_lock();  	for_each_domain(cpu, sd) { -		for_each_cpu(i, sched_domain_span(sd)) { +		for_each_cpu_and(i, sched_domain_span(sd), +			housekeeping_cpumask(HK_FLAG_TIMER)) {  			if (cpu == i)  				continue; -			if (!idle_cpu(i) && housekeeping_cpu(i, HK_FLAG_TIMER)) { +			if (!idle_cpu(i)) {  				cpu = i;  				goto unlock;  			}  		}  	} -	if (!housekeeping_cpu(cpu, HK_FLAG_TIMER)) -		cpu = housekeeping_any_cpu(HK_FLAG_TIMER); +	if (default_cpu == -1) +		default_cpu = housekeeping_any_cpu(HK_FLAG_TIMER); +	cpu = default_cpu;  unlock:  	rcu_read_unlock();  	return cpu; @@ -1442,17 +1447,6 @@ void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)  #ifdef CONFIG_SMP -static inline bool is_per_cpu_kthread(struct task_struct *p) -{ -	if (!(p->flags & PF_KTHREAD)) -		return false; - -	if (p->nr_cpus_allowed != 1) -		return false; - -	return true; -} -  /*   * Per-CPU kthreads are allowed to run on !active && online CPUs, see   * __set_cpus_allowed_ptr() and select_fallback_rq(). @@ -3669,28 +3663,32 @@ static void sched_tick_remote(struct work_struct *work)  	 * statistics and checks timeslices in a time-independent way, regardless  	 * of when exactly it is running.  	 */ -	if (idle_cpu(cpu) || !tick_nohz_tick_stopped_cpu(cpu)) +	if (!tick_nohz_tick_stopped_cpu(cpu))  		goto out_requeue;  	rq_lock_irq(rq, &rf);  	curr = rq->curr; -	if (is_idle_task(curr) || cpu_is_offline(cpu)) +	if (cpu_is_offline(cpu))  		goto out_unlock; +	curr = rq->curr;  	update_rq_clock(rq); -	delta = rq_clock_task(rq) - curr->se.exec_start; -	/* -	 * Make sure the next tick runs within a reasonable -	 * amount of time. -	 */ -	WARN_ON_ONCE(delta > (u64)NSEC_PER_SEC * 3); +	if (!is_idle_task(curr)) { +		/* +		 * Make sure the next tick runs within a reasonable +		 * amount of time. +		 */ +		delta = rq_clock_task(rq) - curr->se.exec_start; +		WARN_ON_ONCE(delta > (u64)NSEC_PER_SEC * 3); +	}  	curr->sched_class->task_tick(rq, curr, 0); +	calc_load_nohz_remote(rq);  out_unlock:  	rq_unlock_irq(rq, &rf); -  out_requeue: +  	/*  	 * Run the remote tick once per second (1Hz). This arbitrary  	 * frequency is large enough to avoid overload but short enough @@ -7063,8 +7061,15 @@ void sched_move_task(struct task_struct *tsk)  	if (queued)  		enqueue_task(rq, tsk, queue_flags); -	if (running) +	if (running) {  		set_next_task(rq, tsk); +		/* +		 * After changing group, the running task may have joined a +		 * throttled one but it's still the running task. Trigger a +		 * resched to make sure that task can still run. +		 */ +		resched_curr(rq); +	}  	task_rq_unlock(rq, tsk, &rf);  } @@ -7260,7 +7265,7 @@ capacity_from_percent(char *buf)  					     &req.percent);  		if (req.ret)  			return req; -		if (req.percent > UCLAMP_PERCENT_SCALE) { +		if ((u64)req.percent > UCLAMP_PERCENT_SCALE) {  			req.ret = -ERANGE;  			return req;  		} | 
