IOMMU map/unmap traces become hard to decode i.e., it becomes hard
to associate the map/unmap events with the particular device from
the iova/paddr/size parameters alone when there are multiple
devices attached. So it is useful to add the device name to iommu
trace events which can be used to filter out map/unmap traces for
a particular device when we are debugging iommu faults such as
context faults where we are interested with the map/unmap traces
for a specific device.
Before:
map: IOMMU: iova=0x0000000ffff36000 paddr=0x00000001164d8000 size=4096
unmap: IOMMU: iova=0x0000000ffff36000 size=4096 unmapped_size=4096
After:
map: IOMMU: dev=1d84000.ufshc iova=0x0000000fffa88000 paddr=0x00000001063db000 size=4096
unmap: IOMMU: dev=1d84000.ufshc iova=0x0000000fffa88000 size=4096 unmapped_size=4096
Signed-off-by: Sai Prakash Ranjan <[email protected]>
---
drivers/iommu/iommu.c | 8 +++++---
include/linux/iommu.h | 1 +
include/trace/events/iommu.h | 20 ++++++++++++--------
3 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d0b0a15dba84..37081b745f38 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1947,8 +1947,10 @@ static int __iommu_attach_device(struct iommu_domain *domain,
return -ENODEV;
ret = domain->ops->attach_dev(domain, dev);
- if (!ret)
+ if (!ret) {
trace_attach_device_to_domain(dev);
+ strscpy(domain->dev_name, dev_name(dev), sizeof(domain->dev_name));
+ }
return ret;
}
@@ -2440,7 +2442,7 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova,
if (ret)
iommu_unmap(domain, orig_iova, orig_size - size);
else
- trace_map(orig_iova, orig_paddr, orig_size);
+ trace_map(orig_iova, orig_paddr, orig_size, domain->dev_name);
return ret;
}
@@ -2523,7 +2525,7 @@ static size_t __iommu_unmap(struct iommu_domain *domain,
unmapped += unmapped_page;
}
- trace_unmap(orig_iova, size, unmapped);
+ trace_unmap(orig_iova, size, unmapped, domain->dev_name);
return unmapped;
}
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5e7fe519430a..6064187d9bb6 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -87,6 +87,7 @@ struct iommu_domain {
void *handler_token;
struct iommu_domain_geometry geometry;
void *iova_cookie;
+ char dev_name[32];
};
enum iommu_cap {
diff --git a/include/trace/events/iommu.h b/include/trace/events/iommu.h
index 72b4582322ff..44e48fb8b677 100644
--- a/include/trace/events/iommu.h
+++ b/include/trace/events/iommu.h
@@ -85,47 +85,51 @@ DEFINE_EVENT(iommu_device_event, detach_device_from_domain,
TRACE_EVENT(map,
- TP_PROTO(unsigned long iova, phys_addr_t paddr, size_t size),
+ TP_PROTO(unsigned long iova, phys_addr_t paddr, size_t size, const char *dev_name),
- TP_ARGS(iova, paddr, size),
+ TP_ARGS(iova, paddr, size, dev_name),
TP_STRUCT__entry(
__field(u64, iova)
__field(u64, paddr)
__field(size_t, size)
+ __string(dev_name, dev_name)
),
TP_fast_assign(
__entry->iova = iova;
__entry->paddr = paddr;
__entry->size = size;
+ __assign_str(dev_name, dev_name);
),
- TP_printk("IOMMU: iova=0x%016llx paddr=0x%016llx size=%zu",
- __entry->iova, __entry->paddr, __entry->size
+ TP_printk("IOMMU: dev=%s iova=0x%016llx paddr=0x%016llx size=%zu",
+ __get_str(dev_name), __entry->iova, __entry->paddr, __entry->size
)
);
TRACE_EVENT(unmap,
- TP_PROTO(unsigned long iova, size_t size, size_t unmapped_size),
+ TP_PROTO(unsigned long iova, size_t size, size_t unmapped_size, const char *dev_name),
- TP_ARGS(iova, size, unmapped_size),
+ TP_ARGS(iova, size, unmapped_size, dev_name),
TP_STRUCT__entry(
__field(u64, iova)
__field(size_t, size)
__field(size_t, unmapped_size)
+ __string(dev_name, dev_name)
),
TP_fast_assign(
__entry->iova = iova;
__entry->size = size;
__entry->unmapped_size = unmapped_size;
+ __assign_str(dev_name, dev_name);
),
- TP_printk("IOMMU: iova=0x%016llx size=%zu unmapped_size=%zu",
- __entry->iova, __entry->size, __entry->unmapped_size
+ TP_printk("IOMMU: dev=%s iova=0x%016llx size=%zu unmapped_size=%zu",
+ __get_str(dev_name), __entry->iova, __entry->size, __entry->unmapped_size
)
);
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
On Tue, Feb 09, 2021 at 06:06:20PM +0530, Sai Prakash Ranjan wrote:
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 5e7fe519430a..6064187d9bb6 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -87,6 +87,7 @@ struct iommu_domain {
> void *handler_token;
> struct iommu_domain_geometry geometry;
> void *iova_cookie;
> + char dev_name[32];
> };
No, definitly not. A domain is a device DMA address space which can be
used by more than one device. Just look at IOMMU groups with more than
one member device, in this case just one device name would be very
misleading.
Regards,
Joerg
Hi,
在 2021/2/12 18:50, Joerg Roedel 写道:
> On Tue, Feb 09, 2021 at 06:06:20PM +0530, Sai Prakash Ranjan wrote:
>> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
>> index 5e7fe519430a..6064187d9bb6 100644
>> --- a/include/linux/iommu.h
>> +++ b/include/linux/iommu.h
>> @@ -87,6 +87,7 @@ struct iommu_domain {
>> void *handler_token;
>> struct iommu_domain_geometry geometry;
>> void *iova_cookie;
>> + char dev_name[32];
>> };
> No, definitly not. A domain is a device DMA address space which can be
> used by more than one device. Just look at IOMMU groups with more than
> one member device, in this case just one device name would be very
> misleading.
Is it possible to use group id to identify different domains?
>
> Regards,
>
> Joerg
> _______________________________________________
> iommu mailing list
> [email protected]
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
>
> .
>
On Tue, Apr 06, 2021 at 02:56:53PM +0800, chenxiang (M) wrote:
> Is it possible to use group id to identify different domains?
No, the best is to do this during post-processing of your traces by also
keeping tack of domain-device attachments/detachments.
Regards,
Joerg