mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Tina Zhang <tina.zhang@intel.com>
To: Lu Baolu <baolu.lu@linux.intel.com>, Kevin Tian <kevin.tian@intel.com>
Cc: iommu@lists.linux.dev, linux-kernel@vger.kernel.org,
	Tina Zhang <tina.zhang@intel.com>
Subject: [PATCH 2/2] iommu/vt-d: Batch IOTLB/dev-IOTLB invalidation commands
Date: Fri, 17 May 2024 08:37:28 +0800	[thread overview]
Message-ID: <20240517003728.251115-3-tina.zhang@intel.com> (raw)
In-Reply-To: <20240517003728.251115-1-tina.zhang@intel.com>

Utilize batch command processing in IOTLB/dev-IOTLB invalidation
operations.

Signed-off-by: Tina Zhang <tina.zhang@intel.com>
---
 drivers/iommu/intel/cache.c | 76 ++++++++++++++++++++++++++++++-------
 1 file changed, 62 insertions(+), 14 deletions(-)

diff --git a/drivers/iommu/intel/cache.c b/drivers/iommu/intel/cache.c
index dcf5e0e6af17..0a06e8565554 100644
--- a/drivers/iommu/intel/cache.c
+++ b/drivers/iommu/intel/cache.c
@@ -19,6 +19,14 @@
 #include "pasid.h"
 #include "trace.h"
 
