| From 341660b31751fb6320147b46e9bf4d84f83dc594 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 27 Jul 2022 12:34:14 -0700 |
| Subject: RDMA/srpt: Introduce a reference count in struct srpt_device |
| |
| From: Bart Van Assche <bvanassche@acm.org> |
| |
| [ Upstream commit aa7dfbb41b5a60ab90e244d6f586b8cb5c791c3e ] |
| |
| This will be used to keep struct srpt_device around as long as either the |
| RDMA port exists or a LIO target port is associated with the struct |
| srpt_device. |
| |
| Link: https://lore.kernel.org/r/20220727193415.1583860-3-bvanassche@acm.org |
| Signed-off-by: Bart Van Assche <bvanassche@acm.org> |
| Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/infiniband/ulp/srpt/ib_srpt.c | 17 +++++++++++++++-- |
| drivers/infiniband/ulp/srpt/ib_srpt.h | 2 ++ |
| 2 files changed, 17 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c |
| index 8253d55b9c26..1fbce9225424 100644 |
| --- a/drivers/infiniband/ulp/srpt/ib_srpt.c |
| +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c |
| @@ -3104,6 +3104,18 @@ static int srpt_use_srq(struct srpt_device *sdev, bool use_srq) |
| return ret; |
| } |
| |
| +static void srpt_free_sdev(struct kref *refcnt) |
| +{ |
| + struct srpt_device *sdev = container_of(refcnt, typeof(*sdev), refcnt); |
| + |
| + kfree(sdev); |
| +} |
| + |
| +static void srpt_sdev_put(struct srpt_device *sdev) |
| +{ |
| + kref_put(&sdev->refcnt, srpt_free_sdev); |
| +} |
| + |
| /** |
| * srpt_add_one - InfiniBand device addition callback function |
| * @device: Describes a HCA. |
| @@ -3122,6 +3134,7 @@ static int srpt_add_one(struct ib_device *device) |
| if (!sdev) |
| return -ENOMEM; |
| |
| + kref_init(&sdev->refcnt); |
| sdev->device = device; |
| mutex_init(&sdev->sdev_mutex); |
| |
| @@ -3217,7 +3230,7 @@ static int srpt_add_one(struct ib_device *device) |
| srpt_free_srq(sdev); |
| ib_dealloc_pd(sdev->pd); |
| free_dev: |
| - kfree(sdev); |
| + srpt_sdev_put(sdev); |
| pr_info("%s(%s) failed.\n", __func__, dev_name(&device->dev)); |
| return ret; |
| } |
| @@ -3261,7 +3274,7 @@ static void srpt_remove_one(struct ib_device *device, void *client_data) |
| |
| ib_dealloc_pd(sdev->pd); |
| |
| - kfree(sdev); |
| + srpt_sdev_put(sdev); |
| } |
| |
| static struct ib_client srpt_client = { |
| diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h |
| index 3844a7058559..0cb867d580f1 100644 |
| --- a/drivers/infiniband/ulp/srpt/ib_srpt.h |
| +++ b/drivers/infiniband/ulp/srpt/ib_srpt.h |
| @@ -434,6 +434,7 @@ struct srpt_port { |
| |
| /** |
| * struct srpt_device - information associated by SRPT with a single HCA |
| + * @refcnt: Reference count for this device. |
| * @device: Backpointer to the struct ib_device managed by the IB core. |
| * @pd: IB protection domain. |
| * @lkey: L_Key (local key) with write access to all local memory. |
| @@ -449,6 +450,7 @@ struct srpt_port { |
| * @port: Information about the ports owned by this HCA. |
| */ |
| struct srpt_device { |
| + struct kref refcnt; |
| struct ib_device *device; |
| struct ib_pd *pd; |
| u32 lkey; |
| -- |
| 2.35.1 |
| |