Skip to content

Commit 56cd920

Browse files
Tom CherryGerrit Code Review
Tom Cherry
authored and
Gerrit Code Review
committed
Merge changes If1a62a90,Ibce79cf1,Ia2bbf01a,I1763be56,I56762747, ...
* changes: logd: don't send logs before the start time on the first flushTo() Revert "logd: drop mSequence from LogBufferElement" Revert "logd: regression in handling watermark boundary." Revert "logd: logcat --clear respect pruneMargin" logd: wait for timeout via CLOCK_MONOTONIC Revert "logd: wakeup wrap timeout if realtime changes drastically" logd: do not attempt to sort log messages by time
2 parents 1ec8c39 + 65ab7fe commit 56cd920

9 files changed

+116
-208
lines changed

logd/FlushCommand.cpp

+2-12
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,8 @@ void FlushCommand::runSocketCommand(SocketClient* client) {
4949
return;
5050
}
5151
if (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec) {
52-
if (mReader.logbuf().isMonotonic()) {
53-
LogTimeEntry::unlock();
54-
return;
55-
}
56-
// If the user changes the time in a gross manner that
57-
// invalidates the timeout, fall through and trigger.
58-
log_time now(CLOCK_REALTIME);
59-
if (((entry->mEnd + entry->mTimeout) > now) &&
60-
(now > entry->mEnd)) {
61-
LogTimeEntry::unlock();
62-
return;
63-
}
52+
LogTimeEntry::unlock();
53+
return;
6454
}
6555
entry->triggerReader_Locked();
6656
LogTimeEntry::unlock();

logd/FlushCommand.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#ifndef _FLUSH_COMMAND_H
1717
#define _FLUSH_COMMAND_H
1818

19-
#include <private/android_logger.h>
19+
#include <android/log.h>
2020
#include <sysutils/SocketClientCommand.h>
2121

2222
class LogBufferElement;

logd/LogBuffer.cpp

+24-101
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <unistd.h>
2828

2929
#include <unordered_map>
30+
#include <utility>
3031

3132
#include <cutils/properties.h>
3233
#include <private/android_logger.h>
@@ -43,8 +44,6 @@
4344
// Default
4445
#define log_buffer_size(id) mMaxSize[id]
4546

