[PATCH] nvme-tcp: Fix possible race of io_work and direct send
Or Gerlitz
gerlitz.or at gmail.com
Sun Jan 10 03:06:51 EST 2021
On Fri, Jan 8, 2021 at 10:20 PM Sagi Grimberg <sagi at grimberg.me> wrote:
> Well, this is a heuristic anyways, too bad we need to
> disable preemption just for this...
>
> I'm assuming that this makes the issue go away?
> --
> diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
> index cf856103025a..ea07336ca179 100644
> --- a/drivers/nvme/host/tcp.c
> +++ b/drivers/nvme/host/tcp.c
> @@ -281,8 +281,11 @@ static inline void nvme_tcp_queue_request(struct
> nvme_tcp_request *req,
> bool sync, bool last)
> {
> struct nvme_tcp_queue *queue = req->queue;
> + int cpu;
> bool empty;
>
> + cpu = get_cpu();
> + put_cpu();
> empty = llist_add(&req->lentry, &queue->req_list) &&
> list_empty(&queue->send_list) && !queue->request;
>
> @@ -291,8 +294,8 @@ static inline void nvme_tcp_queue_request(struct
> nvme_tcp_request *req,
> * directly, otherwise queue io_work. Also, only do that if we
> * are on the same cpu, so we don't introduce contention.
> */
> - if (queue->io_cpu == smp_processor_id() &&
> - sync && empty && mutex_trylock(&queue->send_mutex)) {
> + if (queue->io_cpu == cpu && sync && empty &&
if preemption happens here, the value returned by get_cpu() is not where
we run when the actual comparison takes place. So what you are saying
is that overall correctness will not be hurt? worth putting a comment
here for readers / future modifiers of the code
> + mutex_trylock(&queue->send_mutex)) {
> queue->more_requests = !last;
> nvme_tcp_send_all(queue);
> queue->more_requests = false;
More information about the Linux-nvme
mailing list