@@ -89,6 +89,100 @@ static void test_hashmap_sanity(int i, void *data)
89
89
close (map_fd );
90
90
}
91
91
92
+ /* sanity tests for percpu map API */
93
+ static void test_percpu_hashmap_sanity (int task , void * data )
94
+ {
95
+ long long key , next_key ;
96
+ int expected_key_mask = 0 ;
97
+ unsigned int nr_cpus = sysconf (_SC_NPROCESSORS_CONF );
98
+ long long value [nr_cpus ];
99
+ int map_fd , i ;
100
+
101
+ map_fd = bpf_create_map (BPF_MAP_TYPE_PERCPU_HASH , sizeof (key ),
102
+ sizeof (value [0 ]), 2 );
103
+ if (map_fd < 0 ) {
104
+ printf ("failed to create hashmap '%s'\n" , strerror (errno ));
105
+ exit (1 );
106
+ }
107
+
108
+ for (i = 0 ; i < nr_cpus ; i ++ )
109
+ value [i ] = i + 100 ;
110
+ key = 1 ;
111
+ /* insert key=1 element */
112
+ assert (!(expected_key_mask & key ));
113
+ assert (bpf_update_elem (map_fd , & key , value , BPF_ANY ) == 0 );
114
+ expected_key_mask |= key ;
115
+
116
+ /* BPF_NOEXIST means: add new element if it doesn't exist */
117
+ assert (bpf_update_elem (map_fd , & key , value , BPF_NOEXIST ) == -1 &&
118
+ /* key=1 already exists */
119
+ errno == EEXIST );
120
+
121
+ /* -1 is an invalid flag */
122
+ assert (bpf_update_elem (map_fd , & key , value , -1 ) == -1 &&
123
+ errno == EINVAL );
124
+
125
+ /* check that key=1 can be found. value could be 0 if the lookup
126
+ * was run from a different cpu.
127
+ */
128
+ value [0 ] = 1 ;
129
+ assert (bpf_lookup_elem (map_fd , & key , value ) == 0 && value [0 ] == 100 );
130
+
131
+ key = 2 ;
132
+ /* check that key=2 is not found */
133
+ assert (bpf_lookup_elem (map_fd , & key , value ) == -1 && errno == ENOENT );
134
+
135
+ /* BPF_EXIST means: update existing element */
136
+ assert (bpf_update_elem (map_fd , & key , value , BPF_EXIST ) == -1 &&
137
+ /* key=2 is not there */
138
+ errno == ENOENT );
139
+
140
+ /* insert key=2 element */
141
+ assert (!(expected_key_mask & key ));
142
+ assert (bpf_update_elem (map_fd , & key , value , BPF_NOEXIST ) == 0 );
143
+ expected_key_mask |= key ;
144
+
145
+ /* key=1 and key=2 were inserted, check that key=0 cannot be inserted
146
+ * due to max_entries limit
147
+ */
148
+ key = 0 ;
149
+ assert (bpf_update_elem (map_fd , & key , value , BPF_NOEXIST ) == -1 &&
150
+ errno == E2BIG );
151
+
152
+ /* check that key = 0 doesn't exist */
153
+ assert (bpf_delete_elem (map_fd , & key ) == -1 && errno == ENOENT );
154
+
155
+ /* iterate over two elements */
156
+ while (!bpf_get_next_key (map_fd , & key , & next_key )) {
157
+ assert ((expected_key_mask & next_key ) == next_key );
158
+ expected_key_mask &= ~next_key ;
159
+
160
+ assert (bpf_lookup_elem (map_fd , & next_key , value ) == 0 );
161
+ for (i = 0 ; i < nr_cpus ; i ++ )
162
+ assert (value [i ] == i + 100 );
163
+
164
+ key = next_key ;
165
+ }
166
+ assert (errno == ENOENT );
167
+
168
+ /* Update with BPF_EXIST */
169
+ key = 1 ;
170
+ assert (bpf_update_elem (map_fd , & key , value , BPF_EXIST ) == 0 );
171
+
172
+ /* delete both elements */
173
+ key = 1 ;
174
+ assert (bpf_delete_elem (map_fd , & key ) == 0 );
175
+ key = 2 ;
176
+ assert (bpf_delete_elem (map_fd , & key ) == 0 );
177
+ assert (bpf_delete_elem (map_fd , & key ) == -1 && errno == ENOENT );
178
+
179
+ key = 0 ;
180
+ /* check that map is empty */
181
+ assert (bpf_get_next_key (map_fd , & key , & next_key ) == -1 &&
182
+ errno == ENOENT );
183
+ close (map_fd );
184
+ }
185
+
92
186
static void test_arraymap_sanity (int i , void * data )
93
187
{
94
188
int key , next_key , map_fd ;
@@ -209,6 +303,7 @@ static void run_parallel(int tasks, void (*fn)(int i, void *data), void *data)
209
303
static void test_map_stress (void )
210
304
{
211
305
run_parallel (100 , test_hashmap_sanity , NULL );
306
+ run_parallel (100 , test_percpu_hashmap_sanity , NULL );
212
307
run_parallel (100 , test_arraymap_sanity , NULL );
213
308
}
214
309
@@ -282,6 +377,7 @@ static void test_map_parallel(void)
282
377
int main (void )
283
378
{
284
379
test_hashmap_sanity (0 , NULL );
380
+ test_percpu_hashmap_sanity (0 , NULL );
285
381
test_arraymap_sanity (0 , NULL );
286
382
test_map_large ();
287
383
test_map_parallel ();
0 commit comments