-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpf: Support atomic update for htab of maps #8634
base: bpf-next_base
Are you sure you want to change the base?
Conversation
Upstream branch: f282146 |
88feb0d
to
eb5d065
Compare
Upstream branch: 79d93c8 |
7a835f3
to
1386cff
Compare
eb5d065
to
1ceb0d9
Compare
Upstream branch: 74f36a9 |
1386cff
to
8a97e57
Compare
1ceb0d9
to
b7965ce
Compare
Upstream branch: 157a502 |
8a97e57
to
7ffb6db
Compare
b7965ce
to
084fae2
Compare
Upstream branch: 233732b |
7ffb6db
to
87465f7
Compare
084fae2
to
474f6ed
Compare
Upstream branch: a68894a |
87465f7
to
8587951
Compare
474f6ed
to
44c3a1d
Compare
Upstream branch: be741c7 |
8587951
to
51baca3
Compare
44c3a1d
to
720c696
Compare
Upstream branch: 46d38f4 |
51baca3
to
0c868fb
Compare
720c696
to
c17650d
Compare
Upstream branch: 956e816 |
4d1d6fc
to
e14a0d8
Compare
Upstream branch: f3f8649 |
74b3bdf
to
9303360
Compare
e14a0d8
to
503edd4
Compare
Upstream branch: ae0a457 |
9303360
to
d94d92e
Compare
503edd4
to
7e623dc
Compare
Upstream branch: f4edc66 |
d94d92e
to
dc290af
Compare
7e623dc
to
156a3ac
Compare
Upstream branch: 6ca2162 |
dc290af
to
da37d1f
Compare
156a3ac
to
50dba77
Compare
Upstream branch: a259804 |
da37d1f
to
5c4e6eb
Compare
50dba77
to
ce294a5
Compare
Upstream branch: 79db658 |
5c4e6eb
to
259350b
Compare
ce294a5
to
e34fe93
Compare
Upstream branch: e16e64f |
259350b
to
63f1953
Compare
e34fe93
to
8c0b07b
Compare
All hash maps store map key and map value together. The relative offset of the map value compared to the map key is round_up(key_size, 8). Therefore, factor out a common helper htab_elem_value() to calculate the address of the map value instead of duplicating the logic. Signed-off-by: Hou Tao <[email protected]>
…place Rename __htab_percpu_map_update_elem to htab_map_update_elem_in_place, and add a new percpu argument for the helper to support in-place update for both per-cpu htab and htab of maps. Signed-off-by: Hou Tao <[email protected]>
As reported by Cody Haas [1], when there is concurrent map lookup and map update operation in an existing element for htab of maps, the map lookup procedure may return -ENOENT unexpectedly. The root cause is twofold: 1) the update of existing element involves two separated list operation In htab_map_update_elem(), it first inserts the new element at the head of list, then it deletes the old element. Therefore, it is possible a lookup operation has already iterated to the middle of the list when a concurrent update operation begins, and the lookup operation will fail to find the target element. 2) the immediate reuse of htab element. It is more subtle. Even through the lookup operation finds the old element, it is possible that the target element has been removed by a concurrent update operation, and the element has been reused immediately by other update operation which runs on the same CPU as the previous update operation, and the element is inserted into the same bucket list. After these steps above, when the lookup operation tries to compare the key in the old element with the expected key, the match will fail because the key in the old element have been overwritten by other update operation. The two-step update process is relatively straightforward to address. The more challenging aspect is the immediate reuse. As Alexei pointed out: So since 2022 both prealloc and no_prealloc reuse elements. We can consider a new flag for the hash map like F_REUSE_AFTER_RCU_GP that will use _rcu() flavor of freeing into bpf_ma, but it has to have a strong reason. Given that htab of maps doesn't support special field in value and directly stores the inner map pointer in htab_element, just do in-place update for htab of maps instead of attempting to address the immediate reuse issue. [1]: https://lore.kernel.org/xdp-newbies/CAH7f-ULFTwKdoH_t2SFc5rWCVYLEg-14d1fBYWH2eekudsnTRg@mail.gmail.com/ Signed-off-by: Hou Tao <[email protected]>
Upstream branch: 51d6504 |
Add is_fd_htab() helper to check whether the map is htab of maps. Signed-off-by: Hou Tao <[email protected]>
The update of element in fd htab is in-place now, therefore, there is no need to allocate per-cpu extra_elems, just remove it. Signed-off-by: Hou Tao <[email protected]>
Add a test case to verify the atomic update of existing elements in the htab of maps. The test proceeds in three steps: 1) fill the outer map with keys in the range [0, 8] For each inner array map, the value of its first element is set as the key used to lookup the inner map. 2) create 16 threads to lookup these keys concurrently Each lookup thread first lookups the inner map, then it checks whether the first value of the inner array map is the same as the key used to lookup the inner map. 3) create 8 threads to overwrite these keys concurrently Each update thread first creates an inner array, it sets the first value of the array to the key used to update the outer map, then it uses the key and the inner map to update the outer map. Without atomic update support, the lookup operation may return -ENOENT during the lookup of outer map, or return -EINVAL during the comparison of the first value in the inner map and the key used for inner map, and the test will fail. After the atomic update change, both the lookup and the comparison will succeed. Given that the update of outer map is slow, the test case sets the loop number for each thread as 5 to reduce the total running time. However, the loop number could also be adjusted through FD_HTAB_LOOP_NR environment variable. Signed-off-by: Hou Tao <[email protected]>
63f1953
to
26030ed
Compare
Pull request for series with
subject: bpf: Support atomic update for htab of maps
version: 2
url: https://patchwork.kernel.org/project/netdevbpf/list/?series=941775