Skip to content

Commit 13cf017

Browse files
committed
iommu/vt-d: Make use of iova deferred flushing
Remove the deferred flushing implementation in the Intel VT-d driver and use the one from the common iova code instead. Signed-off-by: Joerg Roedel <[email protected]>
1 parent c8acb28 commit 13cf017

File tree

1 file changed

+38
-159
lines changed

1 file changed

+38
-159
lines changed

drivers/iommu/intel-iommu.c

Lines changed: 38 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -458,31 +458,6 @@ static LIST_HEAD(dmar_rmrr_units);
458458
#define for_each_rmrr_units(rmrr) \
459459
list_for_each_entry(rmrr, &dmar_rmrr_units, list)
460460

461-
static void flush_unmaps_timeout(unsigned long data);
462-
463-
struct deferred_flush_entry {
464-
unsigned long iova_pfn;
465-
unsigned long nrpages;
466-
struct dmar_domain *domain;
467-
struct page *freelist;
468-
};
469-
470-
#define HIGH_WATER_MARK 250
471-
struct deferred_flush_table {
472-
int next;
473-
struct deferred_flush_entry entries[HIGH_WATER_MARK];
474-
};
475-
476-
struct deferred_flush_data {
477-
spinlock_t lock;
478-
int timer_on;
479-
struct timer_list timer;
480-
long size;
481-
struct deferred_flush_table *tables;
482-
};
483-
484-
static DEFINE_PER_CPU(struct deferred_flush_data, deferred_flush);
485-
486461
/* bitmap for indexing intel_iommus */
487462
static int g_num_of_iommus;
488463

@@ -1309,6 +1284,13 @@ static void dma_free_pagelist(struct page *freelist)
13091284
}
13101285
}
13111286

1287+
static void iova_entry_free(unsigned long data)
1288+
{
1289+
struct page *freelist = (struct page *)data;
1290+
1291+
dma_free_pagelist(freelist);
1292+
}
1293+
13121294
/* iommu handling */
13131295
static int iommu_alloc_root_entry(struct intel_iommu *iommu)
13141296
{
@@ -1622,6 +1604,25 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
16221604
addr, mask);
16231605
}
16241606

