Commit ac2e067b authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Remove the old sessmem allocator/freelist stuff, and replace with

a run of the mill mempool.
parent 8129edff
......@@ -634,9 +634,9 @@ struct sess {
/* Cross references ------------------------------------------*/
struct sesspool *sesspool;
struct worker *wrk;
struct req *req;
struct sessmem *mem;
/* Session related fields ------------------------------------*/
......
......@@ -44,31 +44,16 @@
#include "waiter/waiter.h"
#include "vtim.h"
/*--------------------------------------------------------------------*/
struct sessmem {
unsigned magic;
#define SESSMEM_MAGIC 0x555859c5
struct sesspool *pool;
unsigned workspace;
uint16_t nhttp;
void *wsp;
VTAILQ_ENTRY(sessmem) list;
static unsigned ses_size = sizeof (struct sess);
struct sess sess;
};
/*--------------------------------------------------------------------*/
struct sesspool {
unsigned magic;
#define SESSPOOL_MAGIC 0xd916e202
struct pool *pool;
VTAILQ_HEAD(,sessmem) freelist;
struct lock mtx;
unsigned nsess;
unsigned dly_free_cnt;
struct mempool *mpl_req;
struct mempool *mpl_sess;
};
/*--------------------------------------------------------------------
......@@ -91,78 +76,15 @@ SES_Charge(struct sess *sp)
#undef ACCT
}
/*--------------------------------------------------------------------
* This function allocates a session + assorted peripheral data
* structures in one single malloc operation.
*/
static struct sessmem *
ses_sm_alloc(void)
{
struct sessmem *sm;
unsigned char *p, *q;
unsigned nws;
uint16_t nhttp;
unsigned l, hl;
/*
* It is not necessary to lock these, but we need to
* cache them locally, to make sure we get a consistent
* view of the value.
*/
nws = cache_param->sess_workspace;
nhttp = (uint16_t)cache_param->http_max_hdr;
hl = HTTP_estimate(nhttp);
l = sizeof *sm + nws + 2 * hl;
VSC_C_main->sessmem_size = l;
p = malloc(l);
if (p == NULL)
return (NULL);
q = p + l;
/* Don't waste time zeroing the workspace */
memset(p, 0, l - nws);
sm = (void*)p;
p += sizeof *sm;
sm->magic = SESSMEM_MAGIC;
sm->workspace = nws;
sm->nhttp = nhttp;
sm->http[0] = HTTP_create(p, nhttp);
p += hl;
sm->http[1] = HTTP_create(p, nhttp);
p += hl;
sm->wsp = p;
p += nws;
assert(p == q);
return (sm);
}
/*--------------------------------------------------------------------
* This prepares a session for use, based on its sessmem structure.
*/
static void
ses_setup(struct sessmem *sm)
ses_setup(struct sess *sp)
{
struct sess *sp;
CHECK_OBJ_NOTNULL(sm, SESSMEM_MAGIC);
sp = &sm->sess;
memset(sp, 0, sizeof *sp);
/* We assume that the sess has been zeroed by the time we get here */
AZ(sp->magic);
sp->magic = SESS_MAGIC;
sp->mem = sm;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
sp->sockaddrlen = sizeof(sp->sockaddr);
sp->mysockaddrlen = sizeof(sp->mysockaddr);
sp->sockaddr.ss_family = sp->mysockaddr.ss_family = PF_UNSPEC;
......@@ -178,39 +100,14 @@ ses_setup(struct sessmem *sm)
struct sess *
SES_New(struct worker *wrk, struct sesspool *pp)
{
struct sessmem *sm;
struct sess *sp;
int do_alloc;
(void)wrk; // XXX
CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC);
do_alloc = 0;
Lck_Lock(&pp->mtx);
sm = VTAILQ_FIRST(&pp->freelist);
if (sm != NULL) {
VTAILQ_REMOVE(&pp->freelist, sm, list);
} else if (pp->nsess < cache_param->max_sess) {
pp->nsess++;
do_alloc = 1;
}
wrk->stats.sessmem_free += pp->dly_free_cnt;
pp->dly_free_cnt = 0;
Lck_Unlock(&pp->mtx);
if (do_alloc) {
sm = ses_sm_alloc();
if (sm != NULL) {
wrk->stats.sessmem_alloc++;
sm->pool = pp;
ses_setup(sm);
} else {
wrk->stats.sessmem_fail++;
}
} else if (sm == NULL) {
wrk->stats.sessmem_limit++;
}
if (sm == NULL)
return (NULL);
sp = &sm->sess;
sp = MPL_Get(pp->mpl_sess, NULL);
sp->magic = SESS_MAGIC;
sp->sesspool = pp;
ses_setup(sp);
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
return (sp);
}
......@@ -223,34 +120,14 @@ struct sess *
SES_Alloc(void)
{
struct sess *sp;
struct sessmem *sm;
sm = ses_sm_alloc();
AN(sm);
ses_setup(sm);
sp = &sm->sess;
sp->sockaddrlen = 0;
ALLOC_OBJ(sp, SESS_MAGIC);
AN(sp);
ses_setup(sp);
/* XXX: sp->req ? */
return (sp);
}
/*--------------------------------------------------------------------
*/
static struct sesspool *
ses_getpool(const struct sess *sp)
{
struct sessmem *sm;
struct sesspool *pp;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
sm = sp->mem;
CHECK_OBJ_NOTNULL(sm, SESSMEM_MAGIC);
pp = sm->pool;
CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC);
return (pp);
}
/*--------------------------------------------------------------------
* Schedule a session back on a work-thread from its pool
*/
......@@ -260,9 +137,10 @@ SES_Schedule(struct sess *sp)
{
struct sesspool *pp;
pp = ses_getpool(sp);
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
AZ(sp->wrk);
pp = sp->sesspool;
CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC);
AN(pp->pool);
if (Pool_Schedule(pp->pool, sp)) {
......@@ -325,14 +203,14 @@ void
SES_Delete(struct sess *sp, const char *reason, double now)
{
struct acct *b;
struct sessmem *sm;
struct worker *wrk;
struct sesspool *pp;
pp = ses_getpool(sp);
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
pp = sp->sesspool;
CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC);
AN(pp->pool);
sm = sp->mem;
CHECK_OBJ_NOTNULL(sm, SESSMEM_MAGIC);
wrk = sp->wrk;
CHECK_OBJ_ORNULL(wrk, WORKER_MAGIC);
......@@ -361,28 +239,8 @@ SES_Delete(struct sess *sp, const char *reason, double now)
b->sess, b->req, b->pipe, b->pass,
b->fetch, b->hdrbytes, b->bodybytes);
if (sm->workspace != cache_param->sess_workspace ||
sm->nhttp != (uint16_t)cache_param->http_max_hdr ||
pp->nsess > cache_param->max_sess) {
free(sm);
Lck_Lock(&pp->mtx);
if (wrk != NULL)
wrk->stats.sessmem_free++;
else
pp->dly_free_cnt++;
pp->nsess--;
Lck_Unlock(&pp->mtx);
} else {
/* Clean and prepare for reuse */
ses_setup(sm);
Lck_Lock(&pp->mtx);
if (wrk != NULL) {
wrk->stats.sessmem_free += pp->dly_free_cnt;
pp->dly_free_cnt = 0;
}
VTAILQ_INSERT_HEAD(&pp->freelist, sm, list);
Lck_Unlock(&pp->mtx);
}
MPL_Free(pp->mpl_sess, sp);
}
/*--------------------------------------------------------------------
......@@ -397,7 +255,11 @@ SES_GetReq(struct sess *sp)
unsigned sz, hl;
char *p;
pp = ses_getpool(sp);
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
pp = sp->sesspool;
CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC);
AN(pp->pool);
AZ(sp->req);
sp->req = MPL_Get(pp->mpl_req, &sz);
AN(sp->req);
......@@ -427,7 +289,10 @@ SES_ReleaseReq(struct sess *sp)
{
struct sesspool *pp;
pp = ses_getpool(sp);
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
pp = sp->sesspool;
CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC);
AN(pp->pool);
CHECK_OBJ_NOTNULL(sp->req, REQ_MAGIC);
MPL_AssertSane(sp->req);
MPL_Free(pp->mpl_req, sp->req);
......@@ -447,33 +312,20 @@ SES_NewPool(struct pool *wp, unsigned pool_no)
ALLOC_OBJ(pp, SESSPOOL_MAGIC);
AN(pp);
pp->pool = wp;
VTAILQ_INIT(&pp->freelist);
Lck_New(&pp->mtx, lck_sessmem);
bprintf(nb, "req%u", pool_no);
pp->mpl_req = MPL_New(nb, &cache_param->req_pool,
&cache_param->sess_workspace);
pp->mpl_sess = MPL_New(nb, &cache_param->sess_pool, &ses_size);
return (pp);
}
void
SES_DeletePool(struct sesspool *pp, struct worker *wrk)
{
struct sessmem *sm;
CHECK_OBJ_NOTNULL(pp, SESSPOOL_MAGIC);
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
Lck_Lock(&pp->mtx);
while (!VTAILQ_EMPTY(&pp->freelist)) {
sm = VTAILQ_FIRST(&pp->freelist);
CHECK_OBJ_NOTNULL(sm, SESSMEM_MAGIC);
VTAILQ_REMOVE(&pp->freelist, sm, list);
FREE_OBJ(sm);
wrk->stats.sessmem_free++;
pp->nsess--;
}
AZ(pp->nsess);
Lck_Unlock(&pp->mtx);
Lck_Delete(&pp->mtx);
MPL_Destroy(&pp->mpl_sess);
MPL_Destroy(&pp->mpl_req);
FREE_OBJ(pp);
}
......@@ -201,4 +201,5 @@ struct params {
struct poolparam vbc_pool;
struct poolparam req_pool;
struct poolparam sess_pool;
};
......@@ -1221,6 +1221,14 @@ static const struct parspec input_parspec[] = {
" max_age -- max age of free element.\n",
0,
"10,100,10", ""},
{ "pool_sess", tweak_poolparam, &mgt_param.sess_pool, 0, 10000,
"Parameters for per worker pool session memory pool.\n"
"The three numbers are:\n"
" min_pool -- minimum size of free pool.\n"
" max_pool -- maximum size of free pool.\n"
" max_age -- max age of free element.\n",
0,
"10,100,10", ""},
{ NULL, NULL, NULL }
};
......
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