1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson * Copyright(c) 2018 Intel Corporation
3a9de470cSBruce Richardson */
4a9de470cSBruce Richardson
5a9de470cSBruce Richardson #include <inttypes.h>
6a9de470cSBruce Richardson #include <locale.h>
7a9de470cSBruce Richardson
8a9de470cSBruce Richardson #include <rte_cycles.h>
9a9de470cSBruce Richardson #include <rte_hash.h>
10a9de470cSBruce Richardson #include <rte_hash_crc.h>
11a9de470cSBruce Richardson #include <rte_jhash.h>
12a9de470cSBruce Richardson #include <rte_launch.h>
13a9de470cSBruce Richardson #include <rte_malloc.h>
14a9de470cSBruce Richardson #include <rte_random.h>
15a9de470cSBruce Richardson #include <rte_spinlock.h>
16a9de470cSBruce Richardson
17a9de470cSBruce Richardson #include "test.h"
18a9de470cSBruce Richardson
19a9de470cSBruce Richardson #define RTE_RWTEST_FAIL 0
20a9de470cSBruce Richardson
21a9de470cSBruce Richardson #define TOTAL_ENTRY (5*1024*1024)
22a9de470cSBruce Richardson #define TOTAL_INSERT (4.5*1024*1024)
23a9de470cSBruce Richardson #define TOTAL_INSERT_EXT (5*1024*1024)
24a9de470cSBruce Richardson
25a9de470cSBruce Richardson #define NUM_TEST 3
26a9de470cSBruce Richardson unsigned int core_cnt[NUM_TEST] = {2, 4, 8};
27a9de470cSBruce Richardson
28cb056611SStephen Hemminger unsigned int worker_core_ids[RTE_MAX_LCORE];
29a9de470cSBruce Richardson struct perf {
30a9de470cSBruce Richardson uint32_t single_read;
31a9de470cSBruce Richardson uint32_t single_write;
32a9de470cSBruce Richardson uint32_t read_only[NUM_TEST];
33a9de470cSBruce Richardson uint32_t write_only[NUM_TEST];
34a9de470cSBruce Richardson uint32_t read_write_r[NUM_TEST];
35a9de470cSBruce Richardson uint32_t read_write_w[NUM_TEST];
36a9de470cSBruce Richardson };
37a9de470cSBruce Richardson
38a9de470cSBruce Richardson static struct perf htm_results, non_htm_results;
39a9de470cSBruce Richardson
40a9de470cSBruce Richardson struct {
41a9de470cSBruce Richardson uint32_t *keys;
42a9de470cSBruce Richardson uint8_t *found;
43a9de470cSBruce Richardson uint32_t num_insert;
44a9de470cSBruce Richardson uint32_t rounded_tot_insert;
45a9de470cSBruce Richardson struct rte_hash *h;
46a9de470cSBruce Richardson } tbl_rw_test_param;
47a9de470cSBruce Richardson
48*b6a7e685STyler Retzlaff static RTE_ATOMIC(uint64_t) gcycles;
49*b6a7e685STyler Retzlaff static RTE_ATOMIC(uint64_t) ginsertions;
50a9de470cSBruce Richardson
51*b6a7e685STyler Retzlaff static RTE_ATOMIC(uint64_t) gread_cycles;
52*b6a7e685STyler Retzlaff static RTE_ATOMIC(uint64_t) gwrite_cycles;
53a9de470cSBruce Richardson
54*b6a7e685STyler Retzlaff static RTE_ATOMIC(uint64_t) greads;
55*b6a7e685STyler Retzlaff static RTE_ATOMIC(uint64_t) gwrites;
56a9de470cSBruce Richardson
57a9de470cSBruce Richardson static int
test_hash_readwrite_worker(__rte_unused void * arg)58f2fc83b4SThomas Monjalon test_hash_readwrite_worker(__rte_unused void *arg)
59a9de470cSBruce Richardson {
60a9de470cSBruce Richardson uint64_t i, offset;
61a9de470cSBruce Richardson uint32_t lcore_id = rte_lcore_id();
62a9de470cSBruce Richardson uint64_t begin, cycles;
63a9de470cSBruce Richardson int *ret;
64a9de470cSBruce Richardson
65a9de470cSBruce Richardson ret = rte_malloc(NULL, sizeof(int) *
66a9de470cSBruce Richardson tbl_rw_test_param.num_insert, 0);
67a9de470cSBruce Richardson for (i = 0; i < rte_lcore_count(); i++) {
68cb056611SStephen Hemminger if (worker_core_ids[i] == lcore_id)
69a9de470cSBruce Richardson break;
70a9de470cSBruce Richardson }
71a9de470cSBruce Richardson offset = tbl_rw_test_param.num_insert * i;
72a9de470cSBruce Richardson
73a9de470cSBruce Richardson printf("Core #%d inserting and reading %d: %'"PRId64" - %'"PRId64"\n",
74a9de470cSBruce Richardson lcore_id, tbl_rw_test_param.num_insert,
75a9de470cSBruce Richardson offset, offset + tbl_rw_test_param.num_insert - 1);
76a9de470cSBruce Richardson
77a9de470cSBruce Richardson begin = rte_rdtsc_precise();
78a9de470cSBruce Richardson
79a9de470cSBruce Richardson for (i = offset; i < offset + tbl_rw_test_param.num_insert; i++) {
80a9de470cSBruce Richardson
81a9de470cSBruce Richardson if (rte_hash_lookup(tbl_rw_test_param.h,
82a9de470cSBruce Richardson tbl_rw_test_param.keys + i) > 0)
83a9de470cSBruce Richardson break;
84a9de470cSBruce Richardson
85a9de470cSBruce Richardson ret[i - offset] = rte_hash_add_key(tbl_rw_test_param.h,
86a9de470cSBruce Richardson tbl_rw_test_param.keys + i);
87a9de470cSBruce Richardson if (ret[i - offset] < 0)
88a9de470cSBruce Richardson break;
89a9de470cSBruce Richardson
90a9de470cSBruce Richardson /* lookup a random key */
91a9de470cSBruce Richardson uint32_t rand = rte_rand() % (i + 1 - offset);
92a9de470cSBruce Richardson
93a9de470cSBruce Richardson if (rte_hash_lookup(tbl_rw_test_param.h,
94a9de470cSBruce Richardson tbl_rw_test_param.keys + rand) != ret[rand])
95a9de470cSBruce Richardson break;
96a9de470cSBruce Richardson
97a9de470cSBruce Richardson
98a9de470cSBruce Richardson if (rte_hash_del_key(tbl_rw_test_param.h,
99a9de470cSBruce Richardson tbl_rw_test_param.keys + rand) != ret[rand])
100a9de470cSBruce Richardson break;
101a9de470cSBruce Richardson
102a9de470cSBruce Richardson ret[rand] = rte_hash_add_key(tbl_rw_test_param.h,
103a9de470cSBruce Richardson tbl_rw_test_param.keys + rand);
104a9de470cSBruce Richardson if (ret[rand] < 0)
105a9de470cSBruce Richardson break;
106a9de470cSBruce Richardson
107a9de470cSBruce Richardson if (rte_hash_lookup(tbl_rw_test_param.h,
108a9de470cSBruce Richardson tbl_rw_test_param.keys + rand) != ret[rand])
109a9de470cSBruce Richardson break;
110a9de470cSBruce Richardson }
111a9de470cSBruce Richardson
112a9de470cSBruce Richardson cycles = rte_rdtsc_precise() - begin;
113*b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit(&gcycles, cycles, rte_memory_order_relaxed);
114*b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit(&ginsertions, i - offset, rte_memory_order_relaxed);
115a9de470cSBruce Richardson
116a9de470cSBruce Richardson for (; i < offset + tbl_rw_test_param.num_insert; i++)
117a9de470cSBruce Richardson tbl_rw_test_param.keys[i] = RTE_RWTEST_FAIL;
118a9de470cSBruce Richardson
119a9de470cSBruce Richardson rte_free(ret);
120a9de470cSBruce Richardson return 0;
121a9de470cSBruce Richardson }
122a9de470cSBruce Richardson
123a9de470cSBruce Richardson static int
init_params(int use_ext,int use_htm,int rw_lf,int use_jhash)12403a0ed1aSHonnappa Nagarahalli init_params(int use_ext, int use_htm, int rw_lf, int use_jhash)
125a9de470cSBruce Richardson {
126a9de470cSBruce Richardson unsigned int i;
127a9de470cSBruce Richardson
128a9de470cSBruce Richardson uint32_t *keys = NULL;
129a9de470cSBruce Richardson uint8_t *found = NULL;
130a9de470cSBruce Richardson struct rte_hash *handle;
131a9de470cSBruce Richardson
132a9de470cSBruce Richardson struct rte_hash_parameters hash_params = {
133a9de470cSBruce Richardson .entries = TOTAL_ENTRY,
134a9de470cSBruce Richardson .key_len = sizeof(uint32_t),
135a9de470cSBruce Richardson .hash_func_init_val = 0,
136a9de470cSBruce Richardson .socket_id = rte_socket_id(),
137a9de470cSBruce Richardson };
138a9de470cSBruce Richardson if (use_jhash)
139a9de470cSBruce Richardson hash_params.hash_func = rte_jhash;
140a9de470cSBruce Richardson else
141a9de470cSBruce Richardson hash_params.hash_func = rte_hash_crc;
142a9de470cSBruce Richardson
14303a0ed1aSHonnappa Nagarahalli hash_params.extra_flag = RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD;
144a9de470cSBruce Richardson if (use_htm)
14503a0ed1aSHonnappa Nagarahalli hash_params.extra_flag |=
14603a0ed1aSHonnappa Nagarahalli RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT;
14703a0ed1aSHonnappa Nagarahalli if (rw_lf)
14803a0ed1aSHonnappa Nagarahalli hash_params.extra_flag |=
14903a0ed1aSHonnappa Nagarahalli RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF;
150a9de470cSBruce Richardson else
15103a0ed1aSHonnappa Nagarahalli hash_params.extra_flag |=
15203a0ed1aSHonnappa Nagarahalli RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY;
153a9de470cSBruce Richardson
154a9de470cSBruce Richardson if (use_ext)
155a9de470cSBruce Richardson hash_params.extra_flag |=
156a9de470cSBruce Richardson RTE_HASH_EXTRA_FLAGS_EXT_TABLE;
157a9de470cSBruce Richardson else
158a9de470cSBruce Richardson hash_params.extra_flag &=
159a9de470cSBruce Richardson ~RTE_HASH_EXTRA_FLAGS_EXT_TABLE;
160a9de470cSBruce Richardson
161a9de470cSBruce Richardson hash_params.name = "tests";
162a9de470cSBruce Richardson
163a9de470cSBruce Richardson handle = rte_hash_create(&hash_params);
164a9de470cSBruce Richardson if (handle == NULL) {
1651afb336dSMin Zhou printf("hash creation failed\n");
166a9de470cSBruce Richardson return -1;
167a9de470cSBruce Richardson }
168a9de470cSBruce Richardson
169a9de470cSBruce Richardson tbl_rw_test_param.h = handle;
170a9de470cSBruce Richardson keys = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_ENTRY, 0);
171a9de470cSBruce Richardson
172a9de470cSBruce Richardson if (keys == NULL) {
173a9de470cSBruce Richardson printf("RTE_MALLOC failed\n");
174a9de470cSBruce Richardson goto err;
175a9de470cSBruce Richardson }
176a9de470cSBruce Richardson
177a9de470cSBruce Richardson found = rte_zmalloc(NULL, sizeof(uint8_t) * TOTAL_ENTRY, 0);
178a9de470cSBruce Richardson if (found == NULL) {
179a9de470cSBruce Richardson printf("RTE_ZMALLOC failed\n");
180a9de470cSBruce Richardson goto err;
181a9de470cSBruce Richardson }
182a9de470cSBruce Richardson
183a9de470cSBruce Richardson tbl_rw_test_param.keys = keys;
184a9de470cSBruce Richardson tbl_rw_test_param.found = found;
185a9de470cSBruce Richardson
186a9de470cSBruce Richardson for (i = 0; i < TOTAL_ENTRY; i++)
187a9de470cSBruce Richardson keys[i] = i;
188a9de470cSBruce Richardson
189a9de470cSBruce Richardson return 0;
190a9de470cSBruce Richardson
191a9de470cSBruce Richardson err:
192a9de470cSBruce Richardson rte_free(keys);
193a9de470cSBruce Richardson rte_hash_free(handle);
194a9de470cSBruce Richardson
195a9de470cSBruce Richardson return -1;
196a9de470cSBruce Richardson }
197a9de470cSBruce Richardson
198a9de470cSBruce Richardson static int
test_hash_readwrite_functional(int use_htm,int use_rw_lf,int use_ext)19903a0ed1aSHonnappa Nagarahalli test_hash_readwrite_functional(int use_htm, int use_rw_lf, int use_ext)
200a9de470cSBruce Richardson {
201a9de470cSBruce Richardson unsigned int i;
202a9de470cSBruce Richardson const void *next_key;
203a9de470cSBruce Richardson void *next_data;
204a9de470cSBruce Richardson uint32_t iter = 0;
205a9de470cSBruce Richardson
206a9de470cSBruce Richardson uint32_t duplicated_keys = 0;
207a9de470cSBruce Richardson uint32_t lost_keys = 0;
208a9de470cSBruce Richardson int use_jhash = 1;
209cb056611SStephen Hemminger int worker_cnt = rte_lcore_count() - 1;
210a9de470cSBruce Richardson uint32_t tot_insert = 0;
211a9de470cSBruce Richardson
212*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&gcycles, 0, rte_memory_order_relaxed);
213*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&ginsertions, 0, rte_memory_order_relaxed);
214a9de470cSBruce Richardson
21503a0ed1aSHonnappa Nagarahalli if (init_params(use_ext, use_htm, use_rw_lf, use_jhash) != 0)
216a9de470cSBruce Richardson goto err;
217a9de470cSBruce Richardson
218a9de470cSBruce Richardson if (use_ext)
219a9de470cSBruce Richardson tot_insert = TOTAL_INSERT_EXT;
220a9de470cSBruce Richardson else
221a9de470cSBruce Richardson tot_insert = TOTAL_INSERT;
222a9de470cSBruce Richardson
223a9de470cSBruce Richardson tbl_rw_test_param.num_insert =
224cb056611SStephen Hemminger tot_insert / worker_cnt;
225a9de470cSBruce Richardson
226a9de470cSBruce Richardson tbl_rw_test_param.rounded_tot_insert =
227cb056611SStephen Hemminger tbl_rw_test_param.num_insert * worker_cnt;
228a9de470cSBruce Richardson
22903a0ed1aSHonnappa Nagarahalli printf("\nHTM = %d, RW-LF = %d, EXT-Table = %d\n",
23003a0ed1aSHonnappa Nagarahalli use_htm, use_rw_lf, use_ext);
231a9de470cSBruce Richardson printf("++++++++Start function tests:+++++++++\n");
232a9de470cSBruce Richardson
233a9de470cSBruce Richardson /* Fire all threads. */
234a9de470cSBruce Richardson rte_eal_mp_remote_launch(test_hash_readwrite_worker,
235cb056611SStephen Hemminger NULL, SKIP_MAIN);
236a9de470cSBruce Richardson rte_eal_mp_wait_lcore();
237a9de470cSBruce Richardson
238a9de470cSBruce Richardson while (rte_hash_iterate(tbl_rw_test_param.h, &next_key,
239a9de470cSBruce Richardson &next_data, &iter) >= 0) {
240a9de470cSBruce Richardson /* Search for the key in the list of keys added .*/
241a9de470cSBruce Richardson i = *(const uint32_t *)next_key;
242a9de470cSBruce Richardson tbl_rw_test_param.found[i]++;
243a9de470cSBruce Richardson }
244a9de470cSBruce Richardson
245a9de470cSBruce Richardson for (i = 0; i < tbl_rw_test_param.rounded_tot_insert; i++) {
246a9de470cSBruce Richardson if (tbl_rw_test_param.keys[i] != RTE_RWTEST_FAIL) {
247a9de470cSBruce Richardson if (tbl_rw_test_param.found[i] > 1) {
248a9de470cSBruce Richardson duplicated_keys++;
249a9de470cSBruce Richardson break;
250a9de470cSBruce Richardson }
251a9de470cSBruce Richardson if (tbl_rw_test_param.found[i] == 0) {
252a9de470cSBruce Richardson lost_keys++;
253a9de470cSBruce Richardson printf("key %d is lost\n", i);
254a9de470cSBruce Richardson break;
255a9de470cSBruce Richardson }
256a9de470cSBruce Richardson }
257a9de470cSBruce Richardson }
258a9de470cSBruce Richardson
259a9de470cSBruce Richardson if (duplicated_keys > 0) {
260a9de470cSBruce Richardson printf("%d key duplicated\n", duplicated_keys);
261a9de470cSBruce Richardson goto err_free;
262a9de470cSBruce Richardson }
263a9de470cSBruce Richardson
264a9de470cSBruce Richardson if (lost_keys > 0) {
265a9de470cSBruce Richardson printf("%d key lost\n", lost_keys);
266a9de470cSBruce Richardson goto err_free;
267a9de470cSBruce Richardson }
268a9de470cSBruce Richardson
269a9de470cSBruce Richardson printf("No key corrupted during read-write test.\n");
270a9de470cSBruce Richardson
271a9de470cSBruce Richardson unsigned long long int cycles_per_insertion =
272*b6a7e685STyler Retzlaff rte_atomic_load_explicit(&gcycles, rte_memory_order_relaxed) /
273*b6a7e685STyler Retzlaff rte_atomic_load_explicit(&ginsertions, rte_memory_order_relaxed);
274a9de470cSBruce Richardson
275a9de470cSBruce Richardson printf("cycles per insertion and lookup: %llu\n", cycles_per_insertion);
276a9de470cSBruce Richardson
277a9de470cSBruce Richardson rte_free(tbl_rw_test_param.found);
278a9de470cSBruce Richardson rte_free(tbl_rw_test_param.keys);
279a9de470cSBruce Richardson rte_hash_free(tbl_rw_test_param.h);
280a9de470cSBruce Richardson printf("+++++++++Complete function tests+++++++++\n");
281a9de470cSBruce Richardson return 0;
282a9de470cSBruce Richardson
283a9de470cSBruce Richardson err_free:
284a9de470cSBruce Richardson rte_free(tbl_rw_test_param.found);
285a9de470cSBruce Richardson rte_free(tbl_rw_test_param.keys);
286a9de470cSBruce Richardson rte_hash_free(tbl_rw_test_param.h);
287a9de470cSBruce Richardson err:
288a9de470cSBruce Richardson return -1;
289a9de470cSBruce Richardson }
290a9de470cSBruce Richardson
291a9de470cSBruce Richardson static int
test_rw_reader(void * arg)292a9de470cSBruce Richardson test_rw_reader(void *arg)
293a9de470cSBruce Richardson {
294a9de470cSBruce Richardson uint64_t i;
295a9de470cSBruce Richardson uint64_t begin, cycles;
296a9de470cSBruce Richardson uint64_t read_cnt = (uint64_t)((uintptr_t)arg);
297a9de470cSBruce Richardson
298a9de470cSBruce Richardson begin = rte_rdtsc_precise();
299a9de470cSBruce Richardson for (i = 0; i < read_cnt; i++) {
3001d3bb890SAndrzej Ostruszka void *data = arg;
301a9de470cSBruce Richardson rte_hash_lookup_data(tbl_rw_test_param.h,
302a9de470cSBruce Richardson tbl_rw_test_param.keys + i,
303a9de470cSBruce Richardson &data);
304a9de470cSBruce Richardson if (i != (uint64_t)(uintptr_t)data) {
305a9de470cSBruce Richardson printf("lookup find wrong value %"PRIu64","
306a9de470cSBruce Richardson "%"PRIu64"\n", i,
307a9de470cSBruce Richardson (uint64_t)(uintptr_t)data);
308a9de470cSBruce Richardson break;
309a9de470cSBruce Richardson }
310a9de470cSBruce Richardson }
311a9de470cSBruce Richardson
312a9de470cSBruce Richardson cycles = rte_rdtsc_precise() - begin;
313*b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit(&gread_cycles, cycles, rte_memory_order_relaxed);
314*b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit(&greads, i, rte_memory_order_relaxed);
315a9de470cSBruce Richardson return 0;
316a9de470cSBruce Richardson }
317a9de470cSBruce Richardson
318a9de470cSBruce Richardson static int
test_rw_writer(void * arg)319a9de470cSBruce Richardson test_rw_writer(void *arg)
320a9de470cSBruce Richardson {
321a9de470cSBruce Richardson uint64_t i;
322a9de470cSBruce Richardson uint32_t lcore_id = rte_lcore_id();
323a9de470cSBruce Richardson uint64_t begin, cycles;
324a9de470cSBruce Richardson int ret;
325a9de470cSBruce Richardson uint64_t start_coreid = (uint64_t)(uintptr_t)arg;
326a9de470cSBruce Richardson uint64_t offset;
327a9de470cSBruce Richardson
328a9de470cSBruce Richardson for (i = 0; i < rte_lcore_count(); i++) {
329cb056611SStephen Hemminger if (worker_core_ids[i] == lcore_id)
330a9de470cSBruce Richardson break;
331a9de470cSBruce Richardson }
332a9de470cSBruce Richardson
333a9de470cSBruce Richardson offset = TOTAL_INSERT / 2 + (i - (start_coreid)) *
334a9de470cSBruce Richardson tbl_rw_test_param.num_insert;
335a9de470cSBruce Richardson begin = rte_rdtsc_precise();
336a9de470cSBruce Richardson for (i = offset; i < offset + tbl_rw_test_param.num_insert; i++) {
337a9de470cSBruce Richardson ret = rte_hash_add_key_data(tbl_rw_test_param.h,
338a9de470cSBruce Richardson tbl_rw_test_param.keys + i,
339a9de470cSBruce Richardson (void *)((uintptr_t)i));
340a9de470cSBruce Richardson if (ret < 0) {
341a9de470cSBruce Richardson printf("writer failed %"PRIu64"\n", i);
342a9de470cSBruce Richardson break;
343a9de470cSBruce Richardson }
344a9de470cSBruce Richardson }
345a9de470cSBruce Richardson
346a9de470cSBruce Richardson cycles = rte_rdtsc_precise() - begin;
347*b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit(&gwrite_cycles, cycles, rte_memory_order_relaxed);
348*b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit(&gwrites, tbl_rw_test_param.num_insert,
349*b6a7e685STyler Retzlaff rte_memory_order_relaxed);
350a9de470cSBruce Richardson return 0;
351a9de470cSBruce Richardson }
352a9de470cSBruce Richardson
353a9de470cSBruce Richardson static int
test_hash_readwrite_perf(struct perf * perf_results,int use_htm,int reader_faster)354a9de470cSBruce Richardson test_hash_readwrite_perf(struct perf *perf_results, int use_htm,
355a9de470cSBruce Richardson int reader_faster)
356a9de470cSBruce Richardson {
357a9de470cSBruce Richardson unsigned int n;
358a9de470cSBruce Richardson int ret;
359a9de470cSBruce Richardson int start_coreid;
360a9de470cSBruce Richardson uint64_t i, read_cnt;
361a9de470cSBruce Richardson
362a9de470cSBruce Richardson const void *next_key;
363a9de470cSBruce Richardson void *next_data;
364a9de470cSBruce Richardson uint32_t iter;
365a9de470cSBruce Richardson int use_jhash = 0;
366a9de470cSBruce Richardson
367a9de470cSBruce Richardson uint32_t duplicated_keys = 0;
368a9de470cSBruce Richardson uint32_t lost_keys = 0;
369a9de470cSBruce Richardson
370a9de470cSBruce Richardson uint64_t start = 0, end = 0;
371a9de470cSBruce Richardson
372*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&gwrites, 0, rte_memory_order_relaxed);
373*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&greads, 0, rte_memory_order_relaxed);
374a9de470cSBruce Richardson
375*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&gread_cycles, 0, rte_memory_order_relaxed);
376*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&gwrite_cycles, 0, rte_memory_order_relaxed);
377a9de470cSBruce Richardson
37803a0ed1aSHonnappa Nagarahalli if (init_params(0, use_htm, 0, use_jhash) != 0)
379a9de470cSBruce Richardson goto err;
380a9de470cSBruce Richardson
381a9de470cSBruce Richardson /*
382a9de470cSBruce Richardson * Do a readers finish faster or writers finish faster test.
383a9de470cSBruce Richardson * When readers finish faster, we timing the readers, and when writers
384a9de470cSBruce Richardson * finish faster, we timing the writers.
385a9de470cSBruce Richardson * Divided by 10 or 2 is just experimental values to vary the workload
386a9de470cSBruce Richardson * of readers.
387a9de470cSBruce Richardson */
388a9de470cSBruce Richardson if (reader_faster) {
389a9de470cSBruce Richardson printf("++++++Start perf test: reader++++++++\n");
390a9de470cSBruce Richardson read_cnt = TOTAL_INSERT / 10;
391a9de470cSBruce Richardson } else {
392a9de470cSBruce Richardson printf("++++++Start perf test: writer++++++++\n");
393a9de470cSBruce Richardson read_cnt = TOTAL_INSERT / 2;
394a9de470cSBruce Richardson }
395a9de470cSBruce Richardson
396a9de470cSBruce Richardson /* We first test single thread performance */
397a9de470cSBruce Richardson start = rte_rdtsc_precise();
398a9de470cSBruce Richardson /* Insert half of the keys */
399a9de470cSBruce Richardson for (i = 0; i < TOTAL_INSERT / 2; i++) {
400a9de470cSBruce Richardson ret = rte_hash_add_key_data(tbl_rw_test_param.h,
401a9de470cSBruce Richardson tbl_rw_test_param.keys + i,
402a9de470cSBruce Richardson (void *)((uintptr_t)i));
403a9de470cSBruce Richardson if (ret < 0) {
404a9de470cSBruce Richardson printf("Failed to insert half of keys\n");
405a9de470cSBruce Richardson goto err_free;
406a9de470cSBruce Richardson }
407a9de470cSBruce Richardson }
408a9de470cSBruce Richardson end = rte_rdtsc_precise() - start;
409a9de470cSBruce Richardson perf_results->single_write = end / i;
410a9de470cSBruce Richardson
411a9de470cSBruce Richardson start = rte_rdtsc_precise();
412a9de470cSBruce Richardson
413a9de470cSBruce Richardson for (i = 0; i < read_cnt; i++) {
414a9de470cSBruce Richardson void *data;
415a9de470cSBruce Richardson rte_hash_lookup_data(tbl_rw_test_param.h,
416a9de470cSBruce Richardson tbl_rw_test_param.keys + i,
417a9de470cSBruce Richardson &data);
418a9de470cSBruce Richardson if (i != (uint64_t)(uintptr_t)data) {
419a9de470cSBruce Richardson printf("lookup find wrong value"
420a9de470cSBruce Richardson " %"PRIu64",%"PRIu64"\n", i,
421a9de470cSBruce Richardson (uint64_t)(uintptr_t)data);
422a9de470cSBruce Richardson break;
423a9de470cSBruce Richardson }
424a9de470cSBruce Richardson }
425a9de470cSBruce Richardson end = rte_rdtsc_precise() - start;
426a9de470cSBruce Richardson perf_results->single_read = end / i;
427a9de470cSBruce Richardson
428a9de470cSBruce Richardson for (n = 0; n < NUM_TEST; n++) {
429cb056611SStephen Hemminger unsigned int tot_worker_lcore = rte_lcore_count() - 1;
430cb056611SStephen Hemminger if (tot_worker_lcore < core_cnt[n] * 2)
431a9de470cSBruce Richardson goto finish;
432a9de470cSBruce Richardson
433*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&greads, 0, rte_memory_order_relaxed);
434*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&gread_cycles, 0, rte_memory_order_relaxed);
435*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&gwrites, 0, rte_memory_order_relaxed);
436*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&gwrite_cycles, 0, rte_memory_order_relaxed);
437a9de470cSBruce Richardson
438a9de470cSBruce Richardson rte_hash_reset(tbl_rw_test_param.h);
439a9de470cSBruce Richardson
440a9de470cSBruce Richardson tbl_rw_test_param.num_insert = TOTAL_INSERT / 2 / core_cnt[n];
441a9de470cSBruce Richardson tbl_rw_test_param.rounded_tot_insert = TOTAL_INSERT / 2 +
442a9de470cSBruce Richardson tbl_rw_test_param.num_insert *
443a9de470cSBruce Richardson core_cnt[n];
444a9de470cSBruce Richardson
445a9de470cSBruce Richardson for (i = 0; i < TOTAL_INSERT / 2; i++) {
446a9de470cSBruce Richardson ret = rte_hash_add_key_data(tbl_rw_test_param.h,
447a9de470cSBruce Richardson tbl_rw_test_param.keys + i,
448a9de470cSBruce Richardson (void *)((uintptr_t)i));
449a9de470cSBruce Richardson if (ret < 0) {
450a9de470cSBruce Richardson printf("Failed to insert half of keys\n");
451a9de470cSBruce Richardson goto err_free;
452a9de470cSBruce Richardson }
453a9de470cSBruce Richardson }
454a9de470cSBruce Richardson
455a9de470cSBruce Richardson /* Then test multiple thread case but only all reads or
456a9de470cSBruce Richardson * all writes
457a9de470cSBruce Richardson */
458a9de470cSBruce Richardson
459a9de470cSBruce Richardson /* Test only reader cases */
460a9de470cSBruce Richardson for (i = 0; i < core_cnt[n]; i++)
461a9de470cSBruce Richardson rte_eal_remote_launch(test_rw_reader,
462a9de470cSBruce Richardson (void *)(uintptr_t)read_cnt,
463cb056611SStephen Hemminger worker_core_ids[i]);
464a9de470cSBruce Richardson
465a9de470cSBruce Richardson rte_eal_mp_wait_lcore();
466a9de470cSBruce Richardson
467a9de470cSBruce Richardson start_coreid = i;
468a9de470cSBruce Richardson /* Test only writer cases */
469a9de470cSBruce Richardson for (; i < core_cnt[n] * 2; i++)
470a9de470cSBruce Richardson rte_eal_remote_launch(test_rw_writer,
471a9de470cSBruce Richardson (void *)((uintptr_t)start_coreid),
472cb056611SStephen Hemminger worker_core_ids[i]);
473a9de470cSBruce Richardson
474a9de470cSBruce Richardson rte_eal_mp_wait_lcore();
475a9de470cSBruce Richardson
476a9de470cSBruce Richardson if (reader_faster) {
477a9de470cSBruce Richardson unsigned long long int cycles_per_insertion =
478*b6a7e685STyler Retzlaff rte_atomic_load_explicit(&gread_cycles, rte_memory_order_relaxed) /
479*b6a7e685STyler Retzlaff rte_atomic_load_explicit(&greads, rte_memory_order_relaxed);
480a9de470cSBruce Richardson perf_results->read_only[n] = cycles_per_insertion;
481a9de470cSBruce Richardson printf("Reader only: cycles per lookup: %llu\n",
482a9de470cSBruce Richardson cycles_per_insertion);
483a9de470cSBruce Richardson }
484a9de470cSBruce Richardson
485a9de470cSBruce Richardson else {
486a9de470cSBruce Richardson unsigned long long int cycles_per_insertion =
487*b6a7e685STyler Retzlaff rte_atomic_load_explicit(&gwrite_cycles, rte_memory_order_relaxed) /
488*b6a7e685STyler Retzlaff rte_atomic_load_explicit(&gwrites, rte_memory_order_relaxed);
489a9de470cSBruce Richardson perf_results->write_only[n] = cycles_per_insertion;
490a9de470cSBruce Richardson printf("Writer only: cycles per writes: %llu\n",
491a9de470cSBruce Richardson cycles_per_insertion);
492a9de470cSBruce Richardson }
493a9de470cSBruce Richardson
494*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&greads, 0, rte_memory_order_relaxed);
495*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&gread_cycles, 0, rte_memory_order_relaxed);
496*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&gwrites, 0, rte_memory_order_relaxed);
497*b6a7e685STyler Retzlaff rte_atomic_store_explicit(&gwrite_cycles, 0, rte_memory_order_relaxed);
498a9de470cSBruce Richardson
499a9de470cSBruce Richardson rte_hash_reset(tbl_rw_test_param.h);
500a9de470cSBruce Richardson
501a9de470cSBruce Richardson for (i = 0; i < TOTAL_INSERT / 2; i++) {
502a9de470cSBruce Richardson ret = rte_hash_add_key_data(tbl_rw_test_param.h,
503a9de470cSBruce Richardson tbl_rw_test_param.keys + i,
504a9de470cSBruce Richardson (void *)((uintptr_t)i));
505a9de470cSBruce Richardson if (ret < 0) {
506a9de470cSBruce Richardson printf("Failed to insert half of keys\n");
507a9de470cSBruce Richardson goto err_free;
508a9de470cSBruce Richardson }
509a9de470cSBruce Richardson }
510a9de470cSBruce Richardson
511a9de470cSBruce Richardson start_coreid = core_cnt[n];
512a9de470cSBruce Richardson
513a9de470cSBruce Richardson if (reader_faster) {
514a9de470cSBruce Richardson for (i = core_cnt[n]; i < core_cnt[n] * 2; i++)
515a9de470cSBruce Richardson rte_eal_remote_launch(test_rw_writer,
516a9de470cSBruce Richardson (void *)((uintptr_t)start_coreid),
517cb056611SStephen Hemminger worker_core_ids[i]);
518a9de470cSBruce Richardson for (i = 0; i < core_cnt[n]; i++)
519a9de470cSBruce Richardson rte_eal_remote_launch(test_rw_reader,
520a9de470cSBruce Richardson (void *)(uintptr_t)read_cnt,
521cb056611SStephen Hemminger worker_core_ids[i]);
522a9de470cSBruce Richardson } else {
523a9de470cSBruce Richardson for (i = 0; i < core_cnt[n]; i++)
524a9de470cSBruce Richardson rte_eal_remote_launch(test_rw_reader,
525a9de470cSBruce Richardson (void *)(uintptr_t)read_cnt,
526cb056611SStephen Hemminger worker_core_ids[i]);
527a9de470cSBruce Richardson for (; i < core_cnt[n] * 2; i++)
528a9de470cSBruce Richardson rte_eal_remote_launch(test_rw_writer,
529a9de470cSBruce Richardson (void *)((uintptr_t)start_coreid),
530cb056611SStephen Hemminger worker_core_ids[i]);
531a9de470cSBruce Richardson }
532a9de470cSBruce Richardson
533a9de470cSBruce Richardson rte_eal_mp_wait_lcore();
534a9de470cSBruce Richardson
535a9de470cSBruce Richardson iter = 0;
536a9de470cSBruce Richardson memset(tbl_rw_test_param.found, 0, TOTAL_ENTRY);
537a9de470cSBruce Richardson while (rte_hash_iterate(tbl_rw_test_param.h,
538a9de470cSBruce Richardson &next_key, &next_data, &iter) >= 0) {
539a9de470cSBruce Richardson /* Search for the key in the list of keys added .*/
540a9de470cSBruce Richardson i = *(const uint32_t *)next_key;
541a9de470cSBruce Richardson tbl_rw_test_param.found[i]++;
542a9de470cSBruce Richardson }
543a9de470cSBruce Richardson
544a9de470cSBruce Richardson for (i = 0; i < tbl_rw_test_param.rounded_tot_insert; i++) {
545a9de470cSBruce Richardson if (tbl_rw_test_param.keys[i] != RTE_RWTEST_FAIL) {
546a9de470cSBruce Richardson if (tbl_rw_test_param.found[i] > 1) {
547a9de470cSBruce Richardson duplicated_keys++;
548a9de470cSBruce Richardson break;
549a9de470cSBruce Richardson }
550a9de470cSBruce Richardson if (tbl_rw_test_param.found[i] == 0) {
551a9de470cSBruce Richardson lost_keys++;
552a9de470cSBruce Richardson printf("key %"PRIu64" is lost\n", i);
553a9de470cSBruce Richardson break;
554a9de470cSBruce Richardson }
555a9de470cSBruce Richardson }
556a9de470cSBruce Richardson }
557a9de470cSBruce Richardson
558a9de470cSBruce Richardson if (duplicated_keys > 0) {
559a9de470cSBruce Richardson printf("%d key duplicated\n", duplicated_keys);
560a9de470cSBruce Richardson goto err_free;
561a9de470cSBruce Richardson }
562a9de470cSBruce Richardson
563a9de470cSBruce Richardson if (lost_keys > 0) {
564a9de470cSBruce Richardson printf("%d key lost\n", lost_keys);
565a9de470cSBruce Richardson goto err_free;
566a9de470cSBruce Richardson }
567a9de470cSBruce Richardson
568a9de470cSBruce Richardson printf("No key corrupted during read-write test.\n");
569a9de470cSBruce Richardson
570a9de470cSBruce Richardson if (reader_faster) {
571a9de470cSBruce Richardson unsigned long long int cycles_per_insertion =
572*b6a7e685STyler Retzlaff rte_atomic_load_explicit(&gread_cycles, rte_memory_order_relaxed) /
573*b6a7e685STyler Retzlaff rte_atomic_load_explicit(&greads, rte_memory_order_relaxed);
574a9de470cSBruce Richardson perf_results->read_write_r[n] = cycles_per_insertion;
575a9de470cSBruce Richardson printf("Read-write cycles per lookup: %llu\n",
576a9de470cSBruce Richardson cycles_per_insertion);
577a9de470cSBruce Richardson }
578a9de470cSBruce Richardson
579a9de470cSBruce Richardson else {
580a9de470cSBruce Richardson unsigned long long int cycles_per_insertion =
581*b6a7e685STyler Retzlaff rte_atomic_load_explicit(&gwrite_cycles, rte_memory_order_relaxed) /
582*b6a7e685STyler Retzlaff rte_atomic_load_explicit(&gwrites, rte_memory_order_relaxed);
583a9de470cSBruce Richardson perf_results->read_write_w[n] = cycles_per_insertion;
584a9de470cSBruce Richardson printf("Read-write cycles per writes: %llu\n",
585a9de470cSBruce Richardson cycles_per_insertion);
586a9de470cSBruce Richardson }
587a9de470cSBruce Richardson }
588a9de470cSBruce Richardson
589a9de470cSBruce Richardson finish:
590a9de470cSBruce Richardson rte_free(tbl_rw_test_param.found);
591a9de470cSBruce Richardson rte_free(tbl_rw_test_param.keys);
592a9de470cSBruce Richardson rte_hash_free(tbl_rw_test_param.h);
593a9de470cSBruce Richardson return 0;
594a9de470cSBruce Richardson
595a9de470cSBruce Richardson err_free:
596a9de470cSBruce Richardson rte_free(tbl_rw_test_param.found);
597a9de470cSBruce Richardson rte_free(tbl_rw_test_param.keys);
598a9de470cSBruce Richardson rte_hash_free(tbl_rw_test_param.h);
599a9de470cSBruce Richardson
600a9de470cSBruce Richardson err:
601a9de470cSBruce Richardson return -1;
602a9de470cSBruce Richardson }
603a9de470cSBruce Richardson
604a9de470cSBruce Richardson static int
test_hash_rw_perf_main(void)605f6208425SAmit Gupta test_hash_rw_perf_main(void)
606a9de470cSBruce Richardson {
607a9de470cSBruce Richardson /*
608a9de470cSBruce Richardson * Variables used to choose different tests.
609a9de470cSBruce Richardson * use_htm indicates if hardware transactional memory should be used.
610a9de470cSBruce Richardson * reader_faster indicates if the reader threads should finish earlier
611a9de470cSBruce Richardson * than writer threads. This is to timing either reader threads or
612a9de470cSBruce Richardson * writer threads for performance numbers.
613a9de470cSBruce Richardson */
614f6208425SAmit Gupta int use_htm, reader_faster;
615a9de470cSBruce Richardson unsigned int i = 0, core_id = 0;
616a9de470cSBruce Richardson
617e0f4a0edSDavid Marchand if (rte_lcore_count() < 3) {
618e0f4a0edSDavid Marchand printf("Not enough cores for hash_readwrite_autotest, expecting at least 3\n");
619e0f4a0edSDavid Marchand return TEST_SKIPPED;
620a9de470cSBruce Richardson }
621a9de470cSBruce Richardson
622cb056611SStephen Hemminger RTE_LCORE_FOREACH_WORKER(core_id) {
623cb056611SStephen Hemminger worker_core_ids[i] = core_id;
624a9de470cSBruce Richardson i++;
625a9de470cSBruce Richardson }
626a9de470cSBruce Richardson
627a9de470cSBruce Richardson setlocale(LC_NUMERIC, "");
628a9de470cSBruce Richardson
629a9de470cSBruce Richardson if (rte_tm_supported()) {
630a9de470cSBruce Richardson printf("Hardware transactional memory (lock elision) "
631a9de470cSBruce Richardson "is supported\n");
632a9de470cSBruce Richardson
633a9de470cSBruce Richardson printf("Test read-write with Hardware transactional memory\n");
634a9de470cSBruce Richardson
635a9de470cSBruce Richardson use_htm = 1;
636a9de470cSBruce Richardson
637a9de470cSBruce Richardson reader_faster = 1;
638a9de470cSBruce Richardson if (test_hash_readwrite_perf(&htm_results, use_htm,
639a9de470cSBruce Richardson reader_faster) < 0)
640a9de470cSBruce Richardson return -1;
641a9de470cSBruce Richardson
642a9de470cSBruce Richardson reader_faster = 0;
643a9de470cSBruce Richardson if (test_hash_readwrite_perf(&htm_results, use_htm,
644a9de470cSBruce Richardson reader_faster) < 0)
645a9de470cSBruce Richardson return -1;
646a9de470cSBruce Richardson } else {
647a9de470cSBruce Richardson printf("Hardware transactional memory (lock elision) "
648a9de470cSBruce Richardson "is NOT supported\n");
649a9de470cSBruce Richardson }
650a9de470cSBruce Richardson
651a9de470cSBruce Richardson printf("Test read-write without Hardware transactional memory\n");
652a9de470cSBruce Richardson use_htm = 0;
653a9de470cSBruce Richardson
654a9de470cSBruce Richardson reader_faster = 1;
655a9de470cSBruce Richardson if (test_hash_readwrite_perf(&non_htm_results, use_htm,
656a9de470cSBruce Richardson reader_faster) < 0)
657a9de470cSBruce Richardson return -1;
658a9de470cSBruce Richardson reader_faster = 0;
659a9de470cSBruce Richardson if (test_hash_readwrite_perf(&non_htm_results, use_htm,
660a9de470cSBruce Richardson reader_faster) < 0)
661a9de470cSBruce Richardson return -1;
662a9de470cSBruce Richardson
663a9de470cSBruce Richardson printf("================\n");
664a9de470cSBruce Richardson printf("Results summary:\n");
665a9de470cSBruce Richardson printf("================\n");
666a9de470cSBruce Richardson
667af0892afSStanislaw Kardach printf("HTM:\n");
668a9de470cSBruce Richardson printf(" single read: %u\n", htm_results.single_read);
669a9de470cSBruce Richardson printf(" single write: %u\n", htm_results.single_write);
670af0892afSStanislaw Kardach printf("non HTM:\n");
671af0892afSStanislaw Kardach printf(" single read: %u\n", non_htm_results.single_read);
672af0892afSStanislaw Kardach printf(" single write: %u\n", non_htm_results.single_write);
673a9de470cSBruce Richardson for (i = 0; i < NUM_TEST; i++) {
674a9de470cSBruce Richardson printf("+++ core_cnt: %u +++\n", core_cnt[i]);
675a9de470cSBruce Richardson printf("HTM:\n");
676a9de470cSBruce Richardson printf(" read only: %u\n", htm_results.read_only[i]);
677a9de470cSBruce Richardson printf(" write only: %u\n", htm_results.write_only[i]);
678a9de470cSBruce Richardson printf(" read-write read: %u\n", htm_results.read_write_r[i]);
679a9de470cSBruce Richardson printf(" read-write write: %u\n", htm_results.read_write_w[i]);
680a9de470cSBruce Richardson
681a9de470cSBruce Richardson printf("non HTM:\n");
682a9de470cSBruce Richardson printf(" read only: %u\n", non_htm_results.read_only[i]);
683a9de470cSBruce Richardson printf(" write only: %u\n", non_htm_results.write_only[i]);
684a9de470cSBruce Richardson printf(" read-write read: %u\n",
685a9de470cSBruce Richardson non_htm_results.read_write_r[i]);
686a9de470cSBruce Richardson printf(" read-write write: %u\n",
687a9de470cSBruce Richardson non_htm_results.read_write_w[i]);
688a9de470cSBruce Richardson }
689a9de470cSBruce Richardson
690a9de470cSBruce Richardson return 0;
691a9de470cSBruce Richardson }
692a9de470cSBruce Richardson
693f6208425SAmit Gupta static int
test_hash_rw_func_main(void)694f6208425SAmit Gupta test_hash_rw_func_main(void)
695f6208425SAmit Gupta {
696f6208425SAmit Gupta /*
697f6208425SAmit Gupta * Variables used to choose different tests.
698f6208425SAmit Gupta * use_htm indicates if hardware transactional memory should be used.
699f6208425SAmit Gupta * reader_faster indicates if the reader threads should finish earlier
700f6208425SAmit Gupta * than writer threads. This is to timing either reader threads or
701f6208425SAmit Gupta * writer threads for performance numbers.
702f6208425SAmit Gupta */
703f6208425SAmit Gupta unsigned int i = 0, core_id = 0;
704f6208425SAmit Gupta
705f6208425SAmit Gupta if (rte_lcore_count() < 3) {
706f6208425SAmit Gupta printf("Not enough cores for hash_readwrite_autotest, expecting at least 3\n");
707f6208425SAmit Gupta return TEST_SKIPPED;
708f6208425SAmit Gupta }
709f6208425SAmit Gupta
710cb056611SStephen Hemminger RTE_LCORE_FOREACH_WORKER(core_id) {
711cb056611SStephen Hemminger worker_core_ids[i] = core_id;
712f6208425SAmit Gupta i++;
713f6208425SAmit Gupta }
714f6208425SAmit Gupta
715f6208425SAmit Gupta setlocale(LC_NUMERIC, "");
716f6208425SAmit Gupta
717f6208425SAmit Gupta if (rte_tm_supported()) {
718f6208425SAmit Gupta printf("Hardware transactional memory (lock elision) "
719f6208425SAmit Gupta "is supported\n");
720f6208425SAmit Gupta
721f6208425SAmit Gupta printf("Test read-write with Hardware transactional memory\n");
722f6208425SAmit Gupta
72303a0ed1aSHonnappa Nagarahalli /* htm = 1, rw_lf = 0, ext = 0 */
72403a0ed1aSHonnappa Nagarahalli if (test_hash_readwrite_functional(1, 0, 0) < 0)
725f6208425SAmit Gupta return -1;
726f6208425SAmit Gupta
72703a0ed1aSHonnappa Nagarahalli /* htm = 1, rw_lf = 1, ext = 0 */
72803a0ed1aSHonnappa Nagarahalli if (test_hash_readwrite_functional(1, 1, 0) < 0)
729f6208425SAmit Gupta return -1;
730f6208425SAmit Gupta
73103a0ed1aSHonnappa Nagarahalli /* htm = 1, rw_lf = 0, ext = 1 */
73203a0ed1aSHonnappa Nagarahalli if (test_hash_readwrite_functional(1, 0, 1) < 0)
73303a0ed1aSHonnappa Nagarahalli return -1;
73403a0ed1aSHonnappa Nagarahalli
73503a0ed1aSHonnappa Nagarahalli /* htm = 1, rw_lf = 1, ext = 1 */
73603a0ed1aSHonnappa Nagarahalli if (test_hash_readwrite_functional(1, 1, 1) < 0)
73703a0ed1aSHonnappa Nagarahalli return -1;
738f6208425SAmit Gupta } else {
739f6208425SAmit Gupta printf("Hardware transactional memory (lock elision) "
740f6208425SAmit Gupta "is NOT supported\n");
741f6208425SAmit Gupta }
742f6208425SAmit Gupta
743f6208425SAmit Gupta printf("Test read-write without Hardware transactional memory\n");
74403a0ed1aSHonnappa Nagarahalli /* htm = 0, rw_lf = 0, ext = 0 */
74503a0ed1aSHonnappa Nagarahalli if (test_hash_readwrite_functional(0, 0, 0) < 0)
746f6208425SAmit Gupta return -1;
747f6208425SAmit Gupta
74803a0ed1aSHonnappa Nagarahalli /* htm = 0, rw_lf = 1, ext = 0 */
74903a0ed1aSHonnappa Nagarahalli if (test_hash_readwrite_functional(0, 1, 0) < 0)
75003a0ed1aSHonnappa Nagarahalli return -1;
75103a0ed1aSHonnappa Nagarahalli
75203a0ed1aSHonnappa Nagarahalli /* htm = 0, rw_lf = 0, ext = 1 */
75303a0ed1aSHonnappa Nagarahalli if (test_hash_readwrite_functional(0, 0, 1) < 0)
75403a0ed1aSHonnappa Nagarahalli return -1;
75503a0ed1aSHonnappa Nagarahalli
75603a0ed1aSHonnappa Nagarahalli /* htm = 0, rw_lf = 1, ext = 1 */
75703a0ed1aSHonnappa Nagarahalli if (test_hash_readwrite_functional(0, 1, 1) < 0)
758f6208425SAmit Gupta return -1;
759f6208425SAmit Gupta
760f6208425SAmit Gupta return 0;
761f6208425SAmit Gupta }
762f6208425SAmit Gupta
763e0a8442cSBruce Richardson REGISTER_FAST_TEST(hash_readwrite_func_autotest, false, true, test_hash_rw_func_main);
764e0a8442cSBruce Richardson REGISTER_PERF_TEST(hash_readwrite_perf_autotest, test_hash_rw_perf_main);
765