From 6d2e80b08ce84d6237d59ba32bfb0cbe1ea1f961 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 and it's for the benefit of CPS. a) Remove the operation of bezeroing all the members of dpvs connection within dp_vs_conn_alloc(). b) 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 values. --- include/ipvs/conn.h | 148 +++++++++++++++++++++++------------------- src/ipvs/ip_vs_conn.c | 20 +++++- 2 files changed, 100 insertions(+), 68 deletions(-) diff --git a/include/ipvs/conn.h b/include/ipvs/conn.h index a7e94bca9..a2b1a8021 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. + * And a new member must be added to either of them. + */ 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]; - 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 */ + 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 */ - /* for FNAT */ - struct dp_vs_laddr *local; /* local address */ - struct dp_vs_seq fnat_seq; + struct rte_mempool *connpool; - /* save last SEQ/ACK from RS for RST when conn expire*/ - uint32_t rs_end_seq; - uint32_t rs_end_ack; + rte_atomic32_t refcnt; + 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); + 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); + struct dp_vs_conn *conn, struct rte_mbuf *mbuf); + /* for FNAT */ + struct dp_vs_laddr *local; /* local address */ + + struct timeval timeout; + +#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,49 @@ 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 */ + /* control members */ + rte_atomic32_t n_control; /* number of connections controlled + by me */ + struct dp_vs_conn *control; /* master who controlls me */ - /* connection redirect in fnat/snat/nat modes */ - struct dp_vs_redirect *redirect; + void *prot_data; /* protocol specific data */ + struct dp_vs_conn_stats stats; /* statistics */ + struct dpvs_timer timer; - /* flag for gfwip */ - bool outwall; + /* 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 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..53efa3e49 100644 --- a/src/ipvs/ip_vs_conn.c +++ b/src/ipvs/ip_vs_conn.c @@ -98,14 +98,13 @@ static struct dp_vs_conn *dp_vs_conn_alloc(enum dpvs_fwd_mode fwdmode, return NULL; } - conn->connpool = this_conn_cache; this_conn_count++; /* no need to create redirect for the global template connection */ if (likely((flags & DPVS_CONN_F_TEMPLATE) == 0)) r = dp_vs_redirect_alloc(fwdmode); - conn->redirect = r; + conn->redirect = r; return conn; } @@ -784,6 +783,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, redirect) + - 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,7 +812,10 @@ struct dp_vs_conn *dp_vs_conn_new(struct rte_mbuf *mbuf, if (unlikely(!new)) return NULL; - new->flags = flags; + dp_vs_conn_pre_init(new); + + new->connpool = this_conn_cache; + new->flags = flags; /* set proper RS port */ if (dp_vs_conn_is_template(new) || param->ct_dport != 0)