Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /*
3 : : * Copyright 2013-2019 IBM Corp.
4 : : */
5 : :
6 : : #include <inttypes.h>
7 : : #include <stdbool.h>
8 : : #include <stddef.h>
9 : : #include <assert.h>
10 : : #include <errno.h>
11 : : #include <stdlib.h>
12 : :
13 : : static bool zalloc_should_fail = false;
14 : : static int zalloc_should_fail_after = 0;
15 : :
16 : : /* Fake top_of_ram -- needed for API's */
17 : : unsigned long top_of_ram = 0xffffffffffffffffULL;
18 : :
19 : 32 : static void *zalloc(size_t size)
20 : : {
21 : 32 : if (zalloc_should_fail && zalloc_should_fail_after == 0) {
22 : 2 : errno = ENOMEM;
23 : 2 : return NULL;
24 : : }
25 : 30 : if (zalloc_should_fail_after > 0)
26 : 3 : zalloc_should_fail_after--;
27 : :
28 : 30 : return calloc(size, 1);
29 : : }
30 : :
31 : : #include "../opal-msg.c"
32 : : #include <skiboot.h>
33 : :
34 : 80 : void lock_caller(struct lock *l, const char *caller)
35 : : {
36 : : (void)caller;
37 : 80 : assert(!l->lock_val);
38 : 80 : l->lock_val = 1;
39 : 80 : }
40 : :
41 : 80 : void unlock(struct lock *l)
42 : : {
43 : 80 : assert(l->lock_val);
44 : 80 : l->lock_val = 0;
45 : 80 : }
46 : :
47 : 54 : void opal_update_pending_evt(uint64_t evt_mask, uint64_t evt_values)
48 : : {
49 : : (void)evt_mask;
50 : : (void)evt_values;
51 : 54 : }
52 : :
53 : : static long magic = 8097883813087437089UL;
54 : 2 : static void callback(void *data, int status)
55 : : {
56 : 2 : assert((status == OPAL_SUCCESS || status == OPAL_PARTIAL));
57 : 2 : assert(*(uint64_t *)data == magic);
58 : 2 : }
59 : :
60 : 81 : static size_t list_count(struct list_head *list)
61 : : {
62 : 81 : size_t count = 0;
63 : : struct opal_msg_entry *dummy;
64 : :
65 : 1073 : list_for_each(list, dummy, link)
66 : 992 : count++;
67 : 81 : return count;
68 : : }
69 : :
70 : 1 : int main(void)
71 : : {
72 : : struct opal_msg_entry* entry;
73 : 1 : int free_size = OPAL_MAX_MSGS;
74 : 1 : int nfree = free_size;
75 : 1 : int npending = 0;
76 : : int r;
77 : : static struct opal_msg m;
78 : 1 : uint64_t *m_ptr = (uint64_t *)&m;
79 : :
80 : 1 : zalloc_should_fail = true;
81 : 1 : zalloc_should_fail_after = 3;
82 : 1 : opal_init_msg();
83 : :
84 : 1 : zalloc_should_fail = false;
85 : 1 : opal_init_msg();
86 : :
87 : 1 : assert(list_count(&msg_pending_list) == npending);
88 : 1 : assert(list_count(&msg_free_list) == nfree);
89 : :
90 : : /* Callback. */
91 : 1 : r = opal_queue_msg(0, &magic, callback, (u64)0, (u64)1, (u64)2);
92 : 1 : assert(r == 0);
93 : :
94 : 1 : assert(list_count(&msg_pending_list) == ++npending);
95 : 1 : assert(list_count(&msg_free_list) == --nfree);
96 : :
97 : 1 : r = opal_get_msg(m_ptr, sizeof(m));
98 : 1 : assert(r == 0);
99 : :
100 : 1 : assert(m.params[0] == 0);
101 : 1 : assert(m.params[1] == 1);
102 : 1 : assert(m.params[2] == 2);
103 : :
104 : 1 : assert(list_count(&msg_pending_list) == --npending);
105 : 1 : assert(list_count(&msg_free_list) == ++nfree);
106 : :
107 : : /* No params. */
108 : 1 : r = opal_queue_msg(0, NULL, NULL);
109 : 1 : assert(r == 0);
110 : :
111 : 1 : assert(list_count(&msg_pending_list) == ++npending);
112 : 1 : assert(list_count(&msg_free_list) == --nfree);
113 : :
114 : 1 : r = opal_get_msg(m_ptr, sizeof(m));
115 : 1 : assert(r == 0);
116 : :
117 : 1 : assert(list_count(&msg_pending_list) == --npending);
118 : 1 : assert(list_count(&msg_free_list) == ++nfree);
119 : :
120 : : /* > 8 params (ARRAY_SIZE(entry->msg.params) */
121 : 1 : r = opal_queue_msg(0, NULL, NULL, 0, 1, 2, 3, 4, 5, 6, 7, 0xBADDA7A);
122 : 1 : assert(r == 0);
123 : :
124 : 1 : assert(list_count(&msg_pending_list) == ++npending);
125 : 1 : assert(list_count(&msg_free_list) == nfree);
126 : :
127 : 1 : r = opal_get_msg(m_ptr, sizeof(m));
128 : 1 : assert(r == OPAL_PARTIAL);
129 : :
130 : 1 : assert(list_count(&msg_pending_list) == --npending);
131 : 1 : assert(list_count(&msg_free_list) == nfree);
132 : :
133 : : /* Return OPAL_PARTIAL to callback */
134 : 1 : r = opal_queue_msg(0, &magic, callback, 0, 1, 2, 3, 4, 5, 6, 7, 0xBADDA7A);
135 : 1 : assert(r == 0);
136 : :
137 : 1 : assert(list_count(&msg_pending_list) == ++npending);
138 : 1 : assert(list_count(&msg_free_list) == nfree);
139 : :
140 : 1 : r = opal_get_msg(m_ptr, sizeof(m));
141 : 1 : assert(r == OPAL_PARTIAL);
142 : :
143 : 1 : assert(list_count(&msg_pending_list) == --npending);
144 : 1 : assert(list_count(&msg_free_list) == nfree);
145 : :
146 : : /* return OPAL_PARAMETER */
147 : 1 : r = _opal_queue_msg(0, NULL, NULL, OPAL_MSG_SIZE, m_ptr);
148 : 1 : assert(r == OPAL_PARAMETER);
149 : :
150 : 1 : assert(m.params[0] == 0);
151 : 1 : assert(m.params[1] == 1);
152 : 1 : assert(m.params[2] == 2);
153 : 1 : assert(m.params[3] == 3);
154 : 1 : assert(m.params[4] == 4);
155 : 1 : assert(m.params[5] == 5);
156 : 1 : assert(m.params[6] == 6);
157 : 1 : assert(m.params[7] == 7);
158 : :
159 : : /* 8 params (ARRAY_SIZE(entry->msg.params) */
160 : 1 : r = opal_queue_msg(0, NULL, NULL, 0, 10, 20, 30, 40, 50, 60, 70);
161 : 1 : assert(r == 0);
162 : :
163 : 1 : assert(list_count(&msg_pending_list) == ++npending);
164 : 1 : assert(list_count(&msg_free_list) == --nfree);
165 : :
166 : 1 : r = opal_get_msg(m_ptr, sizeof(m));
167 : 1 : assert(r == 0);
168 : :
169 : 1 : assert(list_count(&msg_pending_list) == --npending);
170 : 1 : assert(list_count(&msg_free_list) == ++nfree);
171 : :
172 : 1 : assert(m.params[0] == 0);
173 : 1 : assert(m.params[1] == 10);
174 : 1 : assert(m.params[2] == 20);
175 : 1 : assert(m.params[3] == 30);
176 : 1 : assert(m.params[4] == 40);
177 : 1 : assert(m.params[5] == 50);
178 : 1 : assert(m.params[6] == 60);
179 : 1 : assert(m.params[7] == 70);
180 : :
181 : : /* Full list (no free nodes in pending). */
182 : 25 : while (nfree > 0) {
183 : 24 : r = opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL);
184 : 24 : assert(r == 0);
185 : 24 : assert(list_count(&msg_pending_list) == ++npending);
186 : 24 : assert(list_count(&msg_free_list) == --nfree);
187 : : }
188 : 1 : assert(list_count(&msg_free_list) == 0);
189 : 1 : assert(nfree == 0);
190 : 1 : assert(npending == OPAL_MAX_MSGS);
191 : :
192 : 1 : r = opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL);
193 : 1 : assert(r == 0);
194 : :
195 : 1 : assert(list_count(&msg_pending_list) == OPAL_MAX_MSGS+1);
196 : 1 : assert(list_count(&msg_pending_list) == ++npending);
197 : 1 : assert(list_count(&msg_free_list) == nfree);
198 : :
199 : : /* Make zalloc fail to test error handling. */
200 : 1 : zalloc_should_fail = true;
201 : 1 : r = opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL);
202 : 1 : assert(r == OPAL_RESOURCE);
203 : :
204 : 1 : assert(list_count(&msg_pending_list) == OPAL_MAX_MSGS+1);
205 : 1 : assert(list_count(&msg_pending_list) == npending);
206 : 1 : assert(list_count(&msg_free_list) == nfree);
207 : :
208 : : /* Empty list (no nodes). */
209 : 26 : while(!list_empty(&msg_pending_list)) {
210 : 25 : r = opal_get_msg(m_ptr, sizeof(m));
211 : 25 : assert(r == 0);
212 : 25 : npending--;
213 : 25 : nfree++;
214 : : }
215 : 1 : assert(list_count(&msg_pending_list) == npending);
216 : 1 : assert(list_count(&msg_free_list) == nfree);
217 : 1 : assert(npending == 0);
218 : 1 : assert(nfree == OPAL_MAX_MSGS+1);
219 : :
220 : 1 : r = opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL);
221 : 1 : assert(r == 0);
222 : :
223 : 1 : assert(list_count(&msg_pending_list) == ++npending);
224 : 1 : assert(list_count(&msg_free_list) == --nfree);
225 : :
226 : : /* Request invalid size. */
227 : 1 : r = opal_get_msg(m_ptr, sizeof(m) - 1);
228 : 1 : assert(r == OPAL_PARAMETER);
229 : :
230 : : /* Pass null buffer. */
231 : 1 : r = opal_get_msg(NULL, sizeof(m));
232 : 1 : assert(r == OPAL_PARAMETER);
233 : :
234 : : /* Get msg when none are pending. */
235 : 1 : r = opal_get_msg(m_ptr, sizeof(m));
236 : 1 : assert(r == 0);
237 : :
238 : 1 : r = opal_get_msg(m_ptr, sizeof(m));
239 : 1 : assert(r == OPAL_RESOURCE);
240 : :
241 : : #define test_queue_num(type, val) \
242 : : r = opal_queue_msg(0, NULL, NULL, \
243 : : (type)val, (type)val, (type)val, (type)val, \
244 : : (type)val, (type)val, (type)val, (type)val); \
245 : : assert(r == 0); \
246 : : opal_get_msg(m_ptr, sizeof(m)); \
247 : : assert(r == OPAL_SUCCESS); \
248 : : assert(m.params[0] == (type)val); \
249 : : assert(m.params[1] == (type)val); \
250 : : assert(m.params[2] == (type)val); \
251 : : assert(m.params[3] == (type)val); \
252 : : assert(m.params[4] == (type)val); \
253 : : assert(m.params[5] == (type)val); \
254 : : assert(m.params[6] == (type)val); \
255 : : assert(m.params[7] == (type)val)
256 : :
257 : : /* Test types of various widths */
258 : 1 : test_queue_num(u64, -1);
259 : 1 : test_queue_num(s64, -1);
260 : 1 : test_queue_num(u32, -1);
261 : 1 : test_queue_num(s32, -1);
262 : 1 : test_queue_num(u16, -1);
263 : 1 : test_queue_num(s16, -1);
264 : 1 : test_queue_num(u8, -1);
265 : 1 : test_queue_num(s8, -1);
266 : :
267 : : /* Clean up the list to keep valgrind happy. */
268 : 26 : while(!list_empty(&msg_free_list)) {
269 : 25 : entry = list_pop(&msg_free_list, struct opal_msg_entry, link);
270 : 25 : assert(entry);
271 : 25 : free(entry);
272 : : }
273 : :
274 : 1 : while(!list_empty(&msg_pending_list)) {
275 : 0 : entry = list_pop(&msg_pending_list, struct opal_msg_entry, link);
276 : 0 : assert(entry);
277 : 0 : free(entry);
278 : : }
279 : :
280 : 1 : return 0;
281 : : }
|