Skip to content

Commit 071d80d

Browse files
yogaraj-s-5455danielocfb
authored andcommitted
add: support for bpf_map_update_batch method
Signed-off-by: yogaraj.s <[email protected]>
1 parent 4ef1505 commit 071d80d

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

libbpf-rs/src/map.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,56 @@ impl MapHandle {
765765
self.update_raw(key, value, flags)
766766
}
767767

768+
/// Updates many elements in batch mode in the map
769+
///
770+
/// `keys` must have exactly [`MapHandle::key_size()` * count] elements. `value` must have exactly
771+
/// [`MapHandle::key_size()` * count] elements
772+
pub fn update_batch(
773+
&self,
774+
keys: &[u8],
775+
values: &[u8],
776+
count: u32,
777+
elem_flags: MapFlags,
778+
flags: MapFlags,
779+
) -> Result<()> {
780+
if keys.len() as u32 / count != self.key_size() || (keys.len() as u32) % count != 0 {
781+
return Err(Error::with_invalid_data(format!(
782+
"batch key_size {} != {} * {}",
783+
keys.len(),
784+
self.key_size(),
785+
count
786+
)));
787+
};
788+
789+
if values.len() as u32 / count != self.value_size() || (values.len() as u32) % count != 0 {
790+
return Err(Error::with_invalid_data(format!(
791+
"batch value_size {} != {} * {}",
792+
values.len(),
793+
self.value_size(),
794+
count
795+
)));
796+
}
797+
798+
let opts = libbpf_sys::bpf_map_batch_opts {
799+
sz: mem::size_of::<libbpf_sys::bpf_map_batch_opts>() as _,
800+
elem_flags: elem_flags.bits(),
801+
flags: flags.bits(),
802+
};
803+
804+
let mut count = count;
805+
let ret = unsafe {
806+
libbpf_sys::bpf_map_update_batch(
807+
self.fd.as_raw_fd(),
808+
keys.as_ptr() as *const c_void,
809+
values.as_ptr() as *const c_void,
810+
(&mut count) as *mut u32,
811+
&opts as *const libbpf_sys::bpf_map_batch_opts,
812+
)
813+
};
814+
815+
util::parse_ret(ret)
816+
}
817+
768818
/// Update an element in an per-cpu map with one value per cpu.
769819
///
770820
/// `key` must have exactly [`MapHandle::key_size()`] elements. `value` must have one

libbpf-rs/tests/test.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,94 @@ fn test_sudo_object_map_key_value_size() {
200200
.is_err());
201201
}
202202

203+
#[test]
204+
fn test_sudo_object_map_update_batch() {
205+
bump_rlimit_mlock();
206+
207+
let mut obj = get_test_object("runqslower.bpf.o");
208+
let start = obj.map_mut("start").expect("failed to find map");
209+
210+
let key1 = 1u32.to_ne_bytes();
211+
let key2 = 2u32.to_ne_bytes();
212+
let key3 = 3u32.to_ne_bytes();
213+
let key4 = 4u32.to_ne_bytes();
214+
215+
let value1 = 369u64.to_ne_bytes();
216+
let value2 = 258u64.to_ne_bytes();
217+
let value3 = 147u64.to_ne_bytes();
218+
let value4 = 159u64.to_ne_bytes();
219+
220+
let batch_key1 = key1.into_iter().chain(key2).collect::<Vec<_>>();
221+
let batch_value1 = value1.into_iter().chain(value2).collect::<Vec<_>>();
222+
223+
let batch_key2 = key2.into_iter().chain(key3).chain(key4).collect::<Vec<_>>();
224+
let batch_value2 = value2
225+
.into_iter()
226+
.chain(value3)
227+
.chain(value4)
228+
.collect::<Vec<_>>();
229+
230+
// Update batch with wrong key size
231+
assert!(start
232+
.update_batch(
233+
&[1, 2, 3],
234+
&batch_value1,
235+
2,
236+
MapFlags::ANY,
237+
MapFlags::NO_EXIST
238+
)
239+
.is_err());
240+
241+
// Update batch with wrong value size
242+
assert!(start
243+
.update_batch(
244+
&batch_key1,
245+
&[1, 2, 3],
246+
2,
247+
MapFlags::ANY,
248+
MapFlags::NO_EXIST
249+
)
250+
.is_err());
251+
252+
// Update batch with wrong count.
253+
assert!(start
254+
.update_batch(
255+
&batch_key1,
256+
&batch_value1,
257+
1,
258+
MapFlags::ANY,
259+
MapFlags::NO_EXIST
260+
)
261+
.is_err());
262+
263+
// Update batch with 1 key.
264+
assert!(start
265+
.update_batch(&key1, &value1, 1, MapFlags::ANY, MapFlags::NO_EXIST)
266+
.is_ok());
267+
268+
// Update batch with multiple keys.
269+
assert!(start
270+
.update_batch(
271+
&batch_key2,
272+
&batch_value2,
273+
3,
274+
MapFlags::ANY,
275+
MapFlags::NO_EXIST
276+
)
277+
.is_ok());
278+
279+
// Update batch with existing keys.
280+
assert!(start
281+
.update_batch(
282+
&batch_key2,
283+
&batch_value2,
284+
3,
285+
MapFlags::NO_EXIST,
286+
MapFlags::NO_EXIST
287+
)
288+
.is_err());
289+
}
290+
203291
#[test]
204292
fn test_sudo_object_map_delete_batch() {
205293
bump_rlimit_mlock();

0 commit comments

Comments
 (0)