|
@@ -306,66 +306,6 @@ __read_mostly int scheduler_running;
|
|
|
*/
|
|
|
int sysctl_sched_rt_runtime = 950000;
|
|
|
|
|
|
-/*
|
|
|
- * __task_rq_lock - lock the rq @p resides on.
|
|
|
- */
|
|
|
-static inline struct rq *__task_rq_lock(struct task_struct *p)
|
|
|
- __acquires(rq->lock)
|
|
|
-{
|
|
|
- struct rq *rq;
|
|
|
-
|
|
|
- lockdep_assert_held(&p->pi_lock);
|
|
|
-
|
|
|
- for (;;) {
|
|
|
- rq = task_rq(p);
|
|
|
- raw_spin_lock(&rq->lock);
|
|
|
- if (likely(rq == task_rq(p) && !task_on_rq_migrating(p)))
|
|
|
- return rq;
|
|
|
- raw_spin_unlock(&rq->lock);
|
|
|
-
|
|
|
- while (unlikely(task_on_rq_migrating(p)))
|
|
|
- cpu_relax();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * task_rq_lock - lock p->pi_lock and lock the rq @p resides on.
|
|
|
- */
|
|
|
-static struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags)
|
|
|
- __acquires(p->pi_lock)
|
|
|
- __acquires(rq->lock)
|
|
|
-{
|
|
|
- struct rq *rq;
|
|
|
-
|
|
|
- for (;;) {
|
|
|
- raw_spin_lock_irqsave(&p->pi_lock, *flags);
|
|
|
- rq = task_rq(p);
|
|
|
- raw_spin_lock(&rq->lock);
|
|
|
- if (likely(rq == task_rq(p) && !task_on_rq_migrating(p)))
|
|
|
- return rq;
|
|
|
- raw_spin_unlock(&rq->lock);
|
|
|
- raw_spin_unlock_irqrestore(&p->pi_lock, *flags);
|
|
|
-
|
|
|
- while (unlikely(task_on_rq_migrating(p)))
|
|
|
- cpu_relax();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static void __task_rq_unlock(struct rq *rq)
|
|
|
- __releases(rq->lock)
|
|
|
-{
|
|
|
- raw_spin_unlock(&rq->lock);
|
|
|
-}
|
|
|
-
|
|
|
-static inline void
|
|
|
-task_rq_unlock(struct rq *rq, struct task_struct *p, unsigned long *flags)
|
|
|
- __releases(rq->lock)
|
|
|
- __releases(p->pi_lock)
|
|
|
-{
|
|
|
- raw_spin_unlock(&rq->lock);
|
|
|
- raw_spin_unlock_irqrestore(&p->pi_lock, *flags);
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* this_rq_lock - lock this runqueue and disable interrupts.
|
|
|
*/
|
|
@@ -2899,7 +2839,7 @@ void __sched schedule_preempt_disabled(void)
|
|
|
preempt_disable();
|
|
|
}
|
|
|
|
|
|
-static void preempt_schedule_common(void)
|
|
|
+static void __sched notrace preempt_schedule_common(void)
|
|
|
{
|
|
|
do {
|
|
|
__preempt_count_add(PREEMPT_ACTIVE);
|
|
@@ -4418,36 +4358,29 @@ EXPORT_SYMBOL_GPL(yield_to);
|
|
|
* This task is about to go to sleep on IO. Increment rq->nr_iowait so
|
|
|
* that process accounting knows that this is a task in IO wait state.
|
|
|
*/
|
|
|
-void __sched io_schedule(void)
|
|
|
-{
|
|
|
- struct rq *rq = raw_rq();
|
|
|
-
|
|
|
- delayacct_blkio_start();
|
|
|
- atomic_inc(&rq->nr_iowait);
|
|
|
- blk_flush_plug(current);
|
|
|
- current->in_iowait = 1;
|
|
|
- schedule();
|
|
|
- current->in_iowait = 0;
|
|
|
- atomic_dec(&rq->nr_iowait);
|
|
|
- delayacct_blkio_end();
|
|
|
-}
|
|
|
-EXPORT_SYMBOL(io_schedule);
|
|
|
-
|
|
|
long __sched io_schedule_timeout(long timeout)
|
|
|
{
|
|
|
- struct rq *rq = raw_rq();
|
|
|
+ int old_iowait = current->in_iowait;
|
|
|
+ struct rq *rq;
|
|
|
long ret;
|
|
|
|
|
|
+ current->in_iowait = 1;
|
|
|
+ if (old_iowait)
|
|
|
+ blk_schedule_flush_plug(current);
|
|
|
+ else
|
|
|
+ blk_flush_plug(current);
|
|
|
+
|
|
|
delayacct_blkio_start();
|
|
|
+ rq = raw_rq();
|
|
|
atomic_inc(&rq->nr_iowait);
|
|
|
- blk_flush_plug(current);
|
|
|
- current->in_iowait = 1;
|
|
|
ret = schedule_timeout(timeout);
|
|
|
- current->in_iowait = 0;
|
|
|
+ current->in_iowait = old_iowait;
|
|
|
atomic_dec(&rq->nr_iowait);
|
|
|
delayacct_blkio_end();
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
+EXPORT_SYMBOL(io_schedule_timeout);
|
|
|
|
|
|
/**
|
|
|
* sys_sched_get_priority_max - return maximum RT priority.
|
|
@@ -7642,6 +7575,12 @@ static inline int tg_has_rt_tasks(struct task_group *tg)
|
|
|
{
|
|
|
struct task_struct *g, *p;
|
|
|
|
|
|
+ /*
|
|
|
+ * Autogroups do not have RT tasks; see autogroup_create().
|
|
|
+ */
|
|
|
+ if (task_group_is_autogroup(tg))
|
|
|
+ return 0;
|
|
|
+
|
|
|
for_each_process_thread(g, p) {
|
|
|
if (rt_task(p) && task_group(p) == tg)
|
|
|
return 1;
|
|
@@ -7734,6 +7673,17 @@ static int tg_set_rt_bandwidth(struct task_group *tg,
|
|
|
{
|
|
|
int i, err = 0;
|
|
|
|
|
|
+ /*
|
|
|
+ * Disallowing the root group RT runtime is BAD, it would disallow the
|
|
|
+ * kernel creating (and or operating) RT threads.
|
|
|
+ */
|
|
|
+ if (tg == &root_task_group && rt_runtime == 0)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ /* No period doesn't make any sense. */
|
|
|
+ if (rt_period == 0)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
mutex_lock(&rt_constraints_mutex);
|
|
|
read_lock(&tasklist_lock);
|
|
|
err = __rt_schedulable(tg, rt_period, rt_runtime);
|
|
@@ -7790,9 +7740,6 @@ static int sched_group_set_rt_period(struct task_group *tg, long rt_period_us)
|
|
|
rt_period = (u64)rt_period_us * NSEC_PER_USEC;
|
|
|
rt_runtime = tg->rt_bandwidth.rt_runtime;
|
|
|
|
|
|
- if (rt_period == 0)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
return tg_set_rt_bandwidth(tg, rt_period, rt_runtime);
|
|
|
}
|
|
|
|