Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0878a7c1 authored by Mark Salyzyn's avatar Mark Salyzyn
Browse files

logd: logcat --clear respect pruneMargin

While a reader is present, consider it a success, and not busy, if a
buffer is pruned down to pruneMargin plus one second of additional
margin of logspan.  If not busy, no need to trigger any mitigations
regarding the readers, or to report any errors.

Side Effects are we no longer mitigate the reader when performing
chatty filtration. This is a positive side effect because we were
getting --wrap wakeups that seemed premature.

Add kickMe() and isBusy() methods to ease maintenance and uniformity
of actions.

Test: gTest liblog-unit-tests, logd-unit-tests & logcat-unit-tests
Test: manual: 'logcat -b all -c' repeat in a loop, at various logging
      load levels, simultaneously 'logcat -b' all in another session.
Bug: 38046067
Change-Id: I3d0c8a2d416a25c45504eda3bfe70b6f6e09ab27
parent 81824ebf
Loading
Loading
Loading
Loading
+35 −32
Original line number Original line Diff line number Diff line
@@ -605,6 +605,33 @@ class LogBufferElementLast {
    }
    }
};
};


// Determine if watermark is within pruneMargin + 1s from the end of the list,
// the caller will use this result to set an internal busy flag indicating
// the prune operation could not be completed because a reader is blocking
// the request.
bool LogBuffer::isBusy(log_time watermark) {
    LogBufferElementCollection::iterator ei = mLogElements.end();
    --ei;
    return watermark < ((*ei)->getRealTime() - pruneMargin - log_time(1, 0));
}

// If the selected reader is blocking our pruning progress, decide on
// what kind of mitigation is necessary to unblock the situation.
void LogBuffer::kickMe(LogTimeEntry* me, log_id_t id, unsigned long pruneRows) {
    if (stats.sizes(id) > (2 * log_buffer_size(id))) {  // +100%
        // A misbehaving or slow reader has its connection
        // dropped if we hit too much memory pressure.
        me->release_Locked();
    } else if (me->mTimeout.tv_sec || me->mTimeout.tv_nsec) {
        // Allow a blocked WRAP timeout reader to
        // trigger and start reporting the log data.
        me->triggerReader_Locked();
    } else {
        // tell slow reader to skip entries to catch up
        me->triggerSkip_Locked(id, pruneRows);
    }
}

// prune "pruneRows" of type "id" from the buffer.
// prune "pruneRows" of type "id" from the buffer.
//
//
// This garbage collection task is used to expire log entries. It is called to
// This garbage collection task is used to expire log entries. It is called to
@@ -695,12 +722,8 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
            }
            }


            if (oldest && (watermark <= element->getRealTime())) {
            if (oldest && (watermark <= element->getRealTime())) {
                busy = true;
                busy = isBusy(watermark);
                if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) {
                if (busy) kickMe(oldest, id, pruneRows);
                    oldest->triggerReader_Locked();
                } else {
                    oldest->triggerSkip_Locked(id, pruneRows);
                }
                break;
                break;
            }
            }


@@ -787,10 +810,8 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
            LogBufferElement* element = *it;
            LogBufferElement* element = *it;


            if (oldest && (watermark <= element->getRealTime())) {
            if (oldest && (watermark <= element->getRealTime())) {
                busy = true;
                busy = isBusy(watermark);
                if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) {
                // Do not let chatty eliding trigger any reader mitigation
                    oldest->triggerReader_Locked();
                }
                break;
                break;
            }
            }


@@ -941,19 +962,8 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
        }
        }


        if (oldest && (watermark <= element->getRealTime())) {
        if (oldest && (watermark <= element->getRealTime())) {
            busy = true;
            busy = isBusy(watermark);
            if (whitelist) {
            if (!whitelist && busy) kickMe(oldest, id, pruneRows);
                break;
            }

            if (stats.sizes(id) > (2 * log_buffer_size(id))) {
                // kick a misbehaving log reader client off the island
                oldest->release_Locked();
            } else if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) {
                oldest->triggerReader_Locked();
            } else {
                oldest->triggerSkip_Locked(id, pruneRows);
            }
            break;
            break;
        }
        }


@@ -985,15 +995,8 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
            }
            }


            if (oldest && (watermark <= element->getRealTime())) {
            if (oldest && (watermark <= element->getRealTime())) {
                busy = true;
                busy = isBusy(watermark);
                if (stats.sizes(id) > (2 * log_buffer_size(id))) {
                if (busy) kickMe(oldest, id, pruneRows);
                    // kick a misbehaving log reader client off the island
                    oldest->release_Locked();
                } else if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) {
                    oldest->triggerReader_Locked();
                } else {
                    oldest->triggerSkip_Locked(id, pruneRows);
                }
                break;
                break;
            }
            }


+3 −0
Original line number Original line Diff line number Diff line
@@ -184,6 +184,9 @@ class LogBuffer : public LogBufferInterface {
    static const log_time pruneMargin;
    static const log_time pruneMargin;


    void maybePrune(log_id_t id);
    void maybePrune(log_id_t id);
    bool isBusy(log_time watermark);
    void kickMe(LogTimeEntry* me, log_id_t id, unsigned long pruneRows);

    bool prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT);
    bool prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT);
    LogBufferElementCollection::iterator erase(
    LogBufferElementCollection::iterator erase(
        LogBufferElementCollection::iterator it, bool coalesce = false);
        LogBufferElementCollection::iterator it, bool coalesce = false);