Loading services/incremental/IncrementalService.cpp +43 −52 Original line number Original line Diff line number Diff line Loading @@ -1356,16 +1356,9 @@ void IncrementalService::prepareDataLoaderLocked(IncFsMount& ifs, DataLoaderPara fsControlParcel.incremental->log.reset(dup(ifs.control.logs())); fsControlParcel.incremental->log.reset(dup(ifs.control.logs())); fsControlParcel.service = new IncrementalServiceConnector(*this, ifs.mountId); fsControlParcel.service = new IncrementalServiceConnector(*this, ifs.mountId); incfs::UniqueControl healthControl = mIncFs->openMount(ifs.root.c_str()); if (healthControl.pendingReads() < 0) { LOG(ERROR) << "Failed to open health control for: " << ifs.root << "(" << healthControl.cmd() << ":" << healthControl.pendingReads() << ":" << healthControl.logs() << ")"; } ifs.dataLoaderStub = ifs.dataLoaderStub = new DataLoaderStub(*this, ifs.mountId, std::move(params), std::move(fsControlParcel), new DataLoaderStub(*this, ifs.mountId, std::move(params), std::move(fsControlParcel), std::move(healthControl), externalListener); externalListener, path::join(ifs.root, constants().mount)); } } template <class Duration> template <class Duration> Loading Loading @@ -1685,15 +1678,15 @@ void IncrementalService::onAppOpChanged(const std::string& packageName) { IncrementalService::DataLoaderStub::DataLoaderStub(IncrementalService& service, MountId id, IncrementalService::DataLoaderStub::DataLoaderStub(IncrementalService& service, MountId id, DataLoaderParamsParcel&& params, DataLoaderParamsParcel&& params, FileSystemControlParcel&& control, FileSystemControlParcel&& control, incfs::UniqueControl&& healthControl, const DataLoaderStatusListener* externalListener, const DataLoaderStatusListener* externalListener) std::string&& healthPath) : mService(service), : mService(service), mId(id), mId(id), mParams(std::move(params)), mParams(std::move(params)), mControl(std::move(control)), mControl(std::move(control)), mHealthControl(std::move(healthControl)), mListener(externalListener ? *externalListener : DataLoaderStatusListener()), mListener(externalListener ? *externalListener : DataLoaderStatusListener()) { mHealthPath(std::move(healthPath)) { addToCmdLooperLocked(); healthStatusOk(); } } IncrementalService::DataLoaderStub::~DataLoaderStub() { IncrementalService::DataLoaderStub::~DataLoaderStub() { Loading @@ -1708,11 +1701,10 @@ void IncrementalService::DataLoaderStub::cleanupResources() { auto now = Clock::now(); auto now = Clock::now(); std::unique_lock lock(mMutex); std::unique_lock lock(mMutex); removeFromCmdLooperLocked(); unregisterFromPendingReads(); mParams = {}; mParams = {}; mControl = {}; mControl = {}; mHealthControl = {}; mStatusCondition.wait_until(lock, now + 60s, [this] { mStatusCondition.wait_until(lock, now + 60s, [this] { return mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_DESTROYED; return mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_DESTROYED; }); }); Loading Loading @@ -1832,7 +1824,7 @@ bool IncrementalService::DataLoaderStub::fsmStep() { case IDataLoaderStatusListener::DATA_LOADER_STOPPED: case IDataLoaderStatusListener::DATA_LOADER_STOPPED: return start(); return start(); } } // fallthrough [[fallthrough]]; } } case IDataLoaderStatusListener::DATA_LOADER_CREATED: case IDataLoaderStatusListener::DATA_LOADER_CREATED: switch (currentStatus) { switch (currentStatus) { Loading Loading @@ -1895,23 +1887,48 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount return binder::Status::ok(); return binder::Status::ok(); } } void IncrementalService::DataLoaderStub::addToCmdLooperLocked() { void IncrementalService::DataLoaderStub::healthStatusOk() { const auto pendingReadsFd = mHealthControl.pendingReads(); LOG(DEBUG) << "healthStatusOk: " << mId; std::unique_lock lock(mMutex); registerForPendingReads(); } void IncrementalService::DataLoaderStub::healthStatusReadsPending() { LOG(DEBUG) << "healthStatusReadsPending: " << mId; requestStart(); std::unique_lock lock(mMutex); unregisterFromPendingReads(); } void IncrementalService::DataLoaderStub::healthStatusBlocked() {} void IncrementalService::DataLoaderStub::healthStatusUnhealthy() {} void IncrementalService::DataLoaderStub::registerForPendingReads() { auto pendingReadsFd = mHealthControl.pendingReads(); if (pendingReadsFd < 0) { mHealthControl = mService.mIncFs->openMount(mHealthPath); pendingReadsFd = mHealthControl.pendingReads(); if (pendingReadsFd < 0) { if (pendingReadsFd < 0) { LOG(ERROR) << "Failed to open health control for: " << mId << ", path: " << mHealthPath << "(" << mHealthControl.cmd() << ":" << mHealthControl.pendingReads() << ":" << mHealthControl.logs() << ")"; return; return; } } } mService.mLooper->addFd( mService.mLooper->addFd( pendingReadsFd, android::Looper::POLL_CALLBACK, android::Looper::EVENT_INPUT, pendingReadsFd, android::Looper::POLL_CALLBACK, android::Looper::EVENT_INPUT, [](int, int, void* data) -> int { [](int, int, void* data) -> int { auto&& self = (DataLoaderStub*)data; auto&& self = (DataLoaderStub*)data; return self->onCmdLooperEvent(); return self->onPendingReads(); }, }, this); this); mService.mLooper->wake(); mService.mLooper->wake(); } } void IncrementalService::DataLoaderStub::removeFromCmdLooperLocked() { void IncrementalService::DataLoaderStub::unregisterFromPendingReads() { const auto pendingReadsFd = mHealthControl.pendingReads(); const auto pendingReadsFd = mHealthControl.pendingReads(); if (pendingReadsFd < 0) { if (pendingReadsFd < 0) { return; return; Loading @@ -1919,41 +1936,17 @@ void IncrementalService::DataLoaderStub::removeFromCmdLooperLocked() { mService.mLooper->removeFd(pendingReadsFd); mService.mLooper->removeFd(pendingReadsFd); mService.mLooper->wake(); mService.mLooper->wake(); mHealthControl = {}; } } int IncrementalService::DataLoaderStub::onCmdLooperEvent() { int IncrementalService::DataLoaderStub::onPendingReads() { if (!mService.mRunning.load(std::memory_order_relaxed)) { if (!mService.mRunning.load(std::memory_order_relaxed)) { return 0; return 0; } } bool pendingReadsOccur = false; healthStatusReadsPending(); return 0; { std::unique_lock lock(mMutex); const auto now = Clock::now(); if (now < mEarliestMissingPageTs) { // Transition: duration::max -> now. mEarliestMissingPageTs = now; pendingReadsOccur = true; } } if (pendingReadsOccur) { LOG(INFO) << "Pending reads occur for, requesting start for: " << mId; requestStart(); } { // Drop pending reads. static constexpr auto kMaxDropIterations = 3; std::unique_lock lock(mMutex); for (int i = 0; i < kMaxDropIterations; ++i) { if (IncFs_DropPendingReads(mHealthControl) <= 0) { break; } } } return 1; } } void IncrementalService::DataLoaderStub::onDump(int fd) { void IncrementalService::DataLoaderStub::onDump(int fd) { Loading @@ -1962,8 +1955,6 @@ void IncrementalService::DataLoaderStub::onDump(int fd) { dprintf(fd, " targetStatus: %d\n", mTargetStatus); dprintf(fd, " targetStatus: %d\n", mTargetStatus); dprintf(fd, " targetStatusTs: %lldmcs\n", dprintf(fd, " targetStatusTs: %lldmcs\n", (long long)(elapsedMcs(mTargetStatusTs, Clock::now()))); (long long)(elapsedMcs(mTargetStatusTs, Clock::now()))); dprintf(fd, " earliestMissingPageTs: %lldmcs\n", (long long)(elapsedMcs(mEarliestMissingPageTs, Clock::now()))); const auto& params = mParams; const auto& params = mParams; dprintf(fd, " dataLoaderParams: {\n"); dprintf(fd, " dataLoaderParams: {\n"); dprintf(fd, " type: %s\n", toString(params.type).c_str()); dprintf(fd, " type: %s\n", toString(params.type).c_str()); Loading services/incremental/IncrementalService.h +16 −7 Original line number Original line Diff line number Diff line Loading @@ -161,8 +161,7 @@ private: DataLoaderStub(IncrementalService& service, MountId id, DataLoaderStub(IncrementalService& service, MountId id, content::pm::DataLoaderParamsParcel&& params, content::pm::DataLoaderParamsParcel&& params, content::pm::FileSystemControlParcel&& control, content::pm::FileSystemControlParcel&& control, incfs::UniqueControl&& healthControl, const DataLoaderStatusListener* externalListener, std::string&& healthPath); const DataLoaderStatusListener* externalListener); ~DataLoaderStub(); ~DataLoaderStub(); // Cleans up the internal state and invalidates DataLoaderStub. Any subsequent calls will // Cleans up the internal state and invalidates DataLoaderStub. Any subsequent calls will // result in an error. // result in an error. Loading @@ -180,9 +179,9 @@ private: private: private: binder::Status onStatusChanged(MountId mount, int newStatus) final; binder::Status onStatusChanged(MountId mount, int newStatus) final; void addToCmdLooperLocked(); void registerForPendingReads(); void removeFromCmdLooperLocked(); void unregisterFromPendingReads(); int onCmdLooperEvent(); int onPendingReads(); bool isValid() const { return mId != kInvalidStorageId; } bool isValid() const { return mId != kInvalidStorageId; } sp<content::pm::IDataLoader> getDataLoader(); sp<content::pm::IDataLoader> getDataLoader(); Loading @@ -197,13 +196,22 @@ private: bool fsmStep(); bool fsmStep(); // Watching for pending reads. void healthStatusOk(); // Pending reads detected, waiting for Xsecs to confirm blocked state. void healthStatusReadsPending(); // There are reads pending for X+secs, waiting for additional Ysecs to confirm unhealthy // state. void healthStatusBlocked(); // There are reads pending for X+Ysecs, marking storage as unhealthy. void healthStatusUnhealthy(); IncrementalService& mService; IncrementalService& mService; std::mutex mMutex; std::mutex mMutex; MountId mId = kInvalidStorageId; MountId mId = kInvalidStorageId; content::pm::DataLoaderParamsParcel mParams; content::pm::DataLoaderParamsParcel mParams; content::pm::FileSystemControlParcel mControl; content::pm::FileSystemControlParcel mControl; incfs::UniqueControl mHealthControl; DataLoaderStatusListener mListener; DataLoaderStatusListener mListener; std::condition_variable mStatusCondition; std::condition_variable mStatusCondition; Loading @@ -211,7 +219,8 @@ private: int mTargetStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED; int mTargetStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED; TimePoint mTargetStatusTs = {}; TimePoint mTargetStatusTs = {}; TimePoint mEarliestMissingPageTs{Clock::duration::max()}; std::string mHealthPath; incfs::UniqueControl mHealthControl; }; }; using DataLoaderStubPtr = sp<DataLoaderStub>; using DataLoaderStubPtr = sp<DataLoaderStub>; Loading Loading
services/incremental/IncrementalService.cpp +43 −52 Original line number Original line Diff line number Diff line Loading @@ -1356,16 +1356,9 @@ void IncrementalService::prepareDataLoaderLocked(IncFsMount& ifs, DataLoaderPara fsControlParcel.incremental->log.reset(dup(ifs.control.logs())); fsControlParcel.incremental->log.reset(dup(ifs.control.logs())); fsControlParcel.service = new IncrementalServiceConnector(*this, ifs.mountId); fsControlParcel.service = new IncrementalServiceConnector(*this, ifs.mountId); incfs::UniqueControl healthControl = mIncFs->openMount(ifs.root.c_str()); if (healthControl.pendingReads() < 0) { LOG(ERROR) << "Failed to open health control for: " << ifs.root << "(" << healthControl.cmd() << ":" << healthControl.pendingReads() << ":" << healthControl.logs() << ")"; } ifs.dataLoaderStub = ifs.dataLoaderStub = new DataLoaderStub(*this, ifs.mountId, std::move(params), std::move(fsControlParcel), new DataLoaderStub(*this, ifs.mountId, std::move(params), std::move(fsControlParcel), std::move(healthControl), externalListener); externalListener, path::join(ifs.root, constants().mount)); } } template <class Duration> template <class Duration> Loading Loading @@ -1685,15 +1678,15 @@ void IncrementalService::onAppOpChanged(const std::string& packageName) { IncrementalService::DataLoaderStub::DataLoaderStub(IncrementalService& service, MountId id, IncrementalService::DataLoaderStub::DataLoaderStub(IncrementalService& service, MountId id, DataLoaderParamsParcel&& params, DataLoaderParamsParcel&& params, FileSystemControlParcel&& control, FileSystemControlParcel&& control, incfs::UniqueControl&& healthControl, const DataLoaderStatusListener* externalListener, const DataLoaderStatusListener* externalListener) std::string&& healthPath) : mService(service), : mService(service), mId(id), mId(id), mParams(std::move(params)), mParams(std::move(params)), mControl(std::move(control)), mControl(std::move(control)), mHealthControl(std::move(healthControl)), mListener(externalListener ? *externalListener : DataLoaderStatusListener()), mListener(externalListener ? *externalListener : DataLoaderStatusListener()) { mHealthPath(std::move(healthPath)) { addToCmdLooperLocked(); healthStatusOk(); } } IncrementalService::DataLoaderStub::~DataLoaderStub() { IncrementalService::DataLoaderStub::~DataLoaderStub() { Loading @@ -1708,11 +1701,10 @@ void IncrementalService::DataLoaderStub::cleanupResources() { auto now = Clock::now(); auto now = Clock::now(); std::unique_lock lock(mMutex); std::unique_lock lock(mMutex); removeFromCmdLooperLocked(); unregisterFromPendingReads(); mParams = {}; mParams = {}; mControl = {}; mControl = {}; mHealthControl = {}; mStatusCondition.wait_until(lock, now + 60s, [this] { mStatusCondition.wait_until(lock, now + 60s, [this] { return mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_DESTROYED; return mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_DESTROYED; }); }); Loading Loading @@ -1832,7 +1824,7 @@ bool IncrementalService::DataLoaderStub::fsmStep() { case IDataLoaderStatusListener::DATA_LOADER_STOPPED: case IDataLoaderStatusListener::DATA_LOADER_STOPPED: return start(); return start(); } } // fallthrough [[fallthrough]]; } } case IDataLoaderStatusListener::DATA_LOADER_CREATED: case IDataLoaderStatusListener::DATA_LOADER_CREATED: switch (currentStatus) { switch (currentStatus) { Loading Loading @@ -1895,23 +1887,48 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount return binder::Status::ok(); return binder::Status::ok(); } } void IncrementalService::DataLoaderStub::addToCmdLooperLocked() { void IncrementalService::DataLoaderStub::healthStatusOk() { const auto pendingReadsFd = mHealthControl.pendingReads(); LOG(DEBUG) << "healthStatusOk: " << mId; std::unique_lock lock(mMutex); registerForPendingReads(); } void IncrementalService::DataLoaderStub::healthStatusReadsPending() { LOG(DEBUG) << "healthStatusReadsPending: " << mId; requestStart(); std::unique_lock lock(mMutex); unregisterFromPendingReads(); } void IncrementalService::DataLoaderStub::healthStatusBlocked() {} void IncrementalService::DataLoaderStub::healthStatusUnhealthy() {} void IncrementalService::DataLoaderStub::registerForPendingReads() { auto pendingReadsFd = mHealthControl.pendingReads(); if (pendingReadsFd < 0) { mHealthControl = mService.mIncFs->openMount(mHealthPath); pendingReadsFd = mHealthControl.pendingReads(); if (pendingReadsFd < 0) { if (pendingReadsFd < 0) { LOG(ERROR) << "Failed to open health control for: " << mId << ", path: " << mHealthPath << "(" << mHealthControl.cmd() << ":" << mHealthControl.pendingReads() << ":" << mHealthControl.logs() << ")"; return; return; } } } mService.mLooper->addFd( mService.mLooper->addFd( pendingReadsFd, android::Looper::POLL_CALLBACK, android::Looper::EVENT_INPUT, pendingReadsFd, android::Looper::POLL_CALLBACK, android::Looper::EVENT_INPUT, [](int, int, void* data) -> int { [](int, int, void* data) -> int { auto&& self = (DataLoaderStub*)data; auto&& self = (DataLoaderStub*)data; return self->onCmdLooperEvent(); return self->onPendingReads(); }, }, this); this); mService.mLooper->wake(); mService.mLooper->wake(); } } void IncrementalService::DataLoaderStub::removeFromCmdLooperLocked() { void IncrementalService::DataLoaderStub::unregisterFromPendingReads() { const auto pendingReadsFd = mHealthControl.pendingReads(); const auto pendingReadsFd = mHealthControl.pendingReads(); if (pendingReadsFd < 0) { if (pendingReadsFd < 0) { return; return; Loading @@ -1919,41 +1936,17 @@ void IncrementalService::DataLoaderStub::removeFromCmdLooperLocked() { mService.mLooper->removeFd(pendingReadsFd); mService.mLooper->removeFd(pendingReadsFd); mService.mLooper->wake(); mService.mLooper->wake(); mHealthControl = {}; } } int IncrementalService::DataLoaderStub::onCmdLooperEvent() { int IncrementalService::DataLoaderStub::onPendingReads() { if (!mService.mRunning.load(std::memory_order_relaxed)) { if (!mService.mRunning.load(std::memory_order_relaxed)) { return 0; return 0; } } bool pendingReadsOccur = false; healthStatusReadsPending(); return 0; { std::unique_lock lock(mMutex); const auto now = Clock::now(); if (now < mEarliestMissingPageTs) { // Transition: duration::max -> now. mEarliestMissingPageTs = now; pendingReadsOccur = true; } } if (pendingReadsOccur) { LOG(INFO) << "Pending reads occur for, requesting start for: " << mId; requestStart(); } { // Drop pending reads. static constexpr auto kMaxDropIterations = 3; std::unique_lock lock(mMutex); for (int i = 0; i < kMaxDropIterations; ++i) { if (IncFs_DropPendingReads(mHealthControl) <= 0) { break; } } } return 1; } } void IncrementalService::DataLoaderStub::onDump(int fd) { void IncrementalService::DataLoaderStub::onDump(int fd) { Loading @@ -1962,8 +1955,6 @@ void IncrementalService::DataLoaderStub::onDump(int fd) { dprintf(fd, " targetStatus: %d\n", mTargetStatus); dprintf(fd, " targetStatus: %d\n", mTargetStatus); dprintf(fd, " targetStatusTs: %lldmcs\n", dprintf(fd, " targetStatusTs: %lldmcs\n", (long long)(elapsedMcs(mTargetStatusTs, Clock::now()))); (long long)(elapsedMcs(mTargetStatusTs, Clock::now()))); dprintf(fd, " earliestMissingPageTs: %lldmcs\n", (long long)(elapsedMcs(mEarliestMissingPageTs, Clock::now()))); const auto& params = mParams; const auto& params = mParams; dprintf(fd, " dataLoaderParams: {\n"); dprintf(fd, " dataLoaderParams: {\n"); dprintf(fd, " type: %s\n", toString(params.type).c_str()); dprintf(fd, " type: %s\n", toString(params.type).c_str()); Loading
services/incremental/IncrementalService.h +16 −7 Original line number Original line Diff line number Diff line Loading @@ -161,8 +161,7 @@ private: DataLoaderStub(IncrementalService& service, MountId id, DataLoaderStub(IncrementalService& service, MountId id, content::pm::DataLoaderParamsParcel&& params, content::pm::DataLoaderParamsParcel&& params, content::pm::FileSystemControlParcel&& control, content::pm::FileSystemControlParcel&& control, incfs::UniqueControl&& healthControl, const DataLoaderStatusListener* externalListener, std::string&& healthPath); const DataLoaderStatusListener* externalListener); ~DataLoaderStub(); ~DataLoaderStub(); // Cleans up the internal state and invalidates DataLoaderStub. Any subsequent calls will // Cleans up the internal state and invalidates DataLoaderStub. Any subsequent calls will // result in an error. // result in an error. Loading @@ -180,9 +179,9 @@ private: private: private: binder::Status onStatusChanged(MountId mount, int newStatus) final; binder::Status onStatusChanged(MountId mount, int newStatus) final; void addToCmdLooperLocked(); void registerForPendingReads(); void removeFromCmdLooperLocked(); void unregisterFromPendingReads(); int onCmdLooperEvent(); int onPendingReads(); bool isValid() const { return mId != kInvalidStorageId; } bool isValid() const { return mId != kInvalidStorageId; } sp<content::pm::IDataLoader> getDataLoader(); sp<content::pm::IDataLoader> getDataLoader(); Loading @@ -197,13 +196,22 @@ private: bool fsmStep(); bool fsmStep(); // Watching for pending reads. void healthStatusOk(); // Pending reads detected, waiting for Xsecs to confirm blocked state. void healthStatusReadsPending(); // There are reads pending for X+secs, waiting for additional Ysecs to confirm unhealthy // state. void healthStatusBlocked(); // There are reads pending for X+Ysecs, marking storage as unhealthy. void healthStatusUnhealthy(); IncrementalService& mService; IncrementalService& mService; std::mutex mMutex; std::mutex mMutex; MountId mId = kInvalidStorageId; MountId mId = kInvalidStorageId; content::pm::DataLoaderParamsParcel mParams; content::pm::DataLoaderParamsParcel mParams; content::pm::FileSystemControlParcel mControl; content::pm::FileSystemControlParcel mControl; incfs::UniqueControl mHealthControl; DataLoaderStatusListener mListener; DataLoaderStatusListener mListener; std::condition_variable mStatusCondition; std::condition_variable mStatusCondition; Loading @@ -211,7 +219,8 @@ private: int mTargetStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED; int mTargetStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED; TimePoint mTargetStatusTs = {}; TimePoint mTargetStatusTs = {}; TimePoint mEarliestMissingPageTs{Clock::duration::max()}; std::string mHealthPath; incfs::UniqueControl mHealthControl; }; }; using DataLoaderStubPtr = sp<DataLoaderStub>; using DataLoaderStubPtr = sp<DataLoaderStub>; Loading