Skip to content

Commit d79af72

Browse files
committed
RDMA/device: Expose ib_device_try_get(()
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@mellanox.com> Reviewed-by: Steve Wise <swise@opengridcomputing.com> Reviewed-by: Parav Pandit <parav@mellanox.com>
1 parent 09ce351 commit d79af72

File tree

3 files changed

+32
-6
lines changed

3 files changed

+32
-6
lines changed

drivers/infiniband/core/core_priv.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,6 @@ static inline int ib_mad_enforce_security(struct ib_mad_agent_private *map,
267267
#endif
268268

269269
struct ib_device *ib_device_get_by_index(u32 ifindex);
270-
void ib_device_put(struct ib_device *device);
271270
/* RDMA device netlink */
272271
void nldev_init(void);
273272
void nldev_exit(void);

drivers/infiniband/core/device.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,19 +156,26 @@ struct ib_device *ib_device_get_by_index(u32 index)
156156
down_read(&lists_rwsem);
157157
device = __ib_device_get_by_index(index);
158158
if (device) {
159-
/* Do not return a device if unregistration has started. */
160-
if (!refcount_inc_not_zero(&device->refcount))
159+
if (!ib_device_try_get(device))
161160
device = NULL;
162161
}
163162
up_read(&lists_rwsem);
164163
return device;
165164
}
166165

166+
/**
167+
* ib_device_put - Release IB device reference
168+
* @device: device whose reference to be released
169+
*
170+
* ib_device_put() releases reference to the IB device to allow it to be
171+
* unregistered and eventually free.
172+
*/
167173
void ib_device_put(struct ib_device *device)
168174
{
169175
if (refcount_dec_and_test(&device->refcount))
170176
complete(&device->unreg_completion);
171177
}
178+
EXPORT_SYMBOL(ib_device_put);
172179

173180
static struct ib_device *__ib_device_get_by_name(const char *name)
174181
{
@@ -303,7 +310,6 @@ struct ib_device *ib_alloc_device(size_t size)
303310
rwlock_init(&device->client_data_lock);
304311
INIT_LIST_HEAD(&device->client_data_list);
305312
INIT_LIST_HEAD(&device->port_list);
306-
refcount_set(&device->refcount, 1);
307313
init_completion(&device->unreg_completion);
308314

309315
return device;
@@ -620,6 +626,7 @@ int ib_register_device(struct ib_device *device, const char *name,
620626
goto cg_cleanup;
621627
}
622628

629+
refcount_set(&device->refcount, 1);
623630
device->reg_state = IB_DEV_REGISTERED;
624631

625632
list_for_each_entry(client, &client_list, list)

include/rdma/ib_verbs.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2579,9 +2579,10 @@ struct ib_device {
25792579

25802580
const struct uapi_definition *driver_def;
25812581
enum rdma_driver_id driver_id;
2582+
25822583
/*
2583-
* Provides synchronization between device unregistration and netlink
2584-
* commands on a device. To be used only by core.
2584+
* Positive refcount indicates that the device is currently
2585+
* registered and cannot be unregistered.
25852586
*/
25862587
refcount_t refcount;
25872588
struct completion unreg_completion;
@@ -3926,6 +3927,25 @@ static inline bool ib_access_writable(int access_flags)
39263927
int ib_check_mr_status(struct ib_mr *mr, u32 check_mask,
39273928
struct ib_mr_status *mr_status);
39283929

3930+
/**
3931+
* ib_device_try_get: Hold a registration lock
3932+
* device: The device to lock
3933+
*
3934+
* A device under an active registration lock cannot become unregistered. It
3935+
* is only possible to obtain a registration lock on a device that is fully
3936+
* registered, otherwise this function returns false.
3937+
*
3938+
* The registration lock is only necessary for actions which require the
3939+
* device to still be registered. Uses that only require the device pointer to
3940+
* be valid should use get_device(&ibdev->dev) to hold the memory.
3941+
*
3942+
*/
3943+
static inline bool ib_device_try_get(struct ib_device *dev)
3944+
{
3945+
return refcount_inc_not_zero(&dev->refcount);
3946+
}
3947+
3948+
void ib_device_put(struct ib_device *device);
39293949
struct net_device *ib_get_net_dev_by_params(struct ib_device *dev, u8 port,
39303950
u16 pkey, const union ib_gid *gid,
39313951
const struct sockaddr *addr);

0 commit comments

Comments
 (0)