162306a36Sopenharmony_ci#ifndef INTERNAL_IO_WQ_H
262306a36Sopenharmony_ci#define INTERNAL_IO_WQ_H
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#include <linux/refcount.h>
562306a36Sopenharmony_ci#include <linux/io_uring_types.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_cistruct io_wq;
862306a36Sopenharmony_ci
962306a36Sopenharmony_cienum {
1062306a36Sopenharmony_ci	IO_WQ_WORK_CANCEL	= 1,
1162306a36Sopenharmony_ci	IO_WQ_WORK_HASHED	= 2,
1262306a36Sopenharmony_ci	IO_WQ_WORK_UNBOUND	= 4,
1362306a36Sopenharmony_ci	IO_WQ_WORK_CONCURRENT	= 16,
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci	IO_WQ_HASH_SHIFT	= 24,	/* upper 8 bits are used for hash key */
1662306a36Sopenharmony_ci};
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cienum io_wq_cancel {
1962306a36Sopenharmony_ci	IO_WQ_CANCEL_OK,	/* cancelled before started */
2062306a36Sopenharmony_ci	IO_WQ_CANCEL_RUNNING,	/* found, running, and attempted cancelled */
2162306a36Sopenharmony_ci	IO_WQ_CANCEL_NOTFOUND,	/* work not found */
2262306a36Sopenharmony_ci};
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_citypedef struct io_wq_work *(free_work_fn)(struct io_wq_work *);
2562306a36Sopenharmony_citypedef void (io_wq_work_fn)(struct io_wq_work *);
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistruct io_wq_hash {
2862306a36Sopenharmony_ci	refcount_t refs;
2962306a36Sopenharmony_ci	unsigned long map;
3062306a36Sopenharmony_ci	struct wait_queue_head wait;
3162306a36Sopenharmony_ci};
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cistatic inline void io_wq_put_hash(struct io_wq_hash *hash)
3462306a36Sopenharmony_ci{
3562306a36Sopenharmony_ci	if (refcount_dec_and_test(&hash->refs))
3662306a36Sopenharmony_ci		kfree(hash);
3762306a36Sopenharmony_ci}
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistruct io_wq_data {
4062306a36Sopenharmony_ci	struct io_wq_hash *hash;
4162306a36Sopenharmony_ci	struct task_struct *task;
4262306a36Sopenharmony_ci	io_wq_work_fn *do_work;
4362306a36Sopenharmony_ci	free_work_fn *free_work;
4462306a36Sopenharmony_ci};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistruct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data);
4762306a36Sopenharmony_civoid io_wq_exit_start(struct io_wq *wq);
4862306a36Sopenharmony_civoid io_wq_put_and_exit(struct io_wq *wq);
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_civoid io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work);
5162306a36Sopenharmony_civoid io_wq_hash_work(struct io_wq_work *work, void *val);
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ciint io_wq_cpu_affinity(struct io_uring_task *tctx, cpumask_var_t mask);
5462306a36Sopenharmony_ciint io_wq_max_workers(struct io_wq *wq, int *new_count);
5562306a36Sopenharmony_cibool io_wq_worker_stopped(void);
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_cistatic inline bool io_wq_is_hashed(struct io_wq_work *work)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	return work->flags & IO_WQ_WORK_HASHED;
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_citypedef bool (work_cancel_fn)(struct io_wq_work *, void *);
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_cienum io_wq_cancel io_wq_cancel_cb(struct io_wq *wq, work_cancel_fn *cancel,
6562306a36Sopenharmony_ci					void *data, bool cancel_all);
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci#if defined(CONFIG_IO_WQ)
6862306a36Sopenharmony_ciextern void io_wq_worker_sleeping(struct task_struct *);
6962306a36Sopenharmony_ciextern void io_wq_worker_running(struct task_struct *);
7062306a36Sopenharmony_ci#else
7162306a36Sopenharmony_cistatic inline void io_wq_worker_sleeping(struct task_struct *tsk)
7262306a36Sopenharmony_ci{
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_cistatic inline void io_wq_worker_running(struct task_struct *tsk)
7562306a36Sopenharmony_ci{
7662306a36Sopenharmony_ci}
7762306a36Sopenharmony_ci#endif
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_cistatic inline bool io_wq_current_is_worker(void)
8062306a36Sopenharmony_ci{
8162306a36Sopenharmony_ci	return in_task() && (current->flags & PF_IO_WORKER) &&
8262306a36Sopenharmony_ci		current->worker_private;
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci#endif
85