CKRM socket accept queue resource controller
Subsystems (3)
PATCH 6/6 CKRM socket accept queue resource controller
include/linux/tcp.h +35 -2
@@ -128,6 +128,10 @@#define TCP_INFO 11/* Information about this connection. */ #define TCP_QUICKACK 12/* Block/reenable quick acks */ +#ifdef CONFIG_ACCEPT_QUEUES +#define TCP_ACCEPTQ_SHARE 13/* Set accept queue share */ +#endif +#define TCPI_OPT_TIMESTAMPS 1#define TCPI_OPT_SACK 2#define TCPI_OPT_WSCALE 4
@@ -185,6 +189,18 @@__u32 tcpi_reordering; }; +#ifdef CONFIG_ACCEPT_QUEUES + +#define NUM_ACCEPT_QUEUES 8/* Must be power of 2 */ + +struct tcp_acceptq_info { +unsigned char acceptq_shares; +unsigned long acceptq_wait_time; +unsigned int acceptq_qcount; +unsigned int acceptq_count; +}; +#endif +#ifdef __KERNEL__#include <linux/config.h>
@@ -362,8 +378,9 @@/* FIFO of established children */ struct open_request *accept_queue; -struct open_request *accept_queue_tail; - +#ifndef CONFIG_ACCEPT_QUEUES +struct open_request *accept_queue_tail; +#endif int write_pending;/* A write to socket waits to start. */ unsigned int keepalive_time;/* time before keep alive takes place */
@@ -387,6 +404,22 @@__u32 rtt;__u32 rtt_min;/* minimum observed RTT */ } westwood; + +#ifdef CONFIG_ACCEPT_QUEUES +/* move to listen opt... */ +char class_index; +struct { +struct open_request *aq_head; +struct open_request *aq_tail; +unsigned int aq_cnt; +unsigned int aq_ratio; +unsigned int aq_count; +unsigned int aq_qcount; +unsigned int aq_backlog; +unsigned int aq_wait_time; +int aq_valid; + } acceptq[NUM_ACCEPT_QUEUES ]; +#endif };/* WARNING: don't change the layout of the members in tcp_sock! */
include/net/sock.h +1 -0
@@ -245,6 +245,7 @@struct timeval sk_stamp;struct socket *sk_socket;void *sk_user_data; +void *sk_ns;// For use by CKRM struct module *sk_owner;void *sk_security;void (*sk_state_change)(struct sock *sk);
include/net/tcp.h +107 -0
141 lines not on this page · raw message
kernel/ckrm/ckrm_listenaq.c new file +503 -0
503 lines not on this page · raw message
net/ipv4/Kconfig +23 -0
@@ -360,5 +360,28 @@ If unsure, say Y. +config ACCEPT_QUEUES + bool "IP: TCP Multiple accept queues support" + depends on INET && NETFILTER + ---help--- + Support multiple accept queues per listening socket. If you say Y + here, multiple accept queues will be configured per listening + socket. + + Each queue is mapped to a priority class. Incoming connection + requests can be classified (see iptables(8), MARK target), depending + on the packet's src/dest address or other parameters, into one of + the priority classes. The requests are then queued to the relevant + accept queue. + + Each of the queues can be assigned a weight. The accept()ance + of packets is then scheduled in accordance with the weight + assigned to the priority class. + + Be sure to enable "Network packet filtering" if you wish + to use this feature. + + If unsure, say N. + source "net/ipv4/ipvs/Kconfig"
net/ipv4/tcp.c +160 -4
236 lines not on this page · raw message
net/ipv4/tcp_ipv4.c +35 -2
@@ -458,7 +458,6 @@ head = &tcp_listening_hash[tcp_lhashfn (hnum)];if (!hlist_empty (head)) {struct inet_opt *inet =inet_sk ((sk =__sk_head (head))); - if (inet->num == hnum && !sk->sk_node.next && (!inet->rcv_saddr || inet->rcv_saddr == daddr) && (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
@@ -916,7 +915,11 @@ lopt->syn_table[h] = req;write_unlock (&tp->syn_wait_lock); +#ifdef CONFIG_ACCEPT_QUEUES +tcp_synq_added (sk, req); +#else tcp_synq_added (sk); +#endif }
@@ -1413,6 +1416,9 @@__u32 daddr = skb->nh.iph->daddr;__u32 isn =TCP_SKB_CB (skb)->when;struct dst_entry *dst =NULL ; +#ifdef CONFIG_ACCEPT_QUEUES +int class =0 ; +#endif #ifdef CONFIG_SYN_COOKIES int want_cookie =0 ;#else
@@ -1437,12 +1443,32 @@ goto drop; } +#ifdef CONFIG_ACCEPT_QUEUES + class = (skb->nfmark <=0 ) ?0 : + ((skb->nfmark >NUM_ACCEPT_QUEUES ) ?NUM_ACCEPT_QUEUES : + skb->nfmark); +/* +* Accept only if the class has shares set or if the default class +* i.e. class 0 has shares +*/ +if (!(tcp_sk (sk)->acceptq[class].aq_valid)) { +if (tcp_sk (sk)->acceptq[0 ].aq_valid) + class =0 ; +else + goto drop; + } +#endif +/* Accept backlog is full. If we have already queued enough * of warm entries in syn queue, drop request. It is better than * clogging syn queue with openreqs with exponentially increasing * timeout. */ +#ifdef CONFIG_ACCEPT_QUEUES +if (tcp_acceptq_is_full (sk, class) &&tcp_synq_young (sk, class) >1 ) +#else if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1) +#endif goto drop; req =tcp_openreq_alloc ();
@@ -1472,7 +1498,10 @@ tp.tstamp_ok = tp.saw_tstamp;tcp_openreq_init (req, &tp, skb); - +#ifdef CONFIG_ACCEPT_QUEUES + req->acceptq_class = class; + req->acceptq_time_stamp = jiffies; +#endif req->af.v4_req.loc_addr = daddr; req->af.v4_req.rmt_addr = saddr; req->af.v4_req.opt =tcp_v4_save_options (sk, skb);
@@ -1567,7 +1596,11 @@struct tcp_opt *newtp;struct sock *newsk; +#ifdef CONFIG_ACCEPT_QUEUES +if (tcp_acceptq_is_full (sk, req->acceptq_class)) +#else if (tcp_acceptq_is_full(sk)) +#endif goto exit_overflow;if (!dst && (dst =tcp_v4_route_req (sk, req)) ==NULL )
net/ipv4/tcp_minisocks.c +7 -0
@@ -787,7 +787,14 @@ newtp->num_sacks =0 ; newtp->urg_data =0 ; newtp->listen_opt =NULL ; +#ifdef CONFIG_ACCEPT_QUEUES + newtp->accept_queue =NULL ; +memset (newtp->acceptq,0 ,sizeof (newtp->acceptq)); + newtp->class_index =0 ; + +#else newtp->accept_queue = newtp->accept_queue_tail =NULL ; +#endif /* Deinitialize syn_wait_lock to trap illegal accesses. */ memset (&newtp->syn_wait_lock,0 ,sizeof (newtp->syn_wait_lock));
net/ipv4/tcp_timer.c +20 -4
@@ -498,7 +498,16 @@* ones are about to clog our table. */ if (lopt->qlen>>(lopt->max_qlen_log-1 )) { +#ifdef CONFIG_ACCEPT_QUEUES +int young =0 ; + +for (i=0 ; i <NUM_ACCEPT_QUEUES ; i++) + young += lopt->qlen_young[i]; + + young <<=1 ; +#else int young = (lopt->qlen_young<<1 ); +#endif while (thresh >2 ) {if (lopt->qlen < young)
@@ -524,9 +533,12 @@unsigned long timeo; if (req->retrans++ == 0) - lopt->qlen_young--; - timeo =min ((TCP_TIMEOUT_INIT << req->retrans), -TCP_RTO_MAX ); +#ifdef CONFIG_ACCEPT_QUEUES + lopt->qlen_young[req->acceptq_class]--; +#else + lopt->qlen_young--; +#endif + timeo =min ((TCP_TIMEOUT_INIT << req->retrans),TCP_RTO_MAX ); req->expires = now + timeo; reqp = &req->dl_next;continue ;
@@ -538,7 +550,11 @@write_unlock (&tp->syn_wait_lock); lopt->qlen--; if (req->retrans == 0) - lopt->qlen_young--; +#ifdef CONFIG_ACCEPT_QUEUES + lopt->qlen_young[req->acceptq_class]--; +#else + lopt->qlen_young--; +#endif tcp_openreq_free (req);continue ; }