1607+
static void iommu_flush_iova(struct iova_domain *iovad)
1608+
{
1609+
struct dmar_domain *domain;
1610+
int idx;
1611+
1612+
domain = container_of(iovad, struct dmar_domain, iovad);
1613+
1614+
for_each_domain_iommu(idx, domain) {
1615+
struct intel_iommu *iommu = g_iommus[idx];
1616+
u16 did = domain->iommu_did[iommu->seq_id];
1617+
1618+
iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
1619+
1620+
if (!cap_caching_mode(iommu->cap))
1621+
iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1622+
0, MAX_AGAW_PFN_WIDTH);
1623+
}
1624+
}
1625+
16251626
static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
16261627
{
16271628
u32 pmen;
@@ -1932,9 +1933,16 @@ static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
19321933
{
19331934
int adjust_width, agaw;
19341935
unsigned long sagaw;
1936+
int err;
19351937

19361938
init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN,
19371939
DMA_32BIT_PFN);
1940+
1941+
err = init_iova_flush_queue(&domain->iovad,
1942+
iommu_flush_iova, iova_entry_free);
1943+
if (err)
1944+
return err;
1945+
19381946
domain_reserve_special_ranges(domain);
19391947

19401948
/* calculate AGAW */
@@ -1986,14 +1994,6 @@ static void domain_exit(struct dmar_domain *domain)
19861994
if (!domain)
19871995
return;
19881996

1989-
/* Flush any lazy unmaps that may reference this domain */
1990-
if (!intel_iommu_strict) {
1991-
int cpu;
1992-
1993-
for_each_possible_cpu(cpu)
1994-
flush_unmaps_timeout(cpu);
1995-
}
1996-
19971997
/* Remove associated devices and clear attached or cached domains */
19981998
rcu_read_lock();
19991999
domain_remove_dev_info(domain);
@@ -3206,7 +3206,7 @@ static int __init init_dmars(void)
32063206
bool copied_tables = false;
32073207
struct device *dev;
32083208
struct intel_iommu *iommu;
3209-
int i, ret, cpu;
3209+
int i, ret;
32103210

32113211
/*
32123212
* for each drhd
@@ -3239,22 +3239,6 @@ static int __init init_dmars(void)
32393239
goto error;
32403240
}
32413241

3242-
for_each_possible_cpu(cpu) {
3243-
struct deferred_flush_data *dfd = per_cpu_ptr(&deferred_flush,
3244-
cpu);
3245-
3246-
dfd->tables = kzalloc(g_num_of_iommus *
3247-
sizeof(struct deferred_flush_table),
3248-
GFP_KERNEL);
3249-
if (!dfd->tables) {
3250-
ret = -ENOMEM;
3251-
goto free_g_iommus;
3252-
}
3253-
3254-
spin_lock_init(&dfd->lock);
3255-
setup_timer(&dfd->timer, flush_unmaps_timeout, cpu);
3256-
}
3257-
32583242
for_each_active_iommu(iommu, drhd) {
32593243
g_iommus[iommu->seq_id] = iommu;
32603244

@@ -3437,10 +3421,9 @@ static int __init init_dmars(void)
34373421
disable_dmar_iommu(iommu);
34383422
free_dmar_iommu(iommu);
34393423
}
3440-
free_g_iommus:
3441-
for_each_possible_cpu(cpu)
3442-
kfree(per_cpu_ptr(&deferred_flush, cpu)->tables);
3424+
34433425
kfree(g_iommus);
3426+
34443427
error:
34453428
return ret;
34463429
}
@@ -3645,110 +3628,6 @@ static dma_addr_t intel_map_page(struct device *dev, struct page *page,
36453628
dir, *dev->dma_mask);
36463629
}
36473630

3648-
static void flush_unmaps(struct deferred_flush_data *flush_data)
3649-
{
3650-
int i, j;
3651-
3652-
flush_data->timer_on = 0;
3653-
3654-
/* just flush them all */
3655-
for (i = 0; i < g_num_of_iommus; i++) {
3656-
struct intel_iommu *iommu = g_iommus[i];
3657-
struct deferred_flush_table *flush_table =
3658-
&flush_data->tables[i];
3659-
if (!iommu)
3660-
continue;
3661-
3662-
if (!flush_table->next)
3663-
continue;
3664-
3665-
/* In caching mode, global flushes turn emulation expensive */
3666-
if (!cap_caching_mode(iommu->cap))
3667-
iommu->flush.flush_iotlb(iommu, 0, 0, 0,
3668-
DMA_TLB_GLOBAL_FLUSH);
3669-
for (j = 0; j < flush_table->next; j++) {
3670-
unsigned long mask;
3671-
struct deferred_flush_entry *entry =
3672-
&flush_table->entries[j];
3673-
unsigned long iova_pfn = entry->iova_pfn;
3674-
unsigned long nrpages = entry->nrpages;
3675-
struct dmar_domain *domain = entry->domain;
3676-
struct page *freelist = entry->freelist;
3677-
3678-
/* On real hardware multiple invalidations are expensive */
3679-
if (cap_caching_mode(iommu->cap))
3680-
iommu_flush_iotlb_psi(iommu, domain,
3681-
mm_to_dma_pfn(iova_pfn),
3682-
nrpages, !freelist, 0);
3683-
else {
3684-
mask = ilog2(nrpages);
3685-
iommu_flush_dev_iotlb(domain,
3686-
(uint64_t)iova_pfn << PAGE_SHIFT, mask);
3687-
}
3688-
free_iova_fast(&domain->iovad, iova_pfn, nrpages);
3689-
if (freelist)
3690-
dma_free_pagelist(freelist);
3691-
}
3692-
flush_table->next = 0;
3693-
}
3694-
3695-
flush_data->size = 0;
3696-
}
3697-
3698-
static void flush_unmaps_timeout(unsigned long cpuid)
3699-
{
3700-
struct deferred_flush_data *flush_data = per_cpu_ptr(&deferred_flush, cpuid);
3701-
unsigned long flags;
3702-
3703-
spin_lock_irqsave(&flush_data->lock, flags);
3704-
flush_unmaps(flush_data);
3705-
spin_unlock_irqrestore(&flush_data->lock, flags);
3706-
}
3707-
3708-
static void add_unmap(struct dmar_domain *dom, unsigned long iova_pfn,
3709-
unsigned long nrpages, struct page *freelist)
3710-
{
3711-
unsigned long flags;
3712-
int entry_id, iommu_id;
3713-
struct intel_iommu *iommu;
3714-
struct deferred_flush_entry *entry;
3715-
struct deferred_flush_data *flush_data;
3716-
3717-
flush_data = raw_cpu_ptr(&deferred_flush);
3718-
3719-
/* Flush all CPUs' entries to avoid deferring too much. If
3720-
* this becomes a bottleneck, can just flush us, and rely on
3721-
* flush timer for the rest.
3722-
*/
3723-
if (flush_data->size == HIGH_WATER_MARK) {
3724-
int cpu;
3725-
3726-
for_each_online_cpu(cpu)
3727-
flush_unmaps_timeout(cpu);
3728-
}
3729-
3730-
spin_lock_irqsave(&flush_data->lock, flags);
3731-
3732-
iommu = domain_get_iommu(dom);
3733-
iommu_id = iommu->seq_id;
3734-
3735-
entry_id = flush_data->tables[iommu_id].next;
3736-
++(flush_data->tables[iommu_id].next);
3737-
3738-
entry = &flush_data->tables[iommu_id].entries[entry_id];
3739-
entry->domain = dom;
3740-
entry->iova_pfn = iova_pfn;
3741-
entry->nrpages = nrpages;
3742-
entry->freelist = freelist;
3743-
3744-
if (!flush_data->timer_on) {
3745-
mod_timer(&flush_data->timer, jiffies + msecs_to_jiffies(10));
3746-
flush_data->timer_on = 1;
3747-
}
3748-
flush_data->size++;
3749-
spin_unlock_irqrestore(&flush_data->lock, flags);
3750-
}
3751-
37523631
static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
37533632
{
37543633
struct dmar_domain *domain;
@@ -3784,7 +3663,8 @@ static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
37843663
free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
37853664
dma_free_pagelist(freelist);
37863665
} else {
3787-
add_unmap(domain, iova_pfn, nrpages, freelist);
3666+
queue_iova(&domain->iovad, iova_pfn, nrpages,
3667+
(unsigned long)freelist);
37883668
/*
37893669
* queue up the release of the unmap to save the 1/6th of the
37903670
* cpu used up by the iotlb flush operation...
@@ -4721,7 +4601,6 @@ static void free_all_cpu_cached_iovas(unsigned int cpu)
47214601
static int intel_iommu_cpu_dead(unsigned int cpu)
47224602
{
47234603
free_all_cpu_cached_iovas(cpu);
4724-
flush_unmaps_timeout(cpu);
47254604
return 0;
47264605
}
47274606

0 commit comments

Comments
 (0)