* Inserts a syncache entry into the specified bucket row. * Locks and unlocks the syncache_head autonomously. */
| 366 | * Locks and unlocks the syncache_head autonomously. |
| 367 | */ |
| 368 | static void |
| 369 | syncache_insert(struct syncache *sc, struct syncache_head *sch) |
| 370 | { |
| 371 | struct syncache *sc2; |
| 372 | |
| 373 | SCH_LOCK(sch); |
| 374 | |
| 375 | /* |
| 376 | * Make sure that we don't overflow the per-bucket limit. |
| 377 | * If the bucket is full, toss the oldest element. |
| 378 | */ |
| 379 | if (sch->sch_length >= V_tcp_syncache.bucket_limit) { |
| 380 | KASSERT(!TAILQ_EMPTY(&sch->sch_bucket), |
| 381 | ("sch->sch_length incorrect")); |
| 382 | syncache_pause(&sc->sc_inc); |
| 383 | sc2 = TAILQ_LAST(&sch->sch_bucket, sch_head); |
| 384 | sch->sch_last_overflow = time_uptime; |
| 385 | syncache_drop(sc2, sch); |
| 386 | } |
| 387 | |
| 388 | /* Put it into the bucket. */ |
| 389 | TAILQ_INSERT_HEAD(&sch->sch_bucket, sc, sc_hash); |
| 390 | sch->sch_length++; |
| 391 | |
| 392 | #ifdef TCP_OFFLOAD |
| 393 | if (ADDED_BY_TOE(sc)) { |
| 394 | struct toedev *tod = sc->sc_tod; |
| 395 | |
| 396 | tod->tod_syncache_added(tod, sc->sc_todctx); |
| 397 | } |
| 398 | #endif |
| 399 | |
| 400 | /* Reinitialize the bucket row's timer. */ |
| 401 | if (sch->sch_length == 1) |
| 402 | sch->sch_nextc = ticks + INT_MAX; |
| 403 | syncache_timeout(sc, sch, 1); |
| 404 | |
| 405 | SCH_UNLOCK(sch); |
| 406 | |
| 407 | TCPSTATES_INC(TCPS_SYN_RECEIVED); |
| 408 | TCPSTAT_INC(tcps_sc_added); |
| 409 | } |
| 410 | |
| 411 | /* |
| 412 | * Remove and free entry from syncache bucket row. |
no test coverage detected