xref: /dpdk/app/test/test_memory.c (revision e0a8442ccd15bafbb7eb150c35331c8e3b828c53)
1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson  * Copyright(c) 2010-2014 Intel Corporation
3a9de470cSBruce Richardson  */
4a9de470cSBruce Richardson 
5a9de470cSBruce Richardson #include <stdio.h>
6a9de470cSBruce Richardson #include <stdint.h>
7a9de470cSBruce Richardson 
8a9de470cSBruce Richardson #include <rte_eal.h>
9086d4264SBruce Richardson #include <rte_errno.h>
10a9de470cSBruce Richardson #include <rte_memory.h>
11a9de470cSBruce Richardson #include <rte_common.h>
12a9de470cSBruce Richardson #include <rte_memzone.h>
13a9de470cSBruce Richardson 
14a9de470cSBruce Richardson #include "test.h"
15a9de470cSBruce Richardson 
16a9de470cSBruce Richardson /*
17a9de470cSBruce Richardson  * Memory
18a9de470cSBruce Richardson  * ======
19a9de470cSBruce Richardson  *
20a9de470cSBruce Richardson  * - Dump the mapped memory. The python-expect script checks that at
21a9de470cSBruce Richardson  *   least one line is dumped.
22a9de470cSBruce Richardson  *
23a9de470cSBruce Richardson  * - Check that memory size is different than 0.
24a9de470cSBruce Richardson  *
25a9de470cSBruce Richardson  * - Try to read all memory; it should not segfault.
26a9de470cSBruce Richardson  */
27a9de470cSBruce Richardson 
2848ff13efSDavid Marchand /*
2948ff13efSDavid Marchand  * ASan complains about accessing unallocated memory.
3048ff13efSDavid Marchand  * See: https://bugs.dpdk.org/show_bug.cgi?id=880
3148ff13efSDavid Marchand  */
3248ff13efSDavid Marchand __rte_no_asan
33a9de470cSBruce Richardson static int
check_mem(const struct rte_memseg_list * msl __rte_unused,const struct rte_memseg * ms,void * arg __rte_unused)34a9de470cSBruce Richardson check_mem(const struct rte_memseg_list *msl __rte_unused,
35a9de470cSBruce Richardson 		const struct rte_memseg *ms, void *arg __rte_unused)
36a9de470cSBruce Richardson {
37a9de470cSBruce Richardson 	volatile uint8_t *mem = (volatile uint8_t *) ms->addr;
38a9de470cSBruce Richardson 	size_t i, max = ms->len;
39a9de470cSBruce Richardson 
40a9de470cSBruce Richardson 	for (i = 0; i < max; i++, mem++)
41a9de470cSBruce Richardson 		*mem;
42a9de470cSBruce Richardson 	return 0;
43a9de470cSBruce Richardson }
44a9de470cSBruce Richardson 
45a9de470cSBruce Richardson static int
check_seg_fds(const struct rte_memseg_list * msl,const struct rte_memseg * ms,void * arg __rte_unused)46a9de470cSBruce Richardson check_seg_fds(const struct rte_memseg_list *msl, const struct rte_memseg *ms,
47a9de470cSBruce Richardson 		void *arg __rte_unused)
48a9de470cSBruce Richardson {
49a9de470cSBruce Richardson 	size_t offset;
50a9de470cSBruce Richardson 	int ret;
51a9de470cSBruce Richardson 
52a9de470cSBruce Richardson 	/* skip external segments */
53a9de470cSBruce Richardson 	if (msl->external)
54a9de470cSBruce Richardson 		return 0;
55a9de470cSBruce Richardson 
56a9de470cSBruce Richardson 	/* try segment fd first. we're in a callback, so thread-unsafe */
57a9de470cSBruce Richardson 	ret = rte_memseg_get_fd_thread_unsafe(ms);
58a9de470cSBruce Richardson 	if (ret < 0) {
59a9de470cSBruce Richardson 		/* ENOTSUP means segment is valid, but there is not support for
60a9de470cSBruce Richardson 		 * segment fd API (e.g. on FreeBSD).
61a9de470cSBruce Richardson 		 */
62086d4264SBruce Richardson 		if (rte_errno == ENOTSUP)
63a9de470cSBruce Richardson 			return 1;
64a9de470cSBruce Richardson 		/* all other errors are treated as failures */
65a9de470cSBruce Richardson 		return -1;
66a9de470cSBruce Richardson 	}
67a9de470cSBruce Richardson 
68a9de470cSBruce Richardson 	/* we're able to get memseg fd - try getting its offset */
69a9de470cSBruce Richardson 	ret = rte_memseg_get_fd_offset_thread_unsafe(ms, &offset);
70a9de470cSBruce Richardson 	if (ret < 0) {
71068cdfaeSJie Zhou 		if (rte_errno == ENOTSUP)
72a9de470cSBruce Richardson 			return 1;
73a9de470cSBruce Richardson 		return -1;
74a9de470cSBruce Richardson 	}
75a9de470cSBruce Richardson 	return 0;
76a9de470cSBruce Richardson }
77a9de470cSBruce Richardson 
78a9de470cSBruce Richardson static int
test_memory(void)79a9de470cSBruce Richardson test_memory(void)
80a9de470cSBruce Richardson {
81a9de470cSBruce Richardson 	uint64_t s;
82a9de470cSBruce Richardson 	int ret;
83a9de470cSBruce Richardson 
84a9de470cSBruce Richardson 	/*
85a9de470cSBruce Richardson 	 * dump the mapped memory: the python-expect script checks
86a9de470cSBruce Richardson 	 * that at least one line is dumped
87a9de470cSBruce Richardson 	 */
88a9de470cSBruce Richardson 	printf("Dump memory layout\n");
89a9de470cSBruce Richardson 	rte_dump_physmem_layout(stdout);
90a9de470cSBruce Richardson 
91a9de470cSBruce Richardson 	/* check that memory size is != 0 */
92a9de470cSBruce Richardson 	s = rte_eal_get_physmem_size();
93a9de470cSBruce Richardson 	if (s == 0) {
94a9de470cSBruce Richardson 		printf("No memory detected\n");
95a9de470cSBruce Richardson 		return -1;
96a9de470cSBruce Richardson 	}
97a9de470cSBruce Richardson 
98a9de470cSBruce Richardson 	/* try to read memory (should not segfault) */
99a9de470cSBruce Richardson 	rte_memseg_walk(check_mem, NULL);
100a9de470cSBruce Richardson 
101a9de470cSBruce Richardson 	/* check segment fd support */
102a9de470cSBruce Richardson 	ret = rte_memseg_walk(check_seg_fds, NULL);
103a9de470cSBruce Richardson 	if (ret == 1) {
104a9de470cSBruce Richardson 		printf("Segment fd API is unsupported\n");
105a9de470cSBruce Richardson 	} else if (ret == -1) {
106a9de470cSBruce Richardson 		printf("Error getting segment fd's\n");
107a9de470cSBruce Richardson 		return -1;
108a9de470cSBruce Richardson 	}
109a9de470cSBruce Richardson 
110a9de470cSBruce Richardson 	return 0;
111a9de470cSBruce Richardson }
112a9de470cSBruce Richardson 
113*e0a8442cSBruce Richardson REGISTER_FAST_TEST(memory_autotest, false, true, test_memory);
114