Skip to content

Commit b7f394c

Browse files
authored
Merge pull request #3026 from multics69/lavd-cpu-bw15
Add `cpu.max` Support for the SCX Scheduler
2 parents 9245943 + 95af48b commit b7f394c

31 files changed

+3548
-289
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/atq.bpf.c

Lines changed: 65 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ u64 scx_atq_create_internal(bool fifo, size_t capacity)
1717
if (!atq)
1818
return (u64)NULL;
1919

20-
atq->tree = rb_create();
20+
atq->tree = rb_create(RB_NOALLOC, RB_DUPLICATE);
2121
if (!atq->tree)
2222
return (u64)NULL;
2323

@@ -28,102 +28,105 @@ u64 scx_atq_create_internal(bool fifo, size_t capacity)
2828
return (u64)atq;
2929
}
3030

31-
__hidden
32-
int scx_atq_insert(scx_atq_t *atq, u64 taskc_ptr)
31+
__hidden __inline
32+
int scx_atq_insert_vtime_unlocked(scx_atq_t __arg_arena *atq, scx_task_common __arg_arena *taskc, u64 vtime)
3333
{
34-
rbnode_t *node;
34+
rbnode_t *node = &taskc->node;
3535
int ret;
3636

37-
if (!atq->fifo)
38-
return -EINVAL;
37+
if (unlikely(atq->size == atq->capacity))
38+
return -ENOSPC;
3939

40-
/*
41-
* Use dummy sequence number because we're
42-
* outside of the critical section.
43-
*/
44-
node = rb_node_alloc(atq->tree, 0, taskc_ptr);
45-
if (!node)
46-
return -ENOMEM;
47-
48-
ret = arena_spin_lock(&atq->lock);
49-
if (ret) {
50-
rb_node_free(atq->tree, node);
51-
return ret;
52-
}
53-
54-
if (unlikely(atq->size == atq->capacity)) {
55-
ret = -ENOSPC;
56-
goto error;
57-
}
40+
if ((vtime == SCX_ATQ_FIFO) != atq->fifo)
41+
return -EINVAL;
5842

5943
/*
60-
* "Leak" the seq on error. We only want
44+
* For FIFO, "Leak" the seq on error. We only want
6145
* sequence numbers to be monotonic, not
6246
* consecutive.
6347
*/
64-
node->key = atq->seq++;
48+
node->key = (vtime == SCX_ATQ_FIFO) ? atq->seq++ : vtime;
49+
node->value = (u64)taskc;
6550

66-
ret = rb_insert_node(atq->tree, node, RB_DUPLICATE);
51+
ret = rb_insert_node(atq->tree, node);
6752
if (ret)
68-
goto error;
53+
return ret;
6954

55+
taskc->atq = atq;
7056
atq->size += 1;
7157

72-
arena_spin_unlock(&atq->lock);
73-
7458
return 0;
59+
}
60+
61+
/*
62+
* XXXETSAL: We are using the __hidden antipattern for API functions because some
63+
* older kernels do not allow function calls with preemption disabled. We will replace
64+
* these annotations with the proper ones (__weak) at some point in the future.
65+
*/
66+
67+
__hidden
68+
int scx_atq_insert_vtime(scx_atq_t __arg_arena *atq, scx_task_common __arg_arena *taskc, u64 vtime)
69+
{
70+
int ret;
71+
72+
ret = arena_spin_lock(&atq->lock);
73+
if (ret)
74+
return ret;
75+
76+
ret = scx_atq_insert_vtime_unlocked(atq, taskc, vtime);
7577

76-
error:
7778
arena_spin_unlock(&atq->lock);
78-
rb_node_free(atq->tree, node);
7979

8080
return ret;
8181
}
8282

8383
__hidden
84-
int scx_atq_insert_vtime(scx_atq_t *atq, u64 taskc_ptr, u64 vtime)
84+
int scx_atq_insert_unlocked(scx_atq_t *atq, scx_task_common __arg_arena *taskc)
8585
{
86-
rbnode_t *node;
87-
int ret;
86+
return scx_atq_insert_vtime_unlocked(atq, taskc, SCX_ATQ_FIFO);
87+
}
8888

89-
if (atq->fifo)
90-
return -EINVAL;
89+
__hidden
90+
int scx_atq_insert(scx_atq_t *atq, scx_task_common __arg_arena *taskc)
91+
{
92+
return scx_atq_insert_vtime(atq, taskc, SCX_ATQ_FIFO);
93+
}
9194

92-
node = rb_node_alloc(atq->tree, vtime, taskc_ptr);
93-
if (!node)
94-
return -ENOMEM;
95+
__hidden
96+
int scx_atq_remove_unlocked(scx_atq_t *atq, scx_task_common __arg_arena *taskc)
97+
{
98+
int ret;
9599

96-
ret = arena_spin_lock(&atq->lock);
97-
if (ret) {
98-
rb_node_free(atq->tree, node);
99-
return ret;
100-
}
100+
/* Are we in this ATQ in the first place? */
101+
if (taskc->atq != atq)
102+
return -EINVAL;
101103

102-
if (unlikely(atq->size == atq->capacity)) {
103-
ret = -ENOSPC;
104-
goto error;
105-
}
104+
ret = rb_remove_node(atq->tree, &taskc->node);
105+
taskc->atq = NULL;
106106

107-
ret = rb_insert_node(atq->tree, node, RB_DUPLICATE);
108-
if (ret)
109-
goto error;
107+
return ret;
108+
}
110109

111-
atq->size += 1;
110+
__hidden
111+
int scx_atq_remove(scx_atq_t *atq, scx_task_common __arg_arena *taskc)
112+
{
113+
int ret;
112114

113-
arena_spin_unlock(&atq->lock);
115+
ret = arena_spin_lock(&atq->lock);
116+
if (ret)
117+
return ret;
114118

115-
return 0;
119+
ret = scx_atq_remove_unlocked(atq, taskc);
116120

117-
error:
118-
arena_spin_unlock(&atq->lock);
119-
rb_node_free(atq->tree, node);
121+
arena_spin_unlock(&atq->lock);
120122

121-
return ret;
123+
return ret;
122124
}
123125

124126
__hidden
125127
u64 scx_atq_pop(scx_atq_t *atq)
126128
{
129+
scx_task_common *taskc;
127130
u64 vtime, taskc_ptr;
128131
int ret;
129132

@@ -140,6 +143,9 @@ u64 scx_atq_pop(scx_atq_t *atq)
140143
if (!ret)
141144
atq->size -= 1;
142145

146+
taskc = (scx_task_common *)taskc_ptr;
147+
taskc->atq = NULL;
148+
143149
arena_spin_unlock(&atq->lock);
144150

145151
if (ret) {

0 commit comments

Comments
 (0)