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