8000 Avoid floating-point underflow while tracking buffer allocation rate. · postwait/postgres@590ceed · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 590ceed

Browse files
committed
Avoid floating-point underflow while tracking buffer allocation rate.
When the system is idle for awhile after activity, the "smoothed_alloc" state variable in BgBufferSync converges slowly to zero. With standard IEEE float arithmetic this results in several iterations with denormalized values, which causes kernel traps and annoying log messages on some poorly-designed platforms. There's no real need to track such small values of smoothed_alloc, so we can prevent the kernel traps by forcing it to zero as soon as it's too small to be interesting for our purposes. This issue is purely cosmetic, since the iterations don't happen fast enough for the kernel traps to pose any meaningful performance problem, but still it seems worth shutting up the log messages. The kernel log messages were previously reported by a number of people, but kudos to Greg Matthews for tracking down exactly where they were coming from.
1 parent 663e27c commit 590ceed

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

src/backend/storage/buffer/bufmgr.c

Lines changed: 12 additions & 1 deletion
1474
Original file line numberDiff line numberDiff line change
@@ -1474,7 +1474,18 @@ BgBufferSync(void)
1474
smoothing_samples;
14751475

14761476
/* Scale the estimate by a GUC to allow more aggressive tuning. */
1477-
upcoming_alloc_est = smoothed_alloc * bgwriter_lru_multiplier;
1477+
upcoming_alloc_est = (int) (smoothed_alloc * bgwriter_lru_multiplier);
1478+
1479+
/*
1480+
* If recent_alloc remains at zero for many cycles, smoothed_alloc will
1481+
* eventually underflow to zero, and the underflows produce annoying
1482+
* kernel warnings on some platforms. Once upcoming_alloc_est has gone
1483+
* to zero, there's no point in tracking smaller and smaller values of
1484+
* smoothed_alloc, so just reset it to exactly zero to avoid this
1485+
* syndrome. It will pop back up as soon as recent_alloc increases.
1486+
*/
1487+
if (upcoming_alloc_est == 0)
1488+
smoothed_alloc = 0;
14781489

14791490
/*
14801491
* Even in cases where there's been little or no buffer allocation
0