Re: [PATCH rdma-next v2 15/17] RDMA/restrack: Implement software ID interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jan 22, 2019 at 08:15:48PM +0200, Leon Romanovsky wrote:

> +	/*
> +	 * Once all drivers are converted, we can remove this check
> +	 * and remove call to rdma_restrack_add() from rdma_restrack_kadd()
> +	 * and rdma_restrack_uadd()
> +	 */
> +	if (xa_load(xa, res->id))
> +		return 0;

So we check if the ID is present..  Because the driver did something?
But no drivers do in this series, I guess? Don't get it.

>  	kref_init(&res->kref);
>  	init_completion(&res->comp);
>  	res->valid = true;
>  
> -	ret = xa_insert(xa, res_to_id(res), res, GFP_KERNEL);
> -	WARN_ONCE(ret == -EEXIST, "Tried to add non-unique type %d entry\n",
> -		  res->type);
> +	if (rt[res->type].range.max) {
> +		/* Not HW-capable device */
> +		ret = rt_xa_alloc_cyclic(xa, &res->id, res,
> +					 &rt[res->type].range,
> +					 &rt[res->type].next_id, GFP_KERNEL);
> +	} else {
> +		ret = xa_insert(xa, res->id, res, GFP_KERNEL);

Then do insert

> +	}
> +
> +	/*
> +	 * WARNs below indicates an error in driver code.
> +	 * The check of -EEXIST is never occuried and added here
> +	 * to allow simple removal of xa_load above.
> +	 */
> +	WARN_ONCE(ret == -EEXIST, "Tried to add non-unique %s entry %u\n",
> +		  type2str(res->type), res->id);

Then complain (which can't happen because we checked?)

> +	WARN_ONCE(ret == -ENOSPC,
> +		  "There are no more free indexes for type %s entry %u\n",
> +		  type2str(res->type), res->id);
> +

and this one can only happen for alloc_cyclic

really confusing

>  	if (ret)
>  		res->valid = false;
> +
> +	return ret;
>  }
> +EXPORT_SYMBOL(rdma_restrack_add);
>  
>  /**
>   * rdma_restrack_kadd() - add kernel object to the reource tracking database
> @@ -300,10 +356,20 @@ static void rdma_restrack_add(struct rdma_restrack_entry *res)
>   */
>  void rdma_restrack_kadd(struct rdma_restrack_entry *res)
>  {
> +	struct ib_device *dev = res_to_dev(res);
> +	struct xarray *xa = rdma_dev_to_xa(dev, res->type);
> +
>  	res->task = NULL;
>  	set_kern_name(res);
>  	res->user = false;
> -	rdma_restrack_add(res);
> +	/*
> +	 * Temporaly, we are not intested in return value,
> +	 * once conversion will be finished, it will be checked by drivers.
> +	 */
> +	if (rdma_restrack_add(res))
> +		return;
> +
> +	xa_set_mark(xa, res->id, RES_VISIBLE);

And I have no idea what RES_VISIBLE is supposed to do. It is set in
two places, both places are the only callers of rdma_restrack_add
.. so every entry in the xarray has RES_VISIBLE set, except for a very
small time window after rdma_restrack_add returning? Why?

Also looks like rdma_restrack_add() should be made static since there
are no more callers..

> @@ -347,7 +423,8 @@ rdma_restrack_get_byid(struct ib_device *dev,
>  	struct rdma_restrack_entry *res;
>  
>  	res = xa_load(xa, id);
> -	if (!res || xa_is_err(res) || !rdma_restrack_get(res))

xa_load doesn't return an xa_err as far as I can see..

> @@ -393,8 +469,7 @@ void rdma_restrack_del(struct rdma_restrack_entry *res)
>  		return;
>  
>  	xa = rdma_dev_to_xa(dev, res->type);
> -	id = res_to_id(res);
> -	if (!xa_load(xa, id))
> +	if (!xa_load(xa, res->id))
>  		goto out;

Seems strange, isn't this sort of test what valid is supposed to be
used for? Why do we have valid, !NULL in the xarray and RES_VISIBLE
all at once?

>  	rdma_restrack_put(res);
> @@ -402,7 +477,7 @@ void rdma_restrack_del(struct rdma_restrack_entry *res)
>  	wait_for_completion(&res->comp);
>  
>  	down_write(&dev->res[res->type].rwsem);
> -	xa_erase(xa, id);
> +	xa_erase(xa, res->id);
>  	res->valid = false;
>  	up_write(&dev->res[res->type].rwsem);
>  
> @@ -430,5 +505,6 @@ void rdma_rt_set_id_range(struct ib_device *dev, enum rdma_restrack_type type,
>  
>  	rt[type].range.max = max;
>  	rt[type].range.min = reserved;
> +	rt[type].next_id = reserved;
>  }
>  EXPORT_SYMBOL(rdma_rt_set_id_range);
> diff --git a/include/rdma/restrack.h b/include/rdma/restrack.h
> index 0706f51bb1f8..9d329098ddfc 100644
> +++ b/include/rdma/restrack.h
> @@ -93,6 +93,11 @@ struct rdma_restrack_entry {
>  	 * @user: user resource
>  	 */
>  	bool			user;
> +	/*
> +	 * @id: unique to specific type identifier, for HW-capable devices,
> +	 * drivers are supposed to update it, because it is used as an index.
> +	 */
> +	u32 id;
>  };
>  
>  int rdma_restrack_init(struct ib_device *dev);
> @@ -104,6 +109,14 @@ int rdma_restrack_count(struct ib_device *dev,
>  void rdma_restrack_kadd(struct rdma_restrack_entry *res);
>  void rdma_restrack_uadd(struct rdma_restrack_entry *res);
>  
> +/**
> + * Addition of entry is performed in two steps approach:
> + * 1. Driver creates ID and allocates resource entry.
> + * 2. IB/core marks such entry as user/kernel and exports to nldev.c
> + */

This sounds like it is re-coding xa_reserve? Why can't the driver use
xa_reserve to hold its ID and we can just make the xarray value
non-NULL when it the entry is ready to go? Seems simpler if the driver
needs to rely on the retrack allocator for IDs..

Jason



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux