On Wed, Mar 08, 2023 at 05:13:36AM -0800, Yi Liu wrote: > +int iommufd_access_set_ioas(struct iommufd_access *access, u32 ioas_id) > +{ > + struct iommufd_ioas *new_ioas = NULL, *cur_ioas; > + struct iommufd_ctx *ictx = access->ictx; > + struct iommufd_object *obj; > + int rc = 0; > + > + if (ioas_id) { > + obj = iommufd_get_object(ictx, ioas_id, IOMMUFD_OBJ_IOAS); > + if (IS_ERR(obj)) > + return PTR_ERR(obj); > + new_ioas = container_of(obj, struct iommufd_ioas, obj); > + } > + > + mutex_lock(&access->ioas_lock); > + cur_ioas = access->ioas; > + if (cur_ioas == new_ioas) > + goto out_unlock; > + > + if (new_ioas) { > + rc = iopt_add_access(&new_ioas->iopt, access); > + if (rc) > + goto out_unlock; > + iommufd_ref_to_users(obj); > + } > + > + if (cur_ioas) { > + iopt_remove_access(&cur_ioas->iopt, access); > + refcount_dec(&cur_ioas->obj.users); > + } This should match the physical side with an add/remove/replace API. Especially since remove is implicit in destroy this series only needs the add API And the locking shouldn't come in another patch that brings the replace/remove since with just split add we don't need it. That will make this patch alot smaller Jason