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

Appearance settings

Commit c3cc73e

Browse filesBrowse files
committed
Be more careful about barriers when releasing BackgroundWorkerSlots.
ForgetBackgroundWorker lacked any memory barrier at all, while BackgroundWorkerStateChange had one but unaccountably did additional manipulation of the slot after the barrier. AFAICS, the rule must be that the barrier is immediately before setting or clearing slot->in_use. It looks like back in 9.6 when ForgetBackgroundWorker was first written, there might have been some case for not needing a barrier there, but I'm not very convinced of that --- the fact that the load of bgw_notify_pid is in the caller doesn't seem to guarantee no memory ordering problem. So patch 9.6 too. It's likely that this doesn't fix any observable bug on Intel hardware, but machines with weaker memory ordering rules could have problems here. Discussion: https://postgr.es/m/4046084.1620244003@sss.pgh.pa.us
1 parent fa675af commit c3cc73e
Copy full SHA for c3cc73e

File tree

Expand file treeCollapse file tree

1 file changed

+12
-1
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+12
-1
lines changed

‎src/backend/postmaster/bgworker.c

Copy file name to clipboardExpand all lines: src/backend/postmaster/bgworker.c
+12-1Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,11 @@ BackgroundWorkerStateChange(bool allow_new_workers)
327327
notify_pid = slot->worker.bgw_notify_pid;
328328
if ((slot->worker.bgw_flags & BGWORKER_CLASS_PARALLEL) != 0)
329329
BackgroundWorkerData->parallel_terminate_count++;
330-
pg_memory_barrier();
331330
slot->pid = 0;
331+
332+
pg_memory_barrier();
332333
slot->in_use = false;
334+
333335
if (notify_pid != 0)
334336
kill(notify_pid, SIGUSR1);
335337

@@ -416,6 +418,8 @@ BackgroundWorkerStateChange(bool allow_new_workers)
416418
* points to it. This convention allows deletion of workers during
417419
* searches of the worker list, and saves having to search the list again.
418420
*
421+
* Caller is responsible for notifying bgw_notify_pid, if appropriate.
422+
*
419423
* This function must be invoked only in the postmaster.
420424
*/
421425
void
@@ -428,9 +432,16 @@ ForgetBackgroundWorker(slist_mutable_iter *cur)
428432

429433
Assert(rw->rw_shmem_slot < max_worker_processes);
430434
slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
435+
Assert(slot->in_use);
436+
437+
/*
438+
* We need a memory barrier here to make sure that the update of
439+
* parallel_terminate_count completes before the store to in_use.
440+
*/
431441
if ((rw->rw_worker.bgw_flags & BGWORKER_CLASS_PARALLEL) != 0)
432442
BackgroundWorkerData->parallel_terminate_count++;
433443

444+
pg_memory_barrier();
434445
slot->in_use = false;
435446

436447
ereport(DEBUG1,

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.