drivers/iommu/intel/cache.c
Source file repositories/reference/linux-study-clean/drivers/iommu/intel/cache.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iommu/intel/cache.c- Extension
.c- Size
- 14954 bytes
- Lines
- 522
- Domain
- Driver Families
- Bucket
- drivers/iommu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/dmar.hlinux/iommu.hlinux/memory.hlinux/pci.hlinux/spinlock.hiommu.hpasid.htrace.h
Detected Declarations
function Copyrightfunction cache_tag_assignfunction cache_tag_unassignfunction domain_qi_batch_allocfunction __cache_tag_assign_domainfunction __cache_tag_unassign_domainfunction __cache_tag_assign_parent_domainfunction __cache_tag_unassign_parent_domainfunction domain_get_id_for_devfunction successfunction cache_tag_unassign_domainfunction calculate_psi_aligned_addressfunction qi_batch_flush_descsfunction qi_batch_increment_indexfunction qi_batch_add_iotlbfunction qi_batch_add_dev_iotlbfunction qi_batch_add_piotlb_allfunction qi_batch_add_piotlbfunction qi_batch_add_pasid_dev_iotlbfunction intel_domain_use_piotlbfunction cache_tag_flush_iotlbfunction cache_tag_flush_devtlb_psifunction cache_tag_flush_rangefunction cache_tag_flush_allfunction cache_tag_flush_range_np
Annotated Snippet
if (cache_tage_match(temp, did, iommu, dev, pasid, type)) {
temp->users++;
spin_unlock_irqrestore(&domain->cache_lock, flags);
kfree(tag);
trace_cache_tag_assign(temp);
return 0;
}
if (temp->iommu == iommu)
prev = &temp->node;
}
/*
* Link cache tags of same iommu unit together, so corresponding
* flush ops can be batched for iommu unit.
*/
list_add(&tag->node, prev);
spin_unlock_irqrestore(&domain->cache_lock, flags);
trace_cache_tag_assign(tag);
return 0;
}
/* Unassign a cache tag with specified type from domain. */
static void cache_tag_unassign(struct dmar_domain *domain, u16 did,
struct device *dev, ioasid_t pasid,
enum cache_tag_type type)
{
struct device_domain_info *info = dev_iommu_priv_get(dev);
struct intel_iommu *iommu = info->iommu;
struct cache_tag *tag;
unsigned long flags;
spin_lock_irqsave(&domain->cache_lock, flags);
list_for_each_entry(tag, &domain->cache_tags, node) {
if (cache_tage_match(tag, did, iommu, dev, pasid, type)) {
trace_cache_tag_unassign(tag);
if (--tag->users == 0) {
list_del(&tag->node);
kfree(tag);
}
break;
}
}
spin_unlock_irqrestore(&domain->cache_lock, flags);
}
/* domain->qi_batch will be freed in iommu_free_domain() path. */
static int domain_qi_batch_alloc(struct dmar_domain *domain)
{
unsigned long flags;
int ret = 0;
spin_lock_irqsave(&domain->cache_lock, flags);
if (domain->qi_batch)
goto out_unlock;
domain->qi_batch = kzalloc_obj(*domain->qi_batch, GFP_ATOMIC);
if (!domain->qi_batch)
ret = -ENOMEM;
out_unlock:
spin_unlock_irqrestore(&domain->cache_lock, flags);
return ret;
}
static int __cache_tag_assign_domain(struct dmar_domain *domain, u16 did,
struct device *dev, ioasid_t pasid)
{
struct device_domain_info *info = dev_iommu_priv_get(dev);
int ret;
ret = domain_qi_batch_alloc(domain);
if (ret)
return ret;
ret = cache_tag_assign(domain, did, dev, pasid, CACHE_TAG_IOTLB);
if (ret || !info->ats_enabled)
return ret;
ret = cache_tag_assign(domain, did, dev, pasid, CACHE_TAG_DEVTLB);
if (ret)
cache_tag_unassign(domain, did, dev, pasid, CACHE_TAG_IOTLB);
return ret;
}
static void __cache_tag_unassign_domain(struct dmar_domain *domain, u16 did,
struct device *dev, ioasid_t pasid)
{
struct device_domain_info *info = dev_iommu_priv_get(dev);
Annotation
- Immediate include surface: `linux/dmar.h`, `linux/iommu.h`, `linux/memory.h`, `linux/pci.h`, `linux/spinlock.h`, `iommu.h`, `pasid.h`, `trace.h`.
- Detected declarations: `function Copyright`, `function cache_tag_assign`, `function cache_tag_unassign`, `function domain_qi_batch_alloc`, `function __cache_tag_assign_domain`, `function __cache_tag_unassign_domain`, `function __cache_tag_assign_parent_domain`, `function __cache_tag_unassign_parent_domain`, `function domain_get_id_for_dev`, `function success`.
- Atlas domain: Driver Families / drivers/iommu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.