Re: [PATCH v2 8/8] IB/isert: use ib_client API to wrap ib_device

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

 



On Mon, Jun 04, 2018 at 02:30:03PM +0200, Roman Pen wrote:
> ib_client API provides a way to wrap an ib_device with a specific ULP
> structure.  Using that API local lists and mutexes can be completely
> avoided and allocation/removal paths become a bit cleaner.
> 
> Signed-off-by: Roman Pen <roman.penyaev@xxxxxxxxxxxxxxx>
> Cc: Christoph Hellwig <hch@xxxxxx>
> Cc: Steve Wise <swise@xxxxxxxxxxxxxxxxxxxxx>
> Cc: Bart Van Assche <bart.vanassche@xxxxxxxxxxx>
> Cc: Sagi Grimberg <sagi@xxxxxxxxxxx>
> Cc: Doug Ledford <dledford@xxxxxxxxxx>
> Cc: target-devel@xxxxxxxxxxxxxxx
>  drivers/infiniband/ulp/isert/ib_isert.c | 96 ++++++++++++++++++++++-----------
>  1 file changed, 65 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
> index 08dc9d27e5b1..c80f31573919 100644
> +++ b/drivers/infiniband/ulp/isert/ib_isert.c
> @@ -42,8 +42,7 @@ static int isert_debug_level;
>  module_param_named(debug_level, isert_debug_level, int, 0644);
>  MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0 (default:0)");
>  
> -static DEFINE_MUTEX(device_list_mutex);
> -static LIST_HEAD(device_list);
> +static struct ib_client isert_rdma_ib_client;
>  static struct workqueue_struct *isert_comp_wq;
>  static struct workqueue_struct *isert_release_wq;
>  
> @@ -341,7 +340,6 @@ isert_free_device_ib_res(struct isert_device *device)
>  static void
>  isert_device_put(struct isert_device *device)
>  {
> -	mutex_lock(&device_list_mutex);
>  	isert_info("device %p refcount %d\n", device,
>  		   refcount_read(&device->refcount));
>  	if (refcount_dec_and_test(&device->refcount)) {
> @@ -349,48 +347,44 @@ isert_device_put(struct isert_device *device)
>  		list_del(&device->dev_node);
>  		kfree(device);
>  	}
> -	mutex_unlock(&device_list_mutex);
>  }
>  
>  static struct isert_device *
>  isert_device_get(struct rdma_cm_id *cma_id)
>  {
>  	struct isert_device *device;
> -	int ret;
>  
> -	mutex_lock(&device_list_mutex);
> -	list_for_each_entry(device, &device_list, dev_node) {
> -		if (device->ib_device->node_guid == cma_id->device->node_guid) {
> -			refcount_inc(&device->refcount);
> -			isert_info("Found iser device %p refcount %d\n",
> -				   device, refcount_read(&device->refcount));
> -			mutex_unlock(&device_list_mutex);
> -			return device;
> -		}
> -	}
> +	/* Paired with isert_ib_client_remove_one() */
> +	rcu_read_lock();
> +	device = ib_get_client_data(cma_id->device, &isert_rdma_ib_client);
> +	if (device && WARN_ON(!refcount_inc_not_zero(&device->refcount)))
> +		device = NULL;
> +	rcu_read_unlock();

I think I'd prefer a managed kref API instead of tricky
RCU..

ib_get_client_data doesn't use rcu_derference, so this isn't
*technically* right

Something like:

 /* Returns NULL or a valid pointer holding a kref. The kref must be
    freed by the caller */
 struct kref_t *ib_get_client_kref(...);

 /* Atomically releases any kref already held and sets to a new
    value. If non-null a kref is obtained. */
 void ib_set_client_kref(struct kref_t *);

And a client_kref_put function pointer to struct ib_client to point to
the putter function.

The core code can safely manage all the required locking to guarentee
it returns a valid kref'd pointer, without needing to expose RCU.

Looks like many clients fit into this model already, so may as well
help them out.

Jason
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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