From 1d7acfddf7533d2af64306bffc7e14adc58fe9f6 Mon Sep 17 00:00:00 2001 From: Yurii Zubrytskyi Date: Thu, 28 Oct 2021 14:37:12 -0700 Subject: [PATCH] Enable dynamic read logs buffer sizing for incfs Default buffer size of 4 pages causes many missed log records because of ring buffer overflows. This change adds a dynamic sizing, up to 32 pages, that has shown to decrease dropped records pretty much to nil Fallback code automatically decreases the buffer size in case of kernel memory fragmentation - some logs are still much better than no logs at all Bug: 203551890 Test: manual, adb install ; checked for fallback by increasing max size to 1024 pages Change-Id: I0ea46c1ad2534b1dbb5faaead52afab88b66747b --- VoldNativeService.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp index b4b9276..291a0d9 100644 --- a/VoldNativeService.cpp +++ b/VoldNativeService.cpp @@ -1039,16 +1039,30 @@ binder::Status VoldNativeService::setIncFsMountOptions( }; auto cleanup = std::unique_ptr(&incfsControl, cleanupFunc); - if (auto error = incfs::setOptions( - incfsControl, - {.defaultReadTimeoutMs = - enableReadTimeouts ? INCFS_DEFAULT_READ_TIMEOUT_MS : kIncFsReadNoTimeoutMs, - .readLogBufferPages = enableReadLogs ? INCFS_DEFAULT_PAGE_READ_BUFFER_PAGES : 0, - .sysfsName = sysfsName.c_str()}); - error < 0) { - return binder::Status::fromServiceSpecificError(error); - } + constexpr auto minReadLogBufferPages = INCFS_DEFAULT_PAGE_READ_BUFFER_PAGES; + constexpr auto maxReadLogBufferPages = 8 * INCFS_DEFAULT_PAGE_READ_BUFFER_PAGES; + auto options = incfs::MountOptions{ + .defaultReadTimeoutMs = + enableReadTimeouts ? INCFS_DEFAULT_READ_TIMEOUT_MS : kIncFsReadNoTimeoutMs, + .readLogBufferPages = enableReadLogs ? maxReadLogBufferPages : 0, + .sysfsName = sysfsName.c_str()}; + + for (;;) { + const auto error = incfs::setOptions(incfsControl, options); + if (!error) { + return Ok(); + } + if (!enableReadLogs || error != -ENOMEM) { + return binder::Status::fromServiceSpecificError(error); + } + // In case of memory allocation error retry with a smaller buffer. + options.readLogBufferPages /= 2; + if (options.readLogBufferPages < minReadLogBufferPages) { + return binder::Status::fromServiceSpecificError(error); + } + } + // unreachable, but makes the compiler happy return Ok(); }