| 315 | |
| 316 | #ifdef VIMAGE |
| 317 | void |
| 318 | syncache_destroy(void) |
| 319 | { |
| 320 | struct syncache_head *sch; |
| 321 | struct syncache *sc, *nsc; |
| 322 | int i; |
| 323 | |
| 324 | /* |
| 325 | * Stop the re-seed timer before freeing resources. No need to |
| 326 | * possibly schedule it another time. |
| 327 | */ |
| 328 | callout_drain(&V_tcp_syncache.secret.reseed); |
| 329 | |
| 330 | /* Stop the SYN cache pause callout. */ |
| 331 | mtx_lock(&V_tcp_syncache.pause_mtx); |
| 332 | if (callout_stop(&V_tcp_syncache.pause_co) == 0) { |
| 333 | mtx_unlock(&V_tcp_syncache.pause_mtx); |
| 334 | callout_drain(&V_tcp_syncache.pause_co); |
| 335 | } else |
| 336 | mtx_unlock(&V_tcp_syncache.pause_mtx); |
| 337 | |
| 338 | /* Cleanup hash buckets: stop timers, free entries, destroy locks. */ |
| 339 | for (i = 0; i < V_tcp_syncache.hashsize; i++) { |
| 340 | sch = &V_tcp_syncache.hashbase[i]; |
| 341 | callout_drain(&sch->sch_timer); |
| 342 | |
| 343 | SCH_LOCK(sch); |
| 344 | TAILQ_FOREACH_SAFE(sc, &sch->sch_bucket, sc_hash, nsc) |
| 345 | syncache_drop(sc, sch); |
| 346 | SCH_UNLOCK(sch); |
| 347 | KASSERT(TAILQ_EMPTY(&sch->sch_bucket), |
| 348 | ("%s: sch->sch_bucket not empty", __func__)); |
| 349 | KASSERT(sch->sch_length == 0, ("%s: sch->sch_length %d not 0", |
| 350 | __func__, sch->sch_length)); |
| 351 | mtx_destroy(&sch->sch_mtx); |
| 352 | } |
| 353 | |
| 354 | KASSERT(uma_zone_get_cur(V_tcp_syncache.zone) == 0, |
| 355 | ("%s: cache_count not 0", __func__)); |
| 356 | |
| 357 | /* Free the allocated global resources. */ |
| 358 | uma_zdestroy(V_tcp_syncache.zone); |
| 359 | free(V_tcp_syncache.hashbase, M_SYNCACHE); |
| 360 | mtx_destroy(&V_tcp_syncache.pause_mtx); |
| 361 | } |
| 362 | #endif |
| 363 | |
| 364 | /* |
no test coverage detected