Commit 1388c804 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull scheduler fixes from Ingo Molnar:
 "Misc fixes:

   - fix rq->lock lockdep annotation bug

   - fix/improve update_curr_rt() and update_curr_dl() accounting

   - update documentation

   - remove unused macro"

* 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  sched/cpufreq: Remove unused SUGOV_KTHREAD_PRIORITY macro
  sched/core: Fix DEBUG_SPINLOCK annotation for rq->lock
  sched/rt: Make update_curr_rt() more accurate
  sched/deadline: Make update_curr_dl() more accurate
  membarrier-sync-core: Document architecture support
parents e9e3b300 43d1b29b
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
#
# Feature name:          membarrier-sync-core
#         Kconfig:       ARCH_HAS_MEMBARRIER_SYNC_CORE
#         description:   arch supports core serializing membarrier
#
# Architecture requirements
#
# * arm64
#
# Rely on eret context synchronization when returning from IPI handler, and
# when returning to user-space.
#
# * x86
#
# x86-32 uses IRET as return from interrupt, which takes care of the IPI.
# However, it uses both IRET and SYSEXIT to go back to user-space. The IRET
# instruction is core serializing, but not SYSEXIT.
#
# x86-64 uses IRET as return from interrupt, which takes care of the IPI.
# However, it can return to user-space through either SYSRETL (compat code),
# SYSRETQ, or IRET.
#
# Given that neither SYSRET{L,Q}, nor SYSEXIT, are core serializing, we rely
# instead on write_cr3() performed by switch_mm() to provide core serialization
# after changing the current mm, and deal with the special case of kthread ->
# uthread (temporarily keeping current mm into active_mm) by issuing a
# sync_core_before_usermode() in that specific case.
#
    -----------------------
    |         arch |status|
    -----------------------
    |       alpha: | TODO |
    |         arc: | TODO |
    |         arm: | TODO |
    |       arm64: |  ok  |
    |    blackfin: | TODO |
    |         c6x: | TODO |
    |        cris: | TODO |
    |         frv: | TODO |
    |       h8300: | TODO |
    |     hexagon: | TODO |
    |        ia64: | TODO |
    |        m32r: | TODO |
    |        m68k: | TODO |
    |       metag: | TODO |
    |  microblaze: | TODO |
    |        mips: | TODO |
    |     mn10300: | TODO |
    |       nios2: | TODO |
    |    openrisc: | TODO |
    |      parisc: | TODO |
    |     powerpc: | TODO |
    |        s390: | TODO |
    |       score: | TODO |
    |          sh: | TODO |
    |       sparc: | TODO |
    |        tile: | TODO |
    |          um: | TODO |
    |   unicore32: | TODO |
    |         x86: |  ok  |
    |      xtensa: | TODO |
    -----------------------
+16 −11
Original line number Diff line number Diff line
@@ -2601,19 +2601,31 @@ static inline void finish_task(struct task_struct *prev)
#endif
}

static inline void finish_lock_switch(struct rq *rq)
static inline void
prepare_lock_switch(struct rq *rq, struct task_struct *next, struct rq_flags *rf)
{
	/*
	 * Since the runqueue lock will be released by the next
	 * task (which is an invalid locking op but in the case
	 * of the scheduler it's an obvious special-case), so we
	 * do an early lockdep release here:
	 */
	rq_unpin_lock(rq, rf);
	spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
#ifdef CONFIG_DEBUG_SPINLOCK
	/* this is a valid case when another task releases the spinlock */
	rq->lock.owner = current;
	rq->lock.owner = next;
#endif
}

static inline void finish_lock_switch(struct rq *rq)
{
	/*
	 * If we are tracking spinlock dependencies then we have to
	 * fix up the runqueue lock - which gets 'carried over' from
	 * prev into current:
	 */
	spin_acquire(&rq->lock.dep_map, 0, 0, _THIS_IP_);

	raw_spin_unlock_irq(&rq->lock);
}

@@ -2844,14 +2856,7 @@ context_switch(struct rq *rq, struct task_struct *prev,

	rq->clock_update_flags &= ~(RQCF_ACT_SKIP|RQCF_REQ_SKIP);

	/*
	 * Since the runqueue lock will be released by the next
	 * task (which is an invalid locking op but in the case
	 * of the scheduler it's an obvious special-case), so we
	 * do an early lockdep release here:
	 */
	rq_unpin_lock(rq, rf);
	spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
	prepare_lock_switch(rq, next, rf);

	/* Here we just switch the register state and the stack. */
	switch_to(prev, next, prev);
+0 −2
Original line number Diff line number Diff line
@@ -19,8 +19,6 @@

#include "sched.h"

#define SUGOV_KTHREAD_PRIORITY	50

struct sugov_tunables {
	struct gov_attr_set attr_set;
	unsigned int rate_limit_us;
+4 −2
Original line number Diff line number Diff line
@@ -1153,6 +1153,7 @@ static void update_curr_dl(struct rq *rq)
	struct sched_dl_entity *dl_se = &curr->dl;
	u64 delta_exec, scaled_delta_exec;
	int cpu = cpu_of(rq);
	u64 now;

	if (!dl_task(curr) || !on_dl_rq(dl_se))
		return;
@@ -1165,7 +1166,8 @@ static void update_curr_dl(struct rq *rq)
	 * natural solution, but the full ramifications of this
	 * approach need further study.
	 */
	delta_exec = rq_clock_task(rq) - curr->se.exec_start;
	now = rq_clock_task(rq);
	delta_exec = now - curr->se.exec_start;
	if (unlikely((s64)delta_exec <= 0)) {
		if (unlikely(dl_se->dl_yielded))
			goto throttle;
@@ -1178,7 +1180,7 @@ static void update_curr_dl(struct rq *rq)
	curr->se.sum_exec_runtime += delta_exec;
	account_group_exec_runtime(curr, delta_exec);

	curr->se.exec_start = rq_clock_task(rq);
	curr->se.exec_start = now;
	cgroup_account_cputime(curr, delta_exec);

	sched_rt_avg_update(rq, delta_exec);
+2 −1
Original line number Diff line number Diff line
@@ -950,12 +950,13 @@ static void update_curr_rt(struct rq *rq)
{
	struct task_struct *curr = rq->curr;
	struct sched_rt_entity *rt_se = &curr->rt;
	u64 now = rq_clock_task(rq);
	u64 delta_exec;
	u64 now;

	if (curr->sched_class != &rt_sched_class)
		return;

	now = rq_clock_task(rq);
	delta_exec = now - curr->se.exec_start;
	if (unlikely((s64)delta_exec <= 0))
		return;