On Thu, Sep 09, 2021 at 05:35:40AM +0000, John Johnson wrote: > > > > On Sep 7, 2021, at 7:31 AM, Stefan Hajnoczi wrote: > > > > On Mon, Aug 16, 2021 at 09:42:41AM -0700, Elena Ufimtseva wrote: > >> @@ -1514,6 +1515,16 @@ bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info, > >> return true; > >> } > >> > >> +static int vfio_get_region_info_remfd(VFIODevice *vbasedev, int index) > >> +{ > >> + struct vfio_region_info *info; > >> + > >> + if (vbasedev->regions == NULL || vbasedev->regions[index] == NULL) { > >> + vfio_get_region_info(vbasedev, index, &info); > >> + } > > > > Maybe this will be called from other places in the future, but the > > vfio_region_setup() caller below already invoked vfio_get_region_info() > > so I'm not sure it's necessary to do this again? > > > > Perhaps add an int *remfd argument to vfio_get_region_info(). That way > > vfio_get_region_info_remfd() isn't necessary. > > > > I think they could be combined, but the region capabilities are > retrieved with separate calls to vfio_get_region_info_cap(), so I followed > that precedent. > > > >> @@ -2410,6 +2442,24 @@ int vfio_get_region_info(VFIODevice *vbasedev, int index, > >> struct vfio_region_info **info) > >> { > >> size_t argsz = sizeof(struct vfio_region_info); > >> + int fd = -1; > >> + int ret; > >> + > >> + /* create region cache */ > >> + if (vbasedev->regions == NULL) { > >> + vbasedev->regions = g_new0(struct vfio_region_info *, > >> + vbasedev->num_regions); > >> + if (vbasedev->proxy != NULL) { > >> + vbasedev->regfds = g_new0(int, vbasedev->num_regions); > >> + } > >> + } > >> + /* check cache */ > >> + if (vbasedev->regions[index] != NULL) { > >> + *info = g_malloc0(vbasedev->regions[index]->argsz); > >> + memcpy(*info, vbasedev->regions[index], > >> + vbasedev->regions[index]->argsz); > >> + return 0; > >> + } > > > > Why is it necessary to introduce a cache? Is it to avoid passing the > > same fd multiple times? > > > > Yes. For polled regions, the server returns an FD with each > message, so there would be an FD leak if I didn’t check that the region > hadn’t already returned one. Since I had to cache the FD anyway, I > cached the whole struct. If vfio_get_region_info() takes an int *fd argument then fd ownership becomes explicit and the need for the cache falls away. Maybe Alex has a preference for how to structure the code to track per-region fds. Stefan