aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-01-30 00:18:54 -0500
committerDavid S. Miller <davem@davemloft.net>2019-01-30 00:18:54 -0500
commiteaf2a47f40f01ef793d2fc50cf03d199846013ca (patch)
tree0646365688ca76306aaa17ce7983944f5ec411b0 /kernel
parentc829f5f52db9bae0379b98fca2645f6ca9b0fb1e (diff)
parent62967898789dc1f09a06e59fa85ae2c5ca4dc2da (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Diffstat (limited to 'kernel')
-rw-r--r--kernel/exit.c2
-rw-r--r--kernel/futex.c13
-rw-r--r--kernel/irq/irqdesc.c2
-rw-r--r--kernel/irq/manage.c3
-rw-r--r--kernel/locking/rwsem-xadd.c11
-rw-r--r--kernel/sched/core.c19
-rw-r--r--kernel/time/posix-cpu-timers.c1
7 files changed, 39 insertions, 12 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 284f2fe9a293..3fb7be001964 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -307,7 +307,7 @@ void rcuwait_wake_up(struct rcuwait *w)
307 * MB (A) MB (B) 307 * MB (A) MB (B)
308 * [L] cond [L] tsk 308 * [L] cond [L] tsk
309 */ 309 */
310 smp_rmb(); /* (B) */ 310 smp_mb(); /* (B) */
311 311
312 /* 312 /*
313 * Avoid using task_rcu_dereference() magic as long as we are careful, 313 * Avoid using task_rcu_dereference() magic as long as we are careful,
diff --git a/kernel/futex.c b/kernel/futex.c
index be3bff2315ff..fdd312da0992 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1452,11 +1452,7 @@ static void mark_wake_futex(struct wake_q_head *wake_q, struct futex_q *q)
1452 if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n")) 1452 if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n"))
1453 return; 1453 return;
1454 1454
1455 /* 1455 get_task_struct(p);
1456 * Queue the task for later wakeup for after we've released
1457 * the hb->lock. wake_q_add() grabs reference to p.
1458 */
1459 wake_q_add(wake_q, p);
1460 __unqueue_futex(q); 1456 __unqueue_futex(q);
1461 /* 1457 /*
1462 * The waiting task can free the futex_q as soon as q->lock_ptr = NULL 1458 * The waiting task can free the futex_q as soon as q->lock_ptr = NULL
@@ -1466,6 +1462,13 @@ static void mark_wake_futex(struct wake_q_head *wake_q, struct futex_q *q)
1466 * plist_del in __unqueue_futex(). 1462 * plist_del in __unqueue_futex().
1467 */ 1463 */
1468 smp_store_release(&q->lock_ptr, NULL); 1464 smp_store_release(&q->lock_ptr, NULL);
1465
1466 /*
1467 * Queue the task for later wakeup for after we've released
1468 * the hb->lock. wake_q_add() grabs reference to p.
1469 */
1470 wake_q_add(wake_q, p);
1471 put_task_struct(p);
1469} 1472}
1470 1473
1471/* 1474/*
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index ee062b7939d3..ef8ad36cadcf 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -457,7 +457,7 @@ static int alloc_descs(unsigned int start, unsigned int cnt, int node,
457 457
458 /* Validate affinity mask(s) */ 458 /* Validate affinity mask(s) */
459 if (affinity) { 459 if (affinity) {
460 for (i = 0; i < cnt; i++, i++) { 460 for (i = 0; i < cnt; i++) {
461 if (cpumask_empty(&affinity[i].mask)) 461 if (cpumask_empty(&affinity[i].mask))
462 return -EINVAL; 462 return -EINVAL;
463 } 463 }
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index a4888ce4667a..84b54a17b95d 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -393,6 +393,9 @@ int irq_setup_affinity(struct irq_desc *desc)
393 } 393 }
394 394
395 cpumask_and(&mask, cpu_online_mask, set); 395 cpumask_and(&mask, cpu_online_mask, set);
396 if (cpumask_empty(&mask))
397 cpumask_copy(&mask, cpu_online_mask);
398
396 if (node != NUMA_NO_NODE) { 399 if (node != NUMA_NO_NODE) {
397 const struct cpumask *nodemask = cpumask_of_node(node); 400 const struct cpumask *nodemask = cpumask_of_node(node);
398 401
diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c
index 09b180063ee1..50d9af615dc4 100644
--- a/kernel/locking/rwsem-xadd.c
+++ b/kernel/locking/rwsem-xadd.c
@@ -198,15 +198,22 @@ static void __rwsem_mark_wake(struct rw_semaphore *sem,
198 woken++; 198 woken++;
199 tsk = waiter->task; 199 tsk = waiter->task;
200 200
201 wake_q_add(wake_q, tsk); 201 get_task_struct(tsk);
202 list_del(&waiter->list); 202 list_del(&waiter->list);
203 /* 203 /*
204 * Ensure that the last operation is setting the reader 204 * Ensure calling get_task_struct() before setting the reader
205 * waiter to nil such that rwsem_down_read_failed() cannot 205 * waiter to nil such that rwsem_down_read_failed() cannot
206 * race with do_exit() by always holding a reference count 206 * race with do_exit() by always holding a reference count
207 * to the task to wakeup. 207 * to the task to wakeup.
208 */ 208 */
209 smp_store_release(&waiter->task, NULL); 209 smp_store_release(&waiter->task, NULL);
210 /*
211 * Ensure issuing the wakeup (either by us or someone else)
212 * after setting the reader waiter to nil.
213 */
214 wake_q_add(wake_q, tsk);
215 /* wake_q_add() already take the task ref */
216 put_task_struct(tsk);
210 } 217 }
211 218
212 adjustment = woken * RWSEM_ACTIVE_READ_BIAS - adjustment; 219 adjustment = woken * RWSEM_ACTIVE_READ_BIAS - adjustment;
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index a674c7db2f29..d8d76a65cfdd 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -396,6 +396,18 @@ static bool set_nr_if_polling(struct task_struct *p)
396#endif 396#endif
397#endif 397#endif
398 398
399/**
400 * wake_q_add() - queue a wakeup for 'later' waking.
401 * @head: the wake_q_head to add @task to
402 * @task: the task to queue for 'later' wakeup
403 *
404 * Queue a task for later wakeup, most likely by the wake_up_q() call in the
405 * same context, _HOWEVER_ this is not guaranteed, the wakeup can come
406 * instantly.
407 *
408 * This function must be used as-if it were wake_up_process(); IOW the task
409 * must be ready to be woken at this location.
410 */
399void wake_q_add(struct wake_q_head *head, struct task_struct *task) 411void wake_q_add(struct wake_q_head *head, struct task_struct *task)
400{ 412{
401 struct wake_q_node *node = &task->wake_q; 413 struct wake_q_node *node = &task->wake_q;
@@ -405,10 +417,11 @@ void wake_q_add(struct wake_q_head *head, struct task_struct *task)
405 * its already queued (either by us or someone else) and will get the 417 * its already queued (either by us or someone else) and will get the
406 * wakeup due to that. 418 * wakeup due to that.
407 * 419 *
408 * This cmpxchg() executes a full barrier, which pairs with the full 420 * In order to ensure that a pending wakeup will observe our pending
409 * barrier executed by the wakeup in wake_up_q(). 421 * state, even in the failed case, an explicit smp_mb() must be used.
410 */ 422 */
411 if (cmpxchg(&node->next, NULL, WAKE_Q_TAIL)) 423 smp_mb__before_atomic();
424 if (cmpxchg_relaxed(&node->next, NULL, WAKE_Q_TAIL))
412 return; 425 return;
413 426
414 get_task_struct(task); 427 get_task_struct(task);
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index 8f0644af40be..80f955210861 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -685,6 +685,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
685 * set up the signal and overrun bookkeeping. 685 * set up the signal and overrun bookkeeping.
686 */ 686 */
687 timer->it.cpu.incr = timespec64_to_ns(&new->it_interval); 687 timer->it.cpu.incr = timespec64_to_ns(&new->it_interval);
688 timer->it_interval = ns_to_ktime(timer->it.cpu.incr);
688 689
689 /* 690 /*
690 * This acts as a modification timestamp for the timer, 691 * This acts as a modification timestamp for the timer,