lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri, 27 Mar 2020 09:55:43 +0000
From:   "Tian, Kevin" <kevin.tian@...el.com>
To:     Jacob Pan <jacob.jun.pan@...ux.intel.com>,
        Joerg Roedel <joro@...tes.org>,
        Alex Williamson <alex.williamson@...hat.com>,
        Lu Baolu <baolu.lu@...ux.intel.com>,
        "iommu@...ts.linux-foundation.org" <iommu@...ts.linux-foundation.org>,
        LKML <linux-kernel@...r.kernel.org>,
        David Woodhouse <dwmw2@...radead.org>,
        Jean-Philippe Brucker <jean-philippe@...aro.com>
CC:     "Liu, Yi L" <yi.l.liu@...el.com>,
        "Raj, Ashok" <ashok.raj@...el.com>,
        Christoph Hellwig <hch@...radead.org>,
        Jonathan Cameron <jic23@...nel.org>,
        Eric Auger <eric.auger@...hat.com>
Subject: RE: [PATCH 07/10] iommu/ioasid: Use mutex instead of spinlock

> From: Jacob Pan <jacob.jun.pan@...ux.intel.com>
> Sent: Thursday, March 26, 2020 1:55 AM
> 
> Each IOASID or set could have multiple users with its own HW context
> to maintain. Often times access to the HW context requires thread context.
> For example, consumers of IOASIDs can register notification blocks to
> sync up its states. Having an atomic notifier is not feasible for these
> update operations.
> 
> This patch converts allocator lock from spinlock to mutex in preparation
> for IOASID notifier.
> 
> Signed-off-by: Jacob Pan <jacob.jun.pan@...ux.intel.com>
> ---
>  drivers/iommu/ioasid.c | 45 +++++++++++++++++++++++----------------------
>  1 file changed, 23 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/iommu/ioasid.c b/drivers/iommu/ioasid.c
> index f89a595f6978..8612fe6477dc 100644
> --- a/drivers/iommu/ioasid.c
> +++ b/drivers/iommu/ioasid.c
> @@ -98,7 +98,7 @@ struct ioasid_allocator_data {
>  	struct rcu_head rcu;
>  };
> 
> -static DEFINE_SPINLOCK(ioasid_allocator_lock);
> +static DEFINE_MUTEX(ioasid_allocator_lock);
>  static LIST_HEAD(allocators_list);
> 
>  static ioasid_t default_alloc(ioasid_t min, ioasid_t max, void *opaque);
> @@ -121,7 +121,7 @@ static ioasid_t default_alloc(ioasid_t min, ioasid_t
> max, void *opaque)
>  {
>  	ioasid_t id;
> 
> -	if (xa_alloc(&default_allocator.xa, &id, opaque, XA_LIMIT(min, max),
> GFP_ATOMIC)) {
> +	if (xa_alloc(&default_allocator.xa, &id, opaque, XA_LIMIT(min, max),
> GFP_KERNEL)) {
>  		pr_err("Failed to alloc ioasid from %d to %d\n", min, max);
>  		return INVALID_IOASID;
>  	}
> @@ -142,7 +142,7 @@ static struct ioasid_allocator_data
> *ioasid_alloc_allocator(struct ioasid_alloca
>  {
>  	struct ioasid_allocator_data *ia_data;
> 
> -	ia_data = kzalloc(sizeof(*ia_data), GFP_ATOMIC);
> +	ia_data = kzalloc(sizeof(*ia_data), GFP_KERNEL);
>  	if (!ia_data)
>  		return NULL;
> 
> @@ -184,7 +184,7 @@ int ioasid_register_allocator(struct
> ioasid_allocator_ops *ops)
>  	struct ioasid_allocator_data *pallocator;
>  	int ret = 0;
> 
> -	spin_lock(&ioasid_allocator_lock);
> +	mutex_lock(&ioasid_allocator_lock);
> 
>  	ia_data = ioasid_alloc_allocator(ops);
>  	if (!ia_data) {
> @@ -228,12 +228,12 @@ int ioasid_register_allocator(struct
> ioasid_allocator_ops *ops)
>  	}
>  	list_add_tail(&ia_data->list, &allocators_list);
> 
> -	spin_unlock(&ioasid_allocator_lock);
> +	mutex_unlock(&ioasid_allocator_lock);
>  	return 0;
>  out_free:
>  	kfree(ia_data);
>  out_unlock:
> -	spin_unlock(&ioasid_allocator_lock);
> +	mutex_unlock(&ioasid_allocator_lock);
>  	return ret;
>  }
>  EXPORT_SYMBOL_GPL(ioasid_register_allocator);
> @@ -251,7 +251,7 @@ void ioasid_unregister_allocator(struct
> ioasid_allocator_ops *ops)
>  	struct ioasid_allocator_data *pallocator;
>  	struct ioasid_allocator_ops *sops;
> 
> -	spin_lock(&ioasid_allocator_lock);
> +	mutex_lock(&ioasid_allocator_lock);
>  	if (list_empty(&allocators_list)) {
>  		pr_warn("No custom IOASID allocators active!\n");
>  		goto exit_unlock;
> @@ -296,7 +296,7 @@ void ioasid_unregister_allocator(struct
> ioasid_allocator_ops *ops)
>  	}
> 
>  exit_unlock:
> -	spin_unlock(&ioasid_allocator_lock);
> +	mutex_unlock(&ioasid_allocator_lock);
>  }
>  EXPORT_SYMBOL_GPL(ioasid_unregister_allocator);
> 
> @@ -313,13 +313,13 @@ int ioasid_attach_data(ioasid_t ioasid, void *data)
>  	struct ioasid_data *ioasid_data;
>  	int ret = 0;
> 
> -	spin_lock(&ioasid_allocator_lock);
> +	mutex_lock(&ioasid_allocator_lock);
>  	ioasid_data = xa_load(&active_allocator->xa, ioasid);
>  	if (ioasid_data)
>  		rcu_assign_pointer(ioasid_data->private, data);
>  	else
>  		ret = -ENOENT;
> -	spin_unlock(&ioasid_allocator_lock);
> +	mutex_unlock(&ioasid_allocator_lock);
> 
>  	/*
>  	 * Wait for readers to stop accessing the old private data, so the
> @@ -374,7 +374,7 @@ ioasid_t ioasid_alloc(int sid, ioasid_t min, ioasid_t
> max, void *private)
>  	 * Custom allocator needs allocator data to perform platform specific
>  	 * operations.
>  	 */
> -	spin_lock(&ioasid_allocator_lock);
> +	mutex_lock(&ioasid_allocator_lock);
>  	adata = active_allocator->flags & IOASID_ALLOCATOR_CUSTOM ?
> active_allocator->ops->pdata : data;
>  	id = active_allocator->ops->alloc(min, max, adata);
>  	if (id == INVALID_IOASID) {
> @@ -383,7 +383,7 @@ ioasid_t ioasid_alloc(int sid, ioasid_t min, ioasid_t
> max, void *private)
>  	}
> 
>  	if ((active_allocator->flags & IOASID_ALLOCATOR_CUSTOM) &&
> -	     xa_alloc(&active_allocator->xa, &id, data, XA_LIMIT(id, id),
> GFP_ATOMIC)) {
> +	     xa_alloc(&active_allocator->xa, &id, data, XA_LIMIT(id, id),
> GFP_KERNEL)) {
>  		/* Custom allocator needs framework to store and track
> allocation results */
>  		pr_err("Failed to alloc ioasid from %d\n", id);
>  		active_allocator->ops->free(id, active_allocator->ops->pdata);
> @@ -394,10 +394,11 @@ ioasid_t ioasid_alloc(int sid, ioasid_t min, ioasid_t
> max, void *private)
>  	/* Store IOASID in the per set data */
>  	xa_store(&sdata->xa, id, data, GFP_KERNEL);
>  	sdata->nr_ioasids++;
> -	spin_unlock(&ioasid_allocator_lock);
> +	mutex_unlock(&ioasid_allocator_lock);
> +
>  	return id;
>  exit_free:
> -	spin_unlock(&ioasid_allocator_lock);
> +	mutex_unlock(&ioasid_allocator_lock);
>  	kfree(data);
>  	return INVALID_IOASID;
>  }
> @@ -440,9 +441,9 @@ static void ioasid_free_locked(ioasid_t ioasid)
>   */
>  void ioasid_free(ioasid_t ioasid)
>  {
> -	spin_lock(&ioasid_allocator_lock);
> +	mutex_lock(&ioasid_allocator_lock);
>  	ioasid_free_locked(ioasid);
> -	spin_unlock(&ioasid_allocator_lock);
> +	mutex_unlock(&ioasid_allocator_lock);
>  }
>  EXPORT_SYMBOL_GPL(ioasid_free);
> 
> @@ -473,7 +474,7 @@ int ioasid_alloc_set(struct ioasid_set *token, ioasid_t
> quota, int *sid)
>  	if (!sdata)
>  		return -ENOMEM;
> 
> -	spin_lock(&ioasid_allocator_lock);
> +	mutex_lock(&ioasid_allocator_lock);
> 
>  	ret = xa_alloc(&ioasid_sets, &id, sdata,
>  		       XA_LIMIT(0, ioasid_capacity_avail - quota),
> @@ -497,7 +498,7 @@ int ioasid_alloc_set(struct ioasid_set *token, ioasid_t
> quota, int *sid)
>  	*sid = id;
> 
>  error:
> -	spin_unlock(&ioasid_allocator_lock);
> +	mutex_unlock(&ioasid_allocator_lock);
> 
>  	return ret;
>  }
> @@ -518,7 +519,7 @@ void ioasid_free_set(int sid, bool destroy_set)
>  	struct ioasid_data *entry;
>  	unsigned long index;
> 
> -	spin_lock(&ioasid_allocator_lock);
> +	mutex_lock(&ioasid_allocator_lock);
>  	sdata = xa_load(&ioasid_sets, sid);
>  	if (!sdata) {
>  		pr_err("No IOASID set found to free %d\n", sid);
> @@ -549,7 +550,7 @@ void ioasid_free_set(int sid, bool destroy_set)
>  	}
> 
>  done_unlock:
> -	spin_unlock(&ioasid_allocator_lock);
> +	mutex_unlock(&ioasid_allocator_lock);
>  }
>  EXPORT_SYMBOL_GPL(ioasid_free_set);
> 
> @@ -613,11 +614,11 @@ int ioasid_find_sid(ioasid_t ioasid)
>  	struct ioasid_data *ioasid_data;
>  	int ret = 0;
> 
> -	spin_lock(&ioasid_allocator_lock);
> +	mutex_lock(&ioasid_allocator_lock);
>  	ioasid_data = xa_load(&active_allocator->xa, ioasid);
>  	ret = (ioasid_data) ? ioasid_data->sdata->sid : -ENOENT;
> 
> -	spin_unlock(&ioasid_allocator_lock);
> +	mutex_unlock(&ioasid_allocator_lock);
> 
>  	return ret;
>  }
> --
> 2.7.4

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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