exit.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (c) 2024 Meta Platforms, Inc. and affiliates.
  4. * Copyright (c) 2024 David Vernet <dvernet@meta.com>
  5. */
  6. #include <bpf/bpf.h>
  7. #include <sched.h>
  8. #include <scx/common.h>
  9. #include <sys/wait.h>
  10. #include <unistd.h>
  11. #include "exit.bpf.skel.h"
  12. #include "scx_test.h"
  13. #include "exit_test.h"
  14. static enum scx_test_status run(void *ctx)
  15. {
  16. enum exit_test_case tc;
  17. for (tc = 0; tc < NUM_EXITS; tc++) {
  18. struct exit *skel;
  19. struct bpf_link *link;
  20. char buf[16];
  21. /*
  22. * On single-CPU systems, ops.select_cpu() is never
  23. * invoked, so skip this test to avoid getting stuck
  24. * indefinitely.
  25. */
  26. if (tc == EXIT_SELECT_CPU && libbpf_num_possible_cpus() == 1)
  27. continue;
  28. skel = exit__open();
  29. SCX_ENUM_INIT(skel);
  30. skel->rodata->exit_point = tc;
  31. exit__load(skel);
  32. link = bpf_map__attach_struct_ops(skel->maps.exit_ops);
  33. if (!link) {
  34. SCX_ERR("Failed to attach scheduler");
  35. exit__destroy(skel);
  36. return SCX_TEST_FAIL;
  37. }
  38. /* Assumes uei.kind is written last */
  39. while (skel->data->uei.kind == EXIT_KIND(SCX_EXIT_NONE))
  40. sched_yield();
  41. SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_UNREG_BPF));
  42. SCX_EQ(skel->data->uei.exit_code, tc);
  43. sprintf(buf, "%d", tc);
  44. SCX_ASSERT(!strcmp(skel->data->uei.msg, buf));
  45. bpf_link__destroy(link);
  46. exit__destroy(skel);
  47. }
  48. return SCX_TEST_PASS;
  49. }
  50. struct scx_test exit_test = {
  51. .name = "exit",
  52. .description = "Verify we can cleanly exit a scheduler in multiple places",
  53. .run = run,
  54. };
  55. REGISTER_SCX_TEST(&exit_test)