Skip to content

Commit 3fcb9d1

Browse files
lreeze123axboe
authored andcommittedMar 1, 2024
io_uring/sqpoll: statistics of the true utilization of sq threads
Count the running time and actual IO processing time of the sqpoll thread, and output the statistical data to fdinfo. Variable description: "work_time" in the code represents the sum of the jiffies of the sq thread actually processing IO, that is, how many milliseconds it actually takes to process IO. "total_time" represents the total time that the sq thread has elapsed from the beginning of the loop to the current time point, that is, how many milliseconds it has spent in total. The test tool is fio, and its parameters are as follows: [global] ioengine=io_uring direct=1 group_reporting bs=128k norandommap=1 randrepeat=0 refill_buffers ramp_time=30s time_based runtime=1m clocksource=clock_gettime overwrite=1 log_avg_msec=1000 numjobs=1 [disk0] filename=/dev/nvme0n1 rw=read iodepth=16 hipri sqthread_poll=1 The test results are as follows: Every 2.0s: cat /proc/9230/fdinfo/6 | grep -E Sq SqMask: 0x3 SqHead: 3197153 SqTail: 3197153 CachedSqHead: 3197153 SqThread: 9231 SqThreadCpu: 11 SqTotalTime: 18099614 SqWorkTime: 16748316 The test results corresponding to different iodepths are as follows: |-----------|-------|-------|-------|------|-------| | iodepth | 1 | 4 | 8 | 16 | 64 | |-----------|-------|-------|-------|------|-------| |utilization| 2.9% | 8.8% | 10.9% | 92.9%| 84.4% | |-----------|-------|-------|-------|------|-------| | idle | 97.1% | 91.2% | 89.1% | 7.1% | 15.6% | |-----------|-------|-------|-------|------|-------| Signed-off-by: Xiaobing Li <xiaobing.li@samsung.com> Link: https://lore.kernel.org/r/20240228091251.543383-1-xiaobing.li@samsung.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent eb18c29 commit 3fcb9d1

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed
 

‎io_uring/fdinfo.c

+7
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ __cold void io_uring_show_fdinfo(struct seq_file *m, struct file *f)
5555
struct io_ring_ctx *ctx = f->private_data;
5656
struct io_overflow_cqe *ocqe;
5757
struct io_rings *r = ctx->rings;
58+
struct rusage sq_usage;
5859
unsigned int sq_mask = ctx->sq_entries - 1, cq_mask = ctx->cq_entries - 1;
5960
unsigned int sq_head = READ_ONCE(r->sq.head);
6061
unsigned int sq_tail = READ_ONCE(r->sq.tail);
@@ -64,6 +65,7 @@ __cold void io_uring_show_fdinfo(struct seq_file *m, struct file *f)
6465
unsigned int sq_shift = 0;
6566
unsigned int sq_entries, cq_entries;
6667
int sq_pid = -1, sq_cpu = -1;
68+
u64 sq_total_time = 0, sq_work_time = 0;
6769
bool has_lock;
6870
unsigned int i;
6971

@@ -147,10 +149,15 @@ __cold void io_uring_show_fdinfo(struct seq_file *m, struct file *f)
147149

148150
sq_pid = sq->task_pid;
149151
sq_cpu = sq->sq_cpu;
152+
getrusage(sq->thread, RUSAGE_SELF, &sq_usage);
153+
sq_total_time = sq_usage.ru_stime.tv_sec * 1000000 + sq_usage.ru_stime.tv_usec;
154+
sq_work_time = sq->work_time;
150155
}
151156

152157
seq_printf(m, "SqThread:\t%d\n", sq_pid);
153158
seq_printf(m, "SqThreadCpu:\t%d\n", sq_cpu);
159+
seq_printf(m, "SqTotalTime:\t%llu\n", sq_total_time);
160+
seq_printf(m, "SqWorkTime:\t%llu\n", sq_work_time);
154161
seq_printf(m, "UserFiles:\t%u\n", ctx->nr_user_files);
155162
for (i = 0; has_lock && i < ctx->nr_user_files; i++) {
156163
struct file *f = io_file_from_index(&ctx->file_table, i);

‎io_uring/sqpoll.c

+16-1
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,23 @@ static bool io_sq_tw_pending(struct llist_node *retry_list)
253253
return retry_list || !llist_empty(&tctx->task_list);
254254
}
255255

256+
static void io_sq_update_worktime(struct io_sq_data *sqd, struct rusage *start)
257+
{
258+
struct rusage end;
259+
260+
getrusage(current, RUSAGE_SELF, &end);
261+
end.ru_stime.tv_sec -= start->ru_stime.tv_sec;
262+
end.ru_stime.tv_usec -= start->ru_stime.tv_usec;
263+
264+
sqd->work_time += end.ru_stime.tv_usec + end.ru_stime.tv_sec * 1000000;
265+
}
266+
256267
static int io_sq_thread(void *data)
257268
{
258269
struct llist_node *retry_list = NULL;
259270
struct io_sq_data *sqd = data;
260271
struct io_ring_ctx *ctx;
272+
struct rusage start;
261273
unsigned long timeout = 0;
262274
char buf[TASK_COMM_LEN];
263275
DEFINE_WAIT(wait);
@@ -286,6 +298,7 @@ static int io_sq_thread(void *data)
286298
}
287299

288300
cap_entries = !list_is_singular(&sqd->ctx_list);
301+
getrusage(current, RUSAGE_SELF, &start);
289302
list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) {
290303
int ret = __io_sq_thread(ctx, cap_entries);
291304

@@ -296,8 +309,10 @@ static int io_sq_thread(void *data)
296309
sqt_spin = true;
297310

298311
if (sqt_spin || !time_after(jiffies, timeout)) {
299-
if (sqt_spin)
312+
if (sqt_spin) {
313+
io_sq_update_worktime(sqd, &start);
300314
timeout = jiffies + sqd->sq_thread_idle;
315+
}
301316
if (unlikely(need_resched())) {
302317
mutex_unlock(&sqd->lock);
303318
cond_resched();

‎io_uring/sqpoll.h

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct io_sq_data {
1616
pid_t task_pid;
1717
pid_t task_tgid;
1818

19+
u64 work_time;
1920
unsigned long state;
2021
struct completion exited;
2122
};

0 commit comments

Comments
 (0)
Please sign in to comment.