Changeset 6f7cd4b


Ignore:
Timestamp:
01/13/17 14:27:15 (4 years ago)
Author:
Richard Sanger <rsanger@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, master, ndag_format, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
174b3c7
Parents:
d31b952
Message:

Makes a couple of modifications to the DPDK RSS hash key patch

  • Ensure CUSTOM_HASHER still returns -1 to libtrace
  • Rework to allow any size of hash
  • Rework to malloc the key I'm not 100% convinced DPDK does not hold on to the reference.
  • Also fixes a bug in the fallback libtrace hasher handling. Which was always sending packets to the same thread.
Location:
lib
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • lib/format_dpdk.c

    re47ab4d r6f7cd4b  
    365365        char mempool_name[MEMPOOL_NAME_LEN]; /* The name of the mempool that we are using */
    366366        enum hasher_types hasher_type;
     367        uint8_t *rss_key;
    367368        /* To improve single-threaded performance we always batch reading
    368369         * packets, in a burst, otherwise the parallel library does this for us */
     
    857858        FORMAT(libtrace)->burst_offset = 0;
    858859        FORMAT(libtrace)->hasher_type = HASHER_BALANCE;
     860        FORMAT(libtrace)->rss_key = NULL;
    859861
    860862        /* Make our first stream */
     
    930932                return 0;
    931933        case TRACE_OPTION_HASHER:
    932                 FORMAT(libtrace)->hasher_type=*(enum hasher_types*)data;
    933                 return 0;
     934                switch (*((enum hasher_types *) data))
     935                {
     936                case HASHER_BALANCE:
     937                case HASHER_UNIDIRECTIONAL:
     938                case HASHER_BIDIRECTIONAL:
     939                        FORMAT(libtrace)->hasher_type = *(enum hasher_types*)data;
     940                        if (FORMAT(libtrace)->rss_key)
     941                                free(FORMAT(libtrace)->rss_key);
     942                        FORMAT(libtrace)->rss_key = NULL;
     943                        return 0;
     944                case HASHER_CUSTOM:
     945                        // Let libtrace do this
     946                        return -1;
     947                }
     948                break;
    934949        case TRACE_OPTION_FILTER:
    935950                /* TODO filtering */
     
    13401355        }
    13411356
    1342         // for symmetric rss, repeat 2 bytes
    1343         // otherwise, use default rss key in drivers
    1344         uint8_t rss_key[52]; // 52 for i40e, 40 for others
    1345         if (format_data->hasher_type == HASHER_BIDIRECTIONAL) {
     1357        /* Generate the hash key, based on the device */
     1358        uint8_t rss_size = 52; // 52 for i40e, 40 for others, use the largest by default
     1359        // In new versions DPDK we can query the size
    13461360#if RTE_VERSION >= RTE_VERSION_NUM(2, 1, 0, 0)
    1347                 struct rte_eth_dev_info dev_info;
    1348                 rte_eth_dev_info_get(format_data->port, &dev_info);
    1349                 port_conf.rx_adv_conf.rss_conf.rss_key_len = dev_info.hash_key_size;
    1350 #else
    1351                 port_conf.rx_adv_conf.rss_conf.rss_key_len = sizeof(rss_key);
    1352 #endif
    1353                 // first 2 bytes of rss_intel_key from drivers/net/e1000/igb_rxtx.c
    1354                 static uint8_t rss_key_2bytes[] = {0x6D, 0x5A};
    1355                 int i;
    1356                 for (i=0; i<port_conf.rx_adv_conf.rss_conf.rss_key_len; i += sizeof(rss_key_2bytes))
    1357                         memcpy(rss_key + i, rss_key_2bytes, sizeof(rss_key_2bytes));
    1358                 port_conf.rx_adv_conf.rss_conf.rss_key = rss_key;
     1361        struct rte_eth_dev_info dev_info;
     1362        rte_eth_dev_info_get(format_data->port, &dev_info);
     1363        rss_size = dev_info.hash_key_size;
     1364#endif
     1365        if (rss_size != 0) {
     1366                format_data->rss_key = malloc(rss_size);
     1367                if (format_data->hasher_type == HASHER_BIDIRECTIONAL) {
     1368                        toeplitz_ncreate_bikey(format_data->rss_key, rss_size);
     1369                } else {
     1370                        toeplitz_ncreate_unikey(format_data->rss_key, rss_size);
     1371                }
     1372                port_conf.rx_adv_conf.rss_conf.rss_key = format_data->rss_key;
     1373#if RTE_VERSION >= RTE_VERSION_NUM(1, 7, 0, 1)
     1374                port_conf.rx_adv_conf.rss_conf.rss_key_len = rss_size;
     1375#endif
     1376        } else {
     1377                fprintf(stderr, "DPDK couldn't configure RSS hashing!");
    13591378        }
    13601379
     
    17621781                libtrace_list_deinit(FORMAT(libtrace)->per_stream);
    17631782                /* filter here if we used it */
     1783                if (FORMAT(libtrace)->rss_key)
     1784                        free(FORMAT(libtrace)->rss_key);
    17641785                free(libtrace->format_data);
    17651786        }
  • lib/hash_toeplitz.c

    ree6e802 r6f7cd4b  
    7171 * Creates a random unidirectional RSS key - a ip or ip+port combination in
    7272 * the opposite directions will most likely get different hashes.
     73 * @param key An array of bytes to retrieve the RSS key
     74 * @param num The number of bytes in key
     75 */
     76void toeplitz_ncreate_unikey(uint8_t *key, size_t num) {
     77        size_t i;
     78        unsigned int seed = time(NULL);
     79        for (i = 0; i < num; i++) {
     80                key[i] = (uint8_t) rand_r(&seed);
     81        }
     82}
     83
     84/**
     85 * Creates a random 40 byte unidirectional RSS key - a ip or ip+port combination
     86 * in the opposite directions will most likely get different hashes.
    7387 * @param key must have 40 bytes of space to retrieve random the key
    74  */ 
     88 */
    7589void toeplitz_create_unikey(uint8_t *key) {
    76         int i;
    77         unsigned int seed = time(NULL);
    78         for (i = 0; i < 40; i++) {
    79                 key[i] = (uint8_t) rand_r(&seed);
    80         }
     90        toeplitz_ncreate_unikey(key, 40);
    8191}
    8292
     
    8595 * in opposite directions will receive the same hash
    8696 * @param key must have 40 bytes of space to retrieve random the key
    87  */
    88 void toeplitz_create_bikey(uint8_t *key) {
     97 * @param num The number of bytes in the key, must be a multiple of 2
     98 */
     99void toeplitz_ncreate_bikey(uint8_t *key, size_t num) {
    89100        unsigned int seed = time(NULL);
    90         int i;
     101        size_t i;
     102        if (num % 2 != 0) {
     103                perror("Can not create a bidirectional key for an odd length key");
     104        }
    91105        // Every thing is 16bit (port=16, ipv4=32, ipv6=128
    92106        // aligned so this will make the hash bidirectional
    93107        uint16_t bi_key = (uint16_t) rand_r(&seed);
    94108        uint16_t *bi_rep = (uint16_t *) key;
    95         for (i = 0; i < 20; i++) {
     109        for (i = 0; i < num/2; i++) {
    96110                bi_rep[i] = bi_key;
    97111        }
     112}
     113
     114/**
     115 * Create a 40 byte bidirectional RSS key, i.e. ip and ip+port configurations
     116 * in opposite directions will receive the same hash
     117 * @param key An array of bytes to retrieve the RSS key
     118 */
     119void toeplitz_create_bikey(uint8_t *key) {
     120        toeplitz_ncreate_bikey(key, 40);
    98121}
    99122
     
    106129        }
    107130        toeplitz_hash_expand_key(conf);
     131        conf->hash_ipv4 = 1;
     132        conf->hash_ipv6 = 1;
     133        conf->hash_tcp_ipv4 = 1;
     134        conf->x_hash_udp_ipv4 = 1;
     135        conf->hash_tcp_ipv6 = 1;
     136        conf->x_hash_udp_ipv6 = 1;
    108137}
    109138
  • lib/hash_toeplitz.h

    ree6e802 r6f7cd4b  
    5858void toeplitz_init_config(toeplitz_conf_t *conf, bool bidirectional);
    5959uint64_t toeplitz_hash_packet(const libtrace_packet_t * pkt, const toeplitz_conf_t *cnf);
     60void toeplitz_ncreate_bikey(uint8_t *key, size_t num);
    6061void toeplitz_create_bikey(uint8_t *key);
     62void toeplitz_ncreate_unikey(uint8_t *key, size_t num);
    6163void toeplitz_create_unikey(uint8_t *key);
    6264
Note: See TracChangeset for help on using the changeset viewer.