Skip to content

Commit 6462dd5

Browse files
committed
sched_ext: Compact struct bpf_iter_scx_dsq_kern
struct scx_iter_scx_dsq is defined as 6 u64's and scx_dsq_iter_kern was using 5 of them. We want to add two more u64 fields but it's better if we do so while staying within scx_iter_scx_dsq to maintain binary compatibility. The way scx_iter_scx_dsq_kern is laid out is rather inefficient - the node field takes up three u64's but only one bit of the last u64 is used. Turn the bool into u32 flags and only use the lower 16 bits freeing up 48 bits - 16 bits for flags, 32 bits for a u32 - for use by struct bpf_iter_scx_dsq_kern. This allows moving the dsq_seq and flags fields of bpf_iter_scx_dsq_kern into the cursor field reducing the struct size by a full u64. No behavior changes intended. Signed-off-by: Tejun Heo <[email protected]>
1 parent cf3e944 commit 6462dd5

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

include/linux/sched/ext.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,17 @@ enum scx_kf_mask {
119119
__SCX_KF_TERMINAL = SCX_KF_ENQUEUE | SCX_KF_SELECT_CPU | SCX_KF_REST,
120120
};
121121

122+
enum scx_dsq_lnode_flags {
123+
SCX_DSQ_LNODE_ITER_CURSOR = 1 << 0,
124+
125+
/* high 16 bits can be for iter cursor flags */
126+
__SCX_DSQ_LNODE_PRIV_SHIFT = 16,
127+
};
128+
122129
struct scx_dsq_list_node {
123130
struct list_head node;
124-
bool is_bpf_iter_cursor;
131+
u32 flags;
132+
u32 priv; /* can be used by iter cursor */
125133
};
126134

127135
/*

kernel/sched/ext.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,7 @@ static struct task_struct *nldsq_next_task(struct scx_dispatch_q *dsq,
11911191

11921192
dsq_lnode = container_of(list_node, struct scx_dsq_list_node,
11931193
node);
1194-
} while (dsq_lnode->is_bpf_iter_cursor);
1194+
} while (dsq_lnode->flags & SCX_DSQ_LNODE_ITER_CURSOR);
11951195

11961196
return container_of(dsq_lnode, struct task_struct, scx.dsq_list);
11971197
}
@@ -1209,16 +1209,15 @@ static struct task_struct *nldsq_next_task(struct scx_dispatch_q *dsq,
12091209
*/
12101210
enum scx_dsq_iter_flags {
12111211
/* iterate in the reverse dispatch order */
1212-
SCX_DSQ_ITER_REV = 1U << 0,
1212+
SCX_DSQ_ITER_REV = 1U << 16,
12131213

1214-
__SCX_DSQ_ITER_ALL_FLAGS = SCX_DSQ_ITER_REV,
1214+
__SCX_DSQ_ITER_USER_FLAGS = SCX_DSQ_ITER_REV,
1215+
__SCX_DSQ_ITER_ALL_FLAGS = __SCX_DSQ_ITER_USER_FLAGS,
12151216
};
12161217

12171218
struct bpf_iter_scx_dsq_kern {
12181219
struct scx_dsq_list_node cursor;
12191220
struct scx_dispatch_q *dsq;
1220-
u32 dsq_seq;
1221-
u32 flags;
12221221
} __attribute__((aligned(8)));
12231222

12241223
struct bpf_iter_scx_dsq {
@@ -1256,6 +1255,9 @@ static void scx_task_iter_init(struct scx_task_iter *iter)
12561255
{
12571256
lockdep_assert_held(&scx_tasks_lock);
12581257

1258+
BUILD_BUG_ON(__SCX_DSQ_ITER_ALL_FLAGS &
1259+
((1U << __SCX_DSQ_LNODE_PRIV_SHIFT) - 1));
1260+
12591261
iter->cursor = (struct sched_ext_entity){ .flags = SCX_TASK_CURSOR };
12601262
list_add(&iter->cursor.tasks_node, &scx_tasks);
12611263
iter->locked = NULL;
@@ -6285,17 +6287,16 @@ __bpf_kfunc int bpf_iter_scx_dsq_new(struct bpf_iter_scx_dsq *it, u64 dsq_id,
62856287
BUILD_BUG_ON(__alignof__(struct bpf_iter_scx_dsq_kern) !=
62866288
__alignof__(struct bpf_iter_scx_dsq));
62876289

6288-
if (flags & ~__SCX_DSQ_ITER_ALL_FLAGS)
6290+
if (flags & ~__SCX_DSQ_ITER_USER_FLAGS)
62896291
return -EINVAL;
62906292

62916293
kit->dsq = find_non_local_dsq(dsq_id);
62926294
if (!kit->dsq)
62936295
return -ENOENT;
62946296

62956297
INIT_LIST_HEAD(&kit->cursor.node);
6296-
kit->cursor.is_bpf_iter_cursor = true;
6297-
kit->dsq_seq = READ_ONCE(kit->dsq->seq);
6298-
kit->flags = flags;
6298+
kit->cursor.flags |= SCX_DSQ_LNODE_ITER_CURSOR | flags;
6299+
kit->cursor.priv = READ_ONCE(kit->dsq->seq);
62996300

63006301
return 0;
63016302
}
@@ -6309,7 +6310,7 @@ __bpf_kfunc int bpf_iter_scx_dsq_new(struct bpf_iter_scx_dsq *it, u64 dsq_id,
63096310
__bpf_kfunc struct task_struct *bpf_iter_scx_dsq_next(struct bpf_iter_scx_dsq *it)
63106311
{
63116312
struct bpf_iter_scx_dsq_kern *kit = (void *)it;
6312-
bool rev = kit->flags & SCX_DSQ_ITER_REV;
6313+
bool rev = kit->cursor.flags & SCX_DSQ_ITER_REV;
63136314
struct task_struct *p;
63146315
unsigned long flags;
63156316

@@ -6330,7 +6331,7 @@ __bpf_kfunc struct task_struct *bpf_iter_scx_dsq_next(struct bpf_iter_scx_dsq *i
63306331
*/
63316332
do {
63326333
p = nldsq_next_task(kit->dsq, p, rev);
6333-
} while (p && unlikely(u32_before(kit->dsq_seq, p->scx.dsq_seq)));
6334+
} while (p && unlikely(u32_before(kit->cursor.priv, p->scx.dsq_seq)));
63346335

63356336
if (p) {
63366337
if (rev)

0 commit comments

Comments
 (0)