From fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:14:29 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- netwerk/cache2/CacheFileUtils.cpp | 1 - netwerk/cache2/CacheStorageService.cpp | 59 +++++++++++++++++++++------------- netwerk/cache2/CacheStorageService.h | 6 ++-- 3 files changed, 39 insertions(+), 27 deletions(-) (limited to 'netwerk/cache2') diff --git a/netwerk/cache2/CacheFileUtils.cpp b/netwerk/cache2/CacheFileUtils.cpp index 8d68cc82a0..fd1a8665e4 100644 --- a/netwerk/cache2/CacheFileUtils.cpp +++ b/netwerk/cache2/CacheFileUtils.cpp @@ -90,7 +90,6 @@ class KeyParser : protected Tokenizer { break; case 'b': // Leaving to be able to read and understand oldformatted entries - originAttribs.mInIsolatedMozBrowser = true; break; case 'a': isAnonymous = true; diff --git a/netwerk/cache2/CacheStorageService.cpp b/netwerk/cache2/CacheStorageService.cpp index ff5cc51d51..27c83cb699 100644 --- a/netwerk/cache2/CacheStorageService.cpp +++ b/netwerk/cache2/CacheStorageService.cpp @@ -883,13 +883,15 @@ nsresult CacheStorageService::ClearOriginInternal( NS_ERROR("aEntry->HashingKey() failed?"); return rv; } - + MOZ_ASSERT_IF(info->IsPrivate(), !entry->IsUsingDisk()); RemoveExactEntry(table, entryKey, entry, false /* don't overwrite */); } } } - rv = CacheFileIOManager::EvictByContext(info, false /* pinned */, aOrigin); + if (!info->IsPrivate()) { + rv = CacheFileIOManager::EvictByContext(info, false /* pinned */, aOrigin); + } NS_ENSURE_SUCCESS(rv, rv); return NS_OK; @@ -933,9 +935,13 @@ NS_IMETHODIMP CacheStorageService::PurgeFromMemoryRunnable::Run() { } if (mService) { - // TODO not all flags apply to both pools - mService->Pool(MemoryPool::EType::DISK).PurgeAll(mWhat); - mService->Pool(MemoryPool::EType::MEMORY).PurgeAll(mWhat); + // Note that we seem to come here only in the case of "memory-pressure" + // being notified (or in case of tests), so we start from purging in-memory + // entries first and ignore minprogress for disk entries. + // TODO not all flags apply to both pools. + mService->Pool(MemoryPool::EType::MEMORY) + .PurgeAll(mWhat, StaticPrefs::network_cache_purge_minprogress_memory()); + mService->Pool(MemoryPool::EType::DISK).PurgeAll(mWhat, 0); mService = nullptr; } @@ -1349,24 +1355,37 @@ void CacheStorageService::PurgeExpiredOrOverMemoryLimit() { mLastPurgeTime = now; - Pool(MemoryPool::EType::DISK).PurgeExpiredOrOverMemoryLimit(); + // We start purging memory entries first as we care more about RAM over + // disk space beeing freed in case we are interrupted. Pool(MemoryPool::EType::MEMORY).PurgeExpiredOrOverMemoryLimit(); + Pool(MemoryPool::EType::DISK).PurgeExpiredOrOverMemoryLimit(); } void CacheStorageService::MemoryPool::PurgeExpiredOrOverMemoryLimit() { TimeStamp start(TimeStamp::Now()); uint32_t const memoryLimit = Limit(); + size_t minprogress = + (mType == EType::DISK) + ? StaticPrefs::network_cache_purge_minprogress_disk() + : StaticPrefs::network_cache_purge_minprogress_memory(); // We always purge expired entries, even if under our limit. - size_t numExpired = PurgeExpired(); + size_t numExpired = PurgeExpired(minprogress); if (numExpired > 0) { LOG((" found and purged %zu expired entries", numExpired)); } + minprogress = (minprogress > numExpired) ? minprogress - numExpired : 0; // If we are still under pressure, purge LFU entries until we aren't. if (mMemorySize > memoryLimit) { - auto r = PurgeByFrecency(); + // Do not enter PurgeByFrecency if we reached the minimum and are asked to + // deliver entries. + if (minprogress == 0 && CacheIOThread::YieldAndRerun()) { + return; + } + + auto r = PurgeByFrecency(minprogress); if (MOZ_LIKELY(r.isOk())) { size_t numPurged = r.unwrap(); LOG(( @@ -1374,7 +1393,7 @@ void CacheStorageService::MemoryPool::PurgeExpiredOrOverMemoryLimit() { numPurged)); } else { // If we hit an error (OOM), do an emergency PurgeAll. - size_t numPurged = PurgeAll(CacheEntry::PURGE_WHOLE); + size_t numPurged = PurgeAll(CacheEntry::PURGE_WHOLE, minprogress); LOG( (" memory data consumption over the limit, emergency purged all %zu " "entries", @@ -1386,13 +1405,12 @@ void CacheStorageService::MemoryPool::PurgeExpiredOrOverMemoryLimit() { } // This function purges ALL expired entries. -size_t CacheStorageService::MemoryPool::PurgeExpired() { +size_t CacheStorageService::MemoryPool::PurgeExpired(size_t minprogress) { MOZ_ASSERT(IsOnManagementThread()); uint32_t now = NowInSeconds(); size_t numPurged = 0; - // Scan for items to purge. mManagedEntries is not sorted but comparing just // one integer should be faster than anything else, so go scan. RefPtr entry = mManagedEntries.getFirst(); @@ -1412,8 +1430,8 @@ size_t CacheStorageService::MemoryPool::PurgeExpired() { entry = std::move(nextEntry); // To have some progress even under load, we do the check only after - // purging at least one item if under pressure. - if ((numPurged > 0 || mMemorySize <= Limit()) && + // purging at least minprogress items if under pressure. + if ((numPurged >= minprogress || mMemorySize <= Limit()) && CacheIOThread::YieldAndRerun()) { break; } @@ -1422,7 +1440,8 @@ size_t CacheStorageService::MemoryPool::PurgeExpired() { return numPurged; } -Result CacheStorageService::MemoryPool::PurgeByFrecency() { +Result CacheStorageService::MemoryPool::PurgeByFrecency( + size_t minprogress) { MOZ_ASSERT(IsOnManagementThread()); // Pretend the limit is 10% lower so that we get rid of more entries at one @@ -1473,13 +1492,6 @@ Result CacheStorageService::MemoryPool::PurgeByFrecency() { size_t numPurged = 0; - // Given that sorting is expensive, let's ensure to interrupt only if we - // made at least some progress. We expect purging of memory entries to be - // less expensive than disk entries. - size_t minprogress = - (mType == EType::DISK) - ? StaticPrefs::network_cache_purgebyfrecency_minprogress_disk() - : StaticPrefs::network_cache_purgebyfrecency_minprogress_memory(); for (auto& checkPurge : mayPurgeSorted) { if (mMemorySize <= memoryLimit) { break; @@ -1504,7 +1516,8 @@ Result CacheStorageService::MemoryPool::PurgeByFrecency() { return numPurged; } -size_t CacheStorageService::MemoryPool::PurgeAll(uint32_t aWhat) { +size_t CacheStorageService::MemoryPool::PurgeAll(uint32_t aWhat, + size_t minprogress) { LOG(("CacheStorageService::MemoryPool::PurgeAll aWhat=%d", aWhat)); MOZ_ASSERT(IsOnManagementThread()); @@ -1512,7 +1525,7 @@ size_t CacheStorageService::MemoryPool::PurgeAll(uint32_t aWhat) { RefPtr entry = mManagedEntries.getFirst(); while (entry) { - if (numPurged > 0 && CacheIOThread::YieldAndRerun()) break; + if (numPurged >= minprogress && CacheIOThread::YieldAndRerun()) break; // Get the next entry before we may be removed from our list. RefPtr nextEntry = entry->getNext(); diff --git a/netwerk/cache2/CacheStorageService.h b/netwerk/cache2/CacheStorageService.h index 84b63438b0..0adc9f004d 100644 --- a/netwerk/cache2/CacheStorageService.h +++ b/netwerk/cache2/CacheStorageService.h @@ -349,9 +349,9 @@ class CacheStorageService final : public nsICacheStorageService, * Purges entries from memory based on the frecency ordered array. */ void PurgeExpiredOrOverMemoryLimit(); - size_t PurgeExpired(); - Result PurgeByFrecency(); - size_t PurgeAll(uint32_t aWhat); + size_t PurgeExpired(size_t minprogress); + Result PurgeByFrecency(size_t minprogress); + size_t PurgeAll(uint32_t aWhat, size_t minprogress); private: uint32_t Limit() const; -- cgit v1.2.3