summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorAnand B Jyoti <anand.b.jyoti@intel.com>2017-05-08 11:04:07 +0530
committerDeepak S <deepak.s@linux.intel.com>2017-06-01 11:56:00 +0000
commitcd7ce8f25a81fb390ed0cc66992fda8ab1b021cb (patch)
tree2213d3f98ebd409e01d443fac783f132bbbd21dd /common
parentb04a6e5dacc458f81097c9b8a172dcbf16d8fd50 (diff)
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 <anand.b.jyoti@intel.com>
Diffstat (limited to 'common')
-rw-r--r--common/VIL/conntrack/rte_cnxn_tracking.c37
-rw-r--r--common/VIL/conntrack/rte_ct_udp.c18
2 files changed, 43 insertions, 12 deletions
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;
}