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>
This commit is contained in:
parent
cda7005ba2
commit
281e8ccbff
@ -2154,12 +2154,10 @@ static void __queue_flush(struct flush_queue *queue)
|
|||||||
queue->next = 0;
|
queue->next = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void queue_flush_timeout(unsigned long unsused)
|
static void queue_flush_all(void)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
atomic_set(&queue_timer_on, 0);
|
|
||||||
|
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
struct flush_queue *queue;
|
struct flush_queue *queue;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@ -2172,6 +2170,12 @@ void queue_flush_timeout(unsigned long unsused)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void queue_flush_timeout(unsigned long unsused)
|
||||||
|
{
|
||||||
|
atomic_set(&queue_timer_on, 0);
|
||||||
|
queue_flush_all();
|
||||||
|
}
|
||||||
|
|
||||||
static void queue_add(struct dma_ops_domain *dma_dom,
|
static void queue_add(struct dma_ops_domain *dma_dom,
|
||||||
unsigned long address, unsigned long pages)
|
unsigned long address, unsigned long pages)
|
||||||
{
|
{
|
||||||
@ -2877,6 +2881,13 @@ static void amd_iommu_domain_free(struct iommu_domain *dom)
|
|||||||
|
|
||||||
switch (dom->type) {
|
switch (dom->type) {
|
||||||
case IOMMU_DOMAIN_DMA:
|
case IOMMU_DOMAIN_DMA:
|
||||||
|
/*
|
||||||
|
* First make sure the domain is no longer referenced from the
|
||||||
|
* flush queue
|
||||||
|
*/
|
||||||
|
queue_flush_all();
|
||||||
|
|
||||||
|
/* Now release the domain */
|
||||||
dma_dom = domain->priv;
|
dma_dom = domain->priv;
|
||||||
dma_ops_domain_free(dma_dom);
|
dma_ops_domain_free(dma_dom);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user