On Fri, May 30, 2025 at 01:14:55PM -0300, Jason Gunthorpe wrote:
Put a size_t in the driver ops:
size_t size_viommu; size_t size_hw_queue;
Have the driver set it via a macro like INIT_RDMA_OBJ_SIZE
#define INIT_RDMA_OBJ_SIZE(ib_struct, drv_struct, member) \ .size_##ib_struct = \ (sizeof(struct drv_struct) + \ BUILD_BUG_ON_ZERO(offsetof(struct drv_struct, member)) + \ BUILD_BUG_ON_ZERO( \ !__same_type(((struct drv_struct *)NULL)->member, \ struct ib_struct)))
Which proves the core structure is at the front.
Then the core code can allocate the object along with enough space for the driver and call a driver function to init the driver portion of the already allocated object.
I found that the size_viommu or size_hw_queue might not work using a static macro as that RDMA one does:
- The size in vIOMMU case is type dependent. E.g. smmuv3 driver uses one iommu_ops to support two types: vSMMU and vCMDQ
- Changing to a type-indexed size array would eventually result some driver having a big size array, as the type number grows
I came up with two alternatives:
1) Define a get_viommu_size(unsigned int type) op: use a similar macro in the driver function to return with:
#define VIOMMU_STRUCT_SIZE(ib_struct, drv_struct, member) \ (sizeof(drv_struct) + \ BUILD_BUG_ON_ZERO(offsetof(drv_struct, member)) + \ BUILD_BUG_ON_ZERO(!__same_type(((drv_struct *)NULL)->member, \ ib_struct)))
if (type == SMMU) return VIOMMU_STRUCT_SIZE( struct arm_vsmmu, struct iommufd_viommu, core); return 0;
2) Let core allocate with sizeof(struct iommufd_viommu), then let driver krealloc during the viommu_init op call:
viommu = kzalloc(sizeof(struct iommufd_viommu), ...); ... viommu = ops->viommu_init(viommu, dev, parent_dom, type);
I am guessing that you may prefer 1 over 2? Or any better idea?
Thanks Nicolin