On Wed, Jun 25, 2025 at 03:45:08AM +0000, Tian, Kevin wrote:
From: Nicolin Chen nicolinc@nvidia.com Sent: Saturday, June 14, 2025 3:15 PM
- offset =
cmd->nesting_parent_iova - PAGE_ALIGN(cmd-
nesting_parent_iova);
- max_npages = DIV_ROUND_UP(offset + cmd->length, PAGE_SIZE);
- /*
* FIXME allocation may fail when sizeof(*pages) * max_npages is
* larger than PAGE_SIZE. This might need a new API returning a
* bio_vec or something more efficient.
*/
- pages = kcalloc(max_npages, sizeof(*pages), GFP_KERNEL);
- if (!pages)
return ERR_PTR(-ENOMEM);
any allocation may fail... can you elaborate more here? How does PAGE_SIZE become a boundary?
Memory fragmentation can be the reason. It's easy to get one page but not for contiguous pages.
Jason suggested to use kvcalloc, so I am adding this: @@ -249,11 +249,10 @@ iommufd_hw_queue_alloc_phys(struct iommu_hw_queue_alloc *cmd, max_npages = DIV_ROUND_UP(offset + cmd->length, PAGE_SIZE);
/* - * FIXME allocation may fail when sizeof(*pages) * max_npages is - * larger than PAGE_SIZE. This might need a new API returning a - * bio_vec or something more efficient. + * Use kvcalloc() to avoid memory fragmentation for a large page array. + * Set __GFP_NOWARN to avoid syzkaller blowups */ - pages = kcalloc(max_npages, sizeof(*pages), GFP_KERNEL); + pages = kvcalloc(max_npages, sizeof(*pages), GFP_KERNEL | __GFP_NOWARN); if (!pages) return ERR_PTR(-ENOMEM);
Thanks Nicolin