From e4afc47b0d5140bfbf3834e406f7c44a400f84aa Mon Sep 17 00:00:00 2001 From: zhuangyan Date: Mon, 10 Aug 2020 19:44:02 +0800 Subject: [PATCH] dpvs: Split all the members of dpvs connection into two groups for its initialization for the benefit of CPS. - Remove the operation of bezeroing all the members of dpvs connection within dp_vs_conn_alloc(). - Each member of dpvs connection is initialized ONCE via dp_vs_conn_pre_init() or dp_vs_conn_new(). - dp_vs_conn_pre_init() initializes all the member of one group as 0, but ack_mbuf. - dp_vs_conn_new() initializes all the members of the other group with the specific value. --- include/ipvs/conn.h | 151 ++++++++++++++++++++++++------------------ src/ipvs/ip_vs_conn.c | 14 ++++ 2 files changed, 99 insertions(+), 66 deletions(-) diff --git a/include/ipvs/conn.h b/include/ipvs/conn.h index a7e94bca9..379c7ab2d 100644 --- a/include/ipvs/conn.h +++ b/include/ipvs/conn.h @@ -47,27 +47,26 @@ enum { }; struct dp_vs_conn_param { - int af; - uint16_t proto; - const union inet_addr *caddr; - const union inet_addr *vaddr; - uint16_t cport; - uint16_t vport; - uint16_t ct_dport; /* RS port for template connection */ - bool outwall; + uint8_t af; + bool outwall; + uint16_t proto; + uint16_t cport; + uint16_t vport; + const union inet_addr *caddr; + const union inet_addr *vaddr; + uint16_t ct_dport; /* RS port for template connection */ }; struct conn_tuple_hash { struct list_head list; - int direct; /* inbound/outbound */ - - /* tuple info */ - int af; - uint16_t proto; - union inet_addr saddr; /* pkt's source addr */ - union inet_addr daddr; /* pkt's dest addr */ + uint8_t af; + uint8_t proto; + uint8_t direct; /* inbound/outbound */ + uint8_t padding; uint16_t sport; uint16_t dport; + union inet_addr saddr; /* pkt's source addr */ + union inet_addr daddr; /* pkt's dest addr */ } __rte_cache_aligned; struct dp_vs_conn_stats { @@ -80,42 +79,54 @@ struct dp_vs_conn_stats { struct dp_vs_fdir_filt; struct dp_vs_proto; +/* + * All the members of dp_vs_conn are classified into two groups, A and B to + * which a new member must be added. + * + * Additionally, we need to ensure dp_vs_conn is of 8 bytes alignment. + */ struct dp_vs_conn { - int af; + /* + * Group A: the below members are initialized in dp_vs_conn_new(). + */ + struct conn_tuple_hash tuplehash[DPVS_CONN_DIR_MAX]; + + uint8_t af; uint8_t proto; - union inet_addr caddr; /* Client address */ - union inet_addr vaddr; /* Virtual address */ - union inet_addr laddr; /* director Local address */ - union inet_addr daddr; /* Destination (RS) address */ + lcoreid_t lcore; + bool outwall; /* flag for gfwip */ + uint16_t cport; uint16_t vport; uint16_t lport; uint16_t dport; - struct rte_mempool *connpool; - struct conn_tuple_hash tuplehash[DPVS_CONN_DIR_MAX]; + union inet_addr caddr; /* Client address */ + union inet_addr vaddr; /* Virtual address */ + union inet_addr laddr; /* director Local address */ + union inet_addr daddr; /* Destination (RS) address */ + rte_atomic32_t refcnt; - struct dpvs_timer timer; - struct timeval timeout; - lcoreid_t lcore; - struct dp_vs_dest *dest; /* real server */ - void *prot_data; /* protocol specific data */ + volatile uint16_t flags; + struct dp_vs_dest *dest; /* real server */ + + int (*packet_xmit)(struct dp_vs_proto *prot, + struct dp_vs_conn *conn, struct rte_mbuf *mbuf); + int (*packet_out_xmit)(struct dp_vs_proto *prot, + struct dp_vs_conn *conn, struct rte_mbuf *mbuf); /* for FNAT */ - struct dp_vs_laddr *local; /* local address */ - struct dp_vs_seq fnat_seq; + struct dp_vs_laddr *local; /* local address */ - /* save last SEQ/ACK from RS for RST when conn expire*/ - uint32_t rs_end_seq; - uint32_t rs_end_ack; + struct timeval timeout; - int (*packet_xmit)(struct dp_vs_proto *prot, - struct dp_vs_conn *conn, - struct rte_mbuf *mbuf); - int (*packet_out_xmit)(struct dp_vs_proto *prot, - struct dp_vs_conn *conn, - struct rte_mbuf *mbuf); +#ifdef CONFIG_DPVS_IPVS_STATS_DEBUG + uint64_t ctime; /* create time */ +#endif + /* + * Group B: the below members are initialized in dp_vs_conn_pre_init(). + */ /* L2 fast xmit */ struct ether_addr in_smac; struct ether_addr in_dmac; @@ -123,42 +134,50 @@ struct dp_vs_conn { struct ether_addr out_dmac; /* route for neigbour */ - struct netif_port *in_dev; /* inside to rs*/ - struct netif_port *out_dev; /* outside to client*/ - union inet_addr in_nexthop; /* to rs*/ - union inet_addr out_nexthop; /* to client*/ + struct netif_port *in_dev; /* inside to rs */ + struct netif_port *out_dev; /* outside to client */ + union inet_addr in_nexthop; /* to rs*/ + union inet_addr out_nexthop; /* to client*/ - /* statistics */ - struct dp_vs_conn_stats stats; + /* for FNAT */ + struct dp_vs_seq fnat_seq; /* synproxy related members */ - struct dp_vs_seq syn_proxy_seq; /* seq used in synproxy */ - struct list_head ack_mbuf; /* ack mbuf saved in step2 */ - uint32_t ack_num; /* ack mbuf number stored */ - struct rte_mbuf *syn_mbuf; /* saved rs syn packet for retransmition */ - rte_atomic32_t syn_retry_max; /* syn retransmition max packets */ + struct dp_vs_seq syn_proxy_seq; /* seq used in synproxy */ + struct list_head ack_mbuf; /* ack mbuf saved in step2 */ + struct rte_mbuf *syn_mbuf; /* saved rs syn packet for + retransmition */ + uint32_t ack_num; /* ack mbuf number stored */ + rte_atomic32_t syn_retry_max; /* syn retransmition max packets */ + + /* save last SEQ/ACK from RS for RST when conn expire */ + uint32_t rs_end_seq; + uint32_t rs_end_ack; /* add for stopping ack storm */ - uint32_t last_seq; /* seq of the last ack packet */ - uint32_t last_ack_seq; /* ack seq of the last ack packet */ - rte_atomic32_t dup_ack_cnt; /* count of repeated ack packets */ + uint32_t last_seq; /* seq of the last ack packet */ + uint32_t last_ack_seq; /* ack seq of the last ack packet */ + rte_atomic32_t dup_ack_cnt; /* count of repeated ack packets */ - /* flags and state transition */ - volatile uint16_t flags; - volatile uint16_t state; - volatile uint16_t old_state; /* old state, to be used for state transition - triggered synchronization */ - /* controll members */ - struct dp_vs_conn *control; /* master who controlls me */ - rte_atomic32_t n_control; /* number of connections controlled by me*/ - uint64_t ctime; /* create time */ - - /* connection redirect in fnat/snat/nat modes */ - struct dp_vs_redirect *redirect; + /* control members */ + rte_atomic32_t n_control; /* number of connections controlled + by me */ + struct dp_vs_conn *control; /* master who controlls me */ - /* flag for gfwip */ - bool outwall; + void *prot_data; /* protocol specific data */ + struct dp_vs_conn_stats stats; /* statistics */ + struct dpvs_timer timer; + /* state transition */ + volatile uint16_t state; + volatile uint16_t old_state; /* used for state transition + triggered synchronization */ + + /* + * the below member is initialized in dp_vs_conn_alloc(). + */ + struct rte_mempool *connpool; + struct dp_vs_redirect *redirect; /* used in fnat/snat/nat modes */ } __rte_cache_aligned; /* for syn-proxy to save all ack packet in conn before rs's syn-ack arrives */ diff --git a/src/ipvs/ip_vs_conn.c b/src/ipvs/ip_vs_conn.c index 9f94c3d77..7acc369df 100644 --- a/src/ipvs/ip_vs_conn.c +++ b/src/ipvs/ip_vs_conn.c @@ -784,6 +784,18 @@ static void conn_flush(void) #endif } +static inline void dp_vs_conn_pre_init(struct dp_vs_conn *new) +{ + size_t len; + + len = offsetof(struct dp_vs_conn, connpool) + - offsetof(struct dp_vs_conn, in_smac); + + memset(&new->in_smac, 0, len); + + INIT_LIST_HEAD(&new->ack_mbuf); +} + struct dp_vs_conn *dp_vs_conn_new(struct rte_mbuf *mbuf, const struct dp_vs_iphdr *iph, struct dp_vs_conn_param *param, @@ -801,6 +813,8 @@ struct dp_vs_conn *dp_vs_conn_new(struct rte_mbuf *mbuf, if (unlikely(!new)) return NULL; + dp_vs_conn_pre_init(new); + new->flags = flags; /* set proper RS port */