Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: crypto4xx - reduce memory fragmentation

With recent kernels (>5.2), the driver fails to probe, as the
allocation of the driver's scatter buffer fails with -ENOMEM.

This happens in crypto4xx_build_sdr(). Where the driver tries
to get 512KiB (=PPC4XX_SD_BUFFER_SIZE * PPC4XX_NUM_SD) of
continuous memory. This big chunk is by design, since the driver
uses this circumstance in the crypto4xx_copy_pkt_to_dst() to
its advantage:
"all scatter-buffers are all neatly organized in one big
continuous ringbuffer; So scatterwalk_map_and_copy() can be
instructed to copy a range of buffers in one go."

The PowerPC arch does not have support for DMA_CMA. Hence,
this patch reorganizes the order in which the memory
allocations are done. Since the driver itself is responsible
for some of the issues.

Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Christian Lamparter and committed by
Herbert Xu
b87b2c4d af5034e8

+13 -14
+13 -14
drivers/crypto/amcc/crypto4xx_core.c
··· 286 286 287 287 static inline void crypto4xx_destroy_gdr(struct crypto4xx_device *dev) 288 288 { 289 - dma_free_coherent(dev->core_dev->device, 289 + if (dev->gdr) 290 + dma_free_coherent(dev->core_dev->device, 290 291 sizeof(struct ce_gd) * PPC4XX_NUM_GD, 291 292 dev->gdr, dev->gdr_pa); 292 293 } ··· 355 354 { 356 355 int i; 357 356 358 - /* alloc memory for scatter descriptor ring */ 359 - dev->sdr = dma_alloc_coherent(dev->core_dev->device, 360 - sizeof(struct ce_sd) * PPC4XX_NUM_SD, 361 - &dev->sdr_pa, GFP_ATOMIC); 362 - if (!dev->sdr) 363 - return -ENOMEM; 364 - 365 357 dev->scatter_buffer_va = 366 358 dma_alloc_coherent(dev->core_dev->device, 367 359 PPC4XX_SD_BUFFER_SIZE * PPC4XX_NUM_SD, 368 360 &dev->scatter_buffer_pa, GFP_ATOMIC); 369 361 if (!dev->scatter_buffer_va) 362 + return -ENOMEM; 363 + 364 + /* alloc memory for scatter descriptor ring */ 365 + dev->sdr = dma_alloc_coherent(dev->core_dev->device, 366 + sizeof(struct ce_sd) * PPC4XX_NUM_SD, 367 + &dev->sdr_pa, GFP_ATOMIC); 368 + if (!dev->sdr) 370 369 return -ENOMEM; 371 370 372 371 for (i = 0; i < PPC4XX_NUM_SD; i++) { ··· 1440 1439 spin_lock_init(&core_dev->lock); 1441 1440 INIT_LIST_HEAD(&core_dev->dev->alg_list); 1442 1441 ratelimit_default_init(&core_dev->dev->aead_ratelimit); 1442 + rc = crypto4xx_build_sdr(core_dev->dev); 1443 + if (rc) 1444 + goto err_build_sdr; 1443 1445 rc = crypto4xx_build_pdr(core_dev->dev); 1444 1446 if (rc) 1445 - goto err_build_pdr; 1447 + goto err_build_sdr; 1446 1448 1447 1449 rc = crypto4xx_build_gdr(core_dev->dev); 1448 - if (rc) 1449 - goto err_build_pdr; 1450 - 1451 - rc = crypto4xx_build_sdr(core_dev->dev); 1452 1450 if (rc) 1453 1451 goto err_build_sdr; 1454 1452 ··· 1493 1493 err_build_sdr: 1494 1494 crypto4xx_destroy_sdr(core_dev->dev); 1495 1495 crypto4xx_destroy_gdr(core_dev->dev); 1496 - err_build_pdr: 1497 1496 crypto4xx_destroy_pdr(core_dev->dev); 1498 1497 kfree(core_dev->dev); 1499 1498 err_alloc_dev: