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