RE: [PATCH for-rc 1/2] RDMA/device: Expose ib_device_try_get(()

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

 




> From: Jason Gunthorpe <jgg@xxxxxxxxxxxx>
> 
> It turns out future patches need this capability quite widely now, not just for
> netlink, so provide two global functions to manage the registration lock
> refcount.
> 
> This also moves the point the lock becomes 1 to within ib_register_device()
> so that the semantics of the public API are very sane and clear. Calling
> ib_device_try_get() will fail on devices that are only allocated but not yet
> registered.
> 
> Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxxxx>
> ---
>  drivers/infiniband/core/core_priv.h |  1 -
>  drivers/infiniband/core/device.c    |  6 +++---
>  include/rdma/ib_verbs.h             | 24 ++++++++++++++++++++++--
>  3 files changed, 25 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/infiniband/core/core_priv.h
> b/drivers/infiniband/core/core_priv.h
> index 3cd830d52967eb..616734313f0c69 100644
> --- a/drivers/infiniband/core/core_priv.h
> +++ b/drivers/infiniband/core/core_priv.h
> @@ -267,7 +267,6 @@ static inline int ib_mad_enforce_security(struct
> ib_mad_agent_private *map,  #endif
> 
>  struct ib_device *ib_device_get_by_index(u32 ifindex); -void
> ib_device_put(struct ib_device *device);
>  /* RDMA device netlink */
>  void nldev_init(void);
>  void nldev_exit(void);
> diff --git a/drivers/infiniband/core/device.c
> b/drivers/infiniband/core/device.c
> index 8872453e26c07c..9b5c72d3c85a88 100644
> --- a/drivers/infiniband/core/device.c
> +++ b/drivers/infiniband/core/device.c
> @@ -156,8 +156,7 @@ struct ib_device *ib_device_get_by_index(u32 index)
>  	down_read(&lists_rwsem);
>  	device = __ib_device_get_by_index(index);
>  	if (device) {
> -		/* Do not return a device if unregistration has started. */
> -		if (!refcount_inc_not_zero(&device->refcount))
> +		if (!ib_device_try_get(device))
>  			device = NULL;
>  	}
>  	up_read(&lists_rwsem);
> @@ -169,6 +168,7 @@ void ib_device_put(struct ib_device *device)

Please add below hunk comment block for exported symbol.

+/**
+ * ib_device_put - Release IB device reference
+ * @device:	device whose reference to be released
+ *
+ * ib_device_put() releases reference to the IB device to allow
+ * it to be unregistered and eventually free.
+ */

>  	if (refcount_dec_and_test(&device->refcount))
>  		complete(&device->unreg_completion);
>  }
> +EXPORT_SYMBOL(ib_device_put);
> 
>  static struct ib_device *__ib_device_get_by_name(const char *name)  { @@
> -303,7 +303,6 @@ struct ib_device *ib_alloc_device(size_t size)
>  	rwlock_init(&device->client_data_lock);
>  	INIT_LIST_HEAD(&device->client_data_list);
>  	INIT_LIST_HEAD(&device->port_list);
> -	refcount_set(&device->refcount, 1);
>  	init_completion(&device->unreg_completion);
> 
>  	return device;
> @@ -620,6 +619,7 @@ int ib_register_device(struct ib_device *device, const
> char *name,
>  		goto cg_cleanup;
>  	}
> 
> +	refcount_set(&device->refcount, 1);
>  	device->reg_state = IB_DEV_REGISTERED;
> 
>  	list_for_each_entry(client, &client_list, list) diff --git
> a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index
> aa1f126d338350..85e9dab17b9b92 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -2577,9 +2577,10 @@ struct ib_device {
> 
>  	const struct uapi_definition   *driver_def;
>  	enum rdma_driver_id		driver_id;
> +
>  	/*
> -	 * Provides synchronization between device unregistration and
> netlink
> -	 * commands on a device. To be used only by core.
> +	 * If positive refcount indicates that the device is currently
Positive refcount indicates.

Please drop 'If'

> +	 * registered and cannot be unregistered.
>  	 */
>  	refcount_t refcount;
>  	struct completion unreg_completion;
> @@ -3924,6 +3925,25 @@ static inline bool ib_access_writable(int
> access_flags)  int ib_check_mr_status(struct ib_mr *mr, u32 check_mask,
>  		       struct ib_mr_status *mr_status);
> 
> +/**
> + * ib_device_try_get: Hold a registration lock
> + * device: The device to lock
> + *
> + * A device under an active registration lock cannot become
> +unregistered. It
> + * is only possible to obtain a registration lock on a device that is
> +fully
> + * registered, otherwise this function returns false.
> + *
> + * The registration lock is only necessary for actions which require
> +the
> + * device to still be registered. Uses that only require the device
> +pointer to
> + * be valid should use get_device(&ibdev->dev) to hold the memory.
> + *
> + */
> +static inline bool ib_device_try_get(struct ib_device *dev) {
> +	return refcount_inc_not_zero(&dev->refcount);
> +}
> +
> +void ib_device_put(struct ib_device *device);
>  struct net_device *ib_get_net_dev_by_params(struct ib_device *dev, u8
> port,
>  					    u16 pkey, const union ib_gid *gid,
>  					    const struct sockaddr *addr);
> --
> 2.20.1

Reviewed-by: Parav Pandit <parav@xxxxxxxxxxxx>





[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