On Fri, Apr 21, 2023 at 06:06:40PM -0700, Brett Creeley wrote: > +int > +pds_vfio_dirty_status_cmd(struct pds_vfio_pci_device *pds_vfio, > + u64 regions_dma, u8 *max_regions, > + u8 *num_regions) > +{ > + union pds_core_adminq_cmd cmd = { > + .lm_dirty_status.opcode = PDS_LM_CMD_DIRTY_STATUS, > + .lm_dirty_status.vf_id = cpu_to_le16(pds_vfio->vf_id), > + }; You can write these as .lm_dirty_status = { .opcode = .., .vf_if = .., }, And save some stuttering > +static int > +pds_vfio_dirty_alloc_bitmaps(struct pds_vfio_dirty *dirty, > + u32 nbits) > +{ > + unsigned long *host_seq_bmp, *host_ack_bmp; > + > + host_seq_bmp = bitmap_zalloc(nbits, GFP_KERNEL); > + if (!host_seq_bmp) > + return -ENOMEM; > + > + host_ack_bmp = bitmap_zalloc(nbits, GFP_KERNEL); > + if (!host_ack_bmp) { > + bitmap_free(host_seq_bmp); > + return -ENOMEM; > + } nbits looks way too big to call bitmap_zalloc? > +static int > +__pds_vfio_dirty_alloc_sgl(struct pds_vfio_pci_device *pds_vfio, > + struct pds_vfio_bmp_info *bmp_info, > + u32 page_count) > +{ > + struct pci_dev *pdev = pds_vfio->vfio_coredev.pdev; > + struct device *pdsc_dev = &pci_physfn(pdev)->dev; > + struct pds_lm_sg_elem *sgl; > + dma_addr_t sgl_addr; > + size_t sgl_size; > + u32 max_sge; > + > + max_sge = DIV_ROUND_UP(page_count, PAGE_SIZE * 8); > + sgl_size = max_sge * sizeof(struct pds_lm_sg_elem); > + > + sgl = kzalloc(sgl_size, GFP_KERNEL); > + if (!sgl) > + return -ENOMEM; > + > + sgl_addr = dma_map_single(pdsc_dev, sgl, sgl_size, DMA_TO_DEVICE); This needs to use the streaming API in pds_vfio_dirty_seq_ack() Jason