diff options
| author | Rob Herring <robh@kernel.org> | 2018-03-08 10:21:07 -0500 |
|---|---|---|
| committer | Rob Herring <robh@kernel.org> | 2018-03-08 10:21:07 -0500 |
| commit | c679fa6e3aaa5c58fc514b5b88cfa82774b8d390 (patch) | |
| tree | 0c10b339368bd1795152a66a4e245e6f654fb3ec /kernel/locking/qspinlock.c | |
| parent | bdb7013df910681f84eff27b07791d4c160cb76f (diff) | |
| parent | 4fd98e374fd377ae0458a9dc44aa779cf9631ddd (diff) | |
Merge branch 'dtc-update' into dt/next
Diffstat (limited to 'kernel/locking/qspinlock.c')
| -rw-r--r-- | kernel/locking/qspinlock.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c index 38ece035039e..d880296245c5 100644 --- a/kernel/locking/qspinlock.c +++ b/kernel/locking/qspinlock.c | |||
| @@ -379,6 +379,14 @@ queue: | |||
| 379 | tail = encode_tail(smp_processor_id(), idx); | 379 | tail = encode_tail(smp_processor_id(), idx); |
| 380 | 380 | ||
| 381 | node += idx; | 381 | node += idx; |
| 382 | |||
| 383 | /* | ||
| 384 | * Ensure that we increment the head node->count before initialising | ||
| 385 | * the actual node. If the compiler is kind enough to reorder these | ||
| 386 | * stores, then an IRQ could overwrite our assignments. | ||
| 387 | */ | ||
| 388 | barrier(); | ||
| 389 | |||
| 382 | node->locked = 0; | 390 | node->locked = 0; |
| 383 | node->next = NULL; | 391 | node->next = NULL; |
| 384 | pv_init_node(node); | 392 | pv_init_node(node); |
| @@ -408,14 +416,15 @@ queue: | |||
| 408 | */ | 416 | */ |
| 409 | if (old & _Q_TAIL_MASK) { | 417 | if (old & _Q_TAIL_MASK) { |
| 410 | prev = decode_tail(old); | 418 | prev = decode_tail(old); |
| 419 | |||
| 411 | /* | 420 | /* |
| 412 | * The above xchg_tail() is also a load of @lock which | 421 | * We must ensure that the stores to @node are observed before |
| 413 | * generates, through decode_tail(), a pointer. The address | 422 | * the write to prev->next. The address dependency from |
| 414 | * dependency matches the RELEASE of xchg_tail() such that | 423 | * xchg_tail is not sufficient to ensure this because the read |
| 415 | * the subsequent access to @prev happens after. | 424 | * component of xchg_tail is unordered with respect to the |
| 425 | * initialisation of @node. | ||
| 416 | */ | 426 | */ |
| 417 | 427 | smp_store_release(&prev->next, node); | |
| 418 | WRITE_ONCE(prev->next, node); | ||
| 419 | 428 | ||
| 420 | pv_wait_node(node, prev); | 429 | pv_wait_node(node, prev); |
| 421 | arch_mcs_spin_lock_contended(&node->locked); | 430 | arch_mcs_spin_lock_contended(&node->locked); |
