[PATCH 16/24] net, diet: Make TCP fastopen optional

Andi Kleen
2014-05-05T22:27:58Z

From: Andi Kleen <ak@linux.intel.com>

Make TCP fast open a config option. It's not really needed
on small systems. By itself it saves about 3k text,
but the main advantage is that CONFIG_INET doesn't
pull in AES and the crypto subsystem anymore, which
is worth far more savings.

text data bss dec hex filename
6954762 1404960 765952 9125674 8b3f2a vmlinux-with-fastopen
6951618 1400608 765952 9118178 8b21e2 vmlinux-wo-fastopen

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
include/linux/tcp.h | 14 ++++++++++++--
include/net/request_sock.h | 5 +++++
include/net/tcp.h | 9 +++++++++
net/Kconfig | 4 ++--
net/core/request_sock.c | 2 ++
net/ipv4/Kconfig | 4 ++++
net/ipv4/Makefile | 3 ++-
net/ipv4/sysctl_net_ipv4.c | 4 ++++
net/ipv4/tcp.c | 4 ++++
net/ipv4/tcp_ipv4.c | 18 ++++++++++++++++++
10 files changed, 62 insertions(+), 5 deletions(-)

diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 2399468..e0825e2 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -359,6 +359,9 @@ static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk)
return (struct tcp_timewait_sock *)sk;
}

