Mailing List Archive

[7.0] 763cc6ef0 vca: Eliminate heap allocations of sock_opt arguments
commit 763cc6ef0eaa5d805b4b25f4a495d34c9234f919
Author: Dridi Boukelmoune <dridi.boukelmoune@gmail.com>
Date: Mon Sep 27 11:41:27 2021 +0200

vca: Eliminate heap allocations of sock_opt arguments

They can be stored directly in the sock_opts array or on the stack.

Conflicts:
bin/varnishd/cache/cache_acceptor.c

diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c
index 5669383ba..3a884f09e 100644
--- a/bin/varnishd/cache/cache_acceptor.c
+++ b/bin/varnishd/cache/cache_acceptor.c
@@ -80,15 +80,21 @@ struct poolsock {
* TCP options we want to control
*/

+union sock_arg {
+ struct linger lg;
+ struct timeval tv;
+ int i;
+};
+
static struct sock_opt {
int level;
int optname;
const char *strname;
- socklen_t sz;
- void *ptr;
int need;
+ socklen_t sz;
+ union sock_arg arg[1];
} sock_opts[] = {
-#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, sizeof(typ), NULL, 0 },
+#define SOCK_OPT(lvl, nam, typ) { lvl, nam, #nam, 0, sizeof(typ) },

SOCK_OPT(SOL_SOCKET, SO_LINGER, struct linger)
SOCK_OPT(SOL_SOCKET, SO_KEEPALIVE, int)
@@ -155,35 +161,30 @@ vca_sock_opt_init(void)
int n;
int one = 1;
struct sock_opt *so;
- struct timeval tv;
+ union sock_arg tmp;
int chg = 0;
- int x;

- memset(&tv, 0, sizeof tv);
- memset(&x, 0, sizeof x);
+ memset(&tmp, 0, sizeof tmp);

for (n = 0; n < n_sock_opts; n++) {
so = &sock_opts[n];
- if (so->ptr == NULL)
- so->ptr = calloc(1, so->sz);
- AN(so->ptr);
if (!strcmp(so->strname, "SO_LINGER")) {
assert(so->sz == sizeof linger);
- memcpy(so->ptr, &linger, sizeof linger);
+ memcpy(so->arg, &linger, sizeof linger);
so->need = 1;
} else if (!strcmp(so->strname, "TCP_NODELAY")) {
assert(so->sz == sizeof one);
- memcpy(so->ptr, &one, sizeof one);
+ memcpy(so->arg, &one, sizeof one);
so->need = 1;
} else if (!strcmp(so->strname, "SO_KEEPALIVE")) {
assert(so->sz == sizeof one);
- memcpy(so->ptr, &one, sizeof one);
+ memcpy(so->arg, &one, sizeof one);
so->need = 1;
#define NEW_VAL(so, xx) \
do { \
assert(so->sz == sizeof xx); \
- if (memcmp(so->ptr, &(xx), sizeof xx)) { \
- memcpy(so->ptr, &(xx), sizeof xx); \
+ if (memcmp(so->arg, &(xx), sizeof xx)) { \
+ memcpy(so->arg, &(xx), sizeof xx); \
so->need = 1; \
chg = 1; \
need_test = 1; \
@@ -192,24 +193,24 @@ vca_sock_opt_init(void)

#ifdef SO_SNDTIMEO_WORKS
} else if (!strcmp(so->strname, "SO_SNDTIMEO")) {
- tv = VTIM_timeval(cache_param->idle_send_timeout);
- NEW_VAL(so, tv);
+ tmp.tv = VTIM_timeval(cache_param->idle_send_timeout);
+ NEW_VAL(so, tmp.tv);
#endif
#ifdef SO_RCVTIMEO_WORKS
} else if (!strcmp(so->strname, "SO_RCVTIMEO")) {
- tv = VTIM_timeval(cache_param->timeout_idle);
- NEW_VAL(so, tv);
+ tmp.tv = VTIM_timeval(cache_param->timeout_idle);
+ NEW_VAL(so, tmp.tv);
#endif
#ifdef HAVE_TCP_KEEP
} else if (!strcmp(so->strname, "TCP_KEEPIDLE")) {
- x = (int)(cache_param->tcp_keepalive_time);
- NEW_VAL(so, x);
+ tmp.i = (int)(cache_param->tcp_keepalive_time);
+ NEW_VAL(so, tmp.i);
} else if (!strcmp(so->strname, "TCP_KEEPCNT")) {
- x = (int)(cache_param->tcp_keepalive_probes);
- NEW_VAL(so, x);
+ tmp.i = (int)(cache_param->tcp_keepalive_probes);
+ NEW_VAL(so, tmp.i);
} else if (!strcmp(so->strname, "TCP_KEEPINTVL")) {
- x = (int)(cache_param->tcp_keepalive_intvl);
- NEW_VAL(so, x);
+ tmp.i = (int)(cache_param->tcp_keepalive_intvl);
+ NEW_VAL(so, tmp.i);
#endif
}
}
@@ -219,10 +220,10 @@ vca_sock_opt_init(void)
static void
vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp)
{
- int i, n;
struct sock_opt *so;
+ union sock_arg tmp;
socklen_t l;
- void *ptr;
+ int i, n;

CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC);
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
@@ -232,13 +233,11 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp)
if (so->level == IPPROTO_TCP && ls->uds)
continue;
so->need = 1;
- ptr = calloc(1, so->sz);
- AN(ptr);
+ memset(&tmp, 0, sizeof tmp);
l = so->sz;
- i = getsockopt(sp->fd, so->level, so->optname, ptr, &l);
- if (i == 0 && !memcmp(ptr, so->ptr, so->sz))
+ i = getsockopt(sp->fd, so->level, so->optname, &tmp, &l);
+ if (i == 0 && !memcmp(&tmp, so->arg, so->sz))
so->need = 0;
- free(ptr);
if (i && errno != ENOPROTOOPT)
VTCP_Assert(i);
}
@@ -247,8 +246,8 @@ vca_sock_opt_test(const struct listen_sock *ls, const struct sess *sp)
static void
vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp)
{
- int n, sock;
struct sock_opt *so;
+ int n, sock;

CHECK_OBJ_NOTNULL(ls, LISTEN_SOCK_MAGIC);
CHECK_OBJ_ORNULL(sp, SESS_MAGIC);
@@ -260,7 +259,7 @@ vca_sock_opt_set(const struct listen_sock *ls, const struct sess *sp)
continue;
if (so->need || sp == NULL) {
VTCP_Assert(setsockopt(sock,
- so->level, so->optname, so->ptr, so->sz));
+ so->level, so->optname, so->arg, so->sz));
}
}
}
_______________________________________________
varnish-commit mailing list
varnish-commit@varnish-cache.org
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-commit