Commit 777cdd85 authored by Lu Baolu's avatar Lu Baolu Committed by Joerg Roedel
Browse files

iommu/vt-d: Add qi_batch for dmar_domain



Introduces a qi_batch structure to hold batched cache invalidation
descriptors on a per-dmar_domain basis. A fixed-size descriptor
array is used for simplicity. The qi_batch is allocated when the
first cache tag is added to the domain and freed during
iommu_free_domain().

Signed-off-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: default avatarTina Zhang <tina.zhang@intel.com>
Link: https://lore.kernel.org/r/20240815065221.50328-4-tina.zhang@intel.com


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 3297d047
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -190,6 +190,13 @@ int cache_tag_assign_domain(struct dmar_domain *domain,
	u16 did = domain_get_id_for_dev(domain, dev);
	int ret;

	/* domain->qi_bach will be freed in iommu_free_domain() path. */
	if (!domain->qi_batch) {
		domain->qi_batch = kzalloc(sizeof(*domain->qi_batch), GFP_KERNEL);
		if (!domain->qi_batch)
			return -ENOMEM;
	}

	ret = __cache_tag_assign_domain(domain, did, dev, pasid);
	if (ret || domain->domain.type != IOMMU_DOMAIN_NESTED)
		return ret;
+1 −0
Original line number Diff line number Diff line
@@ -1572,6 +1572,7 @@ static void domain_exit(struct dmar_domain *domain)
	if (WARN_ON(!list_empty(&domain->devices)))
		return;

	kfree(domain->qi_batch);
	kfree(domain);
}

+14 −0
Original line number Diff line number Diff line
@@ -584,6 +584,19 @@ struct iommu_domain_info {
					 * to VT-d spec, section 9.3 */
};

/*
 * We start simply by using a fixed size for the batched descriptors. This
 * size is currently sufficient for our needs. Future improvements could
 * involve dynamically allocating the batch buffer based on actual demand,
 * allowing us to adjust the batch size for optimal performance in different
 * scenarios.
 */
#define QI_MAX_BATCHED_DESC_COUNT 16
struct qi_batch {
	struct qi_desc descs[QI_MAX_BATCHED_DESC_COUNT];
	unsigned int index;
};

struct dmar_domain {
	int	nid;			/* node id */
	struct xarray iommu_array;	/* Attached IOMMU array */
@@ -608,6 +621,7 @@ struct dmar_domain {

	spinlock_t cache_lock;		/* Protect the cache tag list */
	struct list_head cache_tags;	/* Cache tag list */
	struct qi_batch *qi_batch;	/* Batched QI descriptors */

	int		iommu_superpage;/* Level of superpages supported:
					   0 == 4KiB (no superpages), 1 == 2MiB,
+1 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ static void intel_nested_domain_free(struct iommu_domain *domain)
	spin_lock(&s2_domain->s1_lock);
	list_del(&dmar_domain->s2_link);
	spin_unlock(&s2_domain->s1_lock);
	kfree(dmar_domain->qi_batch);
	kfree(dmar_domain);
}

+4 −1
Original line number Diff line number Diff line
@@ -184,7 +184,10 @@ static void intel_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)

static void intel_mm_free_notifier(struct mmu_notifier *mn)
{
	kfree(container_of(mn, struct dmar_domain, notifier));
	struct dmar_domain *domain = container_of(mn, struct dmar_domain, notifier);

	kfree(domain->qi_batch);
	kfree(domain);
}

static const struct mmu_notifier_ops intel_mmuops = {