Merge "logd: simplify Clear() + Prune() logic" am: 7a372d168a

Original change: https://android-review.googlesource.com/c/platform/system/core/+/1329340

Change-Id: Iefe47627fec9555ef4abccbdc89465f7dc61925f
This commit is contained in:
Tom Cherry 2020-06-11 17:16:39 +00:00 committed by Automerger Merge Worker
commit b4fc12cc6c
3 changed files with 35 additions and 48 deletions

View File

@ -327,7 +327,6 @@ class LogBufferElementLast {
//
bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
LogReaderThread* oldest = nullptr;
bool busy = false;
bool clearAll = pruneRows == ULONG_MAX;
auto reader_threads_lock = std::lock_guard{reader_list()->reader_threads_lock()};
@ -359,17 +358,16 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
}
if (oldest && oldest->start() <= element.sequence()) {
busy = true;
KickReader(oldest, id, pruneRows);
break;
return false;
}
it = Erase(it);
if (--pruneRows == 0) {
break;
return true;
}
}
return busy;
return true;
}
// prune by worst offenders; by blacklist, UID, and by PID of system UID
@ -440,7 +438,6 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
LogBufferElement& element = *it;
if (oldest && oldest->start() <= element.sequence()) {
busy = true;
// Do not let chatty eliding trigger any reader mitigation
break;
}
@ -577,7 +574,6 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
}
if (oldest && oldest->start() <= element.sequence()) {
busy = true;
if (!whitelist) KickReader(oldest, id, pruneRows);
break;
}
@ -605,7 +601,6 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
}
if (oldest && oldest->start() <= element.sequence()) {
busy = true;
KickReader(oldest, id, pruneRows);
break;
}
@ -615,5 +610,5 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
}
}
return (pruneRows > 0) && busy;
return pruneRows == 0 || it == logs().end();
}

View File

@ -82,7 +82,7 @@ int CommandListener::ClearCmd::runCommand(SocketClient* cli, int argc,
return 0;
}
cli->sendMsg(buf()->Clear((log_id_t)id, uid) ? "busy" : "success");
cli->sendMsg(buf()->Clear((log_id_t)id, uid) ? "success" : "busy");
return 0;
}

View File

@ -212,46 +212,38 @@ bool SimpleLogBuffer::FlushTo(
return true;
}
// clear all rows of type "id" from the buffer.
bool SimpleLogBuffer::Clear(log_id_t id, uid_t uid) {
bool busy = true;
// If it takes more than 4 tries (seconds) to clear, then kill reader(s)
for (int retry = 4;;) {
if (retry == 1) { // last pass
// Check if it is still busy after the sleep, we say prune
// one entry, not another clear run, so we are looking for
// the quick side effect of the return value to tell us if
// we have a _blocked_ reader.
{
auto lock = std::lock_guard{lock_};
busy = Prune(id, 1, uid);
}
// It is still busy, blocked reader(s), lets kill them all!
// otherwise, lets be a good citizen and preserve the slow
// readers and let the clear run (below) deal with determining
// if we are still blocked and return an error code to caller.
if (busy) {
auto reader_threads_lock = std::lock_guard{reader_list_->reader_threads_lock()};
for (const auto& reader_thread : reader_list_->reader_threads()) {
if (reader_thread->IsWatching(id)) {
LOG(WARNING) << "Kicking blocked reader, " << reader_thread->name()
<< ", from LogBuffer::clear()";
reader_thread->release_Locked();
}
}
}
}
// Try three times to clear, then disconnect the readers and try one final time.
for (int retry = 0; retry < 3; ++retry) {
{
auto lock = std::lock_guard{lock_};
busy = Prune(id, ULONG_MAX, uid);
if (Prune(id, ULONG_MAX, uid)) {
return true;
}
}
if (!busy || !--retry) {
break;
}
sleep(1); // Let reader(s) catch up after notification
sleep(1);
}
return busy;
// Check if it is still busy after the sleep, we try to prune one entry, not another clear run,
// so we are looking for the quick side effect of the return value to tell us if we have a
// _blocked_ reader.
bool busy = false;
{
auto lock = std::lock_guard{lock_};
busy = !Prune(id, 1, uid);
}
// It is still busy, disconnect all readers.
if (busy) {
auto reader_threads_lock = std::lock_guard{reader_list_->reader_threads_lock()};
for (const auto& reader_thread : reader_list_->reader_threads()) {
if (reader_thread->IsWatching(id)) {
LOG(WARNING) << "Kicking blocked reader, " << reader_thread->name()
<< ", from LogBuffer::clear()";
reader_thread->release_Locked();
}
}
}
auto lock = std::lock_guard{lock_};
return Prune(id, ULONG_MAX, uid);
}
// get the total space allocated to "id"
@ -313,16 +305,16 @@ bool SimpleLogBuffer::Prune(log_id_t id, unsigned long prune_rows, uid_t caller_
if (oldest && oldest->start() <= element.sequence()) {
KickReader(oldest, id, prune_rows);
return true;
return false;
}
stats_->Subtract(element.ToLogStatisticsElement());
it = Erase(it);
if (--prune_rows == 0) {
return false;
return true;
}
}
return false;
return true;
}
std::list<LogBufferElement>::iterator SimpleLogBuffer::Erase(