scx_sdt.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * SPDX-License-Identifier: GPL-2.0
  3. * Copyright (c) 2025 Meta Platforms, Inc. and affiliates.
  4. * Copyright (c) 2025 Tejun Heo <tj@kernel.org>
  5. * Copyright (c) 2025 Emil Tsalapatis <etsal@meta.com>
  6. */
  7. #pragma once
  8. #ifndef __BPF__
  9. #define __arena
  10. #endif /* __BPF__ */
  11. struct scx_alloc_stats {
  12. __u64 chunk_allocs;
  13. __u64 data_allocs;
  14. __u64 alloc_ops;
  15. __u64 free_ops;
  16. __u64 active_allocs;
  17. __u64 arena_pages_used;
  18. };
  19. struct sdt_pool {
  20. void __arena *slab;
  21. __u64 elem_size;
  22. __u64 max_elems;
  23. __u64 idx;
  24. };
  25. #ifndef div_round_up
  26. #define div_round_up(a, b) (((a) + (b) - 1) / (b))
  27. #endif
  28. #ifndef round_up
  29. #define round_up(a, b) (div_round_up((a), (b)) * (b))
  30. #endif
  31. typedef struct sdt_desc __arena sdt_desc_t;
  32. enum sdt_consts {
  33. SDT_TASK_ENTS_PER_PAGE_SHIFT = 9,
  34. SDT_TASK_LEVELS = 3,
  35. SDT_TASK_ENTS_PER_CHUNK = 1 << SDT_TASK_ENTS_PER_PAGE_SHIFT,
  36. SDT_TASK_CHUNK_BITMAP_U64S = div_round_up(SDT_TASK_ENTS_PER_CHUNK, 64),
  37. SDT_TASK_MIN_ELEM_PER_ALLOC = 8,
  38. };
  39. union sdt_id {
  40. __s64 val;
  41. struct {
  42. __s32 idx; /* index in the radix tree */
  43. __s32 genn; /* ++'d on recycle so that it forms unique'ish 64bit ID */
  44. };
  45. };
  46. struct sdt_chunk;
  47. /*
  48. * Each index page is described by the following descriptor which carries the
  49. * bitmap. This way the actual index can host power-of-two numbers of entries
  50. * which makes indexing cheaper.
  51. */
  52. struct sdt_desc {
  53. __u64 allocated[SDT_TASK_CHUNK_BITMAP_U64S];
  54. __u64 nr_free;
  55. struct sdt_chunk __arena *chunk;
  56. };
  57. /*
  58. * Leaf node containing per-task data.
  59. */
  60. struct sdt_data {
  61. union sdt_id tid;
  62. __u64 payload[];
  63. };
  64. /*
  65. * Intermediate node pointing to another intermediate node or leaf node.
  66. */
  67. struct sdt_chunk {
  68. union {
  69. sdt_desc_t * descs[SDT_TASK_ENTS_PER_CHUNK];
  70. struct sdt_data __arena *data[SDT_TASK_ENTS_PER_CHUNK];
  71. };
  72. };
  73. struct scx_allocator {
  74. struct sdt_pool pool;
  75. sdt_desc_t *root;
  76. };
  77. struct scx_stats {
  78. int seq;
  79. pid_t pid;
  80. __u64 enqueue;
  81. __u64 exit;
  82. __u64 init;
  83. __u64 select_busy_cpu;
  84. __u64 select_idle_cpu;
  85. };
  86. #ifdef __BPF__
  87. void __arena *scx_task_data(struct task_struct *p);
  88. int scx_task_init(__u64 data_size);
  89. void __arena *scx_task_alloc(struct task_struct *p);
  90. void scx_task_free(struct task_struct *p);
  91. void scx_arena_subprog_init(void);
  92. int scx_alloc_init(struct scx_allocator *alloc, __u64 data_size);
  93. u64 scx_alloc_internal(struct scx_allocator *alloc);
  94. int scx_alloc_free_idx(struct scx_allocator *alloc, __u64 idx);
  95. #endif /* __BPF__ */