aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorEric Dumazet <dada1@cosmosbay.com>2006-11-16 05:30:37 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:21:44 -0500
commit72a3effaf633bcae9034b7e176bdbd78d64a71db (patch)
treeb7a331527f1b15335a358f97809134f35587e57a /net/ipv4
parent3c62f75aac7348ee262b1295cfcfeb3473f76815 (diff)
[NET]: Size listen hash tables using backlog hint
We currently allocate a fixed size (TCP_SYNQ_HSIZE=512) slots hash table for each LISTEN socket, regardless of various parameters (listen backlog for example) On x86_64, this means order-1 allocations (might fail), even for 'small' sockets, expecting few connections. On the contrary, a huge server wanting a backlog of 50000 is slowed down a bit because of this fixed limit. This patch makes the sizing of listen hash table a dynamic parameter, depending of : - net.core.somaxconn tunable (default is 128) - net.ipv4.tcp_max_syn_backlog tunable (default : 256, 1024 or 128) - backlog value given by user application (2nd parameter of listen()) For large allocations (bigger than PAGE_SIZE), we use vmalloc() instead of kmalloc(). We still limit memory allocation with the two existing tunables (somaxconn & tcp_max_syn_backlog). So for standard setups, this patch actually reduce RAM usage. Signed-off-by: Eric Dumazet <dada1@cosmosbay.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/inet_connection_sock.c2
-rw-r--r--net/ipv4/tcp_ipv4.c6
3 files changed, 5 insertions, 5 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index edcf0932ac6d..4a81d54a7569 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -204,7 +204,7 @@ int inet_listen(struct socket *sock, int backlog)
204 * we can only allow the backlog to be adjusted. 204 * we can only allow the backlog to be adjusted.
205 */ 205 */
206 if (old_state != TCP_LISTEN) { 206 if (old_state != TCP_LISTEN) {
207 err = inet_csk_listen_start(sk, TCP_SYNQ_HSIZE); 207 err = inet_csk_listen_start(sk, backlog);
208 if (err) 208 if (err)
209 goto out; 209 goto out;
210 } 210 }
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 96bbe2a0aa1b..9d68837888d3 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -343,7 +343,7 @@ struct dst_entry* inet_csk_route_req(struct sock *sk,
343EXPORT_SYMBOL_GPL(inet_csk_route_req); 343EXPORT_SYMBOL_GPL(inet_csk_route_req);
344 344
345static inline u32 inet_synq_hash(const __be32 raddr, const __be16 rport, 345static inline u32 inet_synq_hash(const __be32 raddr, const __be16 rport,
346 const u32 rnd, const u16 synq_hsize) 346 const u32 rnd, const u32 synq_hsize)
347{ 347{
348 return jhash_2words((__force u32)raddr, (__force u32)rport, rnd) & (synq_hsize - 1); 348 return jhash_2words((__force u32)raddr, (__force u32)rport, rnd) & (synq_hsize - 1);
349} 349}
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 22ef8bd26620..5fbf96552cac 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -715,7 +715,7 @@ static struct ip_options *tcp_v4_save_options(struct sock *sk,
715 return dopt; 715 return dopt;
716} 716}
717 717
718struct request_sock_ops tcp_request_sock_ops = { 718struct request_sock_ops tcp_request_sock_ops __read_mostly = {
719 .family = PF_INET, 719 .family = PF_INET,
720 .obj_size = sizeof(struct tcp_request_sock), 720 .obj_size = sizeof(struct tcp_request_sock),
721 .rtx_syn_ack = tcp_v4_send_synack, 721 .rtx_syn_ack = tcp_v4_send_synack,
@@ -1385,7 +1385,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
1385 if (st->state == TCP_SEQ_STATE_OPENREQ) { 1385 if (st->state == TCP_SEQ_STATE_OPENREQ) {
1386 struct request_sock *req = cur; 1386 struct request_sock *req = cur;
1387 1387
1388 icsk = inet_csk(st->syn_wait_sk); 1388 icsk = inet_csk(st->syn_wait_sk);
1389 req = req->dl_next; 1389 req = req->dl_next;
1390 while (1) { 1390 while (1) {
1391 while (req) { 1391 while (req) {
@@ -1395,7 +1395,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
1395 } 1395 }
1396 req = req->dl_next; 1396 req = req->dl_next;
1397 } 1397 }
1398 if (++st->sbucket >= TCP_SYNQ_HSIZE) 1398 if (++st->sbucket >= icsk->icsk_accept_queue.listen_opt->nr_table_entries)
1399 break; 1399 break;
1400get_req: 1400get_req:
1401 req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket]; 1401 req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket];