RE: [PATCH v10 3/6] iommufd: Add iommufd_access_change_ioas(_id) helpers

From: Tian, Kevin
Date: Fri Jul 28 2023 - 00:23:14 EST


> From: Nicolin Chen <nicolinc@xxxxxxxxxx>
> Sent: Friday, July 28, 2023 4:25 AM
>
> +static int iommufd_access_change_ioas(struct iommufd_access *access,
> + struct iommufd_ioas *new_ioas)
> +{
> + u32 iopt_access_list_id = access->iopt_access_list_id;
> + struct iommufd_ioas *cur_ioas = access->ioas;
> + int rc;
> +
> + lockdep_assert_held(&access->ioas_lock);
> +
> + /* We are racing with a concurrent detach, bail */
> + if (cur_ioas != access->ioas_unpin)
> + return -EBUSY;
> +
> + if (IS_ERR(new_ioas))
> + return PTR_ERR(new_ioas);

iommufd_access_change_ioas_id() already checks errors.

> +
> void iommufd_access_destroy_object(struct iommufd_object *obj)
> {
> struct iommufd_access *access =
> container_of(obj, struct iommufd_access, obj);
>
> - if (access->ioas) {
> - iopt_remove_access(&access->ioas->iopt, access,
> - access->iopt_access_list_id);
> - refcount_dec(&access->ioas->obj.users);
> - access->ioas = NULL;
> - }
> + mutex_lock(&access->ioas_lock);
> + if (access->ioas)
> + WARN_ON(iommufd_access_change_ioas(access, NULL));
> + mutex_unlock(&access->ioas_lock);
> iommufd_ctx_put(access->ictx);
> }

this changes the behavior of destroy. Previously it always removes
the access w/o detecting race while now it will give up and throw
out a warning. While I'm fine with this change from bisec p.o.v.
it might be good to split this into a separate patch.

> void iommufd_access_detach(struct iommufd_access *access)
> {
> - struct iommufd_ioas *cur_ioas = access->ioas;
> + int rc;
>
> mutex_lock(&access->ioas_lock);
> - if (WARN_ON(!access->ioas))
> - goto out;
> - /*
> - * Set ioas to NULL to block any further iommufd_access_pin_pages().
> - * iommufd_access_unpin_pages() can continue using access-
> >ioas_unpin.
> - */
> - access->ioas = NULL;
> -
> - if (access->ops->unmap) {
> + if (WARN_ON(!access->ioas)) {
> mutex_unlock(&access->ioas_lock);
> - access->ops->unmap(access->data, 0, ULONG_MAX);
> - mutex_lock(&access->ioas_lock);
> + return;
> }
> - iopt_remove_access(&cur_ioas->iopt, access,
> - access->iopt_access_list_id);
> - refcount_dec(&cur_ioas->obj.users);
> -out:
> - access->ioas_unpin = NULL;
> + rc = iommufd_access_change_ioas(access, NULL);
> + WARN_ON(rc);

'rc' can be removed.

Just "WARN_ON(iommufd_access_change_ioas(access, NULL));"

otherwise looks good to me,

Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx>