Commit 2293b419 authored by Pavel Begunkov's avatar Pavel Begunkov Committed by Jens Axboe
Browse files

io-wq: remove duplicated cancel code



Deduplicate cancellation parts, as many of them looks the same, as do
e.g.
- io_wqe_cancel_cb_work() and io_wqe_cancel_work()
- io_wq_worker_cancel() and io_work_cancel()

Signed-off-by: default avatarPavel Begunkov <asml.silence@gmail.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 3f9d6441
Loading
Loading
Loading
Loading
+24 −112
Original line number Diff line number Diff line
@@ -855,14 +855,13 @@ void io_wq_cancel_all(struct io_wq *wq)
}

struct io_cb_cancel_data {
	struct io_wqe *wqe;
	work_cancel_fn *cancel;
	void *caller_data;
	work_cancel_fn *fn;
	void *data;
};

static bool io_work_cancel(struct io_worker *worker, void *cancel_data)
static bool io_wq_worker_cancel(struct io_worker *worker, void *data)
{
	struct io_cb_cancel_data *data = cancel_data;
	struct io_cb_cancel_data *match = data;
	unsigned long flags;
	bool ret = false;

@@ -873,83 +872,7 @@ static bool io_work_cancel(struct io_worker *worker, void *cancel_data)
	spin_lock_irqsave(&worker->lock, flags);
	if (worker->cur_work &&
	    !(worker->cur_work->flags & IO_WQ_WORK_NO_CANCEL) &&
	    data->cancel(worker->cur_work, data->caller_data)) {
		send_sig(SIGINT, worker->task, 1);
		ret = true;
	}
	spin_unlock_irqrestore(&worker->lock, flags);

	return ret;
}

static enum io_wq_cancel io_wqe_cancel_cb_work(struct io_wqe *wqe,
					       work_cancel_fn *cancel,
					       void *cancel_data)
{
	struct io_cb_cancel_data data = {
		.wqe = wqe,
		.cancel = cancel,
		.caller_data = cancel_data,
	};
	struct io_wq_work_node *node, *prev;
	struct io_wq_work *work;
	unsigned long flags;
	bool found = false;

	spin_lock_irqsave(&wqe->lock, flags);
	wq_list_for_each(node, prev, &wqe->work_list) {
		work = container_of(node, struct io_wq_work, list);

		if (cancel(work, cancel_data)) {
			wq_node_del(&wqe->work_list, node, prev);
			found = true;
			break;
		}
	}
	spin_unlock_irqrestore(&wqe->lock, flags);

	if (found) {
		io_run_cancel(work, wqe);
		return IO_WQ_CANCEL_OK;
	}

	rcu_read_lock();
	found = io_wq_for_each_worker(wqe, io_work_cancel, &data);
	rcu_read_unlock();
	return found ? IO_WQ_CANCEL_RUNNING : IO_WQ_CANCEL_NOTFOUND;
}

enum io_wq_cancel io_wq_cancel_cb(struct io_wq *wq, work_cancel_fn *cancel,
				  void *data)
{
	enum io_wq_cancel ret = IO_WQ_CANCEL_NOTFOUND;
	int node;

	for_each_node(node) {
		struct io_wqe *wqe = wq->wqes[node];

		ret = io_wqe_cancel_cb_work(wqe, cancel, data);
		if (ret != IO_WQ_CANCEL_NOTFOUND)
			break;
	}

	return ret;
}

struct work_match {
	bool (*fn)(struct io_wq_work *, void *data);
	void *data;
};

static bool io_wq_worker_cancel(struct io_worker *worker, void *data)
{
	struct work_match *match = data;
	unsigned long flags;
	bool ret = false;

	spin_lock_irqsave(&worker->lock, flags);
	if (match->fn(worker->cur_work, match->data) &&
	    !(worker->cur_work->flags & IO_WQ_WORK_NO_CANCEL)) {
	    match->fn(worker->cur_work, match->data)) {
		send_sig(SIGINT, worker->task, 1);
		ret = true;
	}
@@ -959,7 +882,7 @@ static bool io_wq_worker_cancel(struct io_worker *worker, void *data)
}

static enum io_wq_cancel io_wqe_cancel_work(struct io_wqe *wqe,
					    struct work_match *match)
					    struct io_cb_cancel_data *match)
{
	struct io_wq_work_node *node, *prev;
	struct io_wq_work *work;
@@ -1000,22 +923,16 @@ static enum io_wq_cancel io_wqe_cancel_work(struct io_wqe *wqe,
	return found ? IO_WQ_CANCEL_RUNNING : IO_WQ_CANCEL_NOTFOUND;
}

static bool io_wq_work_match(struct io_wq_work *work, void *data)
{
	return work == data;
}

enum io_wq_cancel io_wq_cancel_work(struct io_wq *wq, struct io_wq_work *cwork)
enum io_wq_cancel io_wq_cancel_cb(struct io_wq *wq, work_cancel_fn *cancel,
				  void *data)
{
	struct work_match match = {
		.fn	= io_wq_work_match,
		.data	= cwork
	struct io_cb_cancel_data match = {
		.fn	= cancel,
		.data	= data,
	};
	enum io_wq_cancel ret = IO_WQ_CANCEL_NOTFOUND;
	int node;

	cwork->flags |= IO_WQ_WORK_CANCEL;

	for_each_node(node) {
		struct io_wqe *wqe = wq->wqes[node];

@@ -1027,33 +944,28 @@ enum io_wq_cancel io_wq_cancel_work(struct io_wq *wq, struct io_wq_work *cwork)
	return ret;
}

static bool io_wq_io_cb_cancel_data(struct io_wq_work *work, void *data)
{
	return work == data;
}

enum io_wq_cancel io_wq_cancel_work(struct io_wq *wq, struct io_wq_work *cwork)
{
	return io_wq_cancel_cb(wq, io_wq_io_cb_cancel_data, (void *)cwork);
}

static bool io_wq_pid_match(struct io_wq_work *work, void *data)
{
	pid_t pid = (pid_t) (unsigned long) data;

	if (work)
	return work->task_pid == pid;
	return false;
}

enum io_wq_cancel io_wq_cancel_pid(struct io_wq *wq, pid_t pid)
{
	struct work_match match = {
		.fn	= io_wq_pid_match,
		.data	= (void *) (unsigned long) pid
	};
	enum io_wq_cancel ret = IO_WQ_CANCEL_NOTFOUND;
	int node;

	for_each_node(node) {
		struct io_wqe *wqe = wq->wqes[node];
	void *data = (void *) (unsigned long) pid;

		ret = io_wqe_cancel_work(wqe, &match);
		if (ret != IO_WQ_CANCEL_NOTFOUND)
			break;
	}

	return ret;
	return io_wq_cancel_cb(wq, io_wq_pid_match, data);
}

struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)