[master] 7066708 Introduce session attributes which we store as a 16 bit index into the session workspace to compress struct sess.
Poul-Henning Kamp
phk at FreeBSD.org
Wed Mar 18 10:34:48 CET 2015
commit 706670821741cbc552539cd511b5d25122ff3ae1
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed Mar 18 09:34:04 2015 +0000
Introduce session attributes which we store as a 16 bit index into
the session workspace to compress struct sess.
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index cceb572..e68a117 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -119,6 +119,7 @@ struct poolparam;
struct req;
struct sess;
struct sesspool;
+struct suckaddr;
struct vbc;
struct vrt_backend;
struct vrt_priv;
@@ -643,6 +644,14 @@ struct req {
* works, is not realistic without a lot of code changes.
*/
+
+enum sess_attr {
+#define SESS_ATTR(UP, low, typ, len) SA_##UP,
+#include "tbl/sess_attr.h"
+#undef SESS_ATTR
+ SA_LAST
+};
+
struct sess {
unsigned magic;
#define SESS_MAGIC 0x2c2f9c5a
@@ -663,15 +672,7 @@ struct sess {
struct ws ws[1];
- /*
- * This gets quite involved, but we don't want to waste space
- * on up to 4 pointers of 8 bytes in struct sess.
- */
- char *addrs;
-#define sess_remote_addr(sp) \
- ((struct suckaddr *)(void*)((sp)->addrs))
-#define sess_local_addr(sp) \
- ((struct suckaddr *)(void*)((sp)->addrs + vsa_suckaddr_len))
+ uint16_t sattr[SA_LAST];
/* formatted ascii client address */
char *client_addr_str;
@@ -1002,6 +1003,12 @@ struct req *SES_GetReq(const struct worker *, struct sess *);
void SES_ReleaseReq(struct req *);
void SES_sess_pool_task(struct worker *wrk, void *arg);
+#define SESS_ATTR(UP, low, typ, len) \
+ int SES_Get_##low(const struct sess *sp, typ *dst); \
+ void SES_Reserve_##low(struct sess *sp, typ *dst);
+#include "tbl/sess_attr.h"
+#undef SESS_ATTR
+
/* cache_shmlog.c */
extern struct VSC_C_main *VSC_C_main;
void VSM_Init(void);
diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c
index 2da2b10..1408d1f 100644
--- a/bin/varnishd/cache/cache_acceptor.c
+++ b/bin/varnishd/cache/cache_acceptor.c
@@ -291,9 +291,9 @@ vca_make_session(struct worker *wrk, void *arg)
{
struct sesspool *pp;
struct sess *sp;
- const char *lsockname;
struct wrk_accept *wa;
struct sockaddr_storage ss;
+ struct suckaddr *sa;
socklen_t sl;
char laddr[VTCP_ADDRBUFSIZE];
char lport[VTCP_PORTBUFSIZE];
@@ -326,39 +326,44 @@ vca_make_session(struct worker *wrk, void *arg)
sp->fd = wa->acceptsock;
wa->acceptsock = -1;
- lsockname = wa->acceptlsock->name;
- AN(lsockname);
- assert(wa->acceptaddrlen <= vsa_suckaddr_len);
- AN(VSA_Build(sess_remote_addr(sp), &wa->acceptaddr, wa->acceptaddrlen));
- vca_pace_good();
- wrk->stats->sess_conn++;
- WS_Release(wrk->aws, 0);
-
- if (need_test) {
- vca_tcp_opt_test(sp->fd);
- need_test = 0;
- }
- vca_tcp_opt_set(sp->fd, 0);
- AN(sp->addrs);
- sl = sizeof ss;
- AZ(getsockname(sp->fd, (void*)&ss, &sl));
- AN(VSA_Build(sess_local_addr(sp), &ss, sl));
- assert(VSA_Sane(sess_local_addr(sp)));
+ assert(wa->acceptaddrlen <= vsa_suckaddr_len);
+ SES_Reserve_remote_addr(sp, &sa);
+ AN(VSA_Build(sa, &wa->acceptaddr, wa->acceptaddrlen));
+ SES_Reserve_client_addr(sp, &sa);
+ AN(VSA_Build(sa, &wa->acceptaddr, wa->acceptaddrlen));
- VTCP_name(sess_remote_addr(sp), laddr, sizeof laddr,
- lport, sizeof lport);
+ VTCP_name(sa, laddr, sizeof laddr, lport, sizeof lport);
sp->client_addr_str = WS_Copy(sp->ws, laddr, -1);
AN(sp->client_addr_str);
sp->client_port_str = WS_Copy(sp->ws, lport, -1);
AN(sp->client_port_str);
- VTCP_name(sess_local_addr(sp), laddr, sizeof laddr,
- lport, sizeof lport);
+
+ sl = sizeof ss;
+ AZ(getsockname(sp->fd, (void*)&ss, &sl));
+ SES_Reserve_local_addr(sp, &sa);
+ AN(VSA_Build(sa, &ss, sl));
+ SES_Reserve_server_addr(sp, &sa);
+ AN(VSA_Build(sa, &ss, sl));
+
+ VTCP_name(sa, laddr, sizeof laddr, lport, sizeof lport);
+
VSL(SLT_Begin, sp->vxid, "sess 0 HTTP/1");
VSL(SLT_SessOpen, sp->vxid, "%s %s %s %s %s %.6f %d",
- sp->client_addr_str, sp->client_port_str, lsockname, laddr, lport,
+ sp->client_addr_str, sp->client_port_str,
+ wa->acceptlsock->name, laddr, lport,
sp->t_open, sp->fd);
+ WS_Release(wrk->aws, 0);
+
+ vca_pace_good();
+ wrk->stats->sess_conn++;
+
+ if (need_test) {
+ vca_tcp_opt_test(sp->fd);
+ need_test = 0;
+ }
+ vca_tcp_opt_set(sp->fd, 0);
/* SES_sess_pool_task() must be sceduled with reserved WS */
assert(8 == WS_Reserve(sp->ws, 8));
wrk->task.func = SES_sess_pool_task;
diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c
index 0d34de7..9139c72 100644
--- a/bin/varnishd/cache/cache_session.c
+++ b/bin/varnishd/cache/cache_session.c
@@ -61,6 +61,58 @@ struct sesspool {
struct waiter *http1_waiter;
};
+/*--------------------------------------------------------------------*/
+
+static int
+ses_get_attr(const struct sess *sp, enum sess_attr a, void **dst)
+{
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ assert(a < SA_LAST);
+ AN(dst);
+
+ if (sp->sattr[a] == 0xffff) {
+ *dst = NULL;
+ return (-1);
+ } else {
+ *dst = sp->ws->s + sp->sattr[a];
+ return (0);
+ }
+}
+
+static void
+ses_reserve_attr(struct sess *sp, enum sess_attr a, void **dst, int sz)
+{
+ ssize_t o;
+
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ assert(a < SA_LAST);
+ assert(sz >= 0);
+ AN(dst);
+ o = WS_Reserve(sp->ws, sz);
+ assert(o >= sz);
+ *dst = sp->ws->f;
+ o = sp->ws->f - sp->ws->s;
+ WS_Release(sp->ws, sz);
+ assert(o >= 0 && o <= 0xffff);
+ sp->sattr[a] = (uint16_t)o;
+}
+
+#define SESS_ATTR(UP, low, typ, len) \
+ int \
+ SES_Get_##low(const struct sess *sp, typ *dst) \
+ { \
+ return (ses_get_attr(sp, SA_##UP, (void**)dst)); \
+ } \
+ \
+ void \
+ SES_Reserve_##low(struct sess *sp, typ *dst) \
+ { \
+ ses_reserve_attr(sp, SA_##UP, (void*)dst, len); \
+ }
+
+#include "tbl/sess_attr.h"
+#undef SESS_ATTR
+
/*--------------------------------------------------------------------
* Get a new session, preferably by recycling an already ready one
*
@@ -80,14 +132,13 @@ SES_New(struct sesspool *pp)
sp = MPL_Get(pp->mpl_sess, &sz);
sp->magic = SESS_MAGIC;
sp->sesspool = pp;
+ memset(sp->sattr, 0xff, sizeof sp->sattr);
e = (char*)sp + sz;
p = (char*)(sp + 1);
p = (void*)PRNDUP(p);
assert(p < e);
WS_Init(sp->ws, "ses", p, e - p);
- sp->addrs = WS_Alloc(sp->ws, vsa_suckaddr_len * 2);
- AN(sp->addrs);
sp->t_open = NAN;
sp->t_idle = NAN;
@@ -444,6 +495,6 @@ SES_DeletePool(struct sesspool *pp)
MPL_Destroy(&pp->mpl_sess);
MPL_Destroy(&pp->mpl_req);
/* Delete session pool must stop acceptor threads */
- INCOMPL();
FREE_OBJ(pp);
+ INCOMPL();
}
diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c
index a53c07a..a9c30ee 100644
--- a/bin/varnishd/cache/cache_vrt_var.c
+++ b/bin/varnishd/cache/cache_vrt_var.c
@@ -37,7 +37,6 @@
#include "cache_director.h"
#include "vrt.h"
#include "vrt_obj.h"
-#include "vsa.h"
static char vrt_hostname[255] = "";
@@ -598,21 +597,25 @@ VRT_r_req_##field(VRT_CTX) \
VCL_IP
VRT_r_client_ip(VRT_CTX)
{
+ struct suckaddr *sa;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(ctx->req->sp, SESS_MAGIC);
- return (sess_remote_addr(ctx->req->sp));
+ AZ(SES_Get_remote_addr(ctx->req->sp, &sa));
+ return (sa);
}
VCL_IP
VRT_r_server_ip(VRT_CTX)
{
+ struct suckaddr *sa;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(ctx->req->sp, SESS_MAGIC);
- return (sess_local_addr(ctx->req->sp));
+ AZ(SES_Get_local_addr(ctx->req->sp, &sa));
+ return (sa);
}
const char*
diff --git a/include/Makefile.am b/include/Makefile.am
index 603a085..1f116b6 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -16,6 +16,7 @@ nobase_pkginclude_HEADERS = \
tbl/obj_attr.h \
tbl/req_body.h \
tbl/req_flags.h \
+ tbl/sess_attr.h \
tbl/sess_close.h \
tbl/steps.h \
tbl/symbol_kind.h \
diff --git a/include/tbl/sess_attr.h b/include/tbl/sess_attr.h
new file mode 100644
index 0000000..db68fb6
--- /dev/null
+++ b/include/tbl/sess_attr.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2015 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Session attributes should be stored as cheaply as possible in terms of
+ * memory. This stuff implements "small pointers", 16 bit offsets into
+ * the session workspace, for these bits.
+ */
+
+/*lint -save -e525 -e539 */
+
+// upper lower type len
+SESS_ATTR(REMOTE_ADDR, remote_addr, struct suckaddr *, vsa_suckaddr_len)
+SESS_ATTR(LOCAL_ADDR, local_addr, struct suckaddr *, vsa_suckaddr_len)
+SESS_ATTR(CLIENT_ADDR, client_addr, struct suckaddr *, vsa_suckaddr_len)
+SESS_ATTR(SERVER_ADDR, server_addr, struct suckaddr *, vsa_suckaddr_len)
+
+/*lint -restore */
More information about the varnish-commit
mailing list