Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0
2//! Benchmark for find_bit-like methods in Bitmap Rust API.
3
4use kernel::alloc::flags::GFP_KERNEL;
5use kernel::bindings;
6use kernel::bitmap::BitmapVec;
7use kernel::error::{code, Result};
8use kernel::prelude::module;
9use kernel::time::{Instant, Monotonic};
10use kernel::ThisModule;
11use kernel::{pr_cont, pr_err};
12
13const BITMAP_LEN: usize = 4096 * 8 * 10;
14// Reciprocal of the fraction of bits that are set in sparse bitmap.
15const SPARSENESS: usize = 500;
16
17/// Test module that benchmarks performance of traversing bitmaps.
18struct Benchmark();
19
20fn test_next_bit(bitmap: &BitmapVec) {
21 let time = Instant::<Monotonic>::now();
22 let mut cnt = 0;
23 let mut i = 0;
24
25 while let Some(index) = bitmap.next_bit(i) {
26 cnt += 1;
27 i = index + 1;
28 // CONFIG_RUST_BITMAP_HARDENED enforces strict bounds.
29 if i == BITMAP_LEN {
30 break;
31 }
32 }
33
34 let delta = time.elapsed();
35 pr_cont!(
36 "\nnext_bit: {:18} ns, {:6} iterations",
37 delta.as_nanos(),
38 cnt
39 );
40}
41
42fn test_next_zero_bit(bitmap: &BitmapVec) {
43 let time = Instant::<Monotonic>::now();
44 let mut cnt = 0;
45 let mut i = 0;
46
47 while let Some(index) = bitmap.next_zero_bit(i) {
48 cnt += 1;
49 i = index + 1;
50 // CONFIG_RUST_BITMAP_HARDENED enforces strict bounds.
51 if i == BITMAP_LEN {
52 break;
53 }
54 }
55
56 let delta = time.elapsed();
57 pr_cont!(
58 "\nnext_zero_bit: {:18} ns, {:6} iterations",
59 delta.as_nanos(),
60 cnt
61 );
62}
63
64fn find_bit_test() {
65 pr_err!("Benchmark");
66 pr_cont!("\nStart testing find_bit() Rust with random-filled bitmap");
67
68 let mut bitmap = BitmapVec::new(BITMAP_LEN, GFP_KERNEL).expect("alloc bitmap failed");
69 bitmap.fill_random();
70
71 test_next_bit(&bitmap);
72 test_next_zero_bit(&bitmap);
73
74 pr_cont!("\nStart testing find_bit() Rust with sparse bitmap");
75
76 let mut bitmap = BitmapVec::new(BITMAP_LEN, GFP_KERNEL).expect("alloc sparse bitmap failed");
77 let nbits = BITMAP_LEN / SPARSENESS;
78 for _i in 0..nbits {
79 // SAFETY: __get_random_u32_below is safe to call with any u32 argument.
80 let bit =
81 unsafe { bindings::__get_random_u32_below(BITMAP_LEN.try_into().unwrap()) as usize };
82 bitmap.set_bit(bit);
83 }
84
85 test_next_bit(&bitmap);
86 test_next_zero_bit(&bitmap);
87 pr_cont!("\n");
88}
89
90impl kernel::Module for Benchmark {
91 fn init(_module: &'static ThisModule) -> Result<Self> {
92 find_bit_test();
93 // Return error so test module can be inserted again without rmmod.
94 Err(code::EINVAL)
95 }
96}
97
98module! {
99 type: Benchmark,
100 name: "find_bit_benchmark_rust",
101 authors: ["Burak Emir <bqe@google.com>"],
102 description: "Module with benchmark for bitmap Rust API",
103 license: "GPL v2",
104}