When looking up a tracker, remove any timed out / completed trackers.
}
},
"additionalProperties": false
+ },
+ "wrk": {
+ "type": "object",
+ "properties": {
+ "tracker_timeout": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
}
},
"additionalProperties": false
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_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,
DefragGetMemcapExceptionPolicy(), "defrag.memcap_exception_policy.",
uint16_t counter_defrag_no_frags;
uint16_t counter_defrag_tracker_soft_reuse;
uint16_t counter_defrag_tracker_hard_reuse;
+ uint16_t counter_defrag_tracker_timeout;
ExceptionPolicyCounters counter_defrag_memcap_eps;
uint16_t counter_flow_memcap;
}
/* ok, we have a tracker in the bucket. Let's find out if it is our tracker */
+ DefragTracker *prev_dt = NULL;
dt = hb->head;
do {
+ DefragTracker *next_dt = NULL;
+
+ SCMutexLock(&dt->lock);
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)) {
- /* found our tracker, lock & return */
- SCMutexLock(&dt->lock);
+ /* found our tracker, keep locked & return */
(void)DefragTrackerIncrUsecnt(dt);
DRLOCK_UNLOCK(hb);
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) {
- DefragTracker *prev = dt;
+ tracker_removed:
+ if (next_dt == NULL) {
dt = DefragTrackerGetNew(tv, dtv, p);
if (dt == NULL) {
DRLOCK_UNLOCK(hb);
return NULL;
}
- prev->hnext = dt;
+ dt->hnext = hb->head;
+ hb->head = dt;
/* tracker is locked */
return dt;
}
- dt = dt->hnext;
+ dt = next_dt;
} while (dt != NULL);
/* should be unreachable */
tracker2 = DefragGetTracker(&tv, &dtv, p1);
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);
SCFree(p1);