| 389 | } |
| 390 | |
| 391 | static void |
| 392 | rs_destroy(epoch_context_t ctx) |
| 393 | { |
| 394 | struct tcp_rate_set *rs; |
| 395 | bool do_free_rs; |
| 396 | |
| 397 | rs = __containerof(ctx, struct tcp_rate_set, rs_epoch_ctx); |
| 398 | |
| 399 | mtx_lock(&rs_mtx); |
| 400 | rs->rs_flags &= ~RS_FUNERAL_SCHD; |
| 401 | /* |
| 402 | * In theory its possible (but unlikely) |
| 403 | * that while the delete was occuring |
| 404 | * and we were applying the DEAD flag |
| 405 | * someone slipped in and found the |
| 406 | * interface in a lookup. While we |
| 407 | * decided rs_flows_using were 0 and |
| 408 | * scheduling the epoch_call, the other |
| 409 | * thread incremented rs_flow_using. This |
| 410 | * is because users have a pointer and |
| 411 | * we only use the rs_flows_using in an |
| 412 | * atomic fashion, i.e. the other entities |
| 413 | * are not protected. To assure this did |
| 414 | * not occur, we check rs_flows_using here |
| 415 | * before deleting. |
| 416 | */ |
| 417 | do_free_rs = (rs->rs_flows_using == 0); |
| 418 | rs_number_dead--; |
| 419 | mtx_unlock(&rs_mtx); |
| 420 | |
| 421 | if (do_free_rs) { |
| 422 | sysctl_ctx_free(&rs->sysctl_ctx); |
| 423 | free(rs->rs_rlt, M_TCPPACE); |
| 424 | free(rs, M_TCPPACE); |
| 425 | } |
| 426 | } |
| 427 | |
| 428 | static void |
| 429 | rs_defer_destroy(struct tcp_rate_set *rs) |
nothing calls this directly
no test coverage detected