Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb71e37c

Browse files
committed
Prevent potentially hazardous compiler/cpu reordering during lwlock release.
In LWLockRelease() (and in 9.4+ LWLockUpdateVar()) we release enqueuedwaiters using PGSemaphoreUnlock(). As there are other sources of suchunlocks backends only wake up if MyProc->lwWaiting is set to false;which is only done in the aforementioned functions.Before this commit there were dangers because the store to lwWaitLinkcould become visible before the store to lwWaitLink. This could bothhappen due to compiler reordering (on most compilers) and on someplatforms due to the CPU reordering stores.The possible consequence of this is that a backend stops waitingbefore lwWaitLink is set to NULL. If that backend then tries toacquire another lock and has to wait there the list could becomecorrupted once the lwWaitLink store is finally performed.Add a write memory barrier to prevent that issue.Unfortunately the barrier support has been only added in 9.2. Giventhat the issue has not knowingly been observed in praxis it seemssufficient to prohibit compiler reordering using volatile for 9.0 and9.1. Actual problems due to compiler reordering are more likelyanyway.Discussion: 20140210134625.GA15246@awork2.anarazel.de
1 parent3dd740b commitb71e37c

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

‎src/backend/storage/lmgr/lwlock.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include"commands/async.h"
2828
#include"miscadmin.h"
2929
#include"pg_trace.h"
30+
#include"storage/barrier.h"
3031
#include"storage/ipc.h"
3132
#include"storage/predicate.h"
3233
#include"storage/proc.h"
@@ -829,6 +830,17 @@ LWLockRelease(LWLockId lockid)
829830
proc=head;
830831
head=proc->lwWaitLink;
831832
proc->lwWaitLink=NULL;
833+
/*
834+
* Guarantee that lwWaiting being unset only becomes visible once the
835+
* unlink from the link has completed. Otherwise the target backend
836+
* could be woken up for other reason and enqueue for a new lock - if
837+
* that happens before the list unlink happens, the list would end up
838+
* being corrupted.
839+
*
840+
* The barrier pairs with the SpinLockAcquire() when enqueing for
841+
* another lock.
842+
*/
843+
pg_write_barrier();
832844
proc->lwWaiting= false;
833845
PGSemaphoreUnlock(&proc->sem);
834846
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp