From patchwork Fri Jun 22 11:22:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gersner X-Patchwork-Id: 933280 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ua0bVSyo"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41BxLW5rZ0z9s1B for ; Fri, 22 Jun 2018 21:34:43 +1000 (AEST) Received: from localhost ([::1]:32843 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWKKv-00079x-Bs for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 07:34:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58674) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWKAN-0007Vt-Ak for qemu-devel@nongnu.org; Fri, 22 Jun 2018 07:23:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWKAL-0005Zb-Td for qemu-devel@nongnu.org; Fri, 22 Jun 2018 07:23:47 -0400 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:41045) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fWKAI-0005Xa-KE; Fri, 22 Jun 2018 07:23:42 -0400 Received: by mail-wr0-x241.google.com with SMTP id h10-v6so6336531wrq.8; Fri, 22 Jun 2018 04:23:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=bCARgajCYfDTHITTvsIiJfEs0NMSqQ47fieTqivgiL8=; b=ua0bVSyoiQDR4zbQ0zUeN0A7X5JzXx5a1l+5E6enY4lrsnVVfo4nj2+cfLkN3EDTbd /l9yHpaA8VIE0SKhFczWcBylDAJ8xpUSsmX2g5W2hnQVcLEujBiPCQzXpBVFGPeHFLTN gY1eKseZvzhChQL/RhObGdI3XOx3mDSNmzyfm6G7s9RBvy71OzbHhBhfcXEgegpDBNS7 tiVIQhJEVH8lRH4XXhT/ouu3DZuWUZhN1rkfEGBRMUnUVTtePzxyeWHf5yx1mnG9U+R2 anC/LF+xHhINsVfP66FfKowcbZ6Ce9lO8DH5gPrc0wsDqxIcN0Ka3MCE9JbykIAcj5Wx sKeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=bCARgajCYfDTHITTvsIiJfEs0NMSqQ47fieTqivgiL8=; b=MgCT8jvgk25OpCGTNm6TIv+800+0qfcTj6SdT3o1INlbQ6++zKa+HeCBjskNZlZdlw TSXHiBSO2zynK9k4K8vAIYUosqCASqMyOj8alip7X+lqS0/dGnlrCAWGam9Eq/wJSsHY 0v2KShD3rzFEaNUWl05YSFxpcDSIM0/KiV7Vz2cB883C1ihyM8U3w7dJJ+XBkqYyu8bY /hgfa517HslYOpcNgcEkVxwmonCuhTfNeIyRTinMT8NDKS+wwcrEjEieXPlAMTO/UFkT ZWRznzCg0uP3syYF31/wJHoADyLZ7HuMjpBH1geRhZr7RsJfgtViXp4F+CIwfrAyHMJP Vomw== X-Gm-Message-State: APt69E32ALnCPAjQ5BVGx4gnIw8RkC/I9Ln1qfycGjYLudMyQEsymNX2 Eb30Dnbcx9pRmbDtws9JQibLZguUrHY= X-Google-Smtp-Source: AAOMgpevKhj0Rd7zxLLso6SjWdctRj/Rwflx716C+x4hCHobMFODIfChk1327MQL244aRRvO2KGssQ== X-Received: by 2002:adf:b782:: with SMTP id s2-v6mr1211044wre.247.1529666621624; Fri, 22 Jun 2018 04:23:41 -0700 (PDT) Received: from localhost.localdomain (bzq-109-64-22-141.red.bezeqint.net. [109.64.22.141]) by smtp.gmail.com with ESMTPSA id e81-v6sm1758833wmi.28.2018.06.22.04.23.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Jun 2018 04:23:41 -0700 (PDT) From: Shimi Gersner To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 22 Jun 2018 11:22:36 +0000 Message-Id: <20180622112237.2131-4-gersner@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622112237.2131-1-gersner@gmail.com> References: <20180622112237.2131-1-gersner@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::241 Subject: [Qemu-devel] [PATCH 4/5] nvme: Fix phantom irq raise X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Keith Busch , Kevin Wolf , David Sariel , Shimi Gersner , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" CQ irq is asserted when requested are ready for the guest to collect. On edge cases, irq is raised when there is no actual request pending on the queue. Irq is raised for a CQ from nvme_post_cqes uncondtionally if there are processes requests or not. nvme_post_cqes is triggered through timer in two cases - Completion of sync or async request. - CQ was emptied by the guest and pending responses may be queued. Consider the following flow - Async request is made while CQ is full. - Guest reads entire CQ and triggers a DB. nvme_post_cqes is scheduled and executed through timer. - Async request is complete and nvme_post_cqes is scheduled and executed through timer. As nvme_post_cqes raises the irq unconditionally, it leads to a raise of the irq while no pending CQ request is ready. Issue is fixed by adding a fast path exit to nvme_post_cqes when it has no pending processing hence no need to raise the irq. Change-Id: Ib7af6c1bcb63d03022d9b57e079fdb2cf954e7dc Signed-off-by: Shimi Gersner --- hw/block/nvme.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 206d8428fd..f639d7ae73 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -265,6 +265,11 @@ static void nvme_post_cqes(void *opaque) NvmeCtrl *n = cq->ctrl; NvmeRequest *req, *next; + // Fast path if nothing to be processed + if (QTAILQ_EMPTY(&cq->req_list)) { + return; + } + QTAILQ_FOREACH_SAFE(req, &cq->req_list, entry, next) { NvmeSQueue *sq; hwaddr addr; @@ -1130,14 +1135,21 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val) return; } + /* + CLARIFICATION + When CQ was full *before* the db write, nvme_post_cqes skipped processing of responses and + as a side effect SQ was unable to process new requests (As they are limited by size). + When CQ is cleared, spawn both processing of all CQs and SQs. As call to timer_mod + is serial, first handle the CQ to clear any pending requests and then clear the associated SQs. + */ start_sqs = nvme_cq_full(cq) ? 1 : 0; cq->head = new_head; if (start_sqs) { NvmeSQueue *sq; + timer_mod(cq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500); QTAILQ_FOREACH(sq, &cq->sq_list, entry) { timer_mod(sq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500); } - timer_mod(cq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500); } if (cq->tail == cq->head) {