mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-10 11:20:00 -04:00
[9.20] fix: dev: Fix data race in server round-trip time tracking
The SRTT (Smoothed Round-Trip Time) update for remote servers was not atomic — concurrent callers could each read the same value and one update would be silently lost. Additionally, the aging decay applied once per second could run multiple times if several threads entered the function simultaneously. Use compare-and-swap loops for the SRTT update and for the aging timestamp to ensure no updates are lost. Backport of MR !11718 Merge branch 'backport-ondrej/fix-non-atomic-srtt-aging-9.20' into 'bind-9.20' See merge request isc-projects/bind9!11723
This commit is contained in:
commit
31cbfc9fb3
1 changed files with 25 additions and 12 deletions
|
|
@ -3029,22 +3029,35 @@ static void
|
|||
adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor,
|
||||
isc_stdtime_t now) {
|
||||
unsigned int new_srtt;
|
||||
unsigned int old_srtt;
|
||||
|
||||
if (factor == DNS_ADB_RTTADJAGE) {
|
||||
if (atomic_load(&addr->entry->lastage) != now) {
|
||||
new_srtt = (uint64_t)atomic_load(&addr->entry->srtt) *
|
||||
98 / 100;
|
||||
atomic_store(&addr->entry->lastage, now);
|
||||
atomic_store(&addr->entry->srtt, new_srtt);
|
||||
addr->srtt = new_srtt;
|
||||
isc_stdtime_t lastage =
|
||||
atomic_load_acquire(&addr->entry->lastage);
|
||||
|
||||
/* prevent double aging */
|
||||
if (lastage == now ||
|
||||
!atomic_compare_exchange_strong_acq_rel(
|
||||
&addr->entry->lastage, &lastage, now))
|
||||
{
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
new_srtt = ((uint64_t)atomic_load(&addr->entry->srtt) / 10 *
|
||||
factor) +
|
||||
((uint64_t)rtt / 10 * (10 - factor));
|
||||
atomic_store(&addr->entry->srtt, new_srtt);
|
||||
addr->srtt = new_srtt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Correct CAS aging...
|
||||
*/
|
||||
old_srtt = atomic_load_acquire(&addr->entry->srtt);
|
||||
do {
|
||||
if (factor == DNS_ADB_RTTADJAGE) {
|
||||
new_srtt = (uint64_t)old_srtt * 98 / 100;
|
||||
} else {
|
||||
new_srtt = ((uint64_t)old_srtt / 10 * factor) +
|
||||
((uint64_t)rtt / 10 * (10 - factor));
|
||||
}
|
||||
} while (!atomic_compare_exchange_weak_acq_rel(&addr->entry->srtt,
|
||||
&old_srtt, new_srtt));
|
||||
addr->srtt = new_srtt;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Reference in a new issue