Merge branch 'akpm' (patches from Andrew)
[sfrench/cifs-2.6.git] / kernel / sched / core.c
index 916e956e92bebf4cf2caed0298fba5e3da02aa30..ead464a0f2e5dfc71a0c0df16a9823f3677f847a 100644 (file)
@@ -107,11 +107,12 @@ struct rq *task_rq_lock(struct task_struct *p, struct rq_flags *rf)
                 *                                      [L] ->on_rq
                 *      RELEASE (rq->lock)
                 *
-                * If we observe the old CPU in task_rq_lock, the acquire of
+                * If we observe the old CPU in task_rq_lock(), the acquire of
                 * the old rq->lock will fully serialize against the stores.
                 *
-                * If we observe the new CPU in task_rq_lock, the acquire will
-                * pair with the WMB to ensure we must then also see migrating.
+                * If we observe the new CPU in task_rq_lock(), the address
+                * dependency headed by '[L] rq = task_rq()' and the acquire
+                * will pair with the WMB to ensure we then also see migrating.
                 */
                if (likely(rq == task_rq(p) && !task_on_rq_migrating(p))) {
                        rq_pin_lock(rq, rf);
@@ -180,6 +181,7 @@ static void update_rq_clock_task(struct rq *rq, s64 delta)
        if ((irq_delta + steal) && sched_feat(NONTASK_CAPACITY))
                update_irq_load_avg(rq, irq_delta + steal);
 #endif
+       update_rq_clock_pelt(rq, delta);
 }
 
 void update_rq_clock(struct rq *rq)
@@ -396,19 +398,7 @@ static bool set_nr_if_polling(struct task_struct *p)
 #endif
 #endif
 
-/**
- * wake_q_add() - queue a wakeup for 'later' waking.
- * @head: the wake_q_head to add @task to
- * @task: the task to queue for 'later' wakeup
- *
- * Queue a task for later wakeup, most likely by the wake_up_q() call in the
- * same context, _HOWEVER_ this is not guaranteed, the wakeup can come
- * instantly.
- *
- * This function must be used as-if it were wake_up_process(); IOW the task
- * must be ready to be woken at this location.
- */
-void wake_q_add(struct wake_q_head *head, struct task_struct *task)
+static bool __wake_q_add(struct wake_q_head *head, struct task_struct *task)
 {
        struct wake_q_node *node = &task->wake_q;
 
@@ -421,16 +411,56 @@ void wake_q_add(struct wake_q_head *head, struct task_struct *task)
         * state, even in the failed case, an explicit smp_mb() must be used.
         */
        smp_mb__before_atomic();
-       if (cmpxchg_relaxed(&node->next, NULL, WAKE_Q_TAIL))
-               return;
-
-       get_task_struct(task);
+       if (unlikely(cmpxchg_relaxed(&node->next, NULL, WAKE_Q_TAIL)))
+               return false;
 
        /*
         * The head is context local, there can be no concurrency.
         */
        *head->lastp = node;
        head->lastp = &node->next;
+       return true;
+}
+
+/**
+ * wake_q_add() - queue a wakeup for 'later' waking.
+ * @head: the wake_q_head to add @task to
+ * @task: the task to queue for 'later' wakeup
+ *
+ * Queue a task for later wakeup, most likely by the wake_up_q() call in the
+ * same context, _HOWEVER_ this is not guaranteed, the wakeup can come
+ * instantly.
+ *
+ * This function must be used as-if it were wake_up_process(); IOW the task
+ * must be ready to be woken at this location.
+ */
+void wake_q_add(struct wake_q_head *head, struct task_struct *task)
+{
+       if (__wake_q_add(head, task))
+               get_task_struct(task);
+}
+
+/**
+ * wake_q_add_safe() - safely queue a wakeup for 'later' waking.
+ * @head: the wake_q_head to add @task to
+ * @task: the task to queue for 'later' wakeup
+ *
+ * Queue a task for later wakeup, most likely by the wake_up_q() call in the
+ * same context, _HOWEVER_ this is not guaranteed, the wakeup can come
+ * instantly.
+ *
+ * This function must be used as-if it were wake_up_process(); IOW the task
+ * must be ready to be woken at this location.
+ *
+ * This function is essentially a task-safe equivalent to wake_q_add(). Callers
+ * that already hold reference to @task can call the 'safe' version and trust
+ * wake_q to do the right thing depending whether or not the @task is already
+ * queued for wakeup.
+ */
+void wake_q_add_safe(struct wake_q_head *head, struct task_struct *task)
+{
+       if (!__wake_q_add(head, task))
+               put_task_struct(task);
 }
 
 void wake_up_q(struct wake_q_head *head)
@@ -928,7 +958,7 @@ static struct rq *move_queued_task(struct rq *rq, struct rq_flags *rf,
 {
        lockdep_assert_held(&rq->lock);
 
-       p->on_rq = TASK_ON_RQ_MIGRATING;
+       WRITE_ONCE(p->on_rq, TASK_ON_RQ_MIGRATING);
        dequeue_task(rq, p, DEQUEUE_NOCLOCK);
        set_task_cpu(p, new_cpu);
        rq_unlock(rq, rf);
@@ -2434,7 +2464,7 @@ void wake_up_new_task(struct task_struct *p)
 #endif
        rq = __task_rq_lock(p, &rf);
        update_rq_clock(rq);
-       post_init_entity_util_avg(&p->se);
+       post_init_entity_util_avg(p);
 
        activate_task(rq, p, ENQUEUE_NOCLOCK);
        p->on_rq = TASK_ON_RQ_QUEUED;
@@ -5268,9 +5298,8 @@ SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
 }
 
 #ifdef CONFIG_COMPAT_32BIT_TIME
-COMPAT_SYSCALL_DEFINE2(sched_rr_get_interval,
-                      compat_pid_t, pid,
-                      struct old_timespec32 __user *, interval)
+SYSCALL_DEFINE2(sched_rr_get_interval_time32, pid_t, pid,
+               struct old_timespec32 __user *, interval)
 {
        struct timespec64 t;
        int retval = sched_rr_get_interval(pid, &t);
@@ -5870,14 +5899,11 @@ void __init sched_init_smp(void)
        /*
         * There's no userspace yet to cause hotplug operations; hence all the
         * CPU masks are stable and all blatant races in the below code cannot
-        * happen. The hotplug lock is nevertheless taken to satisfy lockdep,
-        * but there won't be any contention on it.
+        * happen.
         */
-       cpus_read_lock();
        mutex_lock(&sched_domains_mutex);
        sched_init_domains(cpu_active_mask);
        mutex_unlock(&sched_domains_mutex);
-       cpus_read_unlock();
 
        /* Move init over to a non-isolated CPU */
        if (set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_FLAG_DOMAIN)) < 0)