From patchwork Fri Oct 25 05:52:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bingbu Cao X-Patchwork-Id: 13850062 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.21]) (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 47A7A176AAD for ; Fri, 25 Oct 2024 05:55:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.21 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729835746; cv=none; b=Ex++v6G2Ub+PcCJ04IWIMlH9rOKyn3834bb+3OW01fr9xqCXE01QUPShIAts3XT63XdWdCivVcVO1zZlw45QonvrkAOalbc2lbUL0zikkNml+aRmfZfqs8jFdsDD8xYQ7zcsaZHkU/eyU71zpeyunZqW6fQ5VSBGIZm+GV9FglA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729835746; c=relaxed/simple; bh=sDyoh2abmr+4TS4Q6WzwHULhlNUvrL81epyGUucy4yU=; h=From:To:Cc:Subject:Date:Message-Id; b=AphHFbUvr2ihfx4bgYQeSOvRraGFhdCV/slkVbNv1pdITSWiKiUaN4B9hLdyhzv1Nx4MnpPy5YUiab1kEr4ig3/NXNLV0PfRezakUg/OgtfuUutVQPF9koDXhudNd0HlrVfSvck6rLwMh7bJrUCqLJK0PSu+FYowv8tfbX/LewQ= 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=P2CD2BVj; arc=none smtp.client-ip=198.175.65.21 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="P2CD2BVj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729835744; x=1761371744; h=from:to:cc:subject:date:message-id; bh=sDyoh2abmr+4TS4Q6WzwHULhlNUvrL81epyGUucy4yU=; b=P2CD2BVjO0IbArcj16oWPRxY/PlecbbN1fDbnsF7UtqaSdF5YRgf6bkt jCg9kAishxpGtUZqVD2cbTNGC0FCPyeVw5ruExhPh8QsLuo05q/ot/KXG qI4oQMztsZ05GpMeE6D0tIDLJorKUWzRZNP9vC2xfpy6ML9NSTQzeu+LQ Ib+f1tfCWPm4QkkDr4LK7MiYjEWx7y7OQJVUDsjl+J5kP55ItxU4QJVAL jqKGBd3SiZmurj9EQ5Hl6C6Hkoqt6/WB/rkHJivkrVHEUafgiLpnug9VJ l/+oK4tYocyb+PZMlWfJEJfq0qBNlPedLJjN/tcW4GAKEc2q4fwCz58aK w==; X-CSE-ConnectionGUID: aRRRemBnSVCOEwJIpPqrBg== X-CSE-MsgGUID: MHrEVyHCTlGibkmvNqqLSg== X-IronPort-AV: E=McAfee;i="6700,10204,11222"; a="29434818" X-IronPort-AV: E=Sophos;i="6.11,199,1725346800"; d="scan'208";a="29434818" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by orvoesa113.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Oct 2024 22:55:42 -0700 X-CSE-ConnectionGUID: tUvzjMgCQn6aYxJQZL1qQQ== X-CSE-MsgGUID: P4ibiiWuTQCxCSbdqiG58A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,231,1725346800"; d="scan'208";a="81651361" Received: from ipu5-build.bj.intel.com ([10.238.232.136]) by orviesa008.jf.intel.com with ESMTP; 24 Oct 2024 22:55:40 -0700 From: Bingbu Cao To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com Cc: bingbu.cao@intel.com, bingbu.cao@linux.intel.com Subject: [PATCH v2 1/3] media: ipu6: move the l2_unmap() up before l2_map() Date: Fri, 25 Oct 2024 13:52:30 +0800 Message-Id: <1729835552-14825-1-git-send-email-bingbu.cao@intel.com> X-Mailer: git-send-email 2.7.4 Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: l2_map() and l2_unmap() are better to be grouped together. l2_unmap() will soon be called from l2_map() for mapping optimization. Signed-off-by: Bingbu Cao Signed-off-by: Jianhui Dai --- v2: reword the commit message to make it clear --- drivers/media/pci/intel/ipu6/ipu6-mmu.c | 80 ++++++++++++++++----------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-mmu.c b/drivers/media/pci/intel/ipu6/ipu6-mmu.c index c3a20507d6db..9ea6789bca5e 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-mmu.c +++ b/drivers/media/pci/intel/ipu6/ipu6-mmu.c @@ -252,6 +252,46 @@ static u32 *alloc_l2_pt(struct ipu6_mmu_info *mmu_info) return pt; } +static size_t l2_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, + phys_addr_t dummy, size_t size) +{ + u32 l1_idx = iova >> ISP_L1PT_SHIFT; + u32 iova_start = iova; + unsigned int l2_idx; + size_t unmapped = 0; + unsigned long flags; + u32 *l2_pt; + + dev_dbg(mmu_info->dev, "unmapping l2 page table for l1 index %u (iova 0x%8.8lx)\n", + l1_idx, iova); + + spin_lock_irqsave(&mmu_info->lock, flags); + if (mmu_info->l1_pt[l1_idx] == mmu_info->dummy_l2_pteval) { + spin_unlock_irqrestore(&mmu_info->lock, flags); + dev_err(mmu_info->dev, + "unmap iova 0x%8.8lx l1 idx %u which was not mapped\n", + iova, l1_idx); + return 0; + } + + for (l2_idx = (iova_start & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT; + (iova_start & ISP_L1PT_MASK) + (l2_idx << ISP_PAGE_SHIFT) + < iova_start + size && l2_idx < ISP_L2PT_PTES; l2_idx++) { + l2_pt = mmu_info->l2_pts[l1_idx]; + dev_dbg(mmu_info->dev, + "unmap l2 index %u with pteval 0x%10.10llx\n", + l2_idx, TBL_PHYS_ADDR(l2_pt[l2_idx])); + l2_pt[l2_idx] = mmu_info->dummy_page_pteval; + + clflush_cache_range((void *)&l2_pt[l2_idx], + sizeof(l2_pt[l2_idx])); + unmapped++; + } + spin_unlock_irqrestore(&mmu_info->lock, flags); + + return unmapped << ISP_PAGE_SHIFT; +} + static int l2_map(struct ipu6_mmu_info *mmu_info, unsigned long iova, phys_addr_t paddr, size_t size) { @@ -336,46 +376,6 @@ static int __ipu6_mmu_map(struct ipu6_mmu_info *mmu_info, unsigned long iova, return l2_map(mmu_info, iova_start, paddr, size); } -static size_t l2_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, - phys_addr_t dummy, size_t size) -{ - u32 l1_idx = iova >> ISP_L1PT_SHIFT; - u32 iova_start = iova; - unsigned int l2_idx; - size_t unmapped = 0; - unsigned long flags; - u32 *l2_pt; - - dev_dbg(mmu_info->dev, "unmapping l2 page table for l1 index %u (iova 0x%8.8lx)\n", - l1_idx, iova); - - spin_lock_irqsave(&mmu_info->lock, flags); - if (mmu_info->l1_pt[l1_idx] == mmu_info->dummy_l2_pteval) { - spin_unlock_irqrestore(&mmu_info->lock, flags); - dev_err(mmu_info->dev, - "unmap iova 0x%8.8lx l1 idx %u which was not mapped\n", - iova, l1_idx); - return 0; - } - - for (l2_idx = (iova_start & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT; - (iova_start & ISP_L1PT_MASK) + (l2_idx << ISP_PAGE_SHIFT) - < iova_start + size && l2_idx < ISP_L2PT_PTES; l2_idx++) { - l2_pt = mmu_info->l2_pts[l1_idx]; - dev_dbg(mmu_info->dev, - "unmap l2 index %u with pteval 0x%10.10llx\n", - l2_idx, TBL_PHYS_ADDR(l2_pt[l2_idx])); - l2_pt[l2_idx] = mmu_info->dummy_page_pteval; - - clflush_cache_range((void *)&l2_pt[l2_idx], - sizeof(l2_pt[l2_idx])); - unmapped++; - } - spin_unlock_irqrestore(&mmu_info->lock, flags); - - return unmapped << ISP_PAGE_SHIFT; -} - static size_t __ipu6_mmu_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, size_t size) { From patchwork Fri Oct 25 05:52:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bingbu Cao X-Patchwork-Id: 13850063 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.21]) (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 DB58018C015 for ; Fri, 25 Oct 2024 05:55:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.21 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729835748; cv=none; b=D515ENktvUD7BfO23NynnOn6l1aHOLgFasISWKVVadhlPgKsVUSualtpsSDW/qNBbf1ONwNZKqH3fnf79gTxwnbi9LQKNbCJ2L/yxvWmlJn/slCgKHxTQMxIstWIL+t/7/E5DcXbkH7ZUltOMSUzBeq5z7pSIwODpM0Q15tv3Uw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729835748; c=relaxed/simple; bh=qBnt9agVmzFcipNsdMc0yoEhzAnQMrB0WlPk43NEI2Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=HI7vL4BPWAu3frQlMQKxFt8IXo308T+BZY3ErW3TEO37tRzH0Y0Eh6hM5VGG8BiofjQwKNDfwoGzuTDQpvasn+AMtq7RZuGxqLk31G3+TLhqcDQBQno3XtuM3XCYvwN2Q4hi6D3Zb8Nz4PXV7hab8Bi/2DqhZleuxGNTJEtMqg4= 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=AKKFdhIn; arc=none smtp.client-ip=198.175.65.21 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="AKKFdhIn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729835746; x=1761371746; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=qBnt9agVmzFcipNsdMc0yoEhzAnQMrB0WlPk43NEI2Q=; b=AKKFdhInQBhRWwvcH5lwG0DW1v3U9lrL2XZsNampXd89W1gz4QrPgrW7 qRnO6ruzC1r9p1sFXRH+XfQQ3sFjvmY3Qsrzj8gtlTgwCozOkuPj9oE3r ILvIIWbXb1SWel/dsjxFuuE+tyo/mxpC8+oVfdg9wdh2z2w55UHXFkc4u hmj4fVh2RKREW+Y/SsWIPtsPhtOkr0CVOJ6zJIGGcl/aAzIQOFeBstZD2 lqVinhuryRHJKkhg7Z1FPYZVzdRxsbxKsS7stalOn8mCw2XKFbx39bIjh SC6td+/vvkrBhSGMyUJahPwtQNZtVzaZTW7Q39OkAXuoSCH7/PgdN78/1 A==; X-CSE-ConnectionGUID: 0EpCjFvOScmLWnrVffiNdw== X-CSE-MsgGUID: lK426CPFThWWDQ+V/idRHg== X-IronPort-AV: E=McAfee;i="6700,10204,11222"; a="29434820" X-IronPort-AV: E=Sophos;i="6.11,199,1725346800"; d="scan'208";a="29434820" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by orvoesa113.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Oct 2024 22:55:44 -0700 X-CSE-ConnectionGUID: LF7qVyZ/TZW7NJWAdxYdNQ== X-CSE-MsgGUID: mmlFo/H+TKCySxjlsDxFIw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,231,1725346800"; d="scan'208";a="81651368" Received: from ipu5-build.bj.intel.com ([10.238.232.136]) by orviesa008.jf.intel.com with ESMTP; 24 Oct 2024 22:55:42 -0700 From: Bingbu Cao To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com Cc: bingbu.cao@intel.com, bingbu.cao@linux.intel.com Subject: [PATCH v2 2/3] media: ipu6: optimize the IPU6 MMU mapping flow Date: Fri, 25 Oct 2024 13:52:31 +0800 Message-Id: <1729835552-14825-2-git-send-email-bingbu.cao@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1729835552-14825-1-git-send-email-bingbu.cao@intel.com> References: <1729835552-14825-1-git-send-email-bingbu.cao@intel.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: ipu6_mmu_map() operated on a per-page basis, it leads frequent spin_lock/unlock() and clflush_cache_range() for each page, it will cause inefficiencies especially when handling dma-bufs with large number of pages. However, the pages are likely concentrated pages by IOMMU DMA driver, IPU MMU driver can map the concentrated pages into less entries in l1 table. This change enhances ipu6_mmu_map() with batching process multiple contiguous pages. It significantly reduces calls for spin_lock/unlock and clflush_cache_range() and improve the performance. Signed-off-by: Bingbu Cao Signed-off-by: Jianhui Dai --- drivers/media/pci/intel/ipu6/ipu6-mmu.c | 144 +++++++++++++++----------------- 1 file changed, 69 insertions(+), 75 deletions(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-mmu.c b/drivers/media/pci/intel/ipu6/ipu6-mmu.c index 9ea6789bca5e..e957ccb4691d 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-mmu.c +++ b/drivers/media/pci/intel/ipu6/ipu6-mmu.c @@ -295,72 +295,90 @@ static size_t l2_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, static int l2_map(struct ipu6_mmu_info *mmu_info, unsigned long iova, phys_addr_t paddr, size_t size) { - u32 l1_idx = iova >> ISP_L1PT_SHIFT; - u32 iova_start = iova; + struct device *dev = mmu_info->dev; + unsigned int l2_entries; u32 *l2_pt, *l2_virt; unsigned int l2_idx; unsigned long flags; + size_t mapped = 0; dma_addr_t dma; u32 l1_entry; - - dev_dbg(mmu_info->dev, - "mapping l2 page table for l1 index %u (iova %8.8x)\n", - l1_idx, (u32)iova); + u32 l1_idx; + int err = 0; spin_lock_irqsave(&mmu_info->lock, flags); - l1_entry = mmu_info->l1_pt[l1_idx]; - if (l1_entry == mmu_info->dummy_l2_pteval) { - l2_virt = mmu_info->l2_pts[l1_idx]; - if (likely(!l2_virt)) { - l2_virt = alloc_l2_pt(mmu_info); - if (!l2_virt) { - spin_unlock_irqrestore(&mmu_info->lock, flags); - return -ENOMEM; - } - } - - dma = map_single(mmu_info, l2_virt); - if (!dma) { - dev_err(mmu_info->dev, "Failed to map l2pt page\n"); - free_page((unsigned long)l2_virt); - spin_unlock_irqrestore(&mmu_info->lock, flags); - return -EINVAL; - } - - l1_entry = dma >> ISP_PADDR_SHIFT; - - dev_dbg(mmu_info->dev, "page for l1_idx %u %p allocated\n", - l1_idx, l2_virt); - mmu_info->l1_pt[l1_idx] = l1_entry; - mmu_info->l2_pts[l1_idx] = l2_virt; - clflush_cache_range((void *)&mmu_info->l1_pt[l1_idx], - sizeof(mmu_info->l1_pt[l1_idx])); - } - - l2_pt = mmu_info->l2_pts[l1_idx]; - - dev_dbg(mmu_info->dev, "l2_pt at %p with dma 0x%x\n", l2_pt, l1_entry); paddr = ALIGN(paddr, ISP_PAGE_SIZE); + for (l1_idx = iova >> ISP_L1PT_SHIFT; + size > 0 && l1_idx < ISP_L1PT_PTES; l1_idx++) { + dev_dbg(dev, + "mapping l2 page table for l1 index %u (iova %8.8x)\n", + l1_idx, (u32)iova); - l2_idx = (iova_start & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT; + l1_entry = mmu_info->l1_pt[l1_idx]; + if (l1_entry == mmu_info->dummy_l2_pteval) { + l2_virt = mmu_info->l2_pts[l1_idx]; + if (likely(!l2_virt)) { + l2_virt = alloc_l2_pt(mmu_info); + if (!l2_virt) { + err = -ENOMEM; + goto error; + } + } - dev_dbg(mmu_info->dev, "l2_idx %u, phys 0x%8.8x\n", l2_idx, - l2_pt[l2_idx]); - if (l2_pt[l2_idx] != mmu_info->dummy_page_pteval) { - spin_unlock_irqrestore(&mmu_info->lock, flags); - return -EINVAL; + dma = map_single(mmu_info, l2_virt); + if (!dma) { + dev_err(dev, "Failed to map l2pt page\n"); + free_page((unsigned long)l2_virt); + err = -EINVAL; + goto error; + } + + l1_entry = dma >> ISP_PADDR_SHIFT; + + dev_dbg(dev, "page for l1_idx %u %p allocated\n", + l1_idx, l2_virt); + mmu_info->l1_pt[l1_idx] = l1_entry; + mmu_info->l2_pts[l1_idx] = l2_virt; + + clflush_cache_range(&mmu_info->l1_pt[l1_idx], + sizeof(mmu_info->l1_pt[l1_idx])); + } + + l2_pt = mmu_info->l2_pts[l1_idx]; + l2_entries = 0; + + for (l2_idx = (iova & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT; + size > 0 && l2_idx < ISP_L2PT_PTES; l2_idx++) { + l2_pt[l2_idx] = paddr >> ISP_PADDR_SHIFT; + + dev_dbg(dev, "l2 index %u mapped as 0x%8.8x\n", l2_idx, + l2_pt[l2_idx]); + + iova += ISP_PAGE_SIZE; + paddr += ISP_PAGE_SIZE; + mapped += ISP_PAGE_SIZE; + size -= ISP_PAGE_SIZE; + + l2_entries++; + } + + WARN_ON_ONCE(!l2_entries); + clflush_cache_range(&l2_pt[l2_idx - l2_entries], + sizeof(l2_pt[0]) * l2_entries); } - l2_pt[l2_idx] = paddr >> ISP_PADDR_SHIFT; - - clflush_cache_range((void *)&l2_pt[l2_idx], sizeof(l2_pt[l2_idx])); spin_unlock_irqrestore(&mmu_info->lock, flags); - dev_dbg(mmu_info->dev, "l2 index %u mapped as 0x%8.8x\n", l2_idx, - l2_pt[l2_idx]); - return 0; + +error: + spin_unlock_irqrestore(&mmu_info->lock, flags); + /* unroll mapping in case something went wrong */ + if (mapped) + l2_unmap(mmu_info, iova - mapped, paddr - mapped, mapped); + + return err; } static int __ipu6_mmu_map(struct ipu6_mmu_info *mmu_info, unsigned long iova, @@ -692,10 +710,7 @@ size_t ipu6_mmu_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, int ipu6_mmu_map(struct ipu6_mmu_info *mmu_info, unsigned long iova, phys_addr_t paddr, size_t size) { - unsigned long orig_iova = iova; unsigned int min_pagesz; - size_t orig_size = size; - int ret = 0; if (mmu_info->pgsize_bitmap == 0UL) return -ENODEV; @@ -718,28 +733,7 @@ int ipu6_mmu_map(struct ipu6_mmu_info *mmu_info, unsigned long iova, dev_dbg(mmu_info->dev, "map: iova 0x%lx pa %pa size 0x%zx\n", iova, &paddr, size); - while (size) { - size_t pgsize = ipu6_mmu_pgsize(mmu_info->pgsize_bitmap, - iova | paddr, size); - - dev_dbg(mmu_info->dev, - "mapping: iova 0x%lx pa %pa pgsize 0x%zx\n", - iova, &paddr, pgsize); - - ret = __ipu6_mmu_map(mmu_info, iova, paddr, pgsize); - if (ret) - break; - - iova += pgsize; - paddr += pgsize; - size -= pgsize; - } - - /* unroll mapping in case something went wrong */ - if (ret) - ipu6_mmu_unmap(mmu_info, orig_iova, orig_size - size); - - return ret; + return __ipu6_mmu_map(mmu_info, iova, paddr, size); } static void ipu6_mmu_destroy(struct ipu6_mmu *mmu) From patchwork Fri Oct 25 05:52:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bingbu Cao X-Patchwork-Id: 13850064 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.21]) (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 F294918E056 for ; Fri, 25 Oct 2024 05:55:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.21 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729835749; cv=none; b=BSyqdozlWf9P+YPESR+X20McGc71lHMPLcLQnSbfnaAKMat+TIUNivKZd5cIBPAQoPzbXDcnyH8rg4289ot1+T3cf07L06YjVkLTfAdspUcfVA8leCtlWORd11eoC0R0qrCN6xY8qzSOVm+QDkfWri/ucs0xhxVGsQ1YGNDh/0s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729835749; c=relaxed/simple; bh=Cyv1W6tiOtJKqysfJe7QQFMNPRiI39lCw6wI7AqDfAc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=uyDl/xQy/H8FHSF8D+a7GGdSrE71th9TdXZzQ2Ctpv2asGTfRD0zhFZCDPgUL3Y/+TP8YKMP8yLQIvlTxPVy9b176ro78kluS8Ka6gYi2f3HuT6nOFvQNLZv3jd3oujaAu9+1wShycyYo7yzU589vr3HBsp0OyTxZPCcmbXhmUk= 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=TRYAJ1MY; arc=none smtp.client-ip=198.175.65.21 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="TRYAJ1MY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729835747; x=1761371747; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=Cyv1W6tiOtJKqysfJe7QQFMNPRiI39lCw6wI7AqDfAc=; b=TRYAJ1MYOo0Ee2HO+DSYzHszidi9eFH0kEQqOmM/fvANJyhL/20m4Kfb oueztEwooNqkQAisDJUHte7QNjy5StMdzzqLX9LG9LxV29Fp3RAKwp6II NgdGdV3XXFhyTH2azjl1+HJif8iu8kthH3VZznM3Z9VesZzFBxqdGLUL5 6oA79wY0rjGqe6p0B3SwZ7c5/aggNXcpD/ox1heB41vBxIkukpPXyWSVg 8vvx9pQpd4y7wG/YpZYBkt6/M6BzuoQ7j7IsAtDC9MWgYZVs4bHFzzzaM DlqvNyTmDtY6/TBeczDMlj7AoscbBZIvm1H2N7AyoCOwHRfvC5gifWsw+ Q==; X-CSE-ConnectionGUID: xB+xPZzxQ6KYrXW819YAGg== X-CSE-MsgGUID: sUr6YEd0R+Cv/iip6/MZuw== X-IronPort-AV: E=McAfee;i="6700,10204,11222"; a="29434822" X-IronPort-AV: E=Sophos;i="6.11,199,1725346800"; d="scan'208";a="29434822" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by orvoesa113.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Oct 2024 22:55:46 -0700 X-CSE-ConnectionGUID: rXYsh1GVRs6YRT/aBq+A2Q== X-CSE-MsgGUID: Ig87gNCkT566h3gLNL7Jgw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,231,1725346800"; d="scan'208";a="81651371" Received: from ipu5-build.bj.intel.com ([10.238.232.136]) by orviesa008.jf.intel.com with ESMTP; 24 Oct 2024 22:55:44 -0700 From: Bingbu Cao To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com Cc: bingbu.cao@intel.com, bingbu.cao@linux.intel.com Subject: [PATCH v2 3/3] media: ipu6: optimize the IPU6 MMU unmapping flow Date: Fri, 25 Oct 2024 13:52:32 +0800 Message-Id: <1729835552-14825-3-git-send-email-bingbu.cao@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1729835552-14825-1-git-send-email-bingbu.cao@intel.com> References: <1729835552-14825-1-git-send-email-bingbu.cao@intel.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: The MMU mapping flow is optimized for improve the performance, the unmapping flow could also be optimized to follow same flow. This patch changes the ipu6_mmu_unmap() as a void function and also remove ipu6_mmu_pgsize() as driver unload this to the PCI core driver DMA ops instead of handling in driver. Signed-off-by: Bingbu Cao --- v2: squash the ipu6_mmu_pgsize() removal into this patchset --- drivers/media/pci/intel/ipu6/ipu6-mmu.c | 125 +++++++++++--------------------- drivers/media/pci/intel/ipu6/ipu6-mmu.h | 4 +- 2 files changed, 45 insertions(+), 84 deletions(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-mmu.c b/drivers/media/pci/intel/ipu6/ipu6-mmu.c index e957ccb4691d..2d9c6fbd5da2 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-mmu.c +++ b/drivers/media/pci/intel/ipu6/ipu6-mmu.c @@ -252,44 +252,51 @@ static u32 *alloc_l2_pt(struct ipu6_mmu_info *mmu_info) return pt; } -static size_t l2_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, - phys_addr_t dummy, size_t size) +static void l2_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, + phys_addr_t dummy, size_t size) { - u32 l1_idx = iova >> ISP_L1PT_SHIFT; - u32 iova_start = iova; + unsigned int l2_entries; unsigned int l2_idx; - size_t unmapped = 0; unsigned long flags; + u32 l1_idx; u32 *l2_pt; - dev_dbg(mmu_info->dev, "unmapping l2 page table for l1 index %u (iova 0x%8.8lx)\n", - l1_idx, iova); - spin_lock_irqsave(&mmu_info->lock, flags); - if (mmu_info->l1_pt[l1_idx] == mmu_info->dummy_l2_pteval) { - spin_unlock_irqrestore(&mmu_info->lock, flags); - dev_err(mmu_info->dev, - "unmap iova 0x%8.8lx l1 idx %u which was not mapped\n", - iova, l1_idx); - return 0; - } - - for (l2_idx = (iova_start & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT; - (iova_start & ISP_L1PT_MASK) + (l2_idx << ISP_PAGE_SHIFT) - < iova_start + size && l2_idx < ISP_L2PT_PTES; l2_idx++) { - l2_pt = mmu_info->l2_pts[l1_idx]; + for (l1_idx = iova >> ISP_L1PT_SHIFT; + size > 0 && l1_idx < ISP_L1PT_PTES; l1_idx++) { dev_dbg(mmu_info->dev, - "unmap l2 index %u with pteval 0x%10.10llx\n", - l2_idx, TBL_PHYS_ADDR(l2_pt[l2_idx])); - l2_pt[l2_idx] = mmu_info->dummy_page_pteval; + "unmapping l2 pgtable (l1 index %u (iova 0x%8.8lx))\n", + l1_idx, iova); - clflush_cache_range((void *)&l2_pt[l2_idx], - sizeof(l2_pt[l2_idx])); - unmapped++; + if (mmu_info->l1_pt[l1_idx] == mmu_info->dummy_l2_pteval) { + dev_err(mmu_info->dev, + "unmap not mapped iova 0x%8.8lx l1 index %u\n", + iova, l1_idx); + continue; + } + l2_pt = mmu_info->l2_pts[l1_idx]; + + l2_entries = 0; + for (l2_idx = (iova & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT; + size > 0 && l2_idx < ISP_L2PT_PTES; l2_idx++) { + dev_dbg(mmu_info->dev, + "unmap l2 index %u with pteval 0x%10.10llx\n", + l2_idx, TBL_PHYS_ADDR(l2_pt[l2_idx])); + l2_pt[l2_idx] = mmu_info->dummy_page_pteval; + + iova += ISP_PAGE_SIZE; + size -= ISP_PAGE_SIZE; + + l2_entries++; + } + + WARN_ON_ONCE(!l2_entries); + clflush_cache_range(&l2_pt[l2_idx - l2_entries], + sizeof(l2_pt[0]) * l2_entries); } + + WARN_ON_ONCE(size); spin_unlock_irqrestore(&mmu_info->lock, flags); - - return unmapped << ISP_PAGE_SHIFT; } static int l2_map(struct ipu6_mmu_info *mmu_info, unsigned long iova, @@ -394,8 +401,8 @@ static int __ipu6_mmu_map(struct ipu6_mmu_info *mmu_info, unsigned long iova, return l2_map(mmu_info, iova_start, paddr, size); } -static size_t __ipu6_mmu_unmap(struct ipu6_mmu_info *mmu_info, - unsigned long iova, size_t size) +static void __ipu6_mmu_unmap(struct ipu6_mmu_info *mmu_info, + unsigned long iova, size_t size) { return l2_unmap(mmu_info, iova, 0, size); } @@ -637,40 +644,13 @@ phys_addr_t ipu6_mmu_iova_to_phys(struct ipu6_mmu_info *mmu_info, return phy_addr; } -static size_t ipu6_mmu_pgsize(unsigned long pgsize_bitmap, - unsigned long addr_merge, size_t size) +void ipu6_mmu_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, + size_t size) { - unsigned int pgsize_idx; - size_t pgsize; - - /* Max page size that still fits into 'size' */ - pgsize_idx = __fls(size); - - if (likely(addr_merge)) { - /* Max page size allowed by address */ - unsigned int align_pgsize_idx = __ffs(addr_merge); - - pgsize_idx = min(pgsize_idx, align_pgsize_idx); - } - - pgsize = (1UL << (pgsize_idx + 1)) - 1; - pgsize &= pgsize_bitmap; - - WARN_ON(!pgsize); - - /* pick the biggest page */ - pgsize_idx = __fls(pgsize); - pgsize = 1UL << pgsize_idx; - - return pgsize; -} - -size_t ipu6_mmu_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, - size_t size) -{ - size_t unmapped_page, unmapped = 0; unsigned int min_pagesz; + dev_dbg(mmu_info->dev, "unmapping iova 0x%lx size 0x%zx\n", iova, size); + /* find out the minimum page size supported */ min_pagesz = 1 << __ffs(mmu_info->pgsize_bitmap); @@ -682,29 +662,10 @@ size_t ipu6_mmu_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, if (!IS_ALIGNED(iova | size, min_pagesz)) { dev_err(NULL, "unaligned: iova 0x%lx size 0x%zx min_pagesz 0x%x\n", iova, size, min_pagesz); - return -EINVAL; + return; } - /* - * Keep iterating until we either unmap 'size' bytes (or more) - * or we hit an area that isn't mapped. - */ - while (unmapped < size) { - size_t pgsize = ipu6_mmu_pgsize(mmu_info->pgsize_bitmap, - iova, size - unmapped); - - unmapped_page = __ipu6_mmu_unmap(mmu_info, iova, pgsize); - if (!unmapped_page) - break; - - dev_dbg(mmu_info->dev, "unmapped: iova 0x%lx size 0x%zx\n", - iova, unmapped_page); - - iova += unmapped_page; - unmapped += unmapped_page; - } - - return unmapped; + return __ipu6_mmu_unmap(mmu_info, iova, size); } int ipu6_mmu_map(struct ipu6_mmu_info *mmu_info, unsigned long iova, diff --git a/drivers/media/pci/intel/ipu6/ipu6-mmu.h b/drivers/media/pci/intel/ipu6/ipu6-mmu.h index 21cdb0f146eb..8e40b4a66d7d 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-mmu.h +++ b/drivers/media/pci/intel/ipu6/ipu6-mmu.h @@ -66,8 +66,8 @@ int ipu6_mmu_hw_init(struct ipu6_mmu *mmu); void ipu6_mmu_hw_cleanup(struct ipu6_mmu *mmu); int ipu6_mmu_map(struct ipu6_mmu_info *mmu_info, unsigned long iova, phys_addr_t paddr, size_t size); -size_t ipu6_mmu_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, - size_t size); +void ipu6_mmu_unmap(struct ipu6_mmu_info *mmu_info, unsigned long iova, + size_t size); phys_addr_t ipu6_mmu_iova_to_phys(struct ipu6_mmu_info *mmu_info, dma_addr_t iova); #endif