@@ -115,9 +115,16 @@ static bool round_up_default_nslabs(void)
115
115
return true;
116
116
}
117
117
118
+ /**
119
+ * swiotlb_adjust_nareas() - adjust the number of areas and slots
120
+ * @nareas: Desired number of areas. Zero is treated as 1.
121
+ *
122
+ * Adjust the default number of areas in a memory pool.
123
+ * The default size of the memory pool may also change to meet minimum area
124
+ * size requirements.
125
+ */
118
126
static void swiotlb_adjust_nareas (unsigned int nareas )
119
127
{
120
- /* use a single area when non is specified */
121
128
if (!nareas )
122
129
nareas = 1 ;
123
130
else if (!is_power_of_2 (nareas ))
@@ -131,6 +138,23 @@ static void swiotlb_adjust_nareas(unsigned int nareas)
131
138
(default_nslabs << IO_TLB_SHIFT ) >> 20 );
132
139
}
133
140
141
+ /**
142
+ * limit_nareas() - get the maximum number of areas for a given memory pool size
143
+ * @nareas: Desired number of areas.
144
+ * @nslots: Total number of slots in the memory pool.
145
+ *
146
+ * Limit the number of areas to the maximum possible number of areas in
147
+ * a memory pool of the given size.
148
+ *
149
+ * Return: Maximum possible number of areas.
150
+ */
151
+ static unsigned int limit_nareas (unsigned int nareas , unsigned long nslots )
152
+ {
153
+ if (nslots < nareas * IO_TLB_SEGSIZE )
154
+ return nslots / IO_TLB_SEGSIZE ;
155
+ return nareas ;
156
+ }
157
+
134
158
static int __init
135
159
setup_io_tlb_npages (char * str )
136
160
{
@@ -290,6 +314,7 @@ void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
290
314
{
291
315
struct io_tlb_mem * mem = & io_tlb_default_mem ;
292
316
unsigned long nslabs ;
317
+ unsigned int nareas ;
293
318
size_t alloc_size ;
294
319
void * tlb ;
295
320
@@ -298,18 +323,16 @@ void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
298
323
if (swiotlb_force_disable )
299
324
return ;
300
325
301
- /*
302
- * default_nslabs maybe changed when adjust area number.
303
- * So allocate bounce buffer after adjusting area number.
304
- */
305
326
if (!default_nareas )
306
327
swiotlb_adjust_nareas (num_possible_cpus ());
307
328
308
329
nslabs = default_nslabs ;
330
+ nareas = limit_nareas (default_nareas , nslabs );
309
331
while ((tlb = swiotlb_memblock_alloc (nslabs , flags , remap )) == NULL ) {
310
332
if (nslabs <= IO_TLB_MIN_SLABS )
311
333
return ;
312
334
nslabs = ALIGN (nslabs >> 1 , IO_TLB_SEGSIZE );
335
+ nareas = limit_nareas (nareas , nslabs );
313
336
}
314
337
315
338
if (default_nslabs != nslabs ) {
@@ -355,6 +378,7 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
355
378
{
356
379
struct io_tlb_mem * mem = & io_tlb_default_mem ;
357
380
unsigned long nslabs = ALIGN (size >> IO_TLB_SHIFT , IO_TLB_SEGSIZE );
381
+ unsigned int nareas ;
358
382
unsigned char * vstart = NULL ;
359
383
unsigned int order , area_order ;
360
384
bool retried = false;
@@ -363,6 +387,9 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
363
387
if (swiotlb_force_disable )
364
388
return 0 ;
365
389
390
+ if (!default_nareas )
391
+ swiotlb_adjust_nareas (num_possible_cpus ());
392
+
366
393
retry :
367
394
order = get_order (nslabs << IO_TLB_SHIFT );
368
395
nslabs = SLABS_PER_PAGE << order ;
@@ -397,11 +424,8 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
397
424
(PAGE_SIZE << order ) >> 20 );
398
425
}
399
426
400
- if (!default_nareas )
401
- swiotlb_adjust_nareas (num_possible_cpus ());
402
-
403
- area_order = get_order (array_size (sizeof (* mem -> areas ),
404
- default_nareas ));
427
+ nareas = limit_nareas (default_nareas , nslabs );
428
+ area_order = get_order (array_size (sizeof (* mem -> areas ), nareas ));
405
429
mem -> areas = (struct io_tlb_area * )
406
430
__get_free_pages (GFP_KERNEL | __GFP_ZERO , area_order );
407
431
if (!mem -> areas )
@@ -415,7 +439,7 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
415
439
set_memory_decrypted ((unsigned long )vstart ,
416
440
(nslabs << IO_TLB_SHIFT ) >> PAGE_SHIFT );
417
441
swiotlb_init_io_tlb_mem (mem , virt_to_phys (vstart ), nslabs , 0 , true,
418
- default_nareas );
442
+ nareas );
419
443
420
444
swiotlb_print_info ();
421
445
return 0 ;
0 commit comments