xref: /linux/io_uring/io-wq.h (revision f4b369c6fe0ceaba2da2daff8c9eb415f85926dd)
1*ccd18ce2STim Bird /* SPDX-License-Identifier: GPL-2.0 */
2ed29b0b4SJens Axboe #ifndef INTERNAL_IO_WQ_H
3ed29b0b4SJens Axboe #define INTERNAL_IO_WQ_H
4ed29b0b4SJens Axboe 
5ed29b0b4SJens Axboe #include <linux/refcount.h>
6ab1c84d8SPavel Begunkov #include <linux/io_uring_types.h>
7ed29b0b4SJens Axboe 
8ed29b0b4SJens Axboe struct io_wq;
9ed29b0b4SJens Axboe 
10ed29b0b4SJens Axboe enum {
11ed29b0b4SJens Axboe 	IO_WQ_WORK_CANCEL	= 1,
12ed29b0b4SJens Axboe 	IO_WQ_WORK_HASHED	= 2,
13ed29b0b4SJens Axboe 	IO_WQ_WORK_UNBOUND	= 4,
14ed29b0b4SJens Axboe 	IO_WQ_WORK_CONCURRENT	= 16,
15ed29b0b4SJens Axboe 
16ed29b0b4SJens Axboe 	IO_WQ_HASH_SHIFT	= 24,	/* upper 8 bits are used for hash key */
17ed29b0b4SJens Axboe };
18ed29b0b4SJens Axboe 
19ed29b0b4SJens Axboe enum io_wq_cancel {
20ed29b0b4SJens Axboe 	IO_WQ_CANCEL_OK,	/* cancelled before started */
21ed29b0b4SJens Axboe 	IO_WQ_CANCEL_RUNNING,	/* found, running, and attempted cancelled */
22ed29b0b4SJens Axboe 	IO_WQ_CANCEL_NOTFOUND,	/* work not found */
23ed29b0b4SJens Axboe };
24ed29b0b4SJens Axboe 
25ed29b0b4SJens Axboe struct io_wq_hash {
26ed29b0b4SJens Axboe 	refcount_t refs;
27ed29b0b4SJens Axboe 	unsigned long map;
28ed29b0b4SJens Axboe 	struct wait_queue_head wait;
29ed29b0b4SJens Axboe };
30ed29b0b4SJens Axboe 
io_wq_put_hash(struct io_wq_hash * hash)31ed29b0b4SJens Axboe static inline void io_wq_put_hash(struct io_wq_hash *hash)
32ed29b0b4SJens Axboe {
33ed29b0b4SJens Axboe 	if (refcount_dec_and_test(&hash->refs))
34ed29b0b4SJens Axboe 		kfree(hash);
35ed29b0b4SJens Axboe }
36ed29b0b4SJens Axboe 
37ed29b0b4SJens Axboe struct io_wq_data {
38ed29b0b4SJens Axboe 	struct io_wq_hash *hash;
39ed29b0b4SJens Axboe 	struct task_struct *task;
40ed29b0b4SJens Axboe };
41ed29b0b4SJens Axboe 
42ed29b0b4SJens Axboe struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data);
43ed29b0b4SJens Axboe void io_wq_exit_start(struct io_wq *wq);
44ed29b0b4SJens Axboe void io_wq_put_and_exit(struct io_wq *wq);
4538aa434aSLi Chen void io_wq_set_exit_on_idle(struct io_wq *wq, bool enable);
46ed29b0b4SJens Axboe 
47ed29b0b4SJens Axboe void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work);
48ed29b0b4SJens Axboe void io_wq_hash_work(struct io_wq_work *work, void *val);
49ed29b0b4SJens Axboe 
50ebdfefc0SJens Axboe int io_wq_cpu_affinity(struct io_uring_task *tctx, cpumask_var_t mask);
51ed29b0b4SJens Axboe int io_wq_max_workers(struct io_wq *wq, int *new_count);
5245500dc4SPavel Begunkov bool io_wq_worker_stopped(void);
53ed29b0b4SJens Axboe 
__io_wq_is_hashed(unsigned int work_flags)546ee78354SMax Kellermann static inline bool __io_wq_is_hashed(unsigned int work_flags)
556ee78354SMax Kellermann {
566ee78354SMax Kellermann 	return work_flags & IO_WQ_WORK_HASHED;
576ee78354SMax Kellermann }
586ee78354SMax Kellermann 
io_wq_is_hashed(struct io_wq_work * work)59ed29b0b4SJens Axboe static inline bool io_wq_is_hashed(struct io_wq_work *work)
60ed29b0b4SJens Axboe {
616ee78354SMax Kellermann 	return __io_wq_is_hashed(atomic_read(&work->flags));
62ed29b0b4SJens Axboe }
63ed29b0b4SJens Axboe 
64ed29b0b4SJens Axboe typedef bool (work_cancel_fn)(struct io_wq_work *, void *);
65ed29b0b4SJens Axboe 
66ed29b0b4SJens Axboe enum io_wq_cancel io_wq_cancel_cb(struct io_wq *wq, work_cancel_fn *cancel,
67ed29b0b4SJens Axboe 					void *data, bool cancel_all);
68ed29b0b4SJens Axboe 
69ed29b0b4SJens Axboe #if defined(CONFIG_IO_WQ)
70ed29b0b4SJens Axboe extern void io_wq_worker_sleeping(struct task_struct *);
71ed29b0b4SJens Axboe extern void io_wq_worker_running(struct task_struct *);
72ed29b0b4SJens Axboe #else
io_wq_worker_sleeping(struct task_struct * tsk)73ed29b0b4SJens Axboe static inline void io_wq_worker_sleeping(struct task_struct *tsk)
74ed29b0b4SJens Axboe {
75ed29b0b4SJens Axboe }
io_wq_worker_running(struct task_struct * tsk)76ed29b0b4SJens Axboe static inline void io_wq_worker_running(struct task_struct *tsk)
77ed29b0b4SJens Axboe {
78ed29b0b4SJens Axboe }
79ed29b0b4SJens Axboe #endif
80ed29b0b4SJens Axboe 
io_wq_current_is_worker(void)81ed29b0b4SJens Axboe static inline bool io_wq_current_is_worker(void)
82ed29b0b4SJens Axboe {
83ed29b0b4SJens Axboe 	return in_task() && (current->flags & PF_IO_WORKER) &&
84ed29b0b4SJens Axboe 		current->worker_private;
85ed29b0b4SJens Axboe }
86ed29b0b4SJens Axboe #endif
87