33#include "percpu_alloc_array.skel.h"
44#include "percpu_alloc_cgrp_local_storage.skel.h"
55#include "percpu_alloc_fail.skel.h"
6+ #include "percpu_array_flag.skel.h"
67
78static void test_array (void )
89{
@@ -115,6 +116,152 @@ static void test_failure(void) {
115116 RUN_TESTS (percpu_alloc_fail );
116117}
117118
119+ static void test_cpu_flag (void )
120+ {
121+ int map_fd , * keys = NULL , value_size , cpu , i , j , nr_cpus , err ;
122+ size_t key_sz = sizeof (int ), value_sz = sizeof (u64 );
123+ u64 batch = 0 , * values = NULL , flags ;
124+ struct percpu_array_flag * skel ;
125+ const u64 value = 0xDEADC0DE ;
126+ u32 count , max_entries ;
127+ struct bpf_map * map ;
128+ LIBBPF_OPTS (bpf_map_batch_opts , batch_opts );
129+
130+ nr_cpus = libbpf_num_possible_cpus ();
131+ if (!ASSERT_GT (nr_cpus , 0 , "libbpf_num_possible_cpus" ))
132+ return ;
133+
134+ skel = percpu_array_flag__open_and_load ();
135+ if (!ASSERT_OK_PTR (skel , "percpu_array_flag__open_and_load" ))
136+ return ;
137+
138+ map = skel -> maps .percpu ;
139+ map_fd = bpf_map__fd (map );
140+ max_entries = bpf_map__max_entries (map );
141+
142+ value_size = value_sz * nr_cpus ;
143+ values = calloc (max_entries , value_size );
144+ if (!ASSERT_OK_PTR (values , "calloc values" ))
145+ goto out ;
146+ keys = calloc (max_entries , key_sz );
147+ if (!ASSERT_OK_PTR (keys , "calloc keys" ))
148+ goto out ;
149+
150+ for (i = 0 ; i < max_entries ; i ++ )
151+ keys [i ] = i ;
152+ memset (values , 0 , max_entries * value_size );
153+
154+ batch_opts .elem_flags = (u64 )nr_cpus << 32 | BPF_F_CPU ;
155+ err = bpf_map_update_batch (map_fd , keys , values , & max_entries , & batch_opts );
156+ if (!ASSERT_EQ (err , - ERANGE , "bpf_map_update_batch -ERANGE" ))
157+ goto out ;
158+
159+ for (cpu = 0 ; cpu < nr_cpus ; cpu ++ ) {
160+ memset (values , 0 , max_entries * value_size );
161+
162+ /* clear values across all CPUs */
163+ batch_opts .elem_flags = (u64 )BPF_ALL_CPUS << 32 | BPF_F_CPU ;
164+ err = bpf_map_update_batch (map_fd , keys , values , & max_entries , & batch_opts );
165+ if (!ASSERT_OK (err , "bpf_map_update_batch all cpus" ))
166+ goto out ;
167+
168+ /* update values on specified CPU */
169+ for (i = 0 ; i < max_entries ; i ++ )
170+ values [i ] = value ;
171+
172+ batch_opts .elem_flags = (u64 )cpu << 32 | BPF_F_CPU ;
173+ err = bpf_map_update_batch (map_fd , keys , values , & max_entries , & batch_opts );
174+ if (!ASSERT_OK (err , "bpf_map_update_batch specified cpu" ))
175+ goto out ;
176+
177+ /* lookup values on specified CPU */
178+ memset (values , 0 , max_entries * value_sz );
179+ err = bpf_map_lookup_batch (map_fd , NULL , & batch , keys , values , & count , & batch_opts );
180+ if (!ASSERT_TRUE (!err || err == - ENOENT , "bpf_map_lookup_batch specified cpu" ))
181+ goto out ;
182+
183+ for (i = 0 ; i < max_entries ; i ++ )
184+ if (!ASSERT_EQ (values [i ], value , "value on specified cpu" ))
185+ goto out ;
186+
187+ /* lookup values from all CPUs */
188+ batch_opts .elem_flags = 0 ;
189+ memset (values , 0 , max_entries * value_size );
190+ err = bpf_map_lookup_batch (map_fd , NULL , & batch , keys , values , & count , & batch_opts );
191+ if (!ASSERT_TRUE (!err || err == - ENOENT , "bpf_map_lookup_batch all cpus" ))
192+ goto out ;
193+
194+ for (i = 0 ; i < max_entries ; i ++ ) {
195+ for (j = 0 ; j < nr_cpus ; j ++ ) {
196+ if (!ASSERT_EQ (values [i * nr_cpus + j ], j != cpu ? 0 : value ,
197+ "value on specified cpu" ))
198+ goto out ;
199+ }
200+ }
201+ }
202+
203+ flags = (u64 )nr_cpus << 32 | BPF_F_CPU ;
204+ err = bpf_map_update_elem (map_fd , keys , values , flags );
205+ if (!ASSERT_EQ (err , - ERANGE , "bpf_map_update_elem -ERANGE" ))
206+ goto out ;
207+
208+ err = bpf_map__update_elem (map , keys , key_sz , values , value_sz , flags );
209+ if (!ASSERT_EQ (err , - ERANGE , "bpf_map__update_elem -ERANGE" ))
210+ goto out ;
211+
212+ err = bpf_map_lookup_elem_flags (map_fd , keys , values , flags );
213+ if (!ASSERT_EQ (err , - ERANGE , "bpf_map_lookup_elem_flags -ERANGE" ))
214+ goto out ;
215+
216+ err = bpf_map__lookup_elem (map , keys , key_sz , values , value_sz , flags );
217+ if (!ASSERT_EQ (err , - ERANGE , "bpf_map__lookup_elem -ERANGE" ))
218+ goto out ;
219+
220+ /* clear value on all cpus */
221+ batch_opts .elem_flags = (u64 )BPF_ALL_CPUS << 32 | BPF_F_CPU ;
222+ memset (values , 0 , max_entries * value_sz );
223+ err = bpf_map_update_batch (map_fd , keys , values , & max_entries , & batch_opts );
224+ if (!ASSERT_OK (err , "bpf_map_update_batch all cpus" ))
225+ goto out ;
226+
227+ for (cpu = 0 ; cpu < nr_cpus ; cpu ++ ) {
228+ /* update value on specified cpu */
229+ values [0 ] = value ;
230+ flags = (u64 )cpu << 32 | BPF_F_CPU ;
231+ for (i = 0 ; i < max_entries ; i ++ ) {
232+ err = bpf_map__update_elem (map , keys + i , key_sz , values , value_sz , flags );
233+ if (!ASSERT_OK (err , "bpf_map__update_elem specified cpu" ))
234+ goto out ;
235+
236+ for (j = 0 ; j < nr_cpus ; j ++ ) {
237+ /* lookup then check value on CPUs */
238+ flags = (u64 )j << 32 | BPF_F_CPU ;
239+ err = bpf_map__lookup_elem (map , keys + i , key_sz , values , value_sz ,
240+ flags );
241+ if (!ASSERT_OK (err , "bpf_map__lookup_elem specified cpu" ))
242+ goto out ;
243+ if (!ASSERT_EQ (values [0 ], j != cpu ? 0 : value ,
244+ "bpf_map__lookup_elem value on specified cpu" ))
245+ goto out ;
246+ }
247+ }
248+
249+ /* clear value on specified cpu */
250+ values [0 ] = 0 ;
251+ flags = (u64 )cpu << 32 | BPF_F_CPU ;
252+ err = bpf_map__update_elem (map , keys , key_sz , values , value_sz , flags );
253+ if (!ASSERT_OK (err , "bpf_map__update_elem specified cpu" ))
254+ goto out ;
255+ }
256+
257+ out :
258+ if (keys )
259+ free (keys );
260+ if (values )
261+ free (values );
262+ percpu_array_flag__destroy (skel );
263+ }
264+
118265void test_percpu_alloc (void )
119266{
120267 if (test__start_subtest ("array" ))
@@ -125,4 +272,6 @@ void test_percpu_alloc(void)
125272 test_cgrp_local_storage ();
126273 if (test__start_subtest ("failure_tests" ))
127274 test_failure ();
275+ if (test__start_subtest ("cpu_flag_tests" ))
276+ test_cpu_flag ();
128277}
0 commit comments