nl_netdev.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #!/usr/bin/env python3
  2. # SPDX-License-Identifier: GPL-2.0
  3. import time
  4. from lib.py import ksft_run, ksft_exit, ksft_pr
  5. from lib.py import ksft_eq, ksft_ge, ksft_busy_wait
  6. from lib.py import NetdevFamily, NetdevSimDev, ip
  7. def empty_check(nf) -> None:
  8. devs = nf.dev_get({}, dump=True)
  9. ksft_ge(len(devs), 1)
  10. def lo_check(nf) -> None:
  11. lo_info = nf.dev_get({"ifindex": 1})
  12. ksft_eq(len(lo_info['xdp-features']), 0)
  13. ksft_eq(len(lo_info['xdp-rx-metadata-features']), 0)
  14. def page_pool_check(nf) -> None:
  15. with NetdevSimDev() as nsimdev:
  16. nsim = nsimdev.nsims[0]
  17. def up():
  18. ip(f"link set dev {nsim.ifname} up")
  19. def down():
  20. ip(f"link set dev {nsim.ifname} down")
  21. def get_pp():
  22. pp_list = nf.page_pool_get({}, dump=True)
  23. return [pp for pp in pp_list if pp.get("ifindex") == nsim.ifindex]
  24. # No page pools when down
  25. down()
  26. ksft_eq(len(get_pp()), 0)
  27. # Up, empty page pool appears
  28. up()
  29. pp_list = get_pp()
  30. ksft_ge(len(pp_list), 0)
  31. refs = sum([pp["inflight"] for pp in pp_list])
  32. ksft_eq(refs, 0)
  33. # Down, it disappears, again
  34. down()
  35. pp_list = get_pp()
  36. ksft_eq(len(pp_list), 0)
  37. # Up, allocate a page
  38. up()
  39. nsim.dfs_write("pp_hold", "y")
  40. pp_list = nf.page_pool_get({}, dump=True)
  41. refs = sum([pp["inflight"] for pp in pp_list if pp.get("ifindex") == nsim.ifindex])
  42. ksft_ge(refs, 1)
  43. # Now let's leak a page
  44. down()
  45. pp_list = get_pp()
  46. ksft_eq(len(pp_list), 1)
  47. refs = sum([pp["inflight"] for pp in pp_list])
  48. ksft_eq(refs, 1)
  49. attached = [pp for pp in pp_list if "detach-time" not in pp]
  50. ksft_eq(len(attached), 0)
  51. # New pp can get created, and we'll have two
  52. up()
  53. pp_list = get_pp()
  54. attached = [pp for pp in pp_list if "detach-time" not in pp]
  55. detached = [pp for pp in pp_list if "detach-time" in pp]
  56. ksft_eq(len(attached), 1)
  57. ksft_eq(len(detached), 1)
  58. # Free the old page and the old pp is gone
  59. nsim.dfs_write("pp_hold", "n")
  60. # Freeing check is once a second so we may need to retry
  61. ksft_busy_wait(lambda: len(get_pp()) == 1, deadline=2)
  62. # And down...
  63. down()
  64. ksft_eq(len(get_pp()), 0)
  65. # Last, leave the page hanging for destroy, nothing to check
  66. # we're trying to exercise the orphaning path in the kernel
  67. up()
  68. nsim.dfs_write("pp_hold", "y")
  69. def main() -> None:
  70. nf = NetdevFamily()
  71. ksft_run([empty_check, lo_check, page_pool_check],
  72. args=(nf, ))
  73. ksft_exit()
  74. if __name__ == "__main__":
  75. main()