[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