diff options
author | Joerg Roedel <jroedel@suse.de> | 2016-07-07 10:12:02 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2016-07-14 04:21:16 -0400 |
commit | 281e8ccbff172899a60579773e72ad63d58b3770 (patch) | |
tree | b0a03aa4ffe518a51d273bd76700288169d0d99c /drivers/iommu/amd_iommu.c | |
parent | cda7005ba2cbd0744fea343dd5b2aa637eba5b9e (diff) |
iommu/amd: Flush iova queue before releasing dma_ops_domain
Before a dma_ops_domain can be freed, we need to make sure
it is not longer referenced by the flush queue. So empty the
queue before a dma_ops_domain can be freed.
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/amd_iommu.c')
-rw-r--r-- | drivers/iommu/amd_iommu.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 5c72d124403c..d13a18633dce 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -2154,12 +2154,10 @@ static void __queue_flush(struct flush_queue *queue) | |||
2154 | queue->next = 0; | 2154 | queue->next = 0; |
2155 | } | 2155 | } |
2156 | 2156 | ||
2157 | void queue_flush_timeout(unsigned long unsused) | 2157 | static void queue_flush_all(void) |
2158 | { | 2158 | { |
2159 | int cpu; | 2159 | int cpu; |
2160 | 2160 | ||
2161 | atomic_set(&queue_timer_on, 0); | ||
2162 | |||
2163 | for_each_possible_cpu(cpu) { | 2161 | for_each_possible_cpu(cpu) { |
2164 | struct flush_queue *queue; | 2162 | struct flush_queue *queue; |
2165 | unsigned long flags; | 2163 | unsigned long flags; |
@@ -2172,6 +2170,12 @@ void queue_flush_timeout(unsigned long unsused) | |||
2172 | } | 2170 | } |
2173 | } | 2171 | } |
2174 | 2172 | ||
2173 | static void queue_flush_timeout(unsigned long unsused) | ||
2174 | { | ||
2175 | atomic_set(&queue_timer_on, 0); | ||
2176 | queue_flush_all(); | ||
2177 | } | ||
2178 | |||
2175 | static void queue_add(struct dma_ops_domain *dma_dom, | 2179 | static void queue_add(struct dma_ops_domain *dma_dom, |
2176 | unsigned long address, unsigned long pages) | 2180 | unsigned long address, unsigned long pages) |
2177 | { | 2181 | { |
@@ -2877,6 +2881,13 @@ static void amd_iommu_domain_free(struct iommu_domain *dom) | |||
2877 | 2881 | ||
2878 | switch (dom->type) { | 2882 | switch (dom->type) { |
2879 | case IOMMU_DOMAIN_DMA: | 2883 | case IOMMU_DOMAIN_DMA: |
2884 | /* | ||
2885 | * First make sure the domain is no longer referenced from the | ||
2886 | * flush queue | ||
2887 | */ | ||
2888 | queue_flush_all(); | ||
2889 | |||
2890 | /* Now release the domain */ | ||
2880 | dma_dom = domain->priv; | 2891 | dma_dom = domain->priv; |
2881 | dma_ops_domain_free(dma_dom); | 2892 | dma_ops_domain_free(dma_dom); |
2882 | break; | 2893 | break; |