defrag: remove trackers on lookup

When looking up a tracker, remove any timed out / completed trackers.
pull/11227/head
Victor Julien 2 years ago committed by Victor Julien
parent 75b78d7643
commit 1190e426f9

@ -5257,6 +5257,15 @@
} }
}, },
"additionalProperties": false "additionalProperties": false
},
"wrk": {
"type": "object",
"properties": {
"tracker_timeout": {
"type": "integer"
}
},
"additionalProperties": false
} }
}, },
"additionalProperties": false "additionalProperties": false

@ -679,6 +679,7 @@ void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
dtv->counter_defrag_no_frags = StatsRegisterCounter("defrag.max_frags_reached", tv); dtv->counter_defrag_no_frags = StatsRegisterCounter("defrag.max_frags_reached", tv);
dtv->counter_defrag_tracker_soft_reuse = StatsRegisterCounter("defrag.tracker_soft_reuse", tv); dtv->counter_defrag_tracker_soft_reuse = StatsRegisterCounter("defrag.tracker_soft_reuse", tv);
dtv->counter_defrag_tracker_hard_reuse = StatsRegisterCounter("defrag.tracker_hard_reuse", tv); dtv->counter_defrag_tracker_hard_reuse = StatsRegisterCounter("defrag.tracker_hard_reuse", tv);
dtv->counter_defrag_tracker_timeout = StatsRegisterCounter("defrag.wrk.tracker_timeout", tv);
ExceptionPolicySetStatsCounters(tv, &dtv->counter_defrag_memcap_eps, &defrag_memcap_eps_stats, ExceptionPolicySetStatsCounters(tv, &dtv->counter_defrag_memcap_eps, &defrag_memcap_eps_stats,
DefragGetMemcapExceptionPolicy(), "defrag.memcap_exception_policy.", DefragGetMemcapExceptionPolicy(), "defrag.memcap_exception_policy.",

@ -1002,6 +1002,7 @@ typedef struct DecodeThreadVars_
uint16_t counter_defrag_no_frags; uint16_t counter_defrag_no_frags;
uint16_t counter_defrag_tracker_soft_reuse; uint16_t counter_defrag_tracker_soft_reuse;
uint16_t counter_defrag_tracker_hard_reuse; uint16_t counter_defrag_tracker_hard_reuse;
uint16_t counter_defrag_tracker_timeout;
ExceptionPolicyCounters counter_defrag_memcap_eps; ExceptionPolicyCounters counter_defrag_memcap_eps;
uint16_t counter_flow_memcap; uint16_t counter_flow_memcap;

@ -555,27 +555,48 @@ DefragTracker *DefragGetTrackerFromHash(ThreadVars *tv, DecodeThreadVars *dtv, P
} }
/* ok, we have a tracker in the bucket. Let's find out if it is our tracker */ /* ok, we have a tracker in the bucket. Let's find out if it is our tracker */
DefragTracker *prev_dt = NULL;
dt = hb->head; dt = hb->head;
do { do {
DefragTracker *next_dt = NULL;
SCMutexLock(&dt->lock);
if (DefragTrackerTimedOut(dt, p->ts)) { if (DefragTrackerTimedOut(dt, p->ts)) {
dt->remove = 1; next_dt = dt->hnext;
dt->hnext = NULL;
if (prev_dt) {
prev_dt->hnext = next_dt;
} else {
hb->head = next_dt;
}
DefragTrackerClearMemory(dt);
SCMutexUnlock(&dt->lock);
DefragTrackerMoveToSpare(dt);
StatsIncr(tv, dtv->counter_defrag_tracker_timeout);
goto tracker_removed;
} else if (!dt->remove && DefragTrackerCompare(dt, p)) { } else if (!dt->remove && DefragTrackerCompare(dt, p)) {
/* found our tracker, lock & return */ /* found our tracker, keep locked & return */
SCMutexLock(&dt->lock);
(void)DefragTrackerIncrUsecnt(dt); (void)DefragTrackerIncrUsecnt(dt);
DRLOCK_UNLOCK(hb); DRLOCK_UNLOCK(hb);
return dt; return dt;
} }
SCMutexUnlock(&dt->lock);
/* unless we removed 'dt', prev_dt needs to point to
* current 'dt' when adding a new tracker below. */
prev_dt = dt;
next_dt = dt->hnext;
if (dt->hnext == NULL) { tracker_removed:
DefragTracker *prev = dt; if (next_dt == NULL) {
dt = DefragTrackerGetNew(tv, dtv, p); dt = DefragTrackerGetNew(tv, dtv, p);
if (dt == NULL) { if (dt == NULL) {
DRLOCK_UNLOCK(hb); DRLOCK_UNLOCK(hb);
return NULL; return NULL;
} }
prev->hnext = dt; dt->hnext = hb->head;
hb->head = dt;
/* tracker is locked */ /* tracker is locked */
@ -586,7 +607,7 @@ DefragTracker *DefragGetTrackerFromHash(ThreadVars *tv, DecodeThreadVars *dtv, P
return dt; return dt;
} }
dt = dt->hnext; dt = next_dt;
} while (dt != NULL); } while (dt != NULL);
/* should be unreachable */ /* should be unreachable */

@ -2571,7 +2571,10 @@ static int DefragTrackerReuseTest(void)
tracker2 = DefragGetTracker(&tv, &dtv, p1); tracker2 = DefragGetTracker(&tv, &dtv, p1);
FAIL_IF_NULL(tracker2); FAIL_IF_NULL(tracker2);
FAIL_IF(tracker2 == tracker1); /* DefragGetTracker will have returned tracker1 to the stack,
* the set up a new tracker. Since it pops the stack, it got
* tracker1. */
FAIL_IF(tracker2 != tracker1);
FAIL_IF(tracker2->remove); FAIL_IF(tracker2->remove);
SCFree(p1); SCFree(p1);

Loading…
Cancel
Save