summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorRalph Campbell <ralph.campbell@qlogic.com>2007-11-14 12:09:05 -0800
committerRoland Dreier <rolandd@cisco.com>2007-11-20 11:04:10 -0800
commit8a278e6d571ebe10b96f2b53c74f01fd0a3f005a (patch)
tree3d6ced2d41c7aa6d0db91e1141b943f202a93c64 /drivers/infiniband
parentfb74dacb0f00dff851c78411773a5bd5d7128b81 (diff)
downloadlinux-8a278e6d571ebe10b96f2b53c74f01fd0a3f005a.tar.gz
linux-8a278e6d571ebe10b96f2b53c74f01fd0a3f005a.tar.bz2
linux-8a278e6d571ebe10b96f2b53c74f01fd0a3f005a.zip
IB/ipath: Fix error path in QP creation
This patch fixes the code which frees the partially allocated QP resources if there was an error while creating the QP. In particular, the QPN wasn't deallocated and the QP wasn't removed from the hash table. Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_qp.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
index 6a41fdbc8e57..b997ff88401b 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -835,7 +835,8 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
init_attr->qp_type);
if (err) {
ret = ERR_PTR(err);
- goto bail_rwq;
+ vfree(qp->r_rq.wq);
+ goto bail_qp;
}
qp->ip = NULL;
ipath_reset_qp(qp);
@@ -863,7 +864,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
sizeof(offset));
if (err) {
ret = ERR_PTR(err);
- goto bail_rwq;
+ goto bail_ip;
}
} else {
u32 s = sizeof(struct ipath_rwq) +
@@ -875,7 +876,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
qp->r_rq.wq);
if (!qp->ip) {
ret = ERR_PTR(-ENOMEM);
- goto bail_rwq;
+ goto bail_ip;
}
err = ib_copy_to_udata(udata, &(qp->ip->offset),
@@ -907,9 +908,11 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
goto bail;
bail_ip:
- kfree(qp->ip);
-bail_rwq:
- vfree(qp->r_rq.wq);
+ if (qp->ip)
+ kref_put(&qp->ip->ref, ipath_release_mmap_info);
+ else
+ vfree(qp->r_rq.wq);
+ ipath_free_qp(&dev->qp_table, qp);
bail_qp:
kfree(qp);
bail_swq: