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