From 1b9e6cc1336a0eeced305bf292864a75f46c41db Mon Sep 17 00:00:00 2001 From: Thibaut Artis Date: Mon, 23 Sep 2024 17:45:47 +0200 Subject: [PATCH] vcp: Poll dying connection pools asynchronously Before, we would wait in a blocking loop for connection pools to be freed before deleting them for good. This commit transforms this blocking loop into a CLI hook that will delete the freed connection pools at each trigger. Refs #4064 Better diff with the --ignore-all-space option. --- bin/varnishd/cache/cache_cli.c | 1 + bin/varnishd/cache/cache_conn_pool.c | 47 +++++++++++++++++++++------- bin/varnishd/cache/cache_varnishd.h | 1 + include/tbl/locks.h | 1 + 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/bin/varnishd/cache/cache_cli.c b/bin/varnishd/cache/cache_cli.c index 0a99bc3cfa5..3670a1bc412 100644 --- a/bin/varnishd/cache/cache_cli.c +++ b/bin/varnishd/cache/cache_cli.c @@ -78,6 +78,7 @@ cli_cb_before(const struct cli *cli) VSL(SLT_CLI, NO_VXID, "Rd %s", VSB_data(cli->cmd)); Lck_Lock(&cli_mtx); VCL_Poll(); + VCP_RelPoll(); } static void diff --git a/bin/varnishd/cache/cache_conn_pool.c b/bin/varnishd/cache/cache_conn_pool.c index b865c3f948f..793d539d877 100644 --- a/bin/varnishd/cache/cache_conn_pool.c +++ b/bin/varnishd/cache/cache_conn_pool.c @@ -106,14 +106,20 @@ struct conn_pool { }; static struct lock conn_pools_mtx; +static struct lock dead_pools_mtx; -static VRBT_HEAD(vrb, conn_pool) conn_pools = VRBT_INITIALIZER(&conn_pools); +VRBT_HEAD(vrb, conn_pool); VRBT_GENERATE_REMOVE_COLOR(vrb, conn_pool, entry, static) VRBT_GENERATE_REMOVE(vrb, conn_pool, entry, static) VRBT_GENERATE_FIND(vrb, conn_pool, entry, vcp_cmp, static) VRBT_GENERATE_INSERT_COLOR(vrb, conn_pool, entry, static) VRBT_GENERATE_INSERT_FINISH(vrb, conn_pool, entry, static) VRBT_GENERATE_INSERT(vrb, conn_pool, entry, vcp_cmp, static) +VRBT_GENERATE_NEXT(vrb, conn_pool, entry, static); +VRBT_GENERATE_MINMAX(vrb, conn_pool, entry, static); + +static struct vrb conn_pools = VRBT_INITIALIZER(&conn_pools); +static struct vrb dead_pools = VRBT_INITIALIZER(&dying_cps); /*-------------------------------------------------------------------- */ @@ -249,17 +255,35 @@ VCP_Rel(struct conn_pool **cpp) (void)shutdown(pfd->fd, SHUT_RDWR); cp->n_kill++; } - while (cp->n_kill) { - Lck_Unlock(&cp->mtx); - (void)usleep(20000); - Lck_Lock(&cp->mtx); - } + + Lck_Lock(&dead_pools_mtx); + VRBT_INSERT(vrb, &dead_pools, cp); + Lck_Unlock(&dead_pools_mtx); Lck_Unlock(&cp->mtx); - Lck_Delete(&cp->mtx); - AZ(cp->n_conn); - AZ(cp->n_kill); - free(cp->endpoint); - FREE_OBJ(cp); +} + +void +VCP_RelPoll(void) +{ + struct conn_pool *cp, *cp2; + + ASSERT_CLI(); + Lck_Lock(&dead_pools_mtx); + VRBT_FOREACH_SAFE(cp, vrb, &dead_pools, cp2) { + CHECK_OBJ_NOTNULL(cp, CONN_POOL_MAGIC); + if (cp->n_kill > 0) + continue; + VRBT_REMOVE(vrb, &dead_pools, cp); + Lck_Unlock(&dead_pools_mtx); + + Lck_Delete(&cp->mtx); + AZ(cp->n_conn); + AZ(cp->n_kill); + free(cp->endpoint); + FREE_OBJ(cp); + Lck_Lock(&dead_pools_mtx); + } + Lck_Unlock(&dead_pools_mtx); } /*-------------------------------------------------------------------- @@ -583,6 +607,7 @@ void VCP_Init(void) { Lck_New(&conn_pools_mtx, lck_conn_pool); + Lck_New(&dead_pools_mtx, lck_dead_pool); } /**********************************************************************/ diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index e0b88b4aae9..e13c921d682 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -475,6 +475,7 @@ void VSL_Flush(struct vsl_log *, int overflow); struct conn_pool; void VCP_Init(void); void VCP_Panic(struct vsb *, struct conn_pool *); +void VCP_RelPoll(void); /* cache_backend_probe.c */ void VBP_Init(void); diff --git a/include/tbl/locks.h b/include/tbl/locks.h index 3de8e33e6a5..773c31ffa1b 100644 --- a/include/tbl/locks.h +++ b/include/tbl/locks.h @@ -45,6 +45,7 @@ LOCK(pipestat) LOCK(probe) LOCK(sess) LOCK(conn_pool) +LOCK(dead_pool) LOCK(vbe) LOCK(vcapace) LOCK(vcl)