Bug 1398847 - Enabling RCWN causes tp6_facebook regression, r=valentin

For some reason, triggering network directly from MaybeRaceCacheWithNetwork() causes performance regression of tp6_facebook tests. This patch changes it so that an event is posted instead.
The patch also adds network.http.rcwn.min_wait_before_racing_ms preference which can be used by users to avoid immediate racing.
This commit is contained in:
Michal Novotny 2017-09-11 22:16:13 +02:00
Родитель 5ff52c6547
Коммит c6167ee19b
3 изменённых файлов: 71 добавлений и 39 удалений

Просмотреть файл

@ -1835,6 +1835,7 @@ pref("network.http.rcwn.cache_queue_priority_threshold", 2);
// is smaller than this size.
pref("network.http.rcwn.small_resource_size_kb", 256);
pref("network.http.rcwn.min_wait_before_racing_ms", 0);
pref("network.http.rcwn.max_wait_before_racing_ms", 500);
// The ratio of the transaction count for the focused window and the count of

Просмотреть файл

@ -128,6 +128,7 @@ static bool sRCWNEnabled = false;
static uint32_t sRCWNQueueSizeNormal = 50;
static uint32_t sRCWNQueueSizePriority = 10;
static uint32_t sRCWNSmallResourceSizeKB = 256;
static uint32_t sRCWNMinWaitMs = 0;
static uint32_t sRCWNMaxWaitMs = 500;
// True if the local cache should be bypassed when processing a request.
@ -625,7 +626,7 @@ nsHttpChannel::ConnectOnTailUnblock()
Unused << ReadFromCache(true);
}
return TriggerNetwork(0);
return TriggerNetwork();
}
nsresult
@ -4513,7 +4514,7 @@ nsHttpChannel::OnCacheEntryAvailableInternal(nsICacheEntry *entry,
Unused << ReadFromCache(true);
}
return TriggerNetwork(0);
return TriggerNetwork();
}
nsresult
@ -6134,6 +6135,7 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
Preferences::AddUintVarCache(&sRCWNQueueSizeNormal, "network.http.rcwn.cache_queue_normal_threshold");
Preferences::AddUintVarCache(&sRCWNQueueSizePriority, "network.http.rcwn.cache_queue_priority_threshold");
Preferences::AddUintVarCache(&sRCWNSmallResourceSizeKB, "network.http.rcwn.small_resource_size_kb");
Preferences::AddUintVarCache(&sRCWNMinWaitMs, "network.http.rcwn.min_wait_before_racing_ms");
Preferences::AddUintVarCache(&sRCWNMaxWaitMs, "network.http.rcwn.max_wait_before_racing_ms");
}
@ -9302,7 +9304,43 @@ nsHttpChannel::Test_triggerDelayedOpenCacheEntry()
}
nsresult
nsHttpChannel::TriggerNetwork(int32_t aTimeout)
nsHttpChannel::TriggerNetworkWithDelay(uint32_t aDelay)
{
MOZ_ASSERT(NS_IsMainThread(), "Must be called on the main thread");
LOG(("nsHttpChannel::TriggerNetworkWithDelay [this=%p, delay=%u]\n",
this, aDelay));
if (mCanceled) {
LOG((" channel was canceled.\n"));
return mStatus;
}
// If a network request has already gone out, there is no point in
// doing this again.
if (mNetworkTriggered) {
LOG((" network already triggered. Returning.\n"));
return NS_OK;
}
if (!aDelay) {
// We cannot call TriggerNetwork() directly here, because it would
// cause performance regression in tp6 tests, see bug 1398847.
return NS_DispatchToMainThread(
NewRunnableMethod("net::nsHttpChannel::TriggerNetworkWithDelay",
this, &nsHttpChannel::TriggerNetwork),
NS_DISPATCH_NORMAL);
}
if (!mNetworkTriggerTimer) {
mNetworkTriggerTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
}
mNetworkTriggerTimer->InitWithCallback(this, aDelay, nsITimer::TYPE_ONE_SHOT);
return NS_OK;
}
nsresult
nsHttpChannel::TriggerNetwork()
{
MOZ_ASSERT(NS_IsMainThread(), "Must be called on the main thread");
@ -9320,36 +9358,29 @@ nsHttpChannel::TriggerNetwork(int32_t aTimeout)
return NS_OK;
}
if (!aTimeout) {
mNetworkTriggered = true;
if (mNetworkTriggerTimer) {
mNetworkTriggerTimer->Cancel();
mNetworkTriggerTimer = nullptr;
}
// If we are waiting for a proxy request, that means we can't trigger
// the next step just yet. We need for mConnectionInfo to be non-null
// before we call TryHSTSPriming. OnProxyAvailable will trigger
// BeginConnect, and Connect will call TryHSTSPriming even if it's
// for the cache callbacks.
if (mProxyRequest) {
LOG((" proxy request in progress. Delaying network trigger.\n"));
mWaitingForProxy = true;
return NS_OK;
}
if (mCacheAsyncOpenCalled && !mOnCacheAvailableCalled) {
mRaceCacheWithNetwork = true;
}
LOG((" triggering network\n"));
return TryHSTSPriming();
mNetworkTriggered = true;
if (mNetworkTriggerTimer) {
mNetworkTriggerTimer->Cancel();
mNetworkTriggerTimer = nullptr;
}
LOG((" setting timer to trigger network: %d ms\n", aTimeout));
mNetworkTriggerTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
mNetworkTriggerTimer->InitWithCallback(this, aTimeout, nsITimer::TYPE_ONE_SHOT);
return NS_OK;
// If we are waiting for a proxy request, that means we can't trigger
// the next step just yet. We need for mConnectionInfo to be non-null
// before we call TryHSTSPriming. OnProxyAvailable will trigger
// BeginConnect, and Connect will call TryHSTSPriming even if it's
// for the cache callbacks.
if (mProxyRequest) {
LOG((" proxy request in progress. Delaying network trigger.\n"));
mWaitingForProxy = true;
return NS_OK;
}
if (mCacheAsyncOpenCalled && !mOnCacheAvailableCalled) {
mRaceCacheWithNetwork = true;
}
LOG((" triggering network\n"));
return TryHSTSPriming();
}
nsresult
@ -9380,23 +9411,22 @@ nsHttpChannel::MaybeRaceCacheWithNetwork()
// We use microseconds in CachePerfStats but we need milliseconds
// for TriggerNetwork.
mRaceDelay /= 1000;
if (mRaceDelay > sRCWNMaxWaitMs) {
mRaceDelay = sRCWNMaxWaitMs;
}
}
MOZ_ASSERT(sRCWNEnabled, "The pref must be truned on.");
mRaceDelay = clamped<uint32_t>(mRaceDelay, sRCWNMinWaitMs, sRCWNMaxWaitMs);
MOZ_ASSERT(sRCWNEnabled, "The pref must be turned on.");
LOG(("nsHttpChannel::MaybeRaceCacheWithNetwork [this=%p, delay=%u]\n",
this, mRaceDelay));
return TriggerNetwork(mRaceDelay);
return TriggerNetworkWithDelay(mRaceDelay);
}
NS_IMETHODIMP
nsHttpChannel::Test_triggerNetwork(int32_t aTimeout)
{
MOZ_ASSERT(NS_IsMainThread(), "Must be called on the main thread");
return TriggerNetwork(aTimeout);
return TriggerNetworkWithDelay(aTimeout);
}
NS_IMETHODIMP
@ -9406,7 +9436,7 @@ nsHttpChannel::Notify(nsITimer *aTimer)
if (aTimer == mCacheOpenTimer) {
return Test_triggerDelayedOpenCacheEntry();
} else if (aTimer == mNetworkTriggerTimer) {
return TriggerNetwork(0);
return TriggerNetwork();
} else {
MOZ_CRASH("Unknown timer");
}

Просмотреть файл

@ -722,7 +722,8 @@ private:
// with the cache fetch, and proceeds to do so.
nsresult MaybeRaceCacheWithNetwork();
nsresult TriggerNetwork(int32_t aTimeout);
nsresult TriggerNetworkWithDelay(uint32_t aDelay);
nsresult TriggerNetwork();
void CancelNetworkRequest(nsresult aStatus);
// Timer used to delay the network request, or to trigger the network
// request if retrieving the cache entry takes too long.