+extern void tcp_sock_destruct(struct sock *sk);
+
+#ifdef CONFIG_TCP_FASTOPEN
static inline bool tcp_passive_fastopen(const struct sock *sk)
{
return (sk->sk_state == TCP_SYN_RECV &&
@@ -370,8 +373,6 @@ static inline bool fastopen_cookie_present(struct tcp_fastopen_cookie *foc)
return foc->len != -1;
}

-extern void tcp_sock_destruct(struct sock *sk);
-
static inline int fastopen_init_queue(struct sock *sk, int backlog)
{
struct request_sock_queue *queue =
@@ -391,4 +392,13 @@ static inline int fastopen_init_queue(struct sock *sk, int backlog)
return 0;
}

+#else
+static inline bool tcp_passive_fastopen(const struct sock *sk)
+{ return false; }
+static inline bool fastopen_cookie_present(struct tcp_fastopen_cookie *foc)
+{ return false; }
+static inline int fastopen_init_queue(struct sock *sk, int backlog)
+{ return 0; }
+#endif
+
#endif /* _LINUX_TCP_H */
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index 7f830ff..ad1f97a 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -168,8 +168,13 @@ int reqsk_queue_alloc(struct request_sock_queue *queue,

void __reqsk_queue_destroy(struct request_sock_queue *queue);
void reqsk_queue_destroy(struct request_sock_queue *queue);
+#ifdef CONFIG_TCP_FASTOPEN
void reqsk_fastopen_remove(struct sock *sk, struct request_sock *req,
bool reset);
+#else
+static inline void reqsk_fastopen_remove(struct sock *sk, struct request_sock *req,
+ bool reset) {}
+#endif

static inline struct request_sock *
reqsk_queue_yank_acceptq(struct request_sock_queue *queue)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index ac9f6bd..1a5e91b 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -251,7 +251,11 @@ extern int sysctl_tcp_retries1;
extern int sysctl_tcp_retries2;
extern int sysctl_tcp_orphan_retries;
extern int sysctl_tcp_syncookies;
+#ifdef CONFIG_TCP_FASTOPEN
extern int sysctl_tcp_fastopen;
+#else
+#define sysctl_tcp_fastopen 0
+#endif
extern int sysctl_tcp_retrans_collapse;
extern int sysctl_tcp_stdurg;
extern int sysctl_tcp_rfc1337;
@@ -1333,7 +1337,12 @@ struct tcp_fastopen_request {
size_t size;
int copied; /* queued in tcp_connect() */
};
+
+#ifdef CONFIG_TCP_FASTOPEN
void tcp_free_fastopen_req(struct tcp_sock *tp);
+#else
+static inline void tcp_free_fastopen_req(struct tcp_sock *tp) {}
+#endif

extern struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;
int tcp_fastopen_reset_cipher(void *key, unsigned int len);
diff --git a/net/Kconfig b/net/Kconfig
index f5196ba..fe6e856 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -61,8 +61,8 @@ source "net/iucv/Kconfig"

config INET
bool "TCP/IP networking"
- select CRYPTO
- select CRYPTO_AES
+ select CRYPTO if TCP_FASTOPEN
+ select CRYPTO_AES if TCP_FASTOPEN
---help---
These are the protocols used on the Internet and on most local
Ethernets. It is highly recommended to say Y here (this will enlarge
diff --git a/net/core/request_sock.c b/net/core/request_sock.c
index 467f326..80ad1dd 100644
--- a/net/core/request_sock.c
+++ b/net/core/request_sock.c
@@ -131,6 +131,7 @@ void reqsk_queue_destroy(struct request_sock_queue *queue)
kfree(lopt);
}

+#ifdef CONFIG_TCP_FASTOPEN
/*
* This function is called to set a Fast Open socket's "fastopen_rsk" field
* to NULL when a TFO socket no longer needs to access the request_sock.
@@ -222,3 +223,4 @@ out:
spin_unlock_bh(&fastopenq->lock);
sock_put(lsk);
}
+#endif
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index c1f9899..df5c569 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -320,6 +320,10 @@ config NET_IPVTI
the notion of a secure tunnel for IPSEC and then use routing protocol
on top.

+config TCP_FASTOPEN
+ bool "Enable TCP fastopen"
+ default y
+
config INET_AH
tristate "IP: AH transformation"
select XFRM_ALGO
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index eb129a4..addecef 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -7,7 +7,7 @@ obj-y := route.o inetpeer.o protocol.o \
ip_output.o ip_sockglue.o inet_hashtables.o \
inet_timewait_sock.o inet_connection_sock.o \
tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \
- tcp_minisocks.o tcp_cong.o tcp_fastopen.o \
+ tcp_minisocks.o tcp_cong.o \
datagram.o raw.o udp.o udplite.o \
arp.o icmp.o devinet.o af_inet.o \
fib_frontend.o fib_semantics.o fib_trie.o \
@@ -55,6 +55,7 @@ obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o
obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o
obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o
obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o
+obj-$(CONFIG_TCP_FASTOPEN) += tcp_fastopen.o
obj-$(CONFIG_MEMCG_KMEM) += tcp_memcontrol.o
obj-$(CONFIG_NETLABEL) += cipso_ipv4.o

diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index fe5823a..9a9f96c 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -200,6 +200,7 @@ static int proc_allowed_congestion_control(struct ctl_table *ctl,
return ret;
}

+#ifdef CONFIG_TCP_FASTOPEN
static int proc_tcp_fastopen_key(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos)
@@ -246,6 +247,7 @@ bad_key:
kfree(tbl.data);
return ret;
}
+#endif

static struct ctl_table ipv4_table[] = {
{
@@ -388,6 +390,7 @@ static struct ctl_table ipv4_table[] = {
.proc_handler = proc_dointvec
},
#endif
+#ifdef CONFIG_TCP_FASTOPEN
{
.procname = "tcp_fastopen",
.data = &sysctl_tcp_fastopen,
@@ -401,6 +404,7 @@ static struct ctl_table ipv4_table[] = {
.maxlen = ((TCP_FASTOPEN_KEY_LENGTH * 2) + 10),
.proc_handler = proc_tcp_fastopen_key,
},
+#endif
{
.procname = "tcp_tw_recycle",
.data = &tcp_death_row.sysctl_tw_recycle,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 3fd48421..ef14cb6 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1036,6 +1036,7 @@ static inline int select_size(const struct sock *sk, bool sg)
return tmp;
}

+#ifdef CONFIG_TCP_FASTOPEN
void tcp_free_fastopen_req(struct tcp_sock *tp)
{
if (tp->fastopen_req != NULL) {
@@ -1069,6 +1070,7 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
tcp_free_fastopen_req(tp);
return err;
}
+#endif

int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t size)
@@ -1084,6 +1086,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
lock_sock(sk);

flags = msg->msg_flags;
+#ifdef CONFIG_TCP_FASTOPEN
if (flags & MSG_FASTOPEN) {
err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size);
if (err == -EINPROGRESS && copied_syn > 0)
@@ -1092,6 +1095,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
goto out_err;
offset = copied_syn;
}
+#endif

timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);

diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 438f3b9..fbddabb 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1260,6 +1260,7 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
};
#endif

+#ifdef CONFIG_TCP_FASTOPEN
static bool tcp_fastopen_check(struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
struct tcp_fastopen_cookie *foc,
@@ -1440,6 +1441,23 @@ static int tcp_v4_conn_req_fastopen(struct sock *sk,
WARN_ON(req->sk == NULL);
return 0;
}
+#else
+static bool tcp_fastopen_check(struct sock *sk, struct sk_buff *skb,
+ struct request_sock *req,
+ struct tcp_fastopen_cookie *foc,
+ struct tcp_fastopen_cookie *valid_foc)
+{
+ return false;
+}
+
+static int tcp_v4_conn_req_fastopen(struct sock *sk,
+ struct sk_buff *skb,
+ struct sk_buff *skb_synack,
+ struct request_sock *req)
+{
+ return 0;
+}
+#endif

int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
{
--
1.9.0