From cd7ce8f25a81fb390ed0cc66992fda8ab1b021cb Mon Sep 17 00:00:00 2001 From: Anand B Jyoti Date: Mon, 8 May 2017 11:04:07 +0530 Subject: CT: Perf optimization through prefetch and condition checks in CT JIRA: SAMPLEVNF-10 LLC miss is possible when the connection data structure is accessed after retrieved from hash table entries for TCP/UDP connection. CPI for rte_ct_udp_packet() is not good due to if/else condition checks. This patch provide a prefetch instructions to pre-fetch the cnxn data entry structure to avoid the LLC miss and also optimize the if/else condition check to improve the CPI for rte_ct_udp_packet() function. Change-Id: Ieaf70815c919ddbe1ff34921222eac030fb41756 Signed-off-by: Anand B Jyoti --- common/VIL/conntrack/rte_cnxn_tracking.c | 37 +++++++++++++++++++++++++++++--- common/VIL/conntrack/rte_ct_udp.c | 18 ++++++++-------- 2 files changed, 43 insertions(+), 12 deletions(-) (limited to 'common/VIL') diff --git a/common/VIL/conntrack/rte_cnxn_tracking.c b/common/VIL/conntrack/rte_cnxn_tracking.c index 461ed422..aa18058e 100644 --- a/common/VIL/conntrack/rte_cnxn_tracking.c +++ b/common/VIL/conntrack/rte_cnxn_tracking.c @@ -52,7 +52,6 @@ #define IP_VERSION_4 4 #define IP_VERSION_6 6 - static void rte_ct_cnxn_tracker_batch_lookup_basic_type( struct rte_ct_cnxn_tracker *ct, @@ -1479,6 +1478,9 @@ rte_ct_cnxn_tracker_batch_lookup_basic_type( int32_t positions[RTE_HASH_LOOKUP_BULK_MAX]; uint32_t i; struct rte_ct_cnxn_data new_cnxn_data; + struct rte_ct_cnxn_data *cnxn_data_entry[RTE_HASH_LOOKUP_BULK_MAX]; + + rte_prefetch0(ct->hash_table_entries); if (CNXN_TRX_DEBUG > 1) { printf("Enter cnxn tracker %p", ct); @@ -1631,6 +1633,35 @@ rte_ct_cnxn_tracker_batch_lookup_basic_type( *pkts_mask = 0; return; /* unknown error, just discard all packets */ } + + /* Pre-fetch hash table entries and counters to avoid LLC miss */ + rte_prefetch0(ct->counters); + for (i = 0; i < packets_for_lookup; i++) { + struct rte_ct_cnxn_data *entry = NULL; + int hash_table_entry = positions[i]; + + if (hash_table_entry >= 0) { + /* Entry found for existing UDP/TCP connection */ + entry = &ct->hash_table_entries[hash_table_entry]; + rte_prefetch0(&entry->counters.packets_forwarded); + rte_prefetch0(entry); + rte_prefetch0(&entry->key_is_client_order); + } + else { + uint8_t pkt_index = compacting_map[i]; + uint32_t *key = ct->hash_key_ptrs[pkt_index]; + uint8_t protocol = *(key + 9); + if (protocol == UDP_PROTOCOL) { + /* Search in new connections only for UDP */ + entry = rte_ct_search_new_connections(ct, key); + rte_prefetch0(&entry->counters.packets_forwarded); + rte_prefetch0(entry); + rte_prefetch0(&entry->key_is_client_order); + } + } + cnxn_data_entry[i] = entry; + } + for (i = 0; i < packets_for_lookup; i++) { /* index into hash table entries */ int hash_table_entry = positions[i]; @@ -1689,7 +1720,7 @@ rte_ct_cnxn_tracker_batch_lookup_basic_type( */ struct rte_ct_cnxn_data *entry = - &ct->hash_table_entries[hash_table_entry]; + cnxn_data_entry[i]; if (rte_ct_udp_packet (ct, entry, pkts[pkt_index], @@ -1704,7 +1735,7 @@ rte_ct_cnxn_tracker_batch_lookup_basic_type( */ struct rte_ct_cnxn_data *recent_entry = - rte_ct_search_new_connections(ct, key); + cnxn_data_entry[i]; if (recent_entry != NULL) { if (rte_ct_udp_packet(ct, recent_entry, diff --git a/common/VIL/conntrack/rte_ct_udp.c b/common/VIL/conntrack/rte_ct_udp.c index 88f3a9a4..6caa788f 100644 --- a/common/VIL/conntrack/rte_ct_udp.c +++ b/common/VIL/conntrack/rte_ct_udp.c @@ -33,17 +33,17 @@ enum rte_ct_packet_action rte_ct_udp_packet(struct rte_ct_cnxn_tracker *ct, uint8_t key_was_flipped) { enum rte_ct_pkt_direction dir; - + enum rte_ct_udp_states ustate = RTE_CT_UDP_UNREPLIED; dir = (cd->key_is_client_order == !key_was_flipped); /* printf("packet received verify"); */ - if (dir == RTE_CT_DIR_REPLY && - cd->connstatus == RTE_INIT_CONN) { - rte_ct_set_cnxn_timer_for_udp(ct, cd, RTE_CT_UDP_REPLIED); + if (dir == RTE_CT_DIR_REPLY && ( + (cd->connstatus == RTE_INIT_CONN) || + (cd->connstatus == RTE_ASSURED_CONN))) + { + ustate = RTE_CT_UDP_REPLIED; cd->connstatus = RTE_ASSURED_CONN; - } else if (dir == RTE_CT_DIR_REPLY && - cd->connstatus == RTE_ASSURED_CONN) - rte_ct_set_cnxn_timer_for_udp(ct, cd, RTE_CT_UDP_REPLIED); - else - rte_ct_set_cnxn_timer_for_udp(ct, cd, RTE_CT_UDP_UNREPLIED); + } + rte_ct_set_cnxn_timer_for_udp(ct, cd, ustate); + return RTE_CT_FORWARD_PACKET; } -- cgit 1.2.3-korg