AMD IOMMU: add stats counter for single iommu domain tlb flushes
[firefly-linux-kernel-4.4.55.git] / arch / x86 / kernel / amd_iommu.c
index 71646c81421a0d4b54aaf4f3f285defafdee9475..e99022d3a3944ecf64a99431426cee939ae03e7b 100644 (file)
@@ -67,6 +67,12 @@ static struct dma_ops_domain *find_protection_domain(u16 devid);
 DECLARE_STATS_COUNTER(compl_wait);
 DECLARE_STATS_COUNTER(cnt_map_single);
 DECLARE_STATS_COUNTER(cnt_unmap_single);
+DECLARE_STATS_COUNTER(cnt_map_sg);
+DECLARE_STATS_COUNTER(cnt_unmap_sg);
+DECLARE_STATS_COUNTER(cnt_alloc_coherent);
+DECLARE_STATS_COUNTER(cnt_free_coherent);
+DECLARE_STATS_COUNTER(cross_page);
+DECLARE_STATS_COUNTER(domain_flush_single);
 
 static struct dentry *stats_dir;
 static struct dentry *de_isolate;
@@ -96,6 +102,12 @@ static void amd_iommu_stats_init(void)
        amd_iommu_stats_add(&compl_wait);
        amd_iommu_stats_add(&cnt_map_single);
        amd_iommu_stats_add(&cnt_unmap_single);
+       amd_iommu_stats_add(&cnt_map_sg);
+       amd_iommu_stats_add(&cnt_unmap_sg);
+       amd_iommu_stats_add(&cnt_alloc_coherent);
+       amd_iommu_stats_add(&cnt_free_coherent);
+       amd_iommu_stats_add(&cross_page);
+       amd_iommu_stats_add(&domain_flush_single);
 }
 
 #endif
@@ -403,6 +415,8 @@ static void iommu_flush_tlb(struct amd_iommu *iommu, u16 domid)
 {
        u64 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
 
+       INC_STATS_COUNTER(domain_flush_single);
+
        iommu_queue_inv_iommu_pages(iommu, address, domid, 0, 1);
 }
 
@@ -1209,6 +1223,9 @@ static dma_addr_t __map_single(struct device *dev,
        pages = iommu_num_pages(paddr, size, PAGE_SIZE);
        paddr &= PAGE_MASK;
 
+       if (pages > 1)
+               INC_STATS_COUNTER(cross_page);
+
        if (align)
                align_mask = (1UL << get_order(size)) - 1;
 
@@ -1377,6 +1394,8 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
        int mapped_elems = 0;
        u64 dma_mask;
 
+       INC_STATS_COUNTER(cnt_map_sg);
+
        if (!check_device(dev))
                return 0;
 
@@ -1439,6 +1458,8 @@ static void unmap_sg(struct device *dev, struct scatterlist *sglist,
        u16 devid;
        int i;
 
+       INC_STATS_COUNTER(cnt_unmap_sg);
+
        if (!check_device(dev) ||
            !get_device_resources(dev, &iommu, &domain, &devid))
                return;
@@ -1473,6 +1494,8 @@ static void *alloc_coherent(struct device *dev, size_t size,
        phys_addr_t paddr;
        u64 dma_mask = dev->coherent_dma_mask;
 
+       INC_STATS_COUNTER(cnt_alloc_coherent);
+
        if (!check_device(dev))
                return NULL;
 
@@ -1529,6 +1552,8 @@ static void free_coherent(struct device *dev, size_t size,
        struct protection_domain *domain;
        u16 devid;
 
+       INC_STATS_COUNTER(cnt_free_coherent);
+
        if (!check_device(dev))
                return;