Samba with multichannel and io_uring
Jens Axboe
axboe at kernel.dk
Fri Oct 16 18:56:52 UTC 2020
On 10/16/20 6:40 AM, Stefan Metzmacher wrote:
> Am 16.10.20 um 14:28 schrieb Stefan Metzmacher via samba-technical:
>>> I just found that proc_task_name() handles PF_WQ_WORKER special
>>> and cat /proc/$pid/comm can expose something like:
>>> kworker/u17:2-btrfs-worker-high
>>>
>>> ps and top still truncate, but that can be fixed.
>>
>> I commented on https://gitlab.com/procps-ng/procps/-/issues/51
>
> Ok, it's already fixed in newer versions:
> https://gitlab.com/procps-ng/procps/-/commit/2cfdbbe897f0d4e41460c7c2b92acfc5804652c8
>
> So it would be great to let proc_task_name() expose more verbose
> for io-wq tasks in order to avoid the limit of set_task_comm().
Here's a first cut, format is explained in the last hunk in io-wq.
We can't easily get the fd in there, so for sequence, it's just
an incrementing long. It shows up in fdinfo as well, so you can
match them up.
diff --git a/fs/io-wq.c b/fs/io-wq.c
index 0c852b75384d..3e2cab10e6f3 100644
--- a/fs/io-wq.c
+++ b/fs/io-wq.c
@@ -41,6 +41,8 @@ enum {
IO_WQE_FLAG_STALLED = 1, /* stalled on hash */
};
+static atomic_long_t seq;
+
/*
* One for each thread in a wqe pool
*/
@@ -117,6 +119,8 @@ struct io_wq {
free_work_fn *free_work;
io_wq_work_fn *do_work;
+ long seq;
+
struct task_struct *manager;
struct user_struct *user;
refcount_t refs;
@@ -671,7 +675,7 @@ static bool create_io_worker(struct io_wq *wq, struct io_wqe *wqe, int index)
spin_lock_init(&worker->lock);
worker->task = kthread_create_on_node(io_wqe_worker, worker, wqe->node,
- "io_wqe_worker-%d/%d", index, wqe->node);
+ "io_wq");
if (IS_ERR(worker->task)) {
kfree(worker);
return false;
@@ -1084,6 +1088,7 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
wq->free_work = data->free_work;
wq->do_work = data->do_work;
+ wq->seq = atomic_long_inc_return(&seq);
/* caller must already hold a reference to this */
wq->user = data->user;
@@ -1177,3 +1182,39 @@ struct task_struct *io_wq_get_task(struct io_wq *wq)
{
return wq->manager;
}
+
+long io_wq_get_seq(struct io_wq *wq)
+{
+ return wq ? wq->seq : 0;
+}
+
+void io_wq_comm(char *buf, size_t size, struct task_struct *task)
+{
+ struct io_worker *worker = kthread_data(task);
+ struct io_wqe *wqe;
+ int off;
+
+ off = strscpy(buf, task->comm, size);
+ if (off < 0)
+ return;
+
+ rcu_read_lock();
+ if (!io_worker_get(worker)) {
+ rcu_read_unlock();
+ return;
+ }
+ rcu_read_unlock();
+
+ spin_lock_irq(&worker->lock);
+ wqe = worker->wqe;
+
+ /*
+ * Format: -seq-node-U/B for bound or unbound. Seq can be found in
+ * the ring fd fdinfo as well.
+ */
+ scnprintf(buf + off, size - off, "-%ld-%d%c%c", wqe->wq->seq, wqe->node,
+ worker->flags & IO_WORKER_F_RUNNING ? '+' : '-',
+ worker->flags & IO_WORKER_F_BOUND ? 'B' : 'U');
+ spin_unlock_irq(&worker->lock);
+ io_worker_release(worker);
+}
diff --git a/fs/io-wq.h b/fs/io-wq.h
index be21c500c925..bede7ab5ac95 100644
--- a/fs/io-wq.h
+++ b/fs/io-wq.h
@@ -136,6 +136,7 @@ enum io_wq_cancel io_wq_cancel_cb(struct io_wq *wq, work_cancel_fn *cancel,
void *data, bool cancel_all);
struct task_struct *io_wq_get_task(struct io_wq *wq);
+long io_wq_get_seq(struct io_wq *wq);
#if defined(CONFIG_IO_WQ)
extern void io_wq_worker_sleeping(struct task_struct *);
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 39c38e48dc11..83df6a326903 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -8980,6 +8980,7 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
seq_printf(m, "SqThread:\t%d\n", sq ? task_pid_nr(sq->thread) : -1);
seq_printf(m, "SqThreadCpu:\t%d\n", sq ? task_cpu(sq->thread) : -1);
+ seq_printf(m, "WqSeq:\t%ld\n", io_wq_get_seq(ctx->io_wq));
seq_printf(m, "UserFiles:\t%u\n", ctx->nr_user_files);
for (i = 0; has_lock && i < ctx->nr_user_files; i++) {
struct fixed_file_table *table;
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 65ec2029fa80..d8f8fbbe9639 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -91,6 +91,7 @@
#include <linux/string_helpers.h>
#include <linux/user_namespace.h>
#include <linux/fs_struct.h>
+#include <linux/io_uring.h>
#include <asm/processor.h>
#include "internal.h"
@@ -104,6 +105,8 @@ void proc_task_name(struct seq_file *m, struct task_struct *p, bool escape)
if (p->flags & PF_WQ_WORKER)
wq_worker_comm(tcomm, sizeof(tcomm), p);
+ else if (p->flags & PF_IO_WORKER)
+ io_wq_comm(tcomm, sizeof(tcomm), p);
else
__get_task_comm(tcomm, sizeof(tcomm), p);
diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h
index 28939820b6b0..507077f3dac9 100644
--- a/include/linux/io_uring.h
+++ b/include/linux/io_uring.h
@@ -34,6 +34,7 @@ struct sock *io_uring_get_socket(struct file *file);
void __io_uring_task_cancel(void);
void __io_uring_files_cancel(struct files_struct *files);
void __io_uring_free(struct task_struct *tsk);
+void io_wq_comm(char *buf, size_t size, struct task_struct *task);
static inline void io_uring_task_cancel(void)
{
@@ -64,6 +65,9 @@ static inline void io_uring_files_cancel(struct files_struct *files)
static inline void io_uring_free(struct task_struct *tsk)
{
}
+static inline void io_wq_comm(char *buf, size_t size, struct task_struct *task)
+{
+}
#endif
#endif
--
Jens Axboe
More information about the samba-technical
mailing list