+/* The max number of descriptors in a batch processing*/
+#define QI_MAX_BATCH_DESC_COUNT 2
+
+struct qi_cmd_batch {
+	struct qi_desc desc[QI_MAX_BATCH_DESC_COUNT];
+	int num;
+};
+
 /* Check if an existing cache tag can be reused for a new association. */
 static bool cache_tage_match(struct cache_tag *tag, u16 domain_id,
 			     struct intel_iommu *iommu, struct device *dev,
@@ -254,6 +262,26 @@ static unsigned long calculate_psi_aligned_address(unsigned long start,
 	return ALIGN_DOWN(start, VTD_PAGE_SIZE << mask);
 }
 
+static inline void cache_invalidate_cmd_batch_submit(struct intel_iommu *iommu,
+						     struct qi_cmd_batch *cmds)
+{
+	if (!cmds->num)
+		return;
+
+	qi_submit_sync(iommu, cmds->desc, cmds->num, 0);
+	memset(cmds, 0, sizeof(struct qi_cmd_batch));
+}
+
+static inline void cache_invalidate_cmd_batch_add(struct intel_iommu *iommu,
+						  struct qi_cmd_batch *cmds)
+{
+	if (!cmds->desc[cmds->num].qw0)
+		return;
+
+	if (++cmds->num == QI_MAX_BATCH_DESC_COUNT)
+		cache_invalidate_cmd_batch_submit(iommu, cmds);
+}
+
 /*
  * Invalidates a range of IOVA from @start (inclusive) to @end (inclusive)
  * when the memory mappings in the target domain have been modified.
@@ -264,21 +292,28 @@ void cache_tag_flush_range(struct dmar_domain *domain, unsigned long start,
 	unsigned long pages, mask, addr;
 	struct cache_tag *tag;
 	unsigned long flags;
+	struct intel_iommu *iommu = NULL;
+	struct qi_cmd_batch cmds = {0};
 
 	addr = calculate_psi_aligned_address(start, end, &pages, &mask);
 
 	spin_lock_irqsave(&domain->cache_lock, flags);
 	list_for_each_entry(tag, &domain->cache_tags, node) {
-		struct intel_iommu *iommu = tag->iommu;
 		struct device_domain_info *info;
 		u16 sid;
 
+		if (iommu != tag->iommu) {
+			cache_invalidate_cmd_batch_submit(iommu, &cmds);
+			iommu = tag->iommu;
+		}
+
 		switch (tag->type) {
 		case CACHE_TAG_IOTLB:
 		case CACHE_TAG_NESTING_IOTLB:
 			if (domain->use_first_level) {
 				qi_flush_piotlb(iommu, tag->domain_id,
-						tag->pasid, addr, pages, ih, NULL);
+						tag->pasid, addr, pages,
+						ih, &cmds.desc[cmds.num]);
 			} else {
 				/*
 				 * Fallback to domain selective flush if no
@@ -288,13 +323,14 @@ void cache_tag_flush_range(struct dmar_domain *domain, unsigned long start,
 				    mask > cap_max_amask_val(iommu->cap))
 					iommu->flush.flush_iotlb(iommu, tag->domain_id,
 								 0, 0, DMA_TLB_DSI_FLUSH,
-								 NULL);
+								 &cmds.desc[cmds.num]);
 				else
 					iommu->flush.flush_iotlb(iommu, tag->domain_id,
 								 addr | ih, mask,
 								 DMA_TLB_PSI_FLUSH,
-								 NULL);
+								 &cmds.desc[cmds.num]);
 			}
+			cache_invalidate_cmd_batch_add(iommu, &cmds);
 			break;
 		case CACHE_TAG_NESTING_DEVTLB:
 			/*
@@ -310,23 +346,25 @@ void cache_tag_flush_range(struct dmar_domain *domain, unsigned long start,
 		case CACHE_TAG_DEVTLB:
 			info = dev_iommu_priv_get(tag->dev);
 			sid = PCI_DEVID(info->bus, info->devfn);
-
 			if (tag->pasid == IOMMU_NO_PASID)
 				qi_flush_dev_iotlb(iommu, sid, info->pfsid,
 						   info->ats_qdep, addr, mask,
-						   NULL);
+						   &cmds.desc[cmds.num]);
 			else
 				qi_flush_dev_iotlb_pasid(iommu, sid, info->pfsid,
 							 tag->pasid, info->ats_qdep,
-							 addr, mask, NULL);
+							 addr, mask, &cmds.desc[cmds.num]);
+			cache_invalidate_cmd_batch_add(iommu, &cmds);
 
 			quirk_extra_dev_tlb_flush(info, addr, mask, tag->pasid,
-						  info->ats_qdep, NULL);
+						  info->ats_qdep, &cmds.desc[cmds.num]);
+			cache_invalidate_cmd_batch_add(iommu, &cmds);
 			break;
 		}
 
 		trace_cache_tag_flush_range(tag, start, end, addr, pages, mask);
 	}
+	cache_invalidate_cmd_batch_submit(iommu, &cmds);
 	spin_unlock_irqrestore(&domain->cache_lock, flags);
 }
 
@@ -338,40 +376,50 @@ void cache_tag_flush_all(struct dmar_domain *domain)
 {
 	struct cache_tag *tag;
 	unsigned long flags;
+	struct intel_iommu *iommu = NULL;
+	struct qi_cmd_batch cmds = {0};
 
 	spin_lock_irqsave(&domain->cache_lock, flags);
 	list_for_each_entry(tag, &domain->cache_tags, node) {
-		struct intel_iommu *iommu = tag->iommu;
 		struct device_domain_info *info;
 		u16 sid;
 
+		if (iommu != tag->iommu) {
+			cache_invalidate_cmd_batch_submit(iommu, &cmds);
+			iommu = tag->iommu;
+		}
+
 		switch (tag->type) {
 		case CACHE_TAG_IOTLB:
 		case CACHE_TAG_NESTING_IOTLB:
 			if (domain->use_first_level)
 				qi_flush_piotlb(iommu, tag->domain_id,
 						tag->pasid, 0, -1, 0,
-						NULL);
+						&cmds.desc[cmds.num]);
 			else
 				iommu->flush.flush_iotlb(iommu, tag->domain_id,
 							 0, 0, DMA_TLB_DSI_FLUSH,
-							 NULL);
+							 &cmds.desc[cmds.num]);
+			cache_invalidate_cmd_batch_add(iommu, &cmds);
 			break;
 		case CACHE_TAG_DEVTLB:
 		case CACHE_TAG_NESTING_DEVTLB:
 			info = dev_iommu_priv_get(tag->dev);
 			sid = PCI_DEVID(info->bus, info->devfn);
-
 			qi_flush_dev_iotlb(iommu, sid, info->pfsid, info->ats_qdep,
-					   0, MAX_AGAW_PFN_WIDTH, NULL);
+					   0, MAX_AGAW_PFN_WIDTH, &cmds.desc[cmds.num]);
+			cache_invalidate_cmd_batch_add(iommu, &cmds);
+
 			quirk_extra_dev_tlb_flush(info, 0, MAX_AGAW_PFN_WIDTH,
 						  IOMMU_NO_PASID, info->ats_qdep,
-						  NULL);
+						  &cmds.desc[cmds.num]);
+			cache_invalidate_cmd_batch_add(iommu, &cmds);
 			break;
 		}
 
 		trace_cache_tag_flush_all(tag);
 	}
+	cache_invalidate_cmd_batch_submit(iommu, &cmds);
 	spin_unlock_irqrestore(&domain->cache_lock, flags);
 }
 
-- 
2.39.3


      parent reply	other threads:[~2024-05-17  0:37 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-17  0:37 [PATCH 0/2] Batch IOTLB/dev-IOTLB invalidation Tina Zhang
2024-05-17  0:37 ` [PATCH 1/2] iommu/vt-d: Support batching IOTLB/dev-IOTLB invalidation commands Tina Zhang
2024-05-19  9:42   ` Baolu Lu
2024-05-20  4:34     ` Zhang, Tina
2024-06-03  7:37     ` Zhang, Tina
2024-06-04  1:14       ` Baolu Lu
2024-06-04  5:59         ` Zhang, Tina
2024-06-04  7:01           ` Baolu Lu
2024-06-04 10:15             ` Zhang, Tina
2024-05-17  0:37 ` Tina Zhang [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240517003728.251115-3-tina.zhang@intel.com \
    --to=tina.zhang@intel.com \
    --cc=baolu.lu@linux.intel.com \
    --cc=iommu@lists.linux.dev \
    --cc=kevin.tian@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®