46-
const log_time LogBuffer::pruneMargin(3, 0);
47-
4847
void LogBuffer::init() {
4948
log_id_for_each(i) {
5049
mLastSet[i] = false;
@@ -390,59 +389,7 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
390389

391390
// assumes LogBuffer::wrlock() held, owns elem, look after garbage collection
392391
void LogBuffer::log(LogBufferElement* elem) {
393-
// cap on how far back we will sort in-place, otherwise append
394-
static uint32_t too_far_back = 5; // five seconds
395-
// Insert elements in time sorted order if possible
396-
// NB: if end is region locked, place element at end of list
397-
LogBufferElementCollection::iterator it = mLogElements.end();
398-
LogBufferElementCollection::iterator last = it;
399-
if (__predict_true(it != mLogElements.begin())) --it;
400-
if (__predict_false(it == mLogElements.begin()) ||
401-
__predict_true((*it)->getRealTime() <= elem->getRealTime()) ||
402-
__predict_false((((*it)->getRealTime().tv_sec - too_far_back) >
403-
elem->getRealTime().tv_sec) &&
404-
(elem->getLogId() != LOG_ID_KERNEL) &&
405-
((*it)->getLogId() != LOG_ID_KERNEL))) {
406-
mLogElements.push_back(elem);
407-
} else {
408-
log_time end(log_time::EPOCH);
409-
bool end_set = false;
410-
bool end_always = false;
411-
412-
LogTimeEntry::rdlock();
413-
414-
LastLogTimes::iterator times = mTimes.begin();
415-
while (times != mTimes.end()) {
416-
LogTimeEntry* entry = times->get();
417-
if (!entry->mNonBlock) {
418-
end_always = true;
419-
break;
420-
}
421-
// it passing mEnd is blocked by the following checks.
422-
if (!end_set || (end <= entry->mEnd)) {
423-
end = entry->mEnd;
424-
end_set = true;
425-
}
426-
times++;
427-
}
428-
429-
if (end_always || (end_set && (end > (*it)->getRealTime()))) {
430-
mLogElements.push_back(elem);
431-
} else {
432-
// should be short as timestamps are localized near end()
433-
do {
434-
last = it;
435-
if (__predict_false(it == mLogElements.begin())) {
436-
break;
437-
}
438-
--it;
439-
} while (((*it)->getRealTime() > elem->getRealTime()) &&
440-
(!end_set || (end <= (*it)->getRealTime())));
441-
mLogElements.insert(last, elem);
442-
}
443-
LogTimeEntry::unlock();
444-
}
445-
392+
mLogElements.push_back(elem);
446393
stats.add(elem);
447394
maybePrune(elem->getLogId());
448395
}
@@ -614,12 +561,11 @@ class LogBufferElementLast {
614561
}
615562

616563
void clear(LogBufferElement* element) {
617-
log_time current =
618-
element->getRealTime() - log_time(EXPIRE_RATELIMIT, 0);
564+
uint64_t current = element->getRealTime().nsec() - (EXPIRE_RATELIMIT * NS_PER_SEC);
619565
for (LogBufferElementMap::iterator it = map.begin(); it != map.end();) {
620566
LogBufferElement* mapElement = it->second;
621-
if ((mapElement->getDropped() >= EXPIRE_THRESHOLD) &&
622-
(current > mapElement->getRealTime())) {
567+
if (mapElement->getDropped() >= EXPIRE_THRESHOLD &&
568+
current > mapElement->getRealTime().nsec()) {
623569
it = map.erase(it);
624570
} else {
625571
++it;
@@ -628,16 +574,6 @@ class LogBufferElementLast {
628574
}
629575
};
630576

631-
// Determine if watermark is within pruneMargin + 1s from the end of the list,
632-
// the caller will use this result to set an internal busy flag indicating
633-
// the prune operation could not be completed because a reader is blocking
634-
// the request.
635-
bool LogBuffer::isBusy(log_time watermark) {
636-
LogBufferElementCollection::iterator ei = mLogElements.end();
637-
--ei;
638-
return watermark < ((*ei)->getRealTime() - pruneMargin - log_time(1, 0));
639-
}
640-
641577
// If the selected reader is blocking our pruning progress, decide on
642578
// what kind of mitigation is necessary to unblock the situation.
643579
void LogBuffer::kickMe(LogTimeEntry* me, log_id_t id, unsigned long pruneRows) {
@@ -726,8 +662,6 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
726662
}
727663
times++;
728664
}
729-
log_time watermark(log_time::tv_sec_max, log_time::tv_nsec_max);
730-
if (oldest) watermark = oldest->mStart - pruneMargin;
731665

732666
LogBufferElementCollection::iterator it;
733667

@@ -749,9 +683,9 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
749683
mLastSet[id] = true;
750684
}
751685

752-
if (oldest && (watermark <= element->getRealTime())) {
753-
busy = isBusy(watermark);
754-
if (busy) kickMe(oldest, id, pruneRows);
686+
if (oldest && oldest->mStart <= element->getSequence()) {
687+
busy = true;
688+
kickMe(oldest, id, pruneRows);
755689
break;
756690
}
757691

@@ -837,8 +771,8 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
837771
while (it != mLogElements.end()) {
838772
LogBufferElement* element = *it;
839773

840-
if (oldest && (watermark <= element->getRealTime())) {
841-
busy = isBusy(watermark);
774+
if (oldest && oldest->mStart <= element->getSequence()) {
775+
busy = true;
842776
// Do not let chatty eliding trigger any reader mitigation
843777
break;
844778
}
@@ -989,9 +923,9 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
989923
mLastSet[id] = true;
990924
}
991925

992-
if (oldest && (watermark <= element->getRealTime())) {
993-
busy = isBusy(watermark);
994-
if (!whitelist && busy) kickMe(oldest, id, pruneRows);
926+
if (oldest && oldest->mStart <= element->getSequence()) {
927+
busy = true;
928+
if (!whitelist) kickMe(oldest, id, pruneRows);
995929
break;
996930
}
997931

@@ -1022,9 +956,9 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
1022956
mLastSet[id] = true;
1023957
}
1024958

1025-
if (oldest && (watermark <= element->getRealTime())) {
1026-
busy = isBusy(watermark);
1027-
if (busy) kickMe(oldest, id, pruneRows);
959+
if (oldest && oldest->mStart <= element->getSequence()) {
960+
busy = true;
961+
kickMe(oldest, id, pruneRows);
1028962
break;
1029963
}
1030964

@@ -1111,43 +1045,32 @@ unsigned long LogBuffer::getSize(log_id_t id) {
11111045
return retval;
11121046
}
11131047

1114-
log_time LogBuffer::flushTo(SocketClient* reader, const log_time& start,
1115-
pid_t* lastTid, bool privileged, bool security,
1116-
int (*filter)(const LogBufferElement* element,
1117-
void* arg),
1118-
void* arg) {
1048+
uint64_t LogBuffer::flushTo(SocketClient* reader, uint64_t start, pid_t* lastTid, bool privileged,
1049+
bool security,
1050+
int (*filter)(const LogBufferElement* element, void* arg), void* arg) {
11191051
LogBufferElementCollection::iterator it;
11201052
uid_t uid = reader->getUid();
11211053

11221054
rdlock();
11231055

1124-
if (start == log_time::EPOCH) {
1056+
if (start <= 1) {
11251057
// client wants to start from the beginning
11261058
it = mLogElements.begin();
11271059
} else {
1128-
// Cap to 300 iterations we look back for out-of-order entries.
1129-
size_t count = 300;
1130-
11311060
// Client wants to start from some specified time. Chances are
11321061
// we are better off starting from the end of the time sorted list.
1133-
LogBufferElementCollection::iterator last;
1134-
for (last = it = mLogElements.end(); it != mLogElements.begin();
1062+
for (it = mLogElements.end(); it != mLogElements.begin();
11351063
/* do nothing */) {
11361064
--it;
11371065
LogBufferElement* element = *it;
1138-
if (element->getRealTime() > start) {
1139-
last = it;
1140-
} else if (element->getRealTime() == start) {
1141-
last = ++it;
1142-
break;
1143-
} else if (!--count) {
1066+
if (element->getSequence() <= start) {
1067+
it++;
11441068
break;
11451069
}
11461070
}
1147-
it = last;
11481071
}
11491072

1150-
log_time curr = start;
1073+
uint64_t curr = start;
11511074

11521075
LogBufferElement* lastElement = nullptr; // iterator corruption paranoia
11531076
static const size_t maxSkip = 4194304; // maximum entries to skip

logd/LogBuffer.h

+2-5
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,10 @@ class LogBuffer {
118118
// lastTid is an optional context to help detect if the last previous
119119
// valid message was from the same source so we can differentiate chatty
120120
// filter types (identical or expired)
121-
log_time flushTo(SocketClient* writer, const log_time& start,
121+
uint64_t flushTo(SocketClient* writer, uint64_t start,
122122
pid_t* lastTid, // &lastTid[LOG_ID_MAX] or nullptr
123123
bool privileged, bool security,
124-
int (*filter)(const LogBufferElement* element,
125-
void* arg) = nullptr,
124+
int (*filter)(const LogBufferElement* element, void* arg) = nullptr,
126125
void* arg = nullptr);
127126

128127
bool clear(log_id_t id, uid_t uid = AID_ROOT);
@@ -175,10 +174,8 @@ class LogBuffer {
175174
private:
176175
static constexpr size_t minPrune = 4;
177176
static constexpr size_t maxPrune = 256;
178-
static const log_time pruneMargin;
179177

180178
void maybePrune(log_id_t id);
181-
bool isBusy(log_time watermark);
182179
void kickMe(LogTimeEntry* me, log_id_t id, unsigned long pruneRows);
183180

184181
bool prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT);

logd/LogBufferElement.cpp

+8-9
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@
3030
#include "LogReader.h"
3131
#include "LogUtils.h"
3232

33-
const log_time LogBufferElement::FLUSH_ERROR((uint32_t)-1, (uint32_t)-1);
33+
const uint64_t LogBufferElement::FLUSH_ERROR(0);
3434
atomic_int_fast64_t LogBufferElement::sequence(1);
3535

36-
LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime,
37-
uid_t uid, pid_t pid, pid_t tid,
38-
const char* msg, uint16_t len)
36+
LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
37+
pid_t tid, const char* msg, uint16_t len)
3938
: mUid(uid),
4039
mPid(pid),
4140
mTid(tid),
41+
mSequence(sequence.fetch_add(1, memory_order_relaxed)),
4242
mRealTime(realtime),
4343
mMsgLen(len),
4444
mLogId(log_id),
@@ -51,6 +51,7 @@ LogBufferElement::LogBufferElement(const LogBufferElement& elem)
5151
: mUid(elem.mUid),
5252
mPid(elem.mPid),
5353
mTid(elem.mTid),
54+
mSequence(elem.mSequence),
5455
mRealTime(elem.mRealTime),
5556
mMsgLen(elem.mMsgLen),
5657
mLogId(elem.mLogId),
@@ -244,7 +245,7 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogBuffer* parent
244245
return retval;
245246
}
246247

247-
log_time LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, bool lastSame) {
248+
uint64_t LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, bool lastSame) {
248249
struct logger_entry entry = {};
249250

250251
entry.hdr_size = sizeof(struct logger_entry);
@@ -263,17 +264,15 @@ log_time LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, bool
263264

264265
if (mDropped) {
265266
entry.len = populateDroppedMessage(buffer, parent, lastSame);
266-
if (!entry.len) return mRealTime;
267+
if (!entry.len) return mSequence;
267268
iovec[1].iov_base = buffer;
268269
} else {
269270
entry.len = mMsgLen;
270271
iovec[1].iov_base = mMsg;
271272
}
272273
iovec[1].iov_len = entry.len;
273274

274-
log_time retval = reader->sendDatav(iovec, 1 + (entry.len != 0))
275-
? FLUSH_ERROR
276-
: mRealTime;
275+
uint64_t retval = reader->sendDatav(iovec, 1 + (entry.len != 0)) ? FLUSH_ERROR : mSequence;
277276

278277
if (buffer) free(buffer);
279278

logd/LogBufferElement.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class __attribute__((packed)) LogBufferElement {
3939
const uint32_t mUid;
4040
const uint32_t mPid;
4141
const uint32_t mTid;
42+
uint64_t mSequence;
4243
log_time mRealTime;
4344
union {
4445
char* mMsg; // mDropped == false
@@ -90,10 +91,12 @@ class __attribute__((packed)) LogBufferElement {
9091
const char* getMsg() const {
9192
return mDropped ? nullptr : mMsg;
9293
}
94+
uint64_t getSequence() const { return mSequence; }
95+
static uint64_t getCurrentSequence() { return sequence.load(memory_order_relaxed); }
9396
log_time getRealTime(void) const {
9497
return mRealTime;
9598
}
9699

97-
static const log_time FLUSH_ERROR;
98-
log_time flushTo(SocketClient* writer, LogBuffer* parent, bool lastSame);
100+
static const uint64_t FLUSH_ERROR;
101+
uint64_t flushTo(SocketClient* writer, LogBuffer* parent, bool lastSame);
99102
};

0 commit comments

Comments
 (0)