From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0AE3B32E728 for ; Thu, 16 Apr 2026 17:57:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.10 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776362253; cv=none; b=chj709Ma8d606MT9W1X8hrLCDytXoRuI1JcnkjZJGbqLGVydiSBQN/z4HKvFXyk5AXXJqwnKVC+iSy43tdRd7kKr9YAZMN80B+RzlcNVzi4ZuBv68NoS1eR6Kjeit8t0KUg3eVTptz6hBFlLwDd8mv2lyaRpL0fzgvvZzmsk1Dk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776362253; c=relaxed/simple; bh=VOdkT7NXbsHNVxTYgvsRx2+hTyXIiHvRLkuOP0upwMQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WrW0Vbs0mutTJGfeczcMKdA/uoRySvqo8jp42uV86e8rT8H26q3DTJr4zLLGNt8ATob66ImZDAGuYtGKt57LXYti+zt7B5F9U1mlx/w739nWpP8+IJ//BJF0Mut2+C3BHNigE0hxn/rApt1n1X0akjhO0RpGXQzoT1QkSs/+pD0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=kVxwGelc; arc=none smtp.client-ip=198.175.65.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="kVxwGelc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1776362252; x=1807898252; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VOdkT7NXbsHNVxTYgvsRx2+hTyXIiHvRLkuOP0upwMQ=; b=kVxwGelcpyXi6VW2Dort8dwlamGwPxHjv0LCWqbZD+G2zqeVafS5il2F v0Z1HoG3sUQf5JNVhuBQEGt8S6YILstaQpJWCdZkg+/jKEgFFNlp66xEL D7n4mgt+NXox4HGSjTE8/fOofrZakstTTiQM3Fxoucd7SOMVsYLienfRL sXnwLXbeaYtpiFoguOCZ6l8FjJ04nPQuYnVgj+yR6YgunFQsXm7LRxI1K 5qWoDjqgmzAQrsy7p1L9UJMYs8AKF3j5SvAcuKBvVp0fwVSvE5UMqg8SF S0k+cVLdYO1YA6tqLeKcQqBCmYB3Ed0U8KXiuPd+n2Uy1HZUSCTh4A87R g==; X-CSE-ConnectionGUID: O+nZHscCTKOYiRkimL0Zcw== X-CSE-MsgGUID: WEK7v/thTEO3y108rAWtUg== X-IronPort-AV: E=McAfee;i="6800,10657,11761"; a="94778390" X-IronPort-AV: E=Sophos;i="6.23,181,1770624000"; d="scan'208";a="94778390" Received: from orviesa005.jf.intel.com ([10.64.159.145]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Apr 2026 10:57:31 -0700 X-CSE-ConnectionGUID: iOg9MuiPSX2ByWY7uE4Z4A== X-CSE-MsgGUID: yB1sEmkbQpCwsks0vTAmVw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.23,181,1770624000"; d="scan'208";a="235784586" Received: from abityuts-desk.ger.corp.intel.com (HELO ahunter6-desk) ([10.245.244.222]) by orviesa005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Apr 2026 10:57:30 -0700 From: Adrian Hunter To: alexandre.belloni@bootlin.com Cc: Frank.Li@nxp.com, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 08/16] i3c: mipi-i3c-hci: Avoid restarting DMA ring after aborting wrong transfer Date: Thu, 16 Apr 2026 20:56:56 +0300 Message-ID: <20260416175704.41217-9-adrian.hunter@intel.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260416175704.41217-1-adrian.hunter@intel.com> References: <20260416175704.41217-1-adrian.hunter@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Intel Finland Oy, Registered Address: c/o Alberga Business Park, 6 krs, Bertel Jungin Aukio 5, 02600 Espoo, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Content-Transfer-Encoding: 8bit Software ABORT of the DMA ring is used to recover from transfer list timeouts, but it is inherently racy. The intended transfer list may complete just before the ABORT takes effect, causing the subsequent transfer list to be aborted instead. In this case, an incomplete transfer list may remain in the ring and has not yet been processed by hci_dma_dequeue_xfer(). Restarting the DMA ring at that point can lead to unpredictable results. Detect when the next queued transfer is not the first entry of a transfer list and does not belong to the list currently being dequeued. In that case, skip restarting the DMA ring and defer recovery until a subsequent call to hci_dma_dequeue_xfer(), which will safely restart the ring once the incomplete list is handled. Signed-off-by: Adrian Hunter --- drivers/i3c/master/mipi-i3c-hci/dma.c | 16 ++++++++++++++++ drivers/i3c/master/mipi-i3c-hci/hci.h | 1 + 2 files changed, 17 insertions(+) diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c index 5eea4fe6ebb3..5b394220a509 100644 --- a/drivers/i3c/master/mipi-i3c-hci/dma.c +++ b/drivers/i3c/master/mipi-i3c-hci/dma.c @@ -503,6 +503,7 @@ static int hci_dma_queue_xfer(struct i3c_hci *hci, u32 *ring_data = rh->xfer + rh->xfer_struct_sz * enqueue_ptr; xfer->completing_xfer = xfer_list + n - 1; + xfer->xfer_list_pos = i; /* store cmd descriptor */ *ring_data++ = xfer->cmd_desc[0]; @@ -669,6 +670,21 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci, } } + /* + * A software ABORT may race with transfer completion and abort the next + * transfer list instead. Detect that case, and do not restart the ring. + * It will be handled by a subsequent dequeue. + */ + if (!did_unqueue) { + struct hci_xfer *xfer = rh->src_xfers[rh->done_ptr]; + + if (xfer && xfer->xfer_list_pos && + xfer->completing_xfer != xfer_list->completing_xfer) { + spin_unlock_irq(&hci->lock); + return false; + } + } + /* restart the ring */ reinit_completion(&rh->op_done); mipi_i3c_hci_resume(hci); diff --git a/drivers/i3c/master/mipi-i3c-hci/hci.h b/drivers/i3c/master/mipi-i3c-hci/hci.h index eee3e11810dd..527345a995ad 100644 --- a/drivers/i3c/master/mipi-i3c-hci/hci.h +++ b/drivers/i3c/master/mipi-i3c-hci/hci.h @@ -107,6 +107,7 @@ struct hci_xfer { struct hci_xfer *completing_xfer; int ring_number; int ring_entry; + int xfer_list_pos; }; }; }; -- 2.51.0