81 lines
3.0 KiB
Plaintext
81 lines
3.0 KiB
Plaintext
This document describes the concept of Dynamic domains, how to use dynamic
|
|
domains and their implementation.
|
|
|
|
Dynamic Domains:
|
|
================
|
|
|
|
Some clients like graphics has many processes and hence
|
|
many domains (one for each process). While switching
|
|
between processes, context bank is updated by client
|
|
driver to point to new domain (or say TTBR0 is updated
|
|
to point to new page table). During this time, client
|
|
driver also invalidates the TLB to discard old page
|
|
table entries from TLB. This is costly operation in
|
|
time.
|
|
|
|
SMMU provides ASID tagging support with each page table.
|
|
If we tag different ASID with each domain, we can omit
|
|
TLB invalidation of out going domain. To make this
|
|
happen, client can attach one base domain and multiple
|
|
_dynamic_ domains. Dynamic domain would represent
|
|
each translation context with unique ASID on same
|
|
context bank.
|
|
|
|
How to use dynamic domains:
|
|
===========================
|
|
|
|
Following is example code of how to use dynamic domains.
|
|
|
|
void fn()
|
|
{
|
|
struct iommu_domain *base_domain, *dyn_domain1, *dyn_domain2;
|
|
|
|
base_domain = iommu_domain_alloc(bus);
|
|
dyn_domain1 = iommu_domain_alloc(bus);
|
|
dyn_domain2 = iommu_domain_alloc(bus);
|
|
|
|
iommu_attach_device(base_domain, dev);
|
|
|
|
iommu_domain_set_attr(dyn_domain1, DOMAIN_ATTR_DYNAMIC, &dynamic);
|
|
iommu_domain_set_attr(dyn_domain2, DOMAIN_ATTR_DYNAMIC, &dynamic);
|
|
iommu_attach_device(dyn_domain1, dev);
|
|
iommu_attach_device(dyn_domain2, dev);
|
|
|
|
while (keep_going) {
|
|
iommu_map(dyn_domain1, ...);
|
|
iommu_map(dyn_domain2, ...);
|
|
use_domain(dyn_domain1, job1);
|
|
use_domain(dyn_domain2, job2);
|
|
iommu_unmap(dyn_domain1, ...);
|
|
iommu_unmap(dyn_domain2, ...);
|
|
}
|
|
|
|
iommu_detach_device(dyn_domain2, dev);
|
|
iommu_detach_device(dyn_domain1, dev);
|
|
iommu_detach_device(base_domain, dev);
|
|
}
|
|
|
|
Some constraints while using dynamic domains:
|
|
============================================
|
|
|
|
* Before detaching the base_domain, we must detach all the dynamic
|
|
domains. This is because, dynamic domain detach will invalidate
|
|
the TLB. At the time of TLB invalidate, we really want the CB
|
|
programming intact. And detach of base_domain will clear the CB
|
|
programming which can cause some issues in TLB invalidation of
|
|
dynamic domains.
|
|
|
|
* At the time of fault, the domain used by fault handler is the
|
|
base_domain. So, any debug info which comes from attached domain
|
|
would be from base_domain where as at the time of fault, it may
|
|
be possible that some dynamic_domain is attached. So, don't trust
|
|
debug info comes out from domain.
|
|
|
|
* Dynamic domains doesn't store its CB device identity. IOMMU drivers
|
|
assumes that only one domain can be attached to one CB at any given
|
|
time. We still attach multiple dynamic domains on top of one
|
|
base_domain to CB. In the background, client driver uses these dynamic
|
|
domains to switch the per-process page tables about which IOMMU driver
|
|
can never be aware. Hence, dynamic domains never really knows its CB
|
|
device.
|