@@ -64,6 +64,179 @@ static int __init iommu_dma_forcedac_setup(char *str)
64
64
}
65
65
early_param ("iommu.forcedac" , iommu_dma_forcedac_setup );
66
66
67
+ #define fq_ring_for_each (i , fq ) \
68
+ for ((i) = (fq)->head; (i) != (fq)->tail; (i) = ((i) + 1) % IOVA_FQ_SIZE)
69
+
70
+ static inline bool fq_full (struct iova_fq * fq )
71
+ {
72
+ assert_spin_locked (& fq -> lock );
73
+ return (((fq -> tail + 1 ) % IOVA_FQ_SIZE ) == fq -> head );
74
+ }
75
+
76
+ static inline unsigned fq_ring_add (struct iova_fq * fq )
77
+ {
78
+ unsigned idx = fq -> tail ;
79
+
80
+ assert_spin_locked (& fq -> lock );
81
+
82
+ fq -> tail = (idx + 1 ) % IOVA_FQ_SIZE ;
83
+
84
+ return idx ;
85
+ }
86
+
87
+ static void fq_ring_free (struct iova_domain * iovad , struct iova_fq * fq )
88
+ {
89
+ u64 counter = atomic64_read (& iovad -> fq_flush_finish_cnt );
90
+ unsigned idx ;
91
+
92
+ assert_spin_locked (& fq -> lock );
93
+
94
+ fq_ring_for_each (idx , fq ) {
95
+
96
+ if (fq -> entries [idx ].counter >= counter )
97
+ break ;
98
+
99
+ put_pages_list (& fq -> entries [idx ].freelist );
100
+ free_iova_fast (iovad ,
101
+ fq -> entries [idx ].iova_pfn ,
102
+ fq -> entries [idx ].pages );
103
+
104
+ fq -> head = (fq -> head + 1 ) % IOVA_FQ_SIZE ;
105
+ }
106
+ }
107
+
108
+ static void iova_domain_flush (struct iova_domain * iovad )
109
+ {
110
+ atomic64_inc (& iovad -> fq_flush_start_cnt );
111
+ iovad -> fq_domain -> ops -> flush_iotlb_all (iovad -> fq_domain );
112
+ atomic64_inc (& iovad -> fq_flush_finish_cnt );
113
+ }
114
+
115
+ static void fq_flush_timeout (struct timer_list * t )
116
+ {
117
+ struct iova_domain * iovad = from_timer (iovad , t , fq_timer );
118
+ int cpu ;
119
+
120
+ atomic_set (& iovad -> fq_timer_on , 0 );
121
+ iova_domain_flush (iovad );
122
+
123
+ for_each_possible_cpu (cpu ) {
124
+ unsigned long flags ;
125
+ struct iova_fq * fq ;
126
+
127
+ fq = per_cpu_ptr (iovad -> fq , cpu );
128
+ spin_lock_irqsave (& fq -> lock , flags );
129
+ fq_ring_free (iovad , fq );
130
+ spin_unlock_irqrestore (& fq -> lock , flags );
131
+ }
132
+ }
133
+
134
+ void queue_iova (struct iova_domain * iovad ,
135
+ unsigned long pfn , unsigned long pages ,
136
+ struct list_head * freelist )
137
+ {
138
+ struct iova_fq * fq ;
139
+ unsigned long flags ;
140
+ unsigned idx ;
141
+
142
+ /*
143
+ * Order against the IOMMU driver's pagetable update from unmapping
144
+ * @pte, to guarantee that iova_domain_flush() observes that if called
145
+ * from a different CPU before we release the lock below. Full barrier
146
+ * so it also pairs with iommu_dma_init_fq() to avoid seeing partially
147
+ * written fq state here.
148
+ */
149
+ smp_mb ();
150
+
151
+ fq = raw_cpu_ptr (iovad -> fq );
152
+ spin_lock_irqsave (& fq -> lock , flags );
153
+
154
+ /*
155
+ * First remove all entries from the flush queue that have already been
156
+ * flushed out on another CPU. This makes the fq_full() check below less
157
+ * likely to be true.
158
+ */
159
+ fq_ring_free (iovad , fq );
160
+
161
+ if (fq_full (fq )) {
162
+ iova_domain_flush (iovad );
163
+ fq_ring_free (iovad , fq );
164
+ }
165
+
166
+ idx = fq_ring_add (fq );
167
+
168
+ fq -> entries [idx ].iova_pfn = pfn ;
169
+ fq -> entries [idx ].pages = pages ;
170
+ fq -> entries [idx ].counter = atomic64_read (& iovad -> fq_flush_start_cnt );
171
+ list_splice (freelist , & fq -> entries [idx ].freelist );
172
+
173
+ spin_unlock_irqrestore (& fq -> lock , flags );
174
+
175
+ /* Avoid false sharing as much as possible. */
176
+ if (!atomic_read (& iovad -> fq_timer_on ) &&
177
+ !atomic_xchg (& iovad -> fq_timer_on , 1 ))
178
+ mod_timer (& iovad -> fq_timer ,
179
+ jiffies + msecs_to_jiffies (IOVA_FQ_TIMEOUT ));
180
+ }
181
+
182
+ static void free_iova_flush_queue (struct iova_domain * iovad )
183
+ {
184
+ int cpu , idx ;
185
+
186
+ if (!iovad -> fq )
187
+ return ;
188
+
189
+ del_timer_sync (& iovad -> fq_timer );
190
+ /*
191
+ * This code runs when the iova_domain is being detroyed, so don't
192
+ * bother to free iovas, just free any remaining pagetable pages.
193
+ */
194
+ for_each_possible_cpu (cpu ) {
195
+ struct iova_fq * fq = per_cpu_ptr (iovad -> fq , cpu );
196
+
197
+ fq_ring_for_each (idx , fq )
198
+ put_pages_list (& fq -> entries [idx ].freelist );
199
+ }
200
+
201
+ free_percpu (iovad -> fq );
202
+
203
+ iovad -> fq = NULL ;
204
+ iovad -> fq_domain = NULL ;
205
+ }
206
+
207
+ int init_iova_flush_queue (struct iova_domain * iovad , struct iommu_domain * fq_domain )
208
+ {
209
+ struct iova_fq __percpu * queue ;
210
+ int i , cpu ;
211
+
212
+ atomic64_set (& iovad -> fq_flush_start_cnt , 0 );
213
+ atomic64_set (& iovad -> fq_flush_finish_cnt , 0 );
214
+
215
+ queue = alloc_percpu (struct iova_fq );
216
+ if (!queue )
217
+ return - ENOMEM ;
218
+
219
+ for_each_possible_cpu (cpu ) {
220
+ struct iova_fq * fq = per_cpu_ptr (queue , cpu );
221
+
222
+ fq -> head = 0 ;
223
+ fq -> tail = 0 ;
224
+
225
+ spin_lock_init (& fq -> lock );
226
+
227
+ for (i = 0 ; i < IOVA_FQ_SIZE ; i ++ )
228
+ INIT_LIST_HEAD (& fq -> entries [i ].freelist );
229
+ }
230
+
231
+ iovad -> fq_domain = fq_domain ;
232
+ iovad -> fq = queue ;
233
+
234
+ timer_setup (& iovad -> fq_timer , fq_flush_timeout , 0 );
235
+ atomic_set (& iovad -> fq_timer_on , 0 );
236
+
237
+ return 0 ;
238
+ }
239
+
67
240
static inline size_t cookie_msi_granule (struct iommu_dma_cookie * cookie )
68
241
{
69
242
if (cookie -> type == IOMMU_DMA_IOVA_COOKIE )
@@ -144,8 +317,10 @@ void iommu_put_dma_cookie(struct iommu_domain *domain)
144
317
if (!cookie )
145
318
return ;
146
319
147
- if (cookie -> type == IOMMU_DMA_IOVA_COOKIE && cookie -> iovad .granule )
320
+ if (cookie -> type == IOMMU_DMA_IOVA_COOKIE && cookie -> iovad .granule ) {
321
+ free_iova_flush_queue (& cookie -> iovad );
148
322
put_iova_domain (& cookie -> iovad );
323
+ }
149
324
150
325
list_for_each_entry_safe (msi , tmp , & cookie -> msi_page_list , list ) {
151
326
list_del (& msi -> list );
0 commit comments