io-wq.h 2.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
#ifndef INTERNAL_IO_WQ_H
#define INTERNAL_IO_WQ_H

struct io_wq;

enum {
	IO_WQ_WORK_CANCEL	= 1,
	IO_WQ_WORK_HAS_MM	= 2,
	IO_WQ_WORK_HASHED	= 4,
	IO_WQ_WORK_NEEDS_USER	= 8,
11
	IO_WQ_WORK_NEEDS_FILES	= 16,
12
	IO_WQ_WORK_UNBOUND	= 32,
13
	IO_WQ_WORK_INTERNAL	= 64,
14
	IO_WQ_WORK_CB		= 128,
15 16 17 18 19 20 21 22 23 24

	IO_WQ_HASH_SHIFT	= 24,	/* upper 8 bits are used for hash key */
};

enum io_wq_cancel {
	IO_WQ_CANCEL_OK,	/* cancelled before started */
	IO_WQ_CANCEL_RUNNING,	/* found, running, and attempted cancelled */
	IO_WQ_CANCEL_NOTFOUND,	/* work not found */
};

J
Jens Axboe 已提交
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
struct io_wq_work_node {
	struct io_wq_work_node *next;
};

struct io_wq_work_list {
	struct io_wq_work_node *first;
	struct io_wq_work_node *last;
};

static inline void wq_list_add_tail(struct io_wq_work_node *node,
				    struct io_wq_work_list *list)
{
	if (!list->first) {
		list->first = list->last = node;
	} else {
		list->last->next = node;
		list->last = node;
	}
}

static inline void wq_node_del(struct io_wq_work_list *list,
			       struct io_wq_work_node *node,
			       struct io_wq_work_node *prev)
{
	if (node == list->first)
		list->first = node->next;
	if (node == list->last)
		list->last = prev;
	if (prev)
		prev->next = node->next;
55
	node->next = NULL;
J
Jens Axboe 已提交
56 57 58 59 60 61 62 63 64 65 66
}

#define wq_list_for_each(pos, prv, head)			\
	for (pos = (head)->first, prv = NULL; pos; prv = pos, pos = (pos)->next)

#define wq_list_empty(list)	((list)->first == NULL)
#define INIT_WQ_LIST(list)	do {				\
	(list)->first = NULL;					\
	(list)->last = NULL;					\
} while (0)

67
struct io_wq_work {
68
	union {
J
Jens Axboe 已提交
69
		struct io_wq_work_node list;
70 71
		void *data;
	};
72
	void (*func)(struct io_wq_work **);
73
	struct files_struct *files;
J
Jens Axboe 已提交
74
	unsigned flags;
75 76 77 78
};

#define INIT_IO_WORK(work, _func)			\
	do {						\
J
Jens Axboe 已提交
79
		(work)->list.next = NULL;		\
80 81
		(work)->func = _func;			\
		(work)->flags = 0;			\
82
		(work)->files = NULL;			\
83 84
	} while (0)					\

85 86 87
typedef void (get_work_fn)(struct io_wq_work *);
typedef void (put_work_fn)(struct io_wq_work *);

88 89 90
struct io_wq_data {
	struct mm_struct *mm;
	struct user_struct *user;
91
	const struct cred *creds;
92 93 94 95 96 97

	get_work_fn *get_work;
	put_work_fn *put_work;
};

struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data);
98 99 100 101 102 103 104 105 106
void io_wq_destroy(struct io_wq *wq);

void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work);
void io_wq_enqueue_hashed(struct io_wq *wq, struct io_wq_work *work, void *val);
void io_wq_flush(struct io_wq *wq);

void io_wq_cancel_all(struct io_wq *wq);
enum io_wq_cancel io_wq_cancel_work(struct io_wq *wq, struct io_wq_work *cwork);

107 108 109 110 111
typedef bool (work_cancel_fn)(struct io_wq_work *, void *);

enum io_wq_cancel io_wq_cancel_cb(struct io_wq *wq, work_cancel_fn *cancel,
					void *data);

112 113 114 115 116 117 118 119 120 121
#if defined(CONFIG_IO_WQ)
extern void io_wq_worker_sleeping(struct task_struct *);
extern void io_wq_worker_running(struct task_struct *);
#else
static inline void io_wq_worker_sleeping(struct task_struct *tsk)
{
}
static inline void io_wq_worker_running(struct task_struct *tsk)
{
}
122
#endif /* CONFIG_IO_WQ */
123

124
#endif /* INTERNAL_IO_WQ_H */