Skip to content

Commit 372a178

Browse files
maorgottliebjgunthorpe
authored andcommitted
IB/srpt: Fix memory leak in srpt_add_one
Failure in srpt_refresh_port() for the second port will leave MAD registered for the first one, however, the srpt_add_one() will be marked as "failed" and SRPT will leak resources for that registered but not used and released first port. Unregister the MAD agent for all ports in case of failure. Fixes: a42d985 ("ib_srpt: Initial SRP Target merge for v3.3-rc1") Link: https://lore.kernel.org/r/20201028065051.112430-1-leon@kernel.org Signed-off-by: Maor Gottlieb <maorg@nvidia.com> Signed-off-by: Leon Romanovsky <leonro@nvidia.com> Reviewed-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
1 parent 683a9c7 commit 372a178

1 file changed

Lines changed: 8 additions & 5 deletions

File tree

drivers/infiniband/ulp/srpt/ib_srpt.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -622,18 +622,19 @@ static int srpt_refresh_port(struct srpt_port *sport)
622622
/**
623623
* srpt_unregister_mad_agent - unregister MAD callback functions
624624
* @sdev: SRPT HCA pointer.
625+
* #port_cnt: number of ports with registered MAD
625626
*
626627
* Note: It is safe to call this function more than once for the same device.
627628
*/
628-
static void srpt_unregister_mad_agent(struct srpt_device *sdev)
629+
static void srpt_unregister_mad_agent(struct srpt_device *sdev, int port_cnt)
629630
{
630631
struct ib_port_modify port_modify = {
631632
.clr_port_cap_mask = IB_PORT_DEVICE_MGMT_SUP,
632633
};
633634
struct srpt_port *sport;
634635
int i;
635636

636-
for (i = 1; i <= sdev->device->phys_port_cnt; i++) {
637+
for (i = 1; i <= port_cnt; i++) {
637638
sport = &sdev->port[i - 1];
638639
WARN_ON(sport->port != i);
639640
if (sport->mad_agent) {
@@ -3185,7 +3186,8 @@ static int srpt_add_one(struct ib_device *device)
31853186
if (ret) {
31863187
pr_err("MAD registration failed for %s-%d.\n",
31873188
dev_name(&sdev->device->dev), i);
3188-
goto err_event;
3189+
i--;
3190+
goto err_port;
31893191
}
31903192
}
31913193

@@ -3197,7 +3199,8 @@ static int srpt_add_one(struct ib_device *device)
31973199
pr_debug("added %s.\n", dev_name(&device->dev));
31983200
return 0;
31993201

3200-
err_event:
3202+
err_port:
3203+
srpt_unregister_mad_agent(sdev, i);
32013204
ib_unregister_event_handler(&sdev->event_handler);
32023205
err_cm:
32033206
if (sdev->cm_id)
@@ -3221,7 +3224,7 @@ static void srpt_remove_one(struct ib_device *device, void *client_data)
32213224
struct srpt_device *sdev = client_data;
32223225
int i;
32233226

3224-
srpt_unregister_mad_agent(sdev);
3227+
srpt_unregister_mad_agent(sdev, sdev->device->phys_port_cnt);
32253228

32263229
ib_unregister_event_handler(&sdev->event_handler);
32273230

0 commit comments

Comments
 (0)