mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 06:29:59 -04:00
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. Merge branch 'ondrej/fix-non-atomic-srtt-aging' into 'main' See merge request isc-projects/bind9!11718
This commit is contained in:
commit
892f50712d
1 changed files with 25 additions and 12 deletions
|
|
@ -2840,22 +2840,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