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