Commit 365e6056 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp Committed by Martin Blix Grydeland

Make param::nuke_limit a total count of nukes allowed for each

object creation.

Fixes #1764

Conflicts:
	bin/varnishd/cache/cache_fetch.c
	bin/varnishd/storage/stevedore.c
	bin/varnishd/storage/storage.h
	bin/varnishd/storage/storage_lru.c
	bin/varnishd/storage/storage_persistent.c
	bin/varnishd/storage/storage_simple.c
parent 68f15e0e
......@@ -343,6 +343,7 @@ struct worker {
struct pool_task task;
double lastused;
int strangelove;
struct v1l *v1l;
......
......@@ -329,6 +329,10 @@ EXP_NukeOne(struct worker *wrk, struct lru *lru)
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(lru, LRU_MAGIC);
if (wrk->strangelove-- <= 0) {
VSLb(wrk->vsl, SLT_ExpKill, "LRU_Exhausted");
return (0);
}
/* Find the first currently unused object on the LRU. */
Lck_Lock(&lru->mtx);
VTAILQ_FOREACH_SAFE(oc, &lru->lru_head, lru_list, oc2) {
......
......@@ -239,7 +239,6 @@ objallocwithnuke(struct worker *wrk, const struct stevedore *stv,
size_t size, int flags)
{
struct storage *st = NULL;
unsigned fail;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
......@@ -252,18 +251,11 @@ objallocwithnuke(struct worker *wrk, const struct stevedore *stv,
assert(size <= UINT_MAX); /* field limit in struct storage */
for (fail = 0; fail <= cache_param->nuke_limit; fail++) {
/* try to allocate from it */
AN(stv->alloc);
AN(stv->alloc);
do {
st = STV_alloc(stv, size, flags);
if (st != NULL)
break;
} while (st == NULL && EXP_NukeOne(wrk, stv->lru) == 1);
/* no luck; try to free some space and keep trying */
if (fail < cache_param->nuke_limit &&
EXP_NukeOne(wrk, stv->lru) == -1)
break;
}
CHECK_OBJ_ORNULL(st, STORAGE_MAGIC);
return (st);
}
......
......@@ -259,13 +259,15 @@ STV_NewObject(struct objcore *oc, struct worker *wrk,
const char *hint, unsigned wsl)
{
struct stevedore *stv, *stv0;
int i, j;
int j;
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
assert(wsl > 0);
wrk->strangelove = cache_param->nuke_limit;
stv = stv0 = stv_pick_stevedore(wrk->vsl, &hint);
AN(stv);
AN(stv->allocobj);
j = stv->allocobj(stv, oc, wsl);
if (j == 0 && hint == NULL) {
......@@ -275,15 +277,12 @@ STV_NewObject(struct objcore *oc, struct worker *wrk,
j = stv->allocobj(stv, oc, wsl);
} while (j == 0 && stv != stv0);
}
if (j == 0) {
while (j == 0) {
/* no luck; try to free some space and keep trying */
for (i = 0; j == 0 && i < cache_param->nuke_limit; i++) {
if (EXP_NukeOne(wrk, stv->lru) == -1)
break;
j = stv->allocobj(stv, oc, wsl);
}
if (EXP_NukeOne(wrk, stv->lru) != 1)
break;
j = stv->allocobj(stv, oc, wsl);
}
if (j == 0)
return (0);
......
varnishtest "Test nuke_limit"
server s1 {
# First consume (almost) all of the storage
rxreq
expect req.url == /url1
txresp -bodylen 200000
rxreq
expect req.url == /url2
txresp -bodylen 200000
rxreq
expect req.url == /url3
txresp -bodylen 200000
rxreq
expect req.url == /url4
txresp -bodylen 200000
rxreq
expect req.url == /url5
txresp -bodylen 1000000
} -start
varnish v1 -arg "-smalloc,1M" -arg "-p nuke_limit=1" -vcl+backend {
sub vcl_backend_response {
set beresp.do_stream = false;
}
} -start
client c1 {
txreq -url /url1
rxresp
expect resp.status == 200
txreq -url /url2
rxresp
expect resp.status == 200
txreq -url /url3
rxresp
expect resp.status == 200
txreq -url /url4
rxresp
expect resp.status == 200
txreq -url /url5
rxresp
expect resp.status == 503
} -run
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment