[6.2] 676e3d2fd Take sizeof pool_task into account when reserving WS in SES_Wait
Martin Blix Grydeland
martin at varnish-software.com
Tue Feb 4 10:03:09 UTC 2020
commit 676e3d2fdf2d44ab2017d0b54eb9cad3535b952c
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date: Mon Dec 16 17:04:43 2019 +0100
Take sizeof pool_task into account when reserving WS in SES_Wait
The assert on WS_ReserveSize() in ses_handle() can not trip because
sizeof (struct pool_task) is less than sizeof (struct waited). But to safe
guard against future problems if that were to change, this patch makes
sure that the session workspace can hold the largest of them before
entering the waiter, erroring out if not.
diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c
index c9a0f5180..b6731b820 100644
--- a/bin/varnishd/cache/cache_session.c
+++ b/bin/varnishd/cache/cache_session.c
@@ -407,6 +407,7 @@ ses_handle(struct waited *wp, enum wait_event ev, vtim_real now)
wp->magic = 0;
wp = NULL;
+ /* The WS was reserved in SES_Wait() */
WS_Release(sp->ws, 0);
switch (ev) {
@@ -419,6 +420,7 @@ ses_handle(struct waited *wp, enum wait_event ev, vtim_real now)
case WAITER_ACTION:
pp = sp->pool;
CHECK_OBJ_NOTNULL(pp, POOL_MAGIC);
+ /* SES_Wait() guarantees the next will not assert. */
assert(sizeof *tp <= WS_ReserveSize(sp->ws, sizeof *tp));
tp = (void*)sp->ws->f;
tp->func = xp->unwait;
@@ -442,6 +444,7 @@ SES_Wait(struct sess *sp, const struct transport *xp)
{
struct pool *pp;
struct waited *wp;
+ unsigned u;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(xp, TRANSPORT_MAGIC);
@@ -455,10 +458,15 @@ SES_Wait(struct sess *sp, const struct transport *xp)
VTCP_nonblocking(sp->fd);
/*
- * put struct waited on the workspace
+ * Put struct waited on the workspace. Make sure that the
+ * workspace can hold enough space for the largest of struct
+ * waited and pool_task, as pool_task will be needed when coming
+ * off the waiter again.
*/
- if (WS_ReserveSize(sp->ws, sizeof(struct waited))
- < sizeof(struct waited)) {
+ u = sizeof (struct waited);
+ if (sizeof (struct pool_task) > u)
+ u = sizeof (struct pool_task);
+ if (!WS_ReserveSize(sp->ws, u)) {
SES_Delete(sp, SC_OVERLOAD, NAN);
return;
}
More information about the varnish-commit
mailing list