2 # SPDX-License-Identifier: GPL-2.0
5 from lib
.py
import ksft_run
, ksft_exit
, ksft_pr
6 from lib
.py
import ksft_eq
, ksft_ge
, ksft_busy_wait
7 from lib
.py
import NetdevFamily
, NetdevSimDev
, ip
10 def empty_check(nf
) -> None:
11 devs
= nf
.dev_get({}, dump
=True)
15 def lo_check(nf
) -> None:
16 lo_info
= nf
.dev_get({"ifindex": 1})
17 ksft_eq(len(lo_info
['xdp-features']), 0)
18 ksft_eq(len(lo_info
['xdp-rx-metadata-features']), 0)
21 def page_pool_check(nf
) -> None:
22 with
NetdevSimDev() as nsimdev
:
23 nsim
= nsimdev
.nsims
[0]
26 ip(f
"link set dev {nsim.ifname} up")
29 ip(f
"link set dev {nsim.ifname} down")
32 pp_list
= nf
.page_pool_get({}, dump
=True)
33 return [pp
for pp
in pp_list
if pp
.get("ifindex") == nsim
.ifindex
]
35 # No page pools when down
37 ksft_eq(len(get_pp()), 0)
39 # Up, empty page pool appears
42 ksft_ge(len(pp_list
), 0)
43 refs
= sum([pp
["inflight"] for pp
in pp_list
])
46 # Down, it disappears, again
49 ksft_eq(len(pp_list
), 0)
53 nsim
.dfs_write("pp_hold", "y")
54 pp_list
= nf
.page_pool_get({}, dump
=True)
55 refs
= sum([pp
["inflight"] for pp
in pp_list
if pp
.get("ifindex") == nsim
.ifindex
])
58 # Now let's leak a page
61 ksft_eq(len(pp_list
), 1)
62 refs
= sum([pp
["inflight"] for pp
in pp_list
])
64 attached
= [pp
for pp
in pp_list
if "detach-time" not in pp
]
65 ksft_eq(len(attached
), 0)
67 # New pp can get created, and we'll have two
70 attached
= [pp
for pp
in pp_list
if "detach-time" not in pp
]
71 detached
= [pp
for pp
in pp_list
if "detach-time" in pp
]
72 ksft_eq(len(attached
), 1)
73 ksft_eq(len(detached
), 1)
75 # Free the old page and the old pp is gone
76 nsim
.dfs_write("pp_hold", "n")
77 # Freeing check is once a second so we may need to retry
78 ksft_busy_wait(lambda: len(get_pp()) == 1, deadline
=2)
82 ksft_eq(len(get_pp()), 0)
84 # Last, leave the page hanging for destroy, nothing to check
85 # we're trying to exercise the orphaning path in the kernel
87 nsim
.dfs_write("pp_hold", "y")
92 ksft_run([empty_check
, lo_check
, page_pool_check
],
97 if __name__
== "__main__":