On Wed, Nov 14, 2018 at 12:43:22AM -0800, Christoph Hellwig wrote:
static int nvme_poll_noirq(struct blk_mq_hw_ctx *hctx, unsigned int tag)
{
struct nvme_queue *nvmeq = hctx->driver_data;quoted
u16 start, end;
bool found;
quoted
if (!nvme_cqe_pending(nvmeq))
return 0;
+ spin_lock(&nvmeq->cq_lock);
found = nvme_process_cq(nvmeq, &start, &end, tag);
+ spin_unlock(&nvmeq->cq_lock);
+
nvme_complete_cqes(nvmeq, start, end);
return found;
And while we are at it: I think for the irq-driven queues in a
separate queue for poll setup we might not even need to take the
CQ lock. Which might be an argument for only allowing polling
if we have the separate queues just to keep everything simple.
That's a pretty cool observation. We still poll interrupt driven queues
in the timeout path as a sanity check (it really has helped in debugging
timeout issues), but we can temporarily disable the cq's irq and be
lockless.