0001 #ifndef INTERNAL_IO_WQ_H
0002 #define INTERNAL_IO_WQ_H
0003
0004 #include <linux/refcount.h>
0005 #include <linux/io_uring_types.h>
0006
0007 struct io_wq;
0008
0009 enum {
0010 IO_WQ_WORK_CANCEL = 1,
0011 IO_WQ_WORK_HASHED = 2,
0012 IO_WQ_WORK_UNBOUND = 4,
0013 IO_WQ_WORK_CONCURRENT = 16,
0014
0015 IO_WQ_HASH_SHIFT = 24,
0016 };
0017
0018 enum io_wq_cancel {
0019 IO_WQ_CANCEL_OK,
0020 IO_WQ_CANCEL_RUNNING,
0021 IO_WQ_CANCEL_NOTFOUND,
0022 };
0023
0024 typedef struct io_wq_work *(free_work_fn)(struct io_wq_work *);
0025 typedef void (io_wq_work_fn)(struct io_wq_work *);
0026
0027 struct io_wq_hash {
0028 refcount_t refs;
0029 unsigned long map;
0030 struct wait_queue_head wait;
0031 };
0032
0033 static inline void io_wq_put_hash(struct io_wq_hash *hash)
0034 {
0035 if (refcount_dec_and_test(&hash->refs))
0036 kfree(hash);
0037 }
0038
0039 struct io_wq_data {
0040 struct io_wq_hash *hash;
0041 struct task_struct *task;
0042 io_wq_work_fn *do_work;
0043 free_work_fn *free_work;
0044 };
0045
0046 struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data);
0047 void io_wq_exit_start(struct io_wq *wq);
0048 void io_wq_put_and_exit(struct io_wq *wq);
0049
0050 void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work);
0051 void io_wq_hash_work(struct io_wq_work *work, void *val);
0052
0053 int io_wq_cpu_affinity(struct io_wq *wq, cpumask_var_t mask);
0054 int io_wq_max_workers(struct io_wq *wq, int *new_count);
0055
0056 static inline bool io_wq_is_hashed(struct io_wq_work *work)
0057 {
0058 return work->flags & IO_WQ_WORK_HASHED;
0059 }
0060
0061 typedef bool (work_cancel_fn)(struct io_wq_work *, void *);
0062
0063 enum io_wq_cancel io_wq_cancel_cb(struct io_wq *wq, work_cancel_fn *cancel,
0064 void *data, bool cancel_all);
0065
0066 #if defined(CONFIG_IO_WQ)
0067 extern void io_wq_worker_sleeping(struct task_struct *);
0068 extern void io_wq_worker_running(struct task_struct *);
0069 #else
0070 static inline void io_wq_worker_sleeping(struct task_struct *tsk)
0071 {
0072 }
0073 static inline void io_wq_worker_running(struct task_struct *tsk)
0074 {
0075 }
0076 #endif
0077
0078 static inline bool io_wq_current_is_worker(void)
0079 {
0080 return in_task() && (current->flags & PF_IO_WORKER) &&
0081 current->worker_private;
0082 }
0083 #endif