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