On Wed, Jun 25, 2025 at 03:45:08AM +0000, Tian, Kevin wrote: > > From: Nicolin Chen <nicol...@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