Commit a6a12947 authored by Joachim Fenkes's avatar Joachim Fenkes Committed by Roland Dreier

IB/ehca: add Shared Receive Queue support

Support SRQs on eHCA2. Since an SRQ is a QP for eHCA2, a lot of code
(structures, create, destroy, post_recv) can be shared between QP and SRQ.
Signed-off-by: default avatarJoachim Fenkes <fenkes@de.ibm.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 9a79fc0a
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* *
* Authors: Heiko J Schick <schickhj@de.ibm.com> * Authors: Heiko J Schick <schickhj@de.ibm.com>
* Christoph Raisch <raisch@de.ibm.com> * Christoph Raisch <raisch@de.ibm.com>
* Joachim Fenkes <fenkes@de.ibm.com>
* *
* Copyright (c) 2005 IBM Corporation * Copyright (c) 2005 IBM Corporation
* *
...@@ -117,9 +118,20 @@ struct ehca_pd { ...@@ -117,9 +118,20 @@ struct ehca_pd {
u32 ownpid; u32 ownpid;
}; };
enum ehca_ext_qp_type {
EQPT_NORMAL = 0,
EQPT_LLQP = 1,
EQPT_SRQBASE = 2,
EQPT_SRQ = 3,
};
struct ehca_qp { struct ehca_qp {
struct ib_qp ib_qp; union {
struct ib_qp ib_qp;
struct ib_srq ib_srq;
};
u32 qp_type; u32 qp_type;
enum ehca_ext_qp_type ext_type;
struct ipz_queue ipz_squeue; struct ipz_queue ipz_squeue;
struct ipz_queue ipz_rqueue; struct ipz_queue ipz_rqueue;
struct h_galpas galpas; struct h_galpas galpas;
...@@ -142,6 +154,10 @@ struct ehca_qp { ...@@ -142,6 +154,10 @@ struct ehca_qp {
u32 mm_count_galpa; u32 mm_count_galpa;
}; };
#define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ)
#define HAS_SQ(qp) (qp->ext_type != EQPT_SRQ)
#define HAS_RQ(qp) (qp->ext_type != EQPT_SRQBASE)
/* must be power of 2 */ /* must be power of 2 */
#define QP_HASHTAB_LEN 8 #define QP_HASHTAB_LEN 8
...@@ -307,6 +323,7 @@ struct ehca_create_qp_resp { ...@@ -307,6 +323,7 @@ struct ehca_create_qp_resp {
u32 qp_num; u32 qp_num;
u32 token; u32 token;
u32 qp_type; u32 qp_type;
u32 ext_type;
u32 qkey; u32 qkey;
/* qp_num assigned by ehca: sqp0/1 may have got different numbers */ /* qp_num assigned by ehca: sqp0/1 may have got different numbers */
u32 real_qp_num; u32 real_qp_num;
...@@ -329,13 +346,6 @@ enum ehca_service_type { ...@@ -329,13 +346,6 @@ enum ehca_service_type {
ST_UD = 3, ST_UD = 3,
}; };
enum ehca_ext_qp_type {
EQPT_NORMAL = 0,
EQPT_LLQP = 1,
EQPT_SRQBASE = 2,
EQPT_SRQ = 3,
};
enum ehca_ll_comp_flags { enum ehca_ll_comp_flags {
LLQP_SEND_COMP = 0x20, LLQP_SEND_COMP = 0x20,
LLQP_RECV_COMP = 0x40, LLQP_RECV_COMP = 0x40,
......
...@@ -228,8 +228,8 @@ struct hcp_modify_qp_control_block { ...@@ -228,8 +228,8 @@ struct hcp_modify_qp_control_block {
#define MQPCB_QP_NUMBER EHCA_BMASK_IBM(8,31) #define MQPCB_QP_NUMBER EHCA_BMASK_IBM(8,31)
#define MQPCB_MASK_QP_ENABLE EHCA_BMASK_IBM(48,48) #define MQPCB_MASK_QP_ENABLE EHCA_BMASK_IBM(48,48)
#define MQPCB_QP_ENABLE EHCA_BMASK_IBM(31,31) #define MQPCB_QP_ENABLE EHCA_BMASK_IBM(31,31)
#define MQPCB_MASK_CURR_SQR_LIMIT EHCA_BMASK_IBM(49,49) #define MQPCB_MASK_CURR_SRQ_LIMIT EHCA_BMASK_IBM(49,49)
#define MQPCB_CURR_SQR_LIMIT EHCA_BMASK_IBM(15,31) #define MQPCB_CURR_SRQ_LIMIT EHCA_BMASK_IBM(16,31)
#define MQPCB_MASK_QP_AFF_ASYN_EV_LOG_REG EHCA_BMASK_IBM(50,50) #define MQPCB_MASK_QP_AFF_ASYN_EV_LOG_REG EHCA_BMASK_IBM(50,50)
#define MQPCB_MASK_SHARED_RQ_HNDL EHCA_BMASK_IBM(51,51) #define MQPCB_MASK_SHARED_RQ_HNDL EHCA_BMASK_IBM(51,51)
......
...@@ -154,6 +154,21 @@ int ehca_post_send(struct ib_qp *qp, struct ib_send_wr *send_wr, ...@@ -154,6 +154,21 @@ int ehca_post_send(struct ib_qp *qp, struct ib_send_wr *send_wr,
int ehca_post_recv(struct ib_qp *qp, struct ib_recv_wr *recv_wr, int ehca_post_recv(struct ib_qp *qp, struct ib_recv_wr *recv_wr,
struct ib_recv_wr **bad_recv_wr); struct ib_recv_wr **bad_recv_wr);
int ehca_post_srq_recv(struct ib_srq *srq,
struct ib_recv_wr *recv_wr,
struct ib_recv_wr **bad_recv_wr);
struct ib_srq *ehca_create_srq(struct ib_pd *pd,
struct ib_srq_init_attr *init_attr,
struct ib_udata *udata);
int ehca_modify_srq(struct ib_srq *srq, struct ib_srq_attr *attr,
enum ib_srq_attr_mask attr_mask, struct ib_udata *udata);
int ehca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
int ehca_destroy_srq(struct ib_srq *srq);
u64 ehca_define_sqp(struct ehca_shca *shca, struct ehca_qp *ibqp, u64 ehca_define_sqp(struct ehca_shca *shca, struct ehca_qp *ibqp,
struct ib_qp_init_attr *qp_init_attr); struct ib_qp_init_attr *qp_init_attr);
......
...@@ -343,7 +343,7 @@ int ehca_init_device(struct ehca_shca *shca) ...@@ -343,7 +343,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 = 6; shca->ib_device.uverbs_abi_ver = 7;
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) |
...@@ -411,6 +411,20 @@ int ehca_init_device(struct ehca_shca *shca) ...@@ -411,6 +411,20 @@ int ehca_init_device(struct ehca_shca *shca)
/* shca->ib_device.process_mad = ehca_process_mad; */ /* shca->ib_device.process_mad = ehca_process_mad; */
shca->ib_device.mmap = ehca_mmap; shca->ib_device.mmap = ehca_mmap;
if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
shca->ib_device.uverbs_cmd_mask |=
(1ull << IB_USER_VERBS_CMD_CREATE_SRQ) |
(1ull << IB_USER_VERBS_CMD_MODIFY_SRQ) |
(1ull << IB_USER_VERBS_CMD_QUERY_SRQ) |
(1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
shca->ib_device.create_srq = ehca_create_srq;
shca->ib_device.modify_srq = ehca_modify_srq;
shca->ib_device.query_srq = ehca_query_srq;
shca->ib_device.destroy_srq = ehca_destroy_srq;
shca->ib_device.post_srq_recv = ehca_post_srq_recv;
}
return ret; return ret;
} }
......
This diff is collapsed.
...@@ -3,8 +3,9 @@ ...@@ -3,8 +3,9 @@
* *
* post_send/recv, poll_cq, req_notify * post_send/recv, poll_cq, req_notify
* *
* Authors: Waleri Fomin <fomin@de.ibm.com> * Authors: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
* Hoang-Nam Nguyen <hnguyen@de.ibm.com> * Waleri Fomin <fomin@de.ibm.com>
* Joachim Fenkes <fenkes@de.ibm.com>
* Reinhard Ernst <rernst@de.ibm.com> * Reinhard Ernst <rernst@de.ibm.com>
* *
* Copyright (c) 2005 IBM Corporation * Copyright (c) 2005 IBM Corporation
...@@ -413,17 +414,23 @@ int ehca_post_send(struct ib_qp *qp, ...@@ -413,17 +414,23 @@ int ehca_post_send(struct ib_qp *qp,
return ret; return ret;
} }
int ehca_post_recv(struct ib_qp *qp, static int internal_post_recv(struct ehca_qp *my_qp,
struct ib_recv_wr *recv_wr, struct ib_device *dev,
struct ib_recv_wr **bad_recv_wr) struct ib_recv_wr *recv_wr,
struct ib_recv_wr **bad_recv_wr)
{ {
struct ehca_qp *my_qp = container_of(qp, struct ehca_qp, ib_qp);
struct ib_recv_wr *cur_recv_wr; struct ib_recv_wr *cur_recv_wr;
struct ehca_wqe *wqe_p; struct ehca_wqe *wqe_p;
int wqe_cnt = 0; int wqe_cnt = 0;
int ret = 0; int ret = 0;
unsigned long spl_flags; unsigned long spl_flags;
if (unlikely(!HAS_RQ(my_qp))) {
ehca_err(dev, "QP has no RQ ehca_qp=%p qp_num=%x ext_type=%d",
my_qp, my_qp->real_qp_num, my_qp->ext_type);
return -ENODEV;
}
/* LOCK the QUEUE */ /* LOCK the QUEUE */
spin_lock_irqsave(&my_qp->spinlock_r, spl_flags); spin_lock_irqsave(&my_qp->spinlock_r, spl_flags);
...@@ -439,8 +446,8 @@ int ehca_post_recv(struct ib_qp *qp, ...@@ -439,8 +446,8 @@ int ehca_post_recv(struct ib_qp *qp,
*bad_recv_wr = cur_recv_wr; *bad_recv_wr = cur_recv_wr;
if (wqe_cnt == 0) { if (wqe_cnt == 0) {
ret = -ENOMEM; ret = -ENOMEM;
ehca_err(qp->device, "Too many posted WQEs " ehca_err(dev, "Too many posted WQEs "
"qp_num=%x", qp->qp_num); "qp_num=%x", my_qp->real_qp_num);
} }
goto post_recv_exit0; goto post_recv_exit0;
} }
...@@ -455,14 +462,14 @@ int ehca_post_recv(struct ib_qp *qp, ...@@ -455,14 +462,14 @@ int ehca_post_recv(struct ib_qp *qp,
*bad_recv_wr = cur_recv_wr; *bad_recv_wr = cur_recv_wr;
if (wqe_cnt == 0) { if (wqe_cnt == 0) {
ret = -EINVAL; ret = -EINVAL;
ehca_err(qp->device, "Could not write WQE " ehca_err(dev, "Could not write WQE "
"qp_num=%x", qp->qp_num); "qp_num=%x", my_qp->real_qp_num);
} }
goto post_recv_exit0; goto post_recv_exit0;
} }
wqe_cnt++; wqe_cnt++;
ehca_gen_dbg("ehca_qp=%p qp_num=%x wqe_cnt=%d", ehca_dbg(dev, "ehca_qp=%p qp_num=%x wqe_cnt=%d",
my_qp, qp->qp_num, wqe_cnt); my_qp, my_qp->real_qp_num, wqe_cnt);
} /* eof for cur_recv_wr */ } /* eof for cur_recv_wr */
post_recv_exit0: post_recv_exit0:
...@@ -472,6 +479,22 @@ int ehca_post_recv(struct ib_qp *qp, ...@@ -472,6 +479,22 @@ int ehca_post_recv(struct ib_qp *qp,
return ret; return ret;
} }
int ehca_post_recv(struct ib_qp *qp,
struct ib_recv_wr *recv_wr,
struct ib_recv_wr **bad_recv_wr)
{
return internal_post_recv(container_of(qp, struct ehca_qp, ib_qp),
qp->device, recv_wr, bad_recv_wr);
}
int ehca_post_srq_recv(struct ib_srq *srq,
struct ib_recv_wr *recv_wr,
struct ib_recv_wr **bad_recv_wr)
{
return internal_post_recv(container_of(srq, struct ehca_qp, ib_srq),
srq->device, recv_wr, bad_recv_wr);
}
/* /*
* ib_wc_opcode table converts ehca wc opcode to ib * ib_wc_opcode table converts ehca wc opcode to ib
* Since we use zero to indicate invalid opcode, the actual ib opcode must * Since we use zero to indicate invalid opcode, the actual ib opcode must
......
...@@ -257,6 +257,7 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) ...@@ -257,6 +257,7 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
struct ehca_cq *cq; struct ehca_cq *cq;
struct ehca_qp *qp; struct ehca_qp *qp;
struct ehca_pd *pd; struct ehca_pd *pd;
struct ib_uobject *uobject;
switch (q_type) { switch (q_type) {
case 1: /* CQ */ case 1: /* CQ */
...@@ -304,7 +305,8 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) ...@@ -304,7 +305,8 @@ int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
return -ENOMEM; return -ENOMEM;
} }
if (!qp->ib_qp.uobject || qp->ib_qp.uobject->context != context) uobject = IS_SRQ(qp) ? qp->ib_srq.uobject : qp->ib_qp.uobject;
if (!uobject || uobject->context != context)
return -EINVAL; return -EINVAL;
ret = ehca_mmap_qp(vma, qp, rsrc_type); ret = ehca_mmap_qp(vma, qp, rsrc_type);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* *
* Authors: Christoph Raisch <raisch@de.ibm.com> * Authors: Christoph Raisch <raisch@de.ibm.com>
* Hoang-Nam Nguyen <hnguyen@de.ibm.com> * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
* Joachim Fenkes <fenkes@de.ibm.com>
* Gerd Bayer <gerd.bayer@de.ibm.com> * Gerd Bayer <gerd.bayer@de.ibm.com>
* Waleri Fomin <fomin@de.ibm.com> * Waleri Fomin <fomin@de.ibm.com>
* *
...@@ -62,6 +63,12 @@ ...@@ -62,6 +63,12 @@
#define H_ALL_RES_QP_MAX_SEND_SGE EHCA_BMASK_IBM(32, 39) #define H_ALL_RES_QP_MAX_SEND_SGE EHCA_BMASK_IBM(32, 39)
#define H_ALL_RES_QP_MAX_RECV_SGE EHCA_BMASK_IBM(40, 47) #define H_ALL_RES_QP_MAX_RECV_SGE EHCA_BMASK_IBM(40, 47)
#define H_ALL_RES_QP_UD_AV_LKEY EHCA_BMASK_IBM(32, 63)
#define H_ALL_RES_QP_SRQ_QP_TOKEN EHCA_BMASK_IBM(0, 31)
#define H_ALL_RES_QP_SRQ_QP_HANDLE EHCA_BMASK_IBM(0, 64)
#define H_ALL_RES_QP_SRQ_LIMIT EHCA_BMASK_IBM(48, 63)
#define H_ALL_RES_QP_SRQ_QPN EHCA_BMASK_IBM(40, 63)
#define H_ALL_RES_QP_ACT_OUTST_SEND_WR EHCA_BMASK_IBM(16, 31) #define H_ALL_RES_QP_ACT_OUTST_SEND_WR EHCA_BMASK_IBM(16, 31)
#define H_ALL_RES_QP_ACT_OUTST_RECV_WR EHCA_BMASK_IBM(48, 63) #define H_ALL_RES_QP_ACT_OUTST_RECV_WR EHCA_BMASK_IBM(48, 63)
#define H_ALL_RES_QP_ACT_SEND_SGE EHCA_BMASK_IBM(8, 15) #define H_ALL_RES_QP_ACT_SEND_SGE EHCA_BMASK_IBM(8, 15)
...@@ -150,7 +157,7 @@ static long ehca_plpar_hcall9(unsigned long opcode, ...@@ -150,7 +157,7 @@ static long ehca_plpar_hcall9(unsigned long opcode,
{ {
long ret; long ret;
int i, sleep_msecs, lock_is_set = 0; int i, sleep_msecs, lock_is_set = 0;
unsigned long flags; unsigned long flags = 0;
ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx " ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx "
"arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx", "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx",
...@@ -282,8 +289,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle, ...@@ -282,8 +289,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
struct ehca_alloc_qp_parms *parms) struct ehca_alloc_qp_parms *parms)
{ {
u64 ret; u64 ret;
u64 allocate_controls; u64 allocate_controls, max_r10_reg, r11, r12;
u64 max_r10_reg;
u64 outs[PLPAR_HCALL9_BUFSIZE]; u64 outs[PLPAR_HCALL9_BUFSIZE];
allocate_controls = allocate_controls =
...@@ -309,6 +315,13 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle, ...@@ -309,6 +315,13 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE, | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE,
parms->max_recv_sge); parms->max_recv_sge);
r11 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QP_TOKEN, parms->srq_token);
if (parms->ext_type == EQPT_SRQ)
r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_LIMIT, parms->srq_limit);
else
r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QPN, parms->srq_qpn);
ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs, ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
adapter_handle.handle, /* r4 */ adapter_handle.handle, /* r4 */
allocate_controls, /* r5 */ allocate_controls, /* r5 */
...@@ -316,9 +329,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle, ...@@ -316,9 +329,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
parms->recv_cq_handle.handle, parms->recv_cq_handle.handle,
parms->eq_handle.handle, parms->eq_handle.handle,
((u64)parms->token << 32) | parms->pd.value, ((u64)parms->token << 32) | parms->pd.value,
max_r10_reg, /* r10 */ max_r10_reg, r11, r12);
parms->ud_av_l_key_ctl, /* r11 */
0);
parms->qp_handle.handle = outs[0]; parms->qp_handle.handle = outs[0];
parms->real_qp_num = (u32)outs[1]; parms->real_qp_num = (u32)outs[1];
......
...@@ -163,6 +163,7 @@ struct hipz_qptemm { ...@@ -163,6 +163,7 @@ struct hipz_qptemm {
#define QPX_SQADDER EHCA_BMASK_IBM(48,63) #define QPX_SQADDER EHCA_BMASK_IBM(48,63)
#define QPX_RQADDER EHCA_BMASK_IBM(48,63) #define QPX_RQADDER EHCA_BMASK_IBM(48,63)
#define QPX_AAELOG_RESET_SRQ_LIMIT EHCA_BMASK_IBM(3,3)
#define QPTEMM_OFFSET(x) offsetof(struct hipz_qptemm,x) #define QPTEMM_OFFSET(x) offsetof(struct hipz_qptemm,x)
......
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