Skip to content

Commit 9003d61

Browse files
committed
iommu/amd: Make use of iova queue flushing
Rip out the implementation in the AMD IOMMU driver and use the one in the common iova code instead. Signed-off-by: Joerg Roedel <[email protected]>
1 parent 9a005a8 commit 9003d61

File tree

1 file changed

+9
-220
lines changed

1 file changed

+9
-220
lines changed

drivers/iommu/amd_iommu.c

Lines changed: 9 additions & 220 deletions
Original file line numberDiff line numberDiff line change
@@ -137,20 +137,7 @@ struct kmem_cache *amd_iommu_irq_cache;
137137
static void update_domain(struct protection_domain *domain);
138138
static int protection_domain_init(struct protection_domain *domain);
139139
static void detach_device(struct device *dev);
140-
141-
#define FLUSH_QUEUE_SIZE 256
142-
143-
struct flush_queue_entry {
144-
unsigned long iova_pfn;
145-
unsigned long pages;
146-
u64 counter; /* Flush counter when this entry was added to the queue */
147-
};
148-
149-
struct flush_queue {
150-
struct flush_queue_entry *entries;
151-
unsigned head, tail;
152-
spinlock_t lock;
153-
};
140+
static void iova_domain_flush_tlb(struct iova_domain *iovad);
154141

155142
/*
156143
* Data container for a dma_ops specific protection domain
@@ -161,36 +148,6 @@ struct dma_ops_domain {
161148

162149
/* IOVA RB-Tree */
163150
struct iova_domain iovad;
164-
165-
struct flush_queue __percpu *flush_queue;
166-
167-
/*
168-
* We need two counter here to be race-free wrt. IOTLB flushing and
169-
* adding entries to the flush queue.
170-
*
171-
* The flush_start_cnt is incremented _before_ the IOTLB flush starts.
172-
* New entries added to the flush ring-buffer get their 'counter' value
173-
* from here. This way we can make sure that entries added to the queue
174-
* (or other per-cpu queues of the same domain) while the TLB is about
175-
* to be flushed are not considered to be flushed already.
176-
*/
177-
atomic64_t flush_start_cnt;
178-
179-
/*
180-
* The flush_finish_cnt is incremented when an IOTLB flush is complete.
181-
* This value is always smaller than flush_start_cnt. The queue_add
182-
* function frees all IOVAs that have a counter value smaller than
183-
* flush_finish_cnt. This makes sure that we only free IOVAs that are
184-
* flushed out of the IOTLB of the domain.
185-
*/
186-
atomic64_t flush_finish_cnt;
187-
188-
/*
189-
* Timer to make sure we don't keep IOVAs around unflushed
190-
* for too long
191-
*/
192-
struct timer_list flush_timer;
193-
atomic_t flush_timer_on;
194151
};
195152

196153
static struct iova_domain reserved_iova_ranges;
@@ -1788,178 +1745,19 @@ static void free_gcr3_table(struct protection_domain *domain)
17881745
free_page((unsigned long)domain->gcr3_tbl);
17891746
}
17901747

1791-
static void dma_ops_domain_free_flush_queue(struct dma_ops_domain *dom)
1792-
{
1793-
int cpu;
1794-
1795-
for_each_possible_cpu(cpu) {
1796-
struct flush_queue *queue;
1797-
1798-
queue = per_cpu_ptr(dom->flush_queue, cpu);
1799-
kfree(queue->entries);
1800-
}
1801-
1802-
free_percpu(dom->flush_queue);
1803-
1804-
dom->flush_queue = NULL;
1805-
}
1806-
1807-
static int dma_ops_domain_alloc_flush_queue(struct dma_ops_domain *dom)
1808-
{
1809-
int cpu;
1810-
1811-
atomic64_set(&dom->flush_start_cnt, 0);
1812-
atomic64_set(&dom->flush_finish_cnt, 0);
1813-
1814-
dom->flush_queue = alloc_percpu(struct flush_queue);
1815-
if (!dom->flush_queue)
1816-
return -ENOMEM;
1817-
1818-
/* First make sure everything is cleared */
1819-
for_each_possible_cpu(cpu) {
1820-
struct flush_queue *queue;
1821-
1822-
queue = per_cpu_ptr(dom->flush_queue, cpu);
1823-
queue->head = 0;
1824-
queue->tail = 0;
1825-
queue->entries = NULL;
1826-
}
1827-
1828-
/* Now start doing the allocation */
1829-
for_each_possible_cpu(cpu) {
1830-
struct flush_queue *queue;
1831-
1832-
queue = per_cpu_ptr(dom->flush_queue, cpu);
1833-
queue->entries = kzalloc(FLUSH_QUEUE_SIZE * sizeof(*queue->entries),
1834-
GFP_KERNEL);
1835-
if (!queue->entries) {
1836-
dma_ops_domain_free_flush_queue(dom);
1837-
return -ENOMEM;
1838-
}
1839-
1840-
spin_lock_init(&queue->lock);
1841-
}
1842-
1843-
return 0;
1844-
}
1845-
18461748
static void dma_ops_domain_flush_tlb(struct dma_ops_domain *dom)
18471749
{
1848-
atomic64_inc(&dom->flush_start_cnt);
18491750
domain_flush_tlb(&dom->domain);
18501751
domain_flush_complete(&dom->domain);
1851-
atomic64_inc(&dom->flush_finish_cnt);
18521752
}
18531753

1854-
static inline bool queue_ring_full(struct flush_queue *queue)
1754+
static void iova_domain_flush_tlb(struct iova_domain *iovad)
18551755
{
1856-
assert_spin_locked(&queue->lock);
1857-
1858-
return (((queue->tail + 1) % FLUSH_QUEUE_SIZE) == queue->head);
1859-
}
1756+
struct dma_ops_domain *dom;
18601757

1861-
#define queue_ring_for_each(i, q) \
1862-
for (i = (q)->head; i != (q)->tail; i = (i + 1) % FLUSH_QUEUE_SIZE)
1863-
1864-
static inline unsigned queue_ring_add(struct flush_queue *queue)
1865-
{
1866-
unsigned idx = queue->tail;
1867-
1868-
assert_spin_locked(&queue->lock);
1869-
queue->tail = (idx + 1) % FLUSH_QUEUE_SIZE;
1870-
1871-
return idx;
1872-
}
1873-
1874-
static inline void queue_ring_remove_head(struct flush_queue *queue)
1875-
{
1876-
assert_spin_locked(&queue->lock);
1877-
queue->head = (queue->head + 1) % FLUSH_QUEUE_SIZE;
1878-
}
1879-
1880-
static void queue_ring_free_flushed(struct dma_ops_domain *dom,
1881-
struct flush_queue *queue)
1882-
{
1883-
u64 counter = atomic64_read(&dom->flush_finish_cnt);
1884-
int idx;
1885-
1886-
queue_ring_for_each(idx, queue) {
1887-
/*
1888-
* This assumes that counter values in the ring-buffer are
1889-
* monotonously rising.
1890-
*/
1891-
if (queue->entries[idx].counter >= counter)
1892-
break;
1893-
1894-
free_iova_fast(&dom->iovad,
1895-
queue->entries[idx].iova_pfn,
1896-
queue->entries[idx].pages);
1897-
1898-
queue_ring_remove_head(queue);
1899-
}
1900-
}
1901-
1902-
static void queue_add(struct dma_ops_domain *dom,
1903-
unsigned long address, unsigned long pages)
1904-
{
1905-
struct flush_queue *queue;
1906-
unsigned long flags;
1907-
int idx;
1908-
1909-
pages = __roundup_pow_of_two(pages);
1910-
address >>= PAGE_SHIFT;
1911-
1912-
queue = get_cpu_ptr(dom->flush_queue);
1913-
spin_lock_irqsave(&queue->lock, flags);
1914-
1915-
/*
1916-
* First remove the enries from the ring-buffer that are already
1917-
* flushed to make the below queue_ring_full() check less likely
1918-
*/
1919-
queue_ring_free_flushed(dom, queue);
1920-
1921-
/*
1922-
* When ring-queue is full, flush the entries from the IOTLB so
1923-
* that we can free all entries with queue_ring_free_flushed()
1924-
* below.
1925-
*/
1926-
if (queue_ring_full(queue)) {
1927-
dma_ops_domain_flush_tlb(dom);
1928-
queue_ring_free_flushed(dom, queue);
1929-
}
1930-
1931-
idx = queue_ring_add(queue);
1932-
1933-
queue->entries[idx].iova_pfn = address;
1934-
queue->entries[idx].pages = pages;
1935-
queue->entries[idx].counter = atomic64_read(&dom->flush_start_cnt);
1936-
1937-
spin_unlock_irqrestore(&queue->lock, flags);
1938-
1939-
if (atomic_cmpxchg(&dom->flush_timer_on, 0, 1) == 0)
1940-
mod_timer(&dom->flush_timer, jiffies + msecs_to_jiffies(10));
1941-
1942-
put_cpu_ptr(dom->flush_queue);
1943-
}
1944-
1945-
static void queue_flush_timeout(unsigned long data)
1946-
{
1947-
struct dma_ops_domain *dom = (struct dma_ops_domain *)data;
1948-
int cpu;
1949-
1950-
atomic_set(&dom->flush_timer_on, 0);
1758+
dom = container_of(iovad, struct dma_ops_domain, iovad);
19511759

19521760
dma_ops_domain_flush_tlb(dom);
1953-
1954-
for_each_possible_cpu(cpu) {
1955-
struct flush_queue *queue;
1956-
unsigned long flags;
1957-
1958-
queue = per_cpu_ptr(dom->flush_queue, cpu);
1959-
spin_lock_irqsave(&queue->lock, flags);
1960-
queue_ring_free_flushed(dom, queue);
1961-
spin_unlock_irqrestore(&queue->lock, flags);
1962-
}
19631761
}
19641762

19651763
/*
@@ -1973,11 +1771,6 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom)
19731771

19741772
del_domain_from_list(&dom->domain);
19751773

1976-
if (timer_pending(&dom->flush_timer))
1977-
del_timer(&dom->flush_timer);
1978-
1979-
dma_ops_domain_free_flush_queue(dom);
1980-
19811774
put_iova_domain(&dom->iovad);
19821775

19831776
free_pagetable(&dom->domain);
@@ -2013,16 +1806,11 @@ static struct dma_ops_domain *dma_ops_domain_alloc(void)
20131806
init_iova_domain(&dma_dom->iovad, PAGE_SIZE,
20141807
IOVA_START_PFN, DMA_32BIT_PFN);
20151808

2016-
/* Initialize reserved ranges */
2017-
copy_reserved_iova(&reserved_iova_ranges, &dma_dom->iovad);
2018-
2019-
if (dma_ops_domain_alloc_flush_queue(dma_dom))
1809+
if (init_iova_flush_queue(&dma_dom->iovad, iova_domain_flush_tlb, NULL))
20201810
goto free_dma_dom;
20211811

2022-
setup_timer(&dma_dom->flush_timer, queue_flush_timeout,
2023-
(unsigned long)dma_dom);
2024-
2025-
atomic_set(&dma_dom->flush_timer_on, 0);
1812+
/* Initialize reserved ranges */
1813+
copy_reserved_iova(&reserved_iova_ranges, &dma_dom->iovad);
20261814

20271815
add_domain_to_list(&dma_dom->domain);
20281816

@@ -2619,7 +2407,8 @@ static void __unmap_single(struct dma_ops_domain *dma_dom,
26192407
domain_flush_tlb(&dma_dom->domain);
26202408
domain_flush_complete(&dma_dom->domain);
26212409
} else {
2622-
queue_add(dma_dom, dma_addr, pages);
2410+
pages = __roundup_pow_of_two(pages);
2411+
queue_iova(&dma_dom->iovad, dma_addr >> PAGE_SHIFT, pages, 0);
26232412
}
26242413
}
26252414

0 commit comments

Comments
 (0)