From 5098f0a9ca95eed28648c3ae44ea6ac659637731 Mon Sep 17 00:00:00 2001 From: Stan Rokita Date: Mon, 4 Nov 2019 13:36:54 -0800 Subject: [PATCH] Bound pending write events queue to avoid OOM Bound the pending write events queue to a large amount of events in total (100,000) so that we do not have out of memory crashes when the sensors framework locks up. Events are 80B of memory each. So this change caps are pending writes event queue to 8MB of memory. Bug: 143302327 Test: atest android.hardware.sensors@2.0-halproxy-unit-tests && vts-tradefed run commandAndExit vts --skip-all-system-status-check --primary-abi-only --skip-preconditions --module VtsHalSensorsV2_0Target Change-Id: I5d0a7f382e3f61fbbe2c74b5c9cf13560432b84c --- sensors/2.0/multihal/HalProxy.cpp | 12 ++++++++---- sensors/2.0/multihal/include/HalProxy.h | 6 ++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/sensors/2.0/multihal/HalProxy.cpp b/sensors/2.0/multihal/HalProxy.cpp index 49c5a0d412..03ff6051a8 100644 --- a/sensors/2.0/multihal/HalProxy.cpp +++ b/sensors/2.0/multihal/HalProxy.cpp @@ -150,6 +150,7 @@ Return HalProxy::initialize( // Clears the queue if any events were pending write before. mPendingWriteEventsQueue = std::queue, size_t>>(); + mSizePendingWriteEventsQueue = 0; // Clears previously connected dynamic sensors mDynamicSensors.clear(); @@ -287,7 +288,7 @@ Return HalProxy::debug(const hidl_handle& fd, const hidl_vec& << " ms ago" << std::endl; // TODO(b/142969448): Add logging for history of wakelock acquisition per subhal. stream << " Wakelock ref count: " << mWakelockRefCount << std::endl; - stream << " Size of pending write events queue: " << mPendingWriteEventsQueue.size() + stream << " # of events on pending write writes queue: " << mSizePendingWriteEventsQueue << std::endl; if (!mPendingWriteEventsQueue.empty()) { stream << " Size of events list on front of pending writes queue: " @@ -490,8 +491,10 @@ void HalProxy::handlePendingWrites() { // all the events ahead of it down to fill gap off array at front after the erase. pendingWriteEvents.erase(pendingWriteEvents.begin(), pendingWriteEvents.begin() + eventQueueSize); + mSizePendingWriteEventsQueue -= eventQueueSize; } else { mPendingWriteEventsQueue.pop(); + mSizePendingWriteEventsQueue -= pendingWriteEvents.size(); } } } @@ -563,11 +566,12 @@ void HalProxy::postEventsToMessageQueue(const std::vector& events, size_t } } } - if (numToWrite < events.size()) { - // TODO(b/143302327): Bound the mPendingWriteEventsQueue so that we do not trigger OOMs if - // framework stalls + size_t numLeft = events.size() - numToWrite; + if (numToWrite < events.size() && + mSizePendingWriteEventsQueue + numLeft <= kMaxSizePendingWriteEventsQueue) { std::vector eventsLeft(events.begin() + numToWrite, events.end()); mPendingWriteEventsQueue.push({eventsLeft, numWakeupEvents}); + mSizePendingWriteEventsQueue += numLeft; mEventQueueWriteCV.notify_one(); } } diff --git a/sensors/2.0/multihal/include/HalProxy.h b/sensors/2.0/multihal/include/HalProxy.h index b1dd737025..ce28e6785f 100644 --- a/sensors/2.0/multihal/include/HalProxy.h +++ b/sensors/2.0/multihal/include/HalProxy.h @@ -200,6 +200,12 @@ class HalProxy : public ISensors, public IScopedWakelockRefCounter { */ std::queue, size_t>> mPendingWriteEventsQueue; + //! The max number of events allowed in the pending write events queue + static constexpr size_t kMaxSizePendingWriteEventsQueue = 100000; + + //! The number of events in the pending write events queue + size_t mSizePendingWriteEventsQueue = 0; + //! The mutex protecting writing to the fmq and the pending events queue std::mutex mEventQueueWriteMutex;