Commit 5281a4b8 authored by Stefan Roscher's avatar Stefan Roscher Committed by Roland Dreier

IB/ehca: Support more than 4k QPs for userspace and kernelspace

Signed-off-by: default avatarJoachim Fenkes <fenkes@de.ibm.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 441633b9
...@@ -166,7 +166,6 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, ...@@ -166,7 +166,6 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
write_lock_irqsave(&ehca_cq_idr_lock, flags); write_lock_irqsave(&ehca_cq_idr_lock, flags);
ret = idr_get_new(&ehca_cq_idr, my_cq, &my_cq->token); ret = idr_get_new(&ehca_cq_idr, my_cq, &my_cq->token);
write_unlock_irqrestore(&ehca_cq_idr_lock, flags); write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
} while (ret == -EAGAIN); } while (ret == -EAGAIN);
if (ret) { if (ret) {
...@@ -176,6 +175,12 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, ...@@ -176,6 +175,12 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
goto create_cq_exit1; goto create_cq_exit1;
} }
if (my_cq->token > 0x1FFFFFF) {
cq = ERR_PTR(-ENOMEM);
ehca_err(device, "Invalid number of cq. device=%p", device);
goto create_cq_exit2;
}
/* /*
* CQs maximum depth is 4GB-64, but we need additional 20 as buffer * CQs maximum depth is 4GB-64, but we need additional 20 as buffer
* for receiving errors CQEs. * for receiving errors CQEs.
......
...@@ -380,7 +380,7 @@ int ehca_init_device(struct ehca_shca *shca) ...@@ -380,7 +380,7 @@ int ehca_init_device(struct ehca_shca *shca)
strlcpy(shca->ib_device.name, "ehca%d", IB_DEVICE_NAME_MAX); strlcpy(shca->ib_device.name, "ehca%d", IB_DEVICE_NAME_MAX);
shca->ib_device.owner = THIS_MODULE; shca->ib_device.owner = THIS_MODULE;
shca->ib_device.uverbs_abi_ver = 7; shca->ib_device.uverbs_abi_ver = 8;
shca->ib_device.uverbs_cmd_mask = shca->ib_device.uverbs_cmd_mask =
(1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
(1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) | (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |
......
...@@ -557,7 +557,6 @@ static struct ehca_qp *internal_create_qp( ...@@ -557,7 +557,6 @@ static struct ehca_qp *internal_create_qp(
write_lock_irqsave(&ehca_qp_idr_lock, flags); write_lock_irqsave(&ehca_qp_idr_lock, flags);
ret = idr_get_new(&ehca_qp_idr, my_qp, &my_qp->token); ret = idr_get_new(&ehca_qp_idr, my_qp, &my_qp->token);
write_unlock_irqrestore(&ehca_qp_idr_lock, flags); write_unlock_irqrestore(&ehca_qp_idr_lock, flags);
} while (ret == -EAGAIN); } while (ret == -EAGAIN);
if (ret) { if (ret) {
...@@ -566,11 +565,17 @@ static struct ehca_qp *internal_create_qp( ...@@ -566,11 +565,17 @@ static struct ehca_qp *internal_create_qp(
goto create_qp_exit0; goto create_qp_exit0;
} }
if (my_qp->token > 0x1FFFFFF) {
ret = -EINVAL;
ehca_err(pd->device, "Invalid number of qp");
goto create_qp_exit1;
}
parms.servicetype = ibqptype2servicetype(qp_type); parms.servicetype = ibqptype2servicetype(qp_type);
if (parms.servicetype < 0) { if (parms.servicetype < 0) {
ret = -EINVAL; ret = -EINVAL;
ehca_err(pd->device, "Invalid qp_type=%x", qp_type); ehca_err(pd->device, "Invalid qp_type=%x", qp_type);
goto create_qp_exit0; goto create_qp_exit1;
} }
if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
......
...@@ -164,7 +164,7 @@ static int ehca_mmap_cq(struct vm_area_struct *vma, struct ehca_cq *cq, ...@@ -164,7 +164,7 @@ static int ehca_mmap_cq(struct vm_area_struct *vma, struct ehca_cq *cq,
int ret; int ret;
switch (rsrc_type) { switch (rsrc_type) {
case 1: /* galpa fw handle */ case 0: /* galpa fw handle */
ehca_dbg(cq->ib_cq.device, "cq_num=%x fw", cq->cq_number); ehca_dbg(cq->ib_cq.device, "cq_num=%x fw", cq->cq_number);
ret = ehca_mmap_fw(vma, &cq->galpas, &cq->mm_count_galpa); ret = ehca_mmap_fw(vma, &cq->galpas, &cq->mm_count_galpa);
if (unlikely(ret)) { if (unlikely(ret)) {
...@@ -175,7 +175,7 @@ static int ehca_mmap_cq(struct vm_area_struct *vma, struct ehca_cq *cq, ...@@ -175,7 +175,7 @@ static int ehca_mmap_cq(struct vm_area_struct *vma, struct ehca_cq *cq,
} }
break; break;
case 2: /* cq queue_addr */ case 1: /* cq queue_addr */
ehca_dbg(cq->ib_cq.device, "cq_num=%x queue", cq->cq_number); ehca_dbg(cq->ib_cq.device, "cq_num=%x queue", cq->cq_number);
ret = ehca_mmap_queue(vma, &cq->ipz_queue, &cq->mm_count_queue); ret = ehca_mmap_queue(vma, &cq->ipz_queue, &cq->mm_count_queue);
if (unlikely(ret)) { if (unlikely(ret)) {
...@@ -201,7 +201,7 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp, ...@@ -201,7 +201,7 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
int ret; int ret;
switch (rsrc_type) { switch (rsrc_type) {
case 1: /* galpa fw handle */ case 0: /* galpa fw handle */
ehca_dbg(qp->ib_qp.device, "qp_num=%x fw", qp->ib_qp.qp_num); ehca_dbg(qp->ib_qp.device, "qp_num=%x fw", qp->ib_qp.qp_num);
ret = ehca_mmap_fw(vma, &qp->galpas, &qp->mm_count_galpa); ret = ehca_mmap_fw(vma, &qp->galpas, &qp->mm_count_galpa);
if (unlikely(ret)) { if (unlikely(ret)) {
...@@ -212,7 +212,7 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp, ...@@ -212,7 +212,7 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
} }
break; break;
case 2: /* qp rqueue_addr */ case 1: /* qp rqueue_addr */
ehca_dbg(qp->ib_qp.device, "qp_num=%x rqueue", ehca_dbg(qp->ib_qp.device, "qp_num=%x rqueue",
qp->ib_qp.qp_num); qp->ib_qp.qp_num);
ret = ehca_mmap_queue(vma, &qp->ipz_rqueue, ret = ehca_mmap_queue(vma, &qp->ipz_rqueue,
...@@ -225,7 +225,7 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp, ...@@ -225,7 +225,7 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
} }
break; break;
case 3: /* qp squeue_addr */ case 2: /* qp squeue_addr */
ehca_dbg(qp->ib_qp.device, "qp_num=%x squeue", ehca_dbg(qp->ib_qp.device, "qp_num=%x squeue",
qp->ib_qp.qp_num); qp->ib_qp.qp_num);
ret = ehca_mmap_queue(vma, &qp->ipz_squeue, ret = ehca_mmap_queue(vma, &qp->ipz_squeue,
...@@ -249,10 +249,10 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp, ...@@ -249,10 +249,10 @@ static int ehca_mmap_qp(struct vm_area_struct *vma, struct ehca_qp *qp,
int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
{ {
u64 fileoffset = vma->vm_pgoff << PAGE_SHIFT; u64 fileoffset = vma->vm_pgoff;
u32 idr_handle = fileoffset >> 32; u32 idr_handle = fileoffset & 0x1FFFFFF;
u32 q_type = (fileoffset >> 28) & 0xF; /* CQ, QP,... */ u32 q_type = (fileoffset >> 27) & 0x1; /* CQ, QP,... */
u32 rsrc_type = (fileoffset >> 24) & 0xF; /* sq,rq,cmnd_window */ u32 rsrc_type = (fileoffset >> 25) & 0x3; /* sq,rq,cmnd_window */
u32 cur_pid = current->tgid; u32 cur_pid = current->tgid;
u32 ret; u32 ret;
struct ehca_cq *cq; struct ehca_cq *cq;
...@@ -261,7 +261,7 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) ...@@ -261,7 +261,7 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
struct ib_uobject *uobject; struct ib_uobject *uobject;
switch (q_type) { switch (q_type) {
case 1: /* CQ */ case 0: /* CQ */
read_lock(&ehca_cq_idr_lock); read_lock(&ehca_cq_idr_lock);
cq = idr_find(&ehca_cq_idr, idr_handle); cq = idr_find(&ehca_cq_idr, idr_handle);
read_unlock(&ehca_cq_idr_lock); read_unlock(&ehca_cq_idr_lock);
...@@ -289,7 +289,7 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) ...@@ -289,7 +289,7 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
} }
break; break;
case 2: /* QP */ case 1: /* QP */
read_lock(&ehca_qp_idr_lock); read_lock(&ehca_qp_idr_lock);
qp = idr_find(&ehca_qp_idr, idr_handle); qp = idr_find(&ehca_qp_idr, idr_handle);
read_unlock(&ehca_qp_idr_lock); read_unlock(&ehca_qp_idr_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment