IB/rdamvt, qib, hfi1: Code cleanups, bug fixes, and perf improvements
Subsystems (3)
cover IB/rdamvt, qib, hfi1: Code cleanups, bug fixes, and perf improvements
This series adds in mostly code clean ups. The driver provided functions are documented and checked based on which verbs drivers are expecting rdmavt to provide. There are also a couple of bug fixes included in this series, along with a performance improvement patch which adds a dual lock to the sending side.
The patches here apply on the previously submitted "Misc bug fixes for hfi1" and can be seen in context at: https://github.com/ddalessa/kernel/tree/for-4.6.
---
Dennis Dalessandro (7):
IB/rdmavt: Clean up comments and add more documentation IB/rdmavt: Add per verb driver callback checking IB/qib: Setup notify free/create mad agent callbacks for rdmavt IB/qib,rdmavt: Move smi_ah to qib
IB/rdmavt: Remove RVT_FLAGs
IB/rdmavt: Remove signal_supported and comments IB/rdmavt: Remove unnecessary exported functions
Harish Chegondi (3):
IB/qib: Rename several functions by adding a "qib_" prefix IB/rdmavt: Add trace and error print statements in post_one_wr IB/qib: Destroy SMI AH before de-allocating the protection domain
Kaike Wan (1):
staging/rdma/hfi1: Put QPs into error state after SL->SC table changes
Mike Marciniszyn (1):
IB/qib,staging/rdma/hfi1: add s_hlock for use in post send
drivers/infiniband/hw/qib/qib.h | 16 - drivers/infiniband/hw/qib/qib_iba7322.c | 8 drivers/infiniband/hw/qib/qib_mad.c | 3 drivers/infiniband/hw/qib/qib_qp.c | 62 +++- drivers/infiniband/hw/qib/qib_rc.c | 44 +-- drivers/infiniband/hw/qib/qib_ruc.c | 11 - drivers/infiniband/hw/qib/qib_uc.c | 22 + drivers/infiniband/hw/qib/qib_ud.c | 22 + drivers/infiniband/hw/qib/qib_verbs.c | 67 +++- drivers/infiniband/hw/qib/qib_verbs.h | 17 + drivers/infiniband/sw/rdmavt/ah.c | 27 ++ drivers/infiniband/sw/rdmavt/cq.c | 35 +- drivers/infiniband/sw/rdmavt/mad.c | 30 +- drivers/infiniband/sw/rdmavt/mcast.c | 34 ++ drivers/infiniband/sw/rdmavt/mmap.c | 32 +- drivers/infiniband/sw/rdmavt/mmap.h | 8 drivers/infiniband/sw/rdmavt/mr.c | 43 ++- drivers/infiniband/sw/rdmavt/pd.c | 16 + drivers/infiniband/sw/rdmavt/qp.c | 382 ++++++++++++++---------- drivers/infiniband/sw/rdmavt/srq.c | 22 + drivers/infiniband/sw/rdmavt/trace.h | 70 ++++ drivers/infiniband/sw/rdmavt/vt.c | 503 ++++++++++++++++++++++++++----- drivers/infiniband/sw/rdmavt/vt.h | 1 drivers/staging/rdma/hfi1/mad.c | 13 + drivers/staging/rdma/hfi1/qp.c | 131 ++++++++ drivers/staging/rdma/hfi1/qp.h | 38 -- drivers/staging/rdma/hfi1/rc.c | 44 +-- drivers/staging/rdma/hfi1/ruc.c | 40 +- drivers/staging/rdma/hfi1/uc.c | 21 + drivers/staging/rdma/hfi1/ud.c | 22 + drivers/staging/rdma/hfi1/verbs.c | 3 drivers/staging/rdma/hfi1/verbs.h | 2 include/rdma/rdma_vt.h | 184 +++++++---- include/rdma/rdmavt_qp.h | 17 + 34 files changed, 1387 insertions(+), 603 deletions(-)
Signature · 5 lines
-Denny -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20160214200613.1410.63195.stgit-9QXIwq+3FY+1XWohqUldA0EOCMrvLtNR@public.gmane.org
PATCH 1/12 IB/qib: Rename several functions by adding a "qib_" prefix
From: Harish Chegondi <[email protected]>
This would avoid conflict with the functions in hfi1 that have similar names when both qib and hfi1 drivers are configured to be built into the kernel. This issue came up in the 0-day build report.
--- drivers/infiniband/hw/qib/qib.h | 16 ++++++++-------- drivers/infiniband/hw/qib/qib_qp.c | 26 +++++++++++++------------- drivers/infiniband/hw/qib/qib_verbs.c | 26 +++++++++++++------------- drivers/infiniband/hw/qib/qib_verbs.h | 10 +++++----- 4 files changed, 39 insertions(+), 39 deletions(-)
drivers/infiniband/hw/qib/qib.h +8 -8
@@ -1540,13 +1540,13 @@ void qib_format_hwerrors(u64 hwerrs,const struct qib_hwerror_msgs *hwerrmsgs, size_t nhwerrmsgs, char *msg, size_t lmsg); -void stop_send_queue (struct rvt_qp *qp); -void quiesce_qp (struct rvt_qp *qp); -void flush_qp_waiters (struct rvt_qp *qp); -int mtu_to_path_mtu (u32 mtu); -u32 mtu_from_qp (struct rvt_dev_info *rdi,struct rvt_qp *qp,u32 pmtu); -void notify_error_qp (struct rvt_qp *qp); -int get_pmtu_from_attr (struct rvt_dev_info *rdi,struct rvt_qp *qp, -struct ib_qp_attr *attr); +void qib_stop_send_queue (struct rvt_qp *qp); +void qib_quiesce_qp (struct rvt_qp *qp); +void qib_flush_qp_waiters (struct rvt_qp *qp); +int qib_mtu_to_path_mtu (u32 mtu); +u32 qib_mtu_from_qp (struct rvt_dev_info *rdi,struct rvt_qp *qp,u32 pmtu); +void qib_notify_error_qp (struct rvt_qp *qp); +int qib_get_pmtu_from_attr (struct rvt_dev_info *rdi,struct rvt_qp *qp, +struct ib_qp_attr *attr);#endif /* _QIB_KERNEL_H */
drivers/infiniband/hw/qib/qib_qp.c +13 -13
@@ -127,8 +127,8 @@ static void get_map_page(struct rvt_qpn_table *qpt, struct rvt_qpn_map *map,* Allocate the next available QPN or * zero/one for QP type IB_QPT_SMI/IB_QPT_GSI. */ -int alloc_qpn (struct rvt_dev_info *rdi,struct rvt_qpn_table *qpt, -enum ib_qp_type type,u8 port,gfp_t gfp) +int qib_alloc_qpn (struct rvt_dev_info *rdi,struct rvt_qpn_table *qpt, +enum ib_qp_type type,u8 port,gfp_t gfp) {u32 i, offset, max_scan, qpn;struct rvt_qpn_map *map;
@@ -232,14 +232,14 @@ unsigned qib_free_all_qps(struct rvt_dev_info *rdi)return qp_inuse; } -void notify_qp_reset (struct rvt_qp *qp) +void qib_notify_qp_reset (struct rvt_qp *qp) {struct qib_qp_priv *priv = qp->priv;atomic_set (&priv->s_dma_busy,0 ); } -void notify_error_qp (struct rvt_qp *qp) +void qib_notify_error_qp (struct rvt_qp *qp) {struct qib_qp_priv *priv = qp->priv;struct qib_ibdev *dev =to_idev (qp->ibqp.device);
@@ -290,8 +290,8 @@ static int mtu_to_enum(u32 mtu)return enum_mtu; } -int get_pmtu_from_attr (struct rvt_dev_info *rdi,struct rvt_qp *qp, -struct ib_qp_attr *attr) +int qib_get_pmtu_from_attr (struct rvt_dev_info *rdi,struct rvt_qp *qp, +struct ib_qp_attr *attr) {int mtu, pmtu, pidx = qp->port_num -1 ; struct qib_ibdev *verbs_dev = container_of(rdi, struct qib_ibdev, rdi);
@@ -308,12 +308,12 @@ int get_pmtu_from_attr(struct rvt_dev_info *rdi, struct rvt_qp *qp,return pmtu; } -int mtu_to_path_mtu (u32 mtu) +int qib_mtu_to_path_mtu (u32 mtu) {return mtu_to_enum (mtu); } -u32 mtu_from_qp (struct rvt_dev_info *rdi,struct rvt_qp *qp,u32 pmtu) +u32 qib_mtu_from_qp (struct rvt_dev_info *rdi,struct rvt_qp *qp,u32 pmtu) {return ib_mtu_enum_to_int (pmtu); }
@@ -378,7 +378,7 @@ __be32 qib_compute_aeth(struct rvt_qp *qp)return cpu_to_be32 (aeth); } -void *qp_priv_alloc (struct rvt_dev_info *rdi,struct rvt_qp *qp,gfp_t gfp) +void *qib_qp_priv_alloc (struct rvt_dev_info *rdi,struct rvt_qp *qp,gfp_t gfp) {struct qib_qp_priv *priv;
@@ -399,7 +399,7 @@ void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp, gfp_t gfp)return priv; } -void qp_priv_free (struct rvt_dev_info *rdi,struct rvt_qp *qp) +void qib_qp_priv_free (struct rvt_dev_info *rdi,struct rvt_qp *qp) {struct qib_qp_priv *priv = qp->priv;
@@ -407,7 +407,7 @@ void qp_priv_free(struct rvt_dev_info *rdi, struct rvt_qp *qp)kfree (priv); } -void stop_send_queue (struct rvt_qp *qp) +void qib_stop_send_queue (struct rvt_qp *qp) {struct qib_qp_priv *priv = qp->priv;
@@ -415,7 +415,7 @@ void stop_send_queue(struct rvt_qp *qp)del_timer_sync (&qp->s_timer); } -void quiesce_qp (struct rvt_qp *qp) +void qib_quiesce_qp (struct rvt_qp *qp) {struct qib_qp_priv *priv = qp->priv;
@@ -426,7 +426,7 @@ void quiesce_qp(struct rvt_qp *qp) } } -void flush_qp_waiters (struct rvt_qp *qp) +void qib_flush_qp_waiters (struct rvt_qp *qp) {struct qib_qp_priv *priv = qp->priv;struct qib_ibdev *dev =to_idev (qp->ibqp.device);
drivers/infiniband/hw/qib/qib_verbs.c +13 -13
@@ -1394,7 +1394,7 @@ bail:return ret; } -static int shut_down_port (struct rvt_dev_info *rdi,u8 port_num) +static int qib_shut_down_port (struct rvt_dev_info *rdi,u8 port_num) { struct qib_ibdev *ibdev = container_of(rdi, struct qib_ibdev, rdi);struct qib_devdata *dd =dd_from_dev (ibdev);
@@ -1663,22 +1663,22 @@ int qib_register_ib_device(struct qib_devdata *dd) dd->verbs_dev.rdi.driver_f.get_pci_dev = qib_get_pci_dev; dd->verbs_dev.rdi.driver_f.check_ah = qib_check_ah; dd->verbs_dev.rdi.driver_f.notify_new_ah = qib_notify_new_ah; - dd->verbs_dev.rdi.driver_f.alloc_qpn = alloc_qpn; - dd->verbs_dev.rdi.driver_f.qp_priv_alloc = qp_priv_alloc; - dd->verbs_dev.rdi.driver_f.qp_priv_free = qp_priv_free; + dd->verbs_dev.rdi.driver_f.alloc_qpn = qib_alloc_qpn; + dd->verbs_dev.rdi.driver_f.qp_priv_alloc = qib_qp_priv_alloc; + dd->verbs_dev.rdi.driver_f.qp_priv_free = qib_qp_priv_free; dd->verbs_dev.rdi.driver_f.free_all_qps = qib_free_all_qps; - dd->verbs_dev.rdi.driver_f.notify_qp_reset = notify_qp_reset; + dd->verbs_dev.rdi.driver_f.notify_qp_reset = qib_notify_qp_reset; dd->verbs_dev.rdi.driver_f.do_send = qib_do_send; dd->verbs_dev.rdi.driver_f.schedule_send = qib_schedule_send; - dd->verbs_dev.rdi.driver_f.quiesce_qp = quiesce_qp; - dd->verbs_dev.rdi.driver_f.stop_send_queue = stop_send_queue; - dd->verbs_dev.rdi.driver_f.flush_qp_waiters = flush_qp_waiters; - dd->verbs_dev.rdi.driver_f.notify_error_qp = notify_error_qp; - dd->verbs_dev.rdi.driver_f.mtu_to_path_mtu = mtu_to_path_mtu; - dd->verbs_dev.rdi.driver_f.mtu_from_qp = mtu_from_qp; - dd->verbs_dev.rdi.driver_f.get_pmtu_from_attr = get_pmtu_from_attr; + dd->verbs_dev.rdi.driver_f.quiesce_qp = qib_quiesce_qp; + dd->verbs_dev.rdi.driver_f.stop_send_queue = qib_stop_send_queue; + dd->verbs_dev.rdi.driver_f.flush_qp_waiters = qib_flush_qp_waiters; + dd->verbs_dev.rdi.driver_f.notify_error_qp = qib_notify_error_qp; + dd->verbs_dev.rdi.driver_f.mtu_to_path_mtu = qib_mtu_to_path_mtu; + dd->verbs_dev.rdi.driver_f.mtu_from_qp = qib_mtu_from_qp; + dd->verbs_dev.rdi.driver_f.get_pmtu_from_attr = qib_get_pmtu_from_attr; dd->verbs_dev.rdi.driver_f.query_port_state = qib_query_port; - dd->verbs_dev.rdi.driver_f.shut_down_port = shut_down_port; + dd->verbs_dev.rdi.driver_f.shut_down_port = qib_shut_down_port; dd->verbs_dev.rdi.driver_f.cap_mask_chg = qib_cap_mask_chg; dd->verbs_dev.rdi.dparms.max_rdma_atomic =QIB_MAX_RDMA_ATOMIC ;
drivers/infiniband/hw/qib/qib_verbs.h +5 -5
@@ -350,11 +350,11 @@ __be32 qib_compute_aeth(struct rvt_qp *qp);* Functions provided by qib driver for rdmavt to use */ unsigned qib_free_all_qps (struct rvt_dev_info *rdi); -void *qp_priv_alloc (struct rvt_dev_info *rdi,struct rvt_qp *qp,gfp_t gfp); -void qp_priv_free (struct rvt_dev_info *rdi,struct rvt_qp *qp); -void notify_qp_reset (struct rvt_qp *qp); -int alloc_qpn (struct rvt_dev_info *rdi,struct rvt_qpn_table *qpt, -enum ib_qp_type type,u8 port,gfp_t gfp); +void *qib_qp_priv_alloc (struct rvt_dev_info *rdi,struct rvt_qp *qp,gfp_t gfp); +void qib_qp_priv_free (struct rvt_dev_info *rdi,struct rvt_qp *qp); +void qib_notify_qp_reset (struct rvt_qp *qp); +int qib_alloc_qpn (struct rvt_dev_info *rdi,struct rvt_qpn_table *qpt, +enum ib_qp_type type,u8 port,gfp_t gfp);#ifdef CONFIG_DEBUG_FS
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/12 IB/qib, staging/rdma/hfi1: add s_hlock for use in post send
In reply to a message not in the archiveFrom: Mike Marciniszyn <[email protected]>
This patch adds an additional lock to reduce contention on the s_lock.
This lock is used in post_send() so that the post_send is not serialized with the send engine and other send related processing.
To do this the s_next_psn is now maintained on post_send() while post_send() related fields are moved to a new cache line. There is an s_avail maintained for the post_send() to mitigate trading cache lines with the send engine. The lock is released/acquired around releasing the just built packet to the egress mechanism.
--- drivers/infiniband/hw/qib/qib_qp.c | 36 ++++++++++++ drivers/infiniband/hw/qib/qib_rc.c | 44 +++------------ drivers/infiniband/hw/qib/qib_ruc.c | 11 ++-- drivers/infiniband/hw/qib/qib_uc.c | 22 +++---- drivers/infiniband/hw/qib/qib_ud.c | 22 ++++--- drivers/infiniband/hw/qib/qib_verbs.c | 37 ++++++++++--- drivers/infiniband/hw/qib/qib_verbs.h | 6 +- drivers/infiniband/sw/rdmavt/qp.c | 97 ++++++++++++++++++++++++++------- drivers/staging/rdma/hfi1/qp.c | 79 ++++++++++++++++++++++++--- drivers/staging/rdma/hfi1/qp.h | 37 +------------ drivers/staging/rdma/hfi1/rc.c | 44 +++------------ drivers/staging/rdma/hfi1/ruc.c | 40 +++++++------- drivers/staging/rdma/hfi1/uc.c | 21 +++---- drivers/staging/rdma/hfi1/ud.c | 22 ++++--- drivers/staging/rdma/hfi1/verbs.c | 3 + drivers/staging/rdma/hfi1/verbs.h | 2 - include/rdma/rdma_vt.h | 4 + include/rdma/rdmavt_qp.h | 13 +++- 18 files changed, 319 insertions(+), 221 deletions(-)
drivers/infiniband/hw/qib/qib_qp.c +36 -0
@@ -474,6 +474,42 @@ void qib_get_credit(struct rvt_qp *qp, u32 aeth) } } +/** +* qib_check_send_wqe - validate wr/wqe +* @qp - The qp +* @wqe - The built wqe +* +* validate wr/wqe. This is called +* prior to inserting the wqe into +* the ring but after the wqe has been +* setup. +* +* Returns 0 on success, -EINVAL on failure +*/ +int qib_check_send_wqe (struct rvt_qp *qp, +struct rvt_swqe *wqe) +{ +struct rvt_ah *ah; + +switch (qp->ibqp.qp_type) { +case IB_QPT_RC : +case IB_QPT_UC : +if (wqe->length >0x80000000U ) +return -EINVAL ; +break ; +case IB_QPT_SMI : +case IB_QPT_GSI : +case IB_QPT_UD : + ah =ibah_to_rvtah (wqe->ud_wr.ah); +if (wqe->length > (1 << ah->log_pmtu)) +return -EINVAL ; +break ; +default : +break ; + } +return 0 ; +} +#ifdef CONFIG_DEBUG_FS struct qib_qp_iter {
drivers/infiniband/hw/qib/qib_rc.c +9 -35
134 lines not on this page · raw message
drivers/infiniband/hw/qib/qib_ruc.c +7 -4
@@ -391,7 +391,8 @@ static void qib_ruc_loopback(struct rvt_qp *sqp) sqp->s_flags |=RVT_S_BUSY ; again: -if (sqp->s_last == sqp->s_head) +smp_read_barrier_depends ();/* see post_one_send() */ +if (sqp->s_last ==ACCESS_ONCE (sqp->s_head)) goto clr_busy; wqe =rvt_get_swqe_ptr (sqp, sqp->s_last);
@@ -765,22 +766,24 @@ void qib_do_send(struct rvt_qp *qp) qp->s_flags |=RVT_S_BUSY ; -spin_unlock_irqrestore (&qp->s_lock, flags); -do {/* Check for a constructed packet to be sent. */ if (qp->s_hdrwords !=0 ) { +spin_unlock_irqrestore (&qp->s_lock, flags);/* * If the packet cannot be sent now, return and * the send tasklet will be woken up later. */ if (qib_verbs_send (qp, priv->s_hdr, qp->s_hdrwords, qp->s_cur_sge, qp->s_cur_size)) -break ; +return ;/* Record that s_hdr is empty. */ qp->s_hdrwords =0 ; +spin_lock_irqsave (&qp->s_lock, flags); } }while (make_req (qp)); + +spin_unlock_irqrestore (&qp->s_lock, flags); }/*
drivers/infiniband/hw/qib/qib_uc.c +9 -13
@@ -41,6 +41,8 @@* qib_make_uc_req - construct a request packet (SEND, RDMA write) * @qp: a pointer to the QP * +* Assumes the s_lock is held. +* * Return 1 if constructed; otherwise, return 0. */ int qib_make_uc_req (struct rvt_qp *qp)
@@ -48,20 +50,18 @@ int qib_make_uc_req(struct rvt_qp *qp)struct qib_qp_priv *priv = qp->priv;struct qib_other_headers *ohdr;struct rvt_swqe *wqe; -unsigned long flags;u32 hwords;u32 bth0;u32 len;u32 pmtu = qp->pmtu;int ret =0 ; -spin_lock_irqsave (&qp->s_lock, flags); -if (!(ib_rvt_state_ops[qp->state] &RVT_PROCESS_SEND_OK )) {if (!(ib_rvt_state_ops[qp->state] &RVT_FLUSH_SEND )) goto bail;/* We are in the error state, flush the work request. */ -if (qp->s_last == qp->s_head) +smp_read_barrier_depends ();/* see post_one_send() */ +if (qp->s_last ==ACCESS_ONCE (qp->s_head)) goto bail;/* If DMAs are in progress, we can't flush immediately. */ if (atomic_read (&priv->s_dma_busy)) {
@@ -90,13 +90,13 @@ int qib_make_uc_req(struct rvt_qp *qp) RVT_PROCESS_NEXT_SEND_OK)) goto bail;/* Check if send work queue is empty. */ -if (qp->s_cur == qp->s_head) +smp_read_barrier_depends ();/* see post_one_send() */ +if (qp->s_cur ==ACCESS_ONCE (qp->s_head)) goto bail;/* * Start a new request. */ - wqe->psn = qp->s_next_psn; - qp->s_psn = qp->s_next_psn; + qp->s_psn = wqe->psn; qp->s_sge.sge = wqe->sg_list[0 ]; qp->s_sge.sg_list = wqe->sg_list +1 ; qp->s_sge.num_sge = wqe->wr.num_sge;
@@ -215,15 +215,11 @@ int qib_make_uc_req(struct rvt_qp *qp) qp->s_cur_sge = &qp->s_sge; qp->s_cur_size = len;qib_make_ruc_header (qp, ohdr, bth0 | (qp->s_state <<24 ), - qp->s_next_psn++ &QIB_PSN_MASK ); + qp->s_psn++ &QIB_PSN_MASK ); done: - ret =1 ; - goto unlock; - +return 1 ; bail: qp->s_flags &= ~RVT_S_BUSY ; -unlock: -spin_unlock_irqrestore (&qp->s_lock, flags);return ret; }
drivers/infiniband/hw/qib/qib_ud.c +11 -11
@@ -234,6 +234,8 @@ drop:* qib_make_ud_req - construct a UD request packet * @qp: the QP * +* Assumes the s_lock is held. +* * Return 1 if constructed; otherwise, return 0. */ int qib_make_ud_req (struct rvt_qp *qp)
@@ -244,7 +246,6 @@ int qib_make_ud_req(struct rvt_qp *qp)struct qib_pportdata *ppd;struct qib_ibport *ibp;struct rvt_swqe *wqe; -unsigned long flags;u32 nwords;u32 extra_bytes;u32 bth0;
@@ -253,13 +254,12 @@ int qib_make_ud_req(struct rvt_qp *qp)int ret =0 ;int next_cur; -spin_lock_irqsave (&qp->s_lock, flags); -if (!(ib_rvt_state_ops[qp->state] &RVT_PROCESS_NEXT_SEND_OK )) {if (!(ib_rvt_state_ops[qp->state] &RVT_FLUSH_SEND )) goto bail;/* We are in the error state, flush the work request. */ -if (qp->s_last == qp->s_head) +smp_read_barrier_depends ();/* see post_one_send */ +if (qp->s_last ==ACCESS_ONCE (qp->s_head)) goto bail;/* If DMAs are in progress, we can't flush immediately. */ if (atomic_read (&priv->s_dma_busy)) {
@@ -271,7 +271,9 @@ int qib_make_ud_req(struct rvt_qp *qp) goto done; } -if (qp->s_cur == qp->s_head) +/* see post_one_send() */ +smp_read_barrier_depends (); +if (qp->s_cur ==ACCESS_ONCE (qp->s_head)) goto bail; wqe =rvt_get_swqe_ptr (qp, qp->s_cur);
@@ -292,6 +294,7 @@ int qib_make_ud_req(struct rvt_qp *qp)this_cpu_inc (ibp->pmastats->n_unicast_xmit); lid = ah_attr->dlid & ~((1 << ppd->lmc) -1 );if (unlikely (lid == ppd->lid)) { +unsigned long flags;/* * If DMAs are in progress, we can't generate * a completion for the loopback packet since
@@ -304,6 +307,7 @@ int qib_make_ud_req(struct rvt_qp *qp) goto bail; } qp->s_cur = next_cur; +local_irq_save (flags);spin_unlock_irqrestore (&qp->s_lock, flags);qib_ud_loopback (qp, wqe);spin_lock_irqsave (&qp->s_lock, flags);
@@ -378,7 +382,7 @@ int qib_make_ud_req(struct rvt_qp *qp) ah_attr->dlid !=be16_to_cpu (IB_LID_PERMISSIVE ) ?cpu_to_be32 (QIB_MULTICAST_QPN ) :cpu_to_be32 (wqe->ud_wr.remote_qpn); - ohdr->bth[2 ] =cpu_to_be32 (qp->s_next_psn++ &QIB_PSN_MASK ); + ohdr->bth[2 ] =cpu_to_be32 (wqe->psn &QIB_PSN_MASK );/* * Qkeys with the high order bit set mean use the * qkey from the QP context instead of the WR (see 10.2.5).
@@ -388,13 +392,9 @@ int qib_make_ud_req(struct rvt_qp *qp) ohdr->u.ud.deth[1 ] =cpu_to_be32 (qp->ibqp.qp_num); done: - ret =1 ; - goto unlock; - +return 1 ; bail: qp->s_flags &= ~RVT_S_BUSY ; -unlock: -spin_unlock_irqrestore (&qp->s_lock, flags);return ret; }
drivers/infiniband/hw/qib/qib_verbs.c +28 -9
@@ -1662,6 +1662,7 @@ int qib_register_ib_device(struct qib_devdata *dd) dd->verbs_dev.rdi.driver_f.get_card_name = qib_get_card_name; dd->verbs_dev.rdi.driver_f.get_pci_dev = qib_get_pci_dev; dd->verbs_dev.rdi.driver_f.check_ah = qib_check_ah; + dd->verbs_dev.rdi.driver_f.check_send_wqe = qib_check_send_wqe; dd->verbs_dev.rdi.driver_f.notify_new_ah = qib_notify_new_ah; dd->verbs_dev.rdi.driver_f.alloc_qpn = qib_alloc_qpn; dd->verbs_dev.rdi.driver_f.qp_priv_alloc = qib_qp_priv_alloc;
@@ -1677,6 +1678,7 @@ int qib_register_ib_device(struct qib_devdata *dd) dd->verbs_dev.rdi.driver_f.mtu_to_path_mtu = qib_mtu_to_path_mtu; dd->verbs_dev.rdi.driver_f.mtu_from_qp = qib_mtu_from_qp; dd->verbs_dev.rdi.driver_f.get_pmtu_from_attr = qib_get_pmtu_from_attr; + dd->verbs_dev.rdi.driver_f.schedule_send_no_lock = _qib_schedule_send; dd->verbs_dev.rdi.driver_f.query_port_state = qib_query_port; dd->verbs_dev.rdi.driver_f.shut_down_port = qib_shut_down_port; dd->verbs_dev.rdi.driver_f.cap_mask_chg = qib_cap_mask_chg;
@@ -1778,17 +1780,34 @@ void qib_unregister_ib_device(struct qib_devdata *dd) dev->pio_hdrs, dev->pio_hdrs_phys); } -/* -* This must be called with s_lock held. +/** +* _qib_schedule_send - schedule progress +* @qp - the qp +* +* This schedules progress w/o regard to the s_flags. +* +* It is only used in post send, which doesn't hold +* the s_lock. */ -void qib_schedule_send (struct rvt_qp *qp) +void _qib_schedule_send (struct rvt_qp *qp) { +struct qib_ibport *ibp = +to_iport (qp->ibqp.device, qp->port_num); +struct qib_pportdata *ppd =ppd_from_ibp (ibp);struct qib_qp_priv *priv = qp->priv; -if (qib_send_ok (qp)) { -struct qib_ibport *ibp = -to_iport (qp->ibqp.device, qp->port_num); -struct qib_pportdata *ppd =ppd_from_ibp (ibp); -queue_work (ppd->qib_wq, &priv->s_work); - } +queue_work (ppd->qib_wq, &priv->s_work); +} + +/** +* qib_schedule_send - schedule progress +* @qp - the qp +* +* This schedules qp progress. The s_lock +* should be held. +*/ +void qib_schedule_send (struct rvt_qp *qp) +{ +if (qib_send_ok (qp)) +_qib_schedule_send (qp); }
drivers/infiniband/hw/qib/qib_verbs.h +3 -3
@@ -298,9 +298,7 @@ static inline int qib_send_ok(struct rvt_qp *qp) !(qp->s_flags & RVT_S_ANY_WAIT_SEND)); } -/* -* This must be called with s_lock held. -*/ +void _qib_schedule_send (struct rvt_qp *qp);void qib_schedule_send (struct rvt_qp *qp);static inline int qib_pkey_ok (u16 pkey1,u16 pkey2)
@@ -392,6 +390,8 @@ void qib_rc_rcv(struct qib_ctxtdata *rcd, struct qib_ib_header *hdr,int qib_check_ah (struct ib_device *ibdev,struct ib_ah_attr *ah_attr); +int qib_check_send_wqe (struct rvt_qp *qp,struct rvt_swqe *wqe); +struct ib_ah *qib_create_qp0_ah (struct qib_ibport *ibp,u16 dlid);void qib_rc_rnr_retry (unsigned long arg);
drivers/infiniband/sw/rdmavt/qp.c +76 -21
227 lines not on this page · raw message
drivers/staging/rdma/hfi1/qp.c +72 -7
94 lines not on this page · raw message
drivers/staging/rdma/hfi1/qp.h +2 -35
@@ -137,41 +137,8 @@ void qp_iter_print(struct seq_file *s, struct qp_iter *iter);*/ void qp_comm_est (struct rvt_qp *qp); -/** -* _hfi1_schedule_send - schedule progress -* @qp: the QP -* -* This schedules qp progress w/o regard to the s_flags. -* -* It is only used in the post send, which doesn't hold -* the s_lock. -*/ -static inline void _hfi1_schedule_send (struct rvt_qp *qp) -{ -struct hfi1_qp_priv *priv = qp->priv; -struct hfi1_ibport *ibp = -to_iport (qp->ibqp.device, qp->port_num); -struct hfi1_pportdata *ppd =ppd_from_ibp (ibp); -struct hfi1_devdata *dd =dd_from_ibdev (qp->ibqp.device); - -iowait_schedule (&priv->s_iowait, ppd->hfi1_wq, - priv->s_sde ? - priv->s_sde->cpu : -cpumask_first (cpumask_of_node (dd->node))); -} - -/** -* hfi1_schedule_send - schedule progress -* @qp: the QP -* -* This schedules qp progress and caller should hold -* the s_lock. -*/ -static inline void hfi1_schedule_send (struct rvt_qp *qp) -{ -if (hfi1_send_ok (qp)) -_hfi1_schedule_send (qp); -} +void _hfi1_schedule_send (struct rvt_qp *qp); +void hfi1_schedule_send (struct rvt_qp *qp);void hfi1_migrate_qp (struct rvt_qp *qp);
drivers/staging/rdma/hfi1/rc.c +9 -35
134 lines not on this page · raw message
drivers/staging/rdma/hfi1/ruc.c +22 -18
@@ -392,7 +392,8 @@ static void ruc_loopback(struct rvt_qp *sqp) sqp->s_flags |=RVT_S_BUSY ; again: -if (sqp->s_last == sqp->s_head) +smp_read_barrier_depends ();/* see post_one_send() */ +if (sqp->s_last ==ACCESS_ONCE (sqp->s_head)) goto clr_busy; wqe =rvt_get_swqe_ptr (sqp, sqp->s_last);
@@ -871,40 +872,43 @@ void hfi1_do_send(struct rvt_qp *qp) qp->s_flags |=RVT_S_BUSY ; -spin_unlock_irqrestore (&qp->s_lock, flags); - timeout = jiffies + (timeout_int) /8 ; cpu = priv->s_sde ? priv->s_sde->cpu :cpumask_first (cpumask_of_node (ps.ppd->dd->node));do {/* Check for a constructed packet to be sent. */ if (qp->s_hdrwords !=0 ) { +spin_unlock_irqrestore (&qp->s_lock, flags);/* * If the packet cannot be sent now, return and * the send tasklet will be woken up later. */ if (hfi1_verbs_send (qp, &ps)) -break ; +return ;/* Record that s_hdr is empty. */ qp->s_hdrwords =0 ; - } - -/* allow other tasks to run */ -if (unlikely (time_after (jiffies, timeout))) { -if (workqueue_congested (cpu, ps.ppd->hfi1_wq)) { -spin_lock_irqsave (&qp->s_lock, flags); - qp->s_flags &= ~RVT_S_BUSY ; -hfi1_schedule_send (qp); -spin_unlock_irqrestore (&qp->s_lock, - flags); +/* allow other tasks to run */ +if (unlikely (time_after (jiffies, timeout))) { +if (workqueue_congested (cpu, + ps.ppd->hfi1_wq)) { +spin_lock_irqsave (&qp->s_lock, flags); + qp->s_flags &= ~RVT_S_BUSY ; +hfi1_schedule_send (qp); +spin_unlock_irqrestore (&qp->s_lock, + flags); +this_cpu_inc ( + *ps.ppd->dd->send_schedule); +return ; + } +cond_resched ();this_cpu_inc (*ps.ppd->dd->send_schedule); -return ; + timeout = jiffies + (timeout_int) /8 ; } -cond_resched (); -this_cpu_inc (*ps.ppd->dd->send_schedule); - timeout = jiffies + (timeout_int) /8 ; +spin_lock_irqsave (&qp->s_lock, flags); } }while (make_req (qp)); + +spin_unlock_irqrestore (&qp->s_lock, flags); }/*
drivers/staging/rdma/hfi1/uc.c +9 -12
@@ -59,6 +59,8 @@* hfi1_make_uc_req - construct a request packet (SEND, RDMA write) * @qp: a pointer to the QP * +* Assume s_lock is held. +* * Return 1 if constructed; otherwise, return 0. */ int hfi1_make_uc_req (struct rvt_qp *qp)
@@ -66,7 +68,6 @@ int hfi1_make_uc_req(struct rvt_qp *qp)struct hfi1_qp_priv *priv = qp->priv;struct hfi1_other_headers *ohdr;struct rvt_swqe *wqe; -unsigned long flags;u32 hwords =5 ;u32 bth0 =0 ;u32 len;
@@ -74,13 +75,12 @@ int hfi1_make_uc_req(struct rvt_qp *qp)int ret =0 ;int middle =0 ; -spin_lock_irqsave (&qp->s_lock, flags); -if (!(ib_rvt_state_ops[qp->state] &RVT_PROCESS_SEND_OK )) {if (!(ib_rvt_state_ops[qp->state] &RVT_FLUSH_SEND )) goto bail;/* We are in the error state, flush the work request. */ -if (qp->s_last == qp->s_head) +smp_read_barrier_depends ();/* see post_one_send() */ +if (qp->s_last ==ACCESS_ONCE (qp->s_head)) goto bail;/* If DMAs are in progress, we can't flush immediately. */ if (atomic_read (&priv->s_iowait.sdma_busy)) {
@@ -106,15 +106,15 @@ int hfi1_make_uc_req(struct rvt_qp *qp) RVT_PROCESS_NEXT_SEND_OK)) goto bail;/* Check if send work queue is empty. */ -if (qp->s_cur == qp->s_head) { +smp_read_barrier_depends ();/* see post_one_send() */ +if (qp->s_cur ==ACCESS_ONCE (qp->s_head)) {clear_ahg (qp); goto bail; }/* * Start a new request. */ - wqe->psn = qp->s_next_psn; - qp->s_psn = qp->s_next_psn; + qp->s_psn = wqe->psn; qp->s_sge.sge = wqe->sg_list[0 ]; qp->s_sge.sg_list = wqe->sg_list +1 ; qp->s_sge.num_sge = wqe->wr.num_sge;
@@ -235,15 +235,12 @@ int hfi1_make_uc_req(struct rvt_qp *qp) qp->s_cur_sge = &qp->s_sge; qp->s_cur_size = len;hfi1_make_ruc_header (qp, ohdr, bth0 | (qp->s_state <<24 ), -mask_psn (qp->s_next_psn++), middle); +mask_psn (qp->s_psn++), middle); done: - ret =1 ; - goto unlock; +return 1 ; bail: qp->s_flags &= ~RVT_S_BUSY ; -unlock: -spin_unlock_irqrestore (&qp->s_lock, flags);return ret; }
drivers/staging/rdma/hfi1/ud.c +11 -11
@@ -261,6 +261,8 @@ drop:* hfi1_make_ud_req - construct a UD request packet * @qp: the QP * +* Assume s_lock is held. +* * Return 1 if constructed; otherwise, return 0. */ int hfi1_make_ud_req (struct rvt_qp *qp)
@@ -271,7 +273,6 @@ int hfi1_make_ud_req(struct rvt_qp *qp)struct hfi1_pportdata *ppd;struct hfi1_ibport *ibp;struct rvt_swqe *wqe; -unsigned long flags;u32 nwords;u32 extra_bytes;u32 bth0;
@@ -281,13 +282,12 @@ int hfi1_make_ud_req(struct rvt_qp *qp)int next_cur;u8 sc5; -spin_lock_irqsave (&qp->s_lock, flags); -if (!(ib_rvt_state_ops[qp->state] &RVT_PROCESS_NEXT_SEND_OK )) {if (!(ib_rvt_state_ops[qp->state] &RVT_FLUSH_SEND )) goto bail;/* We are in the error state, flush the work request. */ -if (qp->s_last == qp->s_head) +smp_read_barrier_depends ();/* see post_one_send */ +if (qp->s_last ==ACCESS_ONCE (qp->s_head)) goto bail;/* If DMAs are in progress, we can't flush immediately. */ if (atomic_read (&priv->s_iowait.sdma_busy)) {
@@ -299,7 +299,9 @@ int hfi1_make_ud_req(struct rvt_qp *qp) goto done; } -if (qp->s_cur == qp->s_head) +/* see post_one_send() */ +smp_read_barrier_depends (); +if (qp->s_cur ==ACCESS_ONCE (qp->s_head)) goto bail; wqe =rvt_get_swqe_ptr (qp, qp->s_cur);
@@ -317,6 +319,7 @@ int hfi1_make_ud_req(struct rvt_qp *qp)if (unlikely (!loopback && (lid == ppd->lid || (lid ==be16_to_cpu (IB_LID_PERMISSIVE ) && qp->ibqp.qp_type ==IB_QPT_GSI )))) { +unsigned long flags;/* * If DMAs are in progress, we can't generate * a completion for the loopback packet since
@@ -329,6 +332,7 @@ int hfi1_make_ud_req(struct rvt_qp *qp) goto bail; } qp->s_cur = next_cur; +local_irq_save (flags);spin_unlock_irqrestore (&qp->s_lock, flags);ud_loopback (qp, wqe);spin_lock_irqsave (&qp->s_lock, flags);
@@ -408,7 +412,7 @@ int hfi1_make_ud_req(struct rvt_qp *qp) bth0 |=hfi1_get_pkey (ibp, qp->s_pkey_index); ohdr->bth[0 ] =cpu_to_be32 (bth0); ohdr->bth[1 ] =cpu_to_be32 (wqe->ud_wr.remote_qpn); - ohdr->bth[2 ] =cpu_to_be32 (mask_psn (qp->s_next_psn++)); + ohdr->bth[2 ] =cpu_to_be32 (mask_psn (wqe->psn));/* * Qkeys with the high order bit set mean use the * qkey from the QP context instead of the WR (see 10.2.5).
@@ -423,13 +427,9 @@ int hfi1_make_ud_req(struct rvt_qp *qp) priv->s_hdr->sde =NULL ; done: - ret =1 ; - goto unlock; - +return 1 ; bail: qp->s_flags &= ~RVT_S_BUSY ; -unlock: -spin_unlock_irqrestore (&qp->s_lock, flags);return ret; }
drivers/staging/rdma/hfi1/verbs.c +2 -1
@@ -1533,6 +1533,7 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd) dd->verbs_dev.rdi.driver_f.notify_qp_reset = notify_qp_reset; dd->verbs_dev.rdi.driver_f.do_send = hfi1_do_send; dd->verbs_dev.rdi.driver_f.schedule_send = hfi1_schedule_send; + dd->verbs_dev.rdi.driver_f.schedule_send_no_lock = _hfi1_schedule_send; dd->verbs_dev.rdi.driver_f.get_pmtu_from_attr = get_pmtu_from_attr; dd->verbs_dev.rdi.driver_f.notify_error_qp = notify_error_qp; dd->verbs_dev.rdi.driver_f.flush_qp_waiters = flush_qp_waiters;
@@ -1543,7 +1544,7 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd) dd->verbs_dev.rdi.driver_f.mtu_to_path_mtu = mtu_to_path_mtu; dd->verbs_dev.rdi.driver_f.check_modify_qp = hfi1_check_modify_qp; dd->verbs_dev.rdi.driver_f.modify_qp = hfi1_modify_qp; - dd->verbs_dev.rdi.driver_f.check_send_wr = hfi1_check_send_wr; + dd->verbs_dev.rdi.driver_f.check_send_wqe = hfi1_check_send_wqe;/* completeion queue */ snprintf(dd->verbs_dev.rdi.dparms.cq_name,
drivers/staging/rdma/hfi1/verbs.h +1 -1
@@ -427,7 +427,7 @@ int hfi1_check_modify_qp(struct rvt_qp *qp, struct ib_qp_attr *attr,void hfi1_modify_qp (struct rvt_qp *qp,struct ib_qp_attr *attr,int attr_mask,struct ib_udata *udata); -int hfi1_check_send_wr (struct rvt_qp *qp,struct ib_send_wr *wr); +int hfi1_check_send_wqe (struct rvt_qp *qp,struct rvt_swqe *wqe);int hfi1_ruc_check_hdr (struct hfi1_ibport *ibp,struct hfi1_ib_header *hdr,int has_grh,struct rvt_qp *qp,u32 bth0);
include/rdma/rdma_vt.h +3 -1
@@ -220,6 +220,7 @@ struct rvt_ah { };struct rvt_dev_info ; +struct rvt_swqe ;struct rvt_driver_provided {/* * The work to create port files in /sys/class Infiniband is different
@@ -240,6 +241,7 @@ struct rvt_driver_provided {void (*qp_priv_free)(struct rvt_dev_info *rdi,struct rvt_qp *qp);void (*notify_qp_reset)(struct rvt_qp *qp);void (*schedule_send)(struct rvt_qp *qp); +void (*schedule_send_no_lock)(struct rvt_qp *qp);void (*do_send)(struct rvt_qp *qp);int (*get_pmtu_from_attr)(struct rvt_dev_info *rdi,struct rvt_qp *qp,struct ib_qp_attr *attr);
@@ -273,7 +275,7 @@ struct rvt_driver_provided {void (*modify_qp)(struct rvt_qp *qp,struct ib_qp_attr *attr,int attr_mask,struct ib_udata *udata); -int (*check_send_wr)(struct rvt_qp *qp,struct ib_send_wr *wr); +int (*check_send_wqe)(struct rvt_qp *qp,struct rvt_swqe *wqe);void (*notify_create_mad_agent)(struct rvt_dev_info *rdi,int port_idx);void (*notify_free_mad_agent)(struct rvt_dev_info *rdi,int port_idx);
include/rdma/rdmavt_qp.h +9 -4
@@ -250,11 +250,12 @@ struct rvt_qp {enum ib_mtu path_mtu;int srate_mbps;/* s_srate (below) converted to Mbit/s */ u32 remote_qpn; -u32 pmtu;/* decoded from path_mtu */ u32 qkey;/* QKEY for this QP (for UD or RD) */ u32 s_size;/* send work queue size */ u32 s_ahgpsn;/* set to the psn in the copy of the header */ +u16 pmtu;/* decoded from path_mtu */ +u8 log_pmtu;/* shift for pmtu */ u8 state;/* QP state */ u8 allowed_ops;/* high order bits of allowed opcodes */ u8 qp_access_flags;
@@ -299,6 +300,13 @@ struct rvt_qp {struct rvt_sge_state r_sge;/* current receive data */ struct rvt_rq r_rq;/* receive work queue */ +/* post send line */ +spinlock_t s_hlock____cacheline_aligned_in_smp ; +u32 s_head;/* new entries added here */ +u32 s_next_psn;/* PSN for next request */ +u32 s_avail;/* number of entries avail */ +u32 s_ssn;/* SSN of tail entry */ +spinlock_t s_lock____cacheline_aligned_in_smp ;struct rvt_sge_state *s_cur_sge;u32 s_flags;
@@ -308,19 +316,16 @@ struct rvt_qp {u32 s_cur_size;/* size of send packet in bytes */ u32 s_len;/* total length of s_sge */ u32 s_rdma_read_len;/* total length of s_rdma_read_sge */ -u32 s_next_psn;/* PSN for next request */ u32 s_last_psn;/* last response PSN processed */ u32 s_sending_psn;/* lowest PSN that is being sent */ u32 s_sending_hpsn;/* highest PSN that is being sent */ u32 s_psn;/* current packet sequence number */ u32 s_ack_rdma_psn;/* PSN for sending RDMA read responses */ u32 s_ack_psn;/* PSN for acking sends and RDMA writes */ -u32 s_head;/* new entries added here */ u32 s_tail;/* next entry to process */ u32 s_cur;/* current work queue entry */ u32 s_acked;/* last un-ACK'ed entry */ u32 s_last;/* last completed entry */ -u32 s_ssn;/* SSN of tail entry */ u32 s_lsn;/* limit sequence number (credit) */ u16 s_hdrwords;/* size of s_hdr in 32 bit words */ u16 s_rdma_ack_cnt;
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 3/12 IB/rdmavt: Add trace and error print statements in post_one_wr
In reply to a message not in the archiveFrom: Harish Chegondi <[email protected]>
These trace and error print statements would help in debugging issues which are caused due to messed up QP ring buffer pointers.
--- drivers/infiniband/sw/rdmavt/qp.c | 8 +++- drivers/infiniband/sw/rdmavt/trace.h | 70 ++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletions(-)
drivers/infiniband/sw/rdmavt/qp.c +7 -1
@@ -1441,7 +1441,12 @@ static int rvt_post_one_wr(struct rvt_qp *qp, struct ib_send_wr *wr)/* check for avail */ if (unlikely (!qp->s_avail)) { qp->s_avail =qp_get_savail (qp); -WARN_ON (qp->s_avail > (qp->s_size -1 )); +if (WARN_ON (qp->s_avail > (qp->s_size -1 ))) +rvt_pr_err (rdi, +"More avail entries than QP RB size.\nQP: %u, size: %u, avail: %u\nhead: %u, tail: %u, cur: %u, acked: %u, last: %u" , + qp->ibqp.qp_num, qp->s_size, qp->s_avail, + qp->s_head, qp->s_tail, qp->s_cur, + qp->s_acked, qp->s_last);if (!qp->s_avail)return -ENOMEM ; }
@@ -1510,6 +1515,7 @@ static int rvt_post_one_wr(struct rvt_qp *qp, struct ib_send_wr *wr) wqe->lpsn = wqe->psn + (wqe->length ? ((wqe->length -1 ) >> log_pmtu) :0 ); qp->s_next_psn = wqe->lpsn +1 ; +trace_rvt_post_one_wr (qp, wqe);smp_wmb ();/* see request builders */ qp->s_avail--; qp->s_head = next;
drivers/infiniband/sw/rdmavt/trace.h +70 -0
82 lines not on this page · raw message
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/12 staging/rdma/hfi1: Put QPs into error state after SL->SC table changes
In reply to a message not in the archiveFrom: Kaike Wan <[email protected]>
If an SL->SC mapping table change occurs after an RC/UC QP is created, there is no mechanism to change the SC nor the VL for that QP. The fix is to place the QP into error state so that ULP can recreate the QP with the new SL->SC mapping.
--- drivers/staging/rdma/hfi1/mad.c | 13 ++++++++-- drivers/staging/rdma/hfi1/qp.c | 52 +++++++++++++++++++++++++++++++++++++++ drivers/staging/rdma/hfi1/qp.h | 1 + 3 files changed, 64 insertions(+), 2 deletions(-)
drivers/staging/rdma/hfi1/mad.c +11 -2
@@ -55,6 +55,7 @@#include "hfi.h" #include "mad.h" #include "trace.h" +#include "qp.h" /* the reset value from the FM is supposed to be 0xffff, handle both */ #define OPA_LINK_WIDTH_RESET_OLD 0x0fff
@@ -1517,14 +1518,22 @@ static int __subn_set_opa_sl_to_sc(struct opa_smp *smp, u32 am, u8 *data,struct hfi1_ibport *ibp =to_iport (ibdev, port);u8 *p = data;int i; +u8 sc;if (am) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); } -for (i =0 ; i <ARRAY_SIZE (ibp->sl_to_sc); i++) - ibp->sl_to_sc[i] = *p++; +for (i =0 ; i <ARRAY_SIZE (ibp->sl_to_sc); i++) { + sc = *p++; +if (ibp->sl_to_sc[i] != sc) { + ibp->sl_to_sc[i] = sc; + +/* Put all stale qps into error state */ +hfi1_error_port_qps (ibp, i); + } + }return __subn_get_opa_sl_to_sc (smp, am, data, ibdev, port, resp_len); }
drivers/staging/rdma/hfi1/qp.c +52 -0
55 lines not on this page · raw message
drivers/staging/rdma/hfi1/qp.h +1 -0
@@ -158,4 +158,5 @@ void stop_send_queue(struct rvt_qp *qp);void quiesce_qp (struct rvt_qp *qp);u32 mtu_from_qp (struct rvt_dev_info *rdi,struct rvt_qp *qp,u32 pmtu);int mtu_to_path_mtu (u32 mtu); +void hfi1_error_port_qps (struct hfi1_ibport *ibp,u8 sl);#endif /* _QP_H */
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 5/12 IB/rdmavt: Clean up comments and add more documentation
In reply to a message not in the archiveAdd, remove, and otherwise clean up existing comments that are leftover from the initial code postings of rdmavt. Many of the comments were added to provide an idea on the direction we were thinking of going. Now that the design is solidified make a pass over and clean everything up. Also add details where lacking.
Ensure all non static functions have nano comments.
--- drivers/infiniband/sw/rdmavt/ah.c | 27 +++++++++++++++ drivers/infiniband/sw/rdmavt/cq.c | 30 +++++++++++----- drivers/infiniband/sw/rdmavt/mad.c | 30 +++++++++++----- drivers/infiniband/sw/rdmavt/mcast.c | 34 +++++++++++++++++-- drivers/infiniband/sw/rdmavt/mmap.c | 28 ++++++++++++--- drivers/infiniband/sw/rdmavt/mr.c | 38 ++++++++++++++------- drivers/infiniband/sw/rdmavt/pd.c | 16 +++++++++ drivers/infiniband/sw/rdmavt/qp.c | 57 ++++++++++++++++++++++++++++--- drivers/infiniband/sw/rdmavt/srq.c | 21 +++++++++++- drivers/infiniband/sw/rdmavt/vt.c | 62 +++++++++++++++++++++++++++------- include/rdma/rdma_vt.h | 15 -------- 11 files changed, 280 insertions(+), 78 deletions(-)
drivers/infiniband/sw/rdmavt/ah.c +27 -0
@@ -53,6 +53,11 @@* rvt_check_ah - validate the attributes of AH * @ibdev: the ib device * @ah_attr: the attributes of the AH +* +* If driver supports a more detailed check_ah function call back to it +* otherwise just check the basics. +* +* Return: 0 on success */ int rvt_check_ah (struct ib_device *ibdev,struct ib_ah_attr *ah_attr)
@@ -95,6 +100,8 @@ EXPORT_SYMBOL(rvt_check_ah);* @ah_attr: the attributes of the AH * * This may be called from interrupt context. +* +* Return: newly allocated ah */ struct ib_ah *rvt_create_ah (struct ib_pd *pd,struct ib_ah_attr *ah_attr)
@@ -129,6 +136,12 @@ struct ib_ah *rvt_create_ah(struct ib_pd *pd,return &ah->ibah; } +/** +* rvt_destory_ah - Destory an address handle +* @ibah: address handle +* +* Return: 0 on success +*/ int rvt_destroy_ah (struct ib_ah *ibah) {struct rvt_dev_info *dev =ib_to_rvt (ibah->device);
@@ -147,6 +160,13 @@ int rvt_destroy_ah(struct ib_ah *ibah)return 0 ; } +/** +* rvt_modify_ah - modify an ah with given attrs +* @ibah: address handle to modify +* @ah_attr: attrs to apply +* +* Return: 0 on success +*/ int rvt_modify_ah (struct ib_ah *ibah,struct ib_ah_attr *ah_attr) {struct rvt_ah *ah =ibah_to_rvtah (ibah);
@@ -159,6 +179,13 @@ int rvt_modify_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)return 0 ; } +/** +* rvt_query_ah - return attrs for ah +* @ibah: address handle to query +* @ah_attr: return info in this +* +* Return: always 0 +*/ int rvt_query_ah (struct ib_ah *ibah,struct ib_ah_attr *ah_attr) {struct rvt_ah *ah =ibah_to_rvtah (ibah);
drivers/infiniband/sw/rdmavt/cq.c +20 -10
@@ -173,10 +173,10 @@ static void send_complete(struct kthread_work *work)* @context: unused by the QLogic_IB driver * @udata: user data for libibverbs.so * -* Returns a pointer to the completion queue or negative errno values -* for failure. -* * Called by ib_create_cq() in the generic verbs code. +* +* Return: pointer to the completion queue or negative errno values +* for failure. */ struct ib_cq *rvt_create_cq(struct ib_device *ibdev, const struct ib_cq_init_attr *attr,
@@ -286,9 +286,9 @@ done:* rvt_destroy_cq - destroy a completion queue * @ibcq: the completion queue to destroy. * -* Returns 0 for success. -* * Called by ib_destroy_cq() in the generic verbs code. +* +* Return: always 0 */ int rvt_destroy_cq (struct ib_cq *ibcq) {
@@ -313,10 +313,10 @@ int rvt_destroy_cq(struct ib_cq *ibcq)* @ibcq: the completion queue * @notify_flags: the type of notification to request * -* Returns 0 for success. -* * This may be called from interrupt context. Also called by * ib_req_notify_cq() in the generic verbs code. +* +* Return: 0 for success. */ int rvt_req_notify_cq (struct ib_cq *ibcq,enum ib_cq_notify_flags notify_flags) {
@@ -345,7 +345,7 @@ int rvt_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags)* rvt_resize_cq - change the size of the CQ * @ibcq: the completion queue * -* Returns 0 for success. +* Return: 0 for success. */ int rvt_resize_cq (struct ib_cq *ibcq,int cqe,struct ib_udata *udata) {
@@ -456,10 +456,10 @@ bail_free:* @num_entries: the maximum number of entries to return * @entry: pointer to array where work completions are placed * -* Returns the number of completion entries polled. -* * This may be called from interrupt context. Also called by ib_poll_cq() * in the generic verbs code. +* +* Return: the number of completion entries polled. */ int rvt_poll_cq (struct ib_cq *ibcq,int num_entries,struct ib_wc *entry) {
@@ -496,6 +496,12 @@ int rvt_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)return npolled; } +/** +* rvt_driver_cq_init - Init cq resources on behalf of driver +* @rdi: rvt dev structure +* +* Return: 0 on success +*/ int rvt_driver_cq_init (struct rvt_dev_info *rdi) {int ret =0 ;
@@ -530,6 +536,10 @@ int rvt_driver_cq_init(struct rvt_dev_info *rdi)return ret; } +/** +* rvt_cq_exit - tear down cq reources +* @rdi: rvt dev structure +*/ void rvt_cq_exit (struct rvt_dev_info *rdi) {struct kthread_worker *worker;
drivers/infiniband/sw/rdmavt/mad.c +20 -10
@@ -59,14 +59,13 @@* @in_mad: the incoming MAD * @out_mad: any outgoing MAD reply * -* Returns IB_MAD_RESULT_SUCCESS if this is a MAD that we are not -* interested in processing. -* * Note that the verbs framework has already done the MAD sanity checks, * and hop count/pointer updating for IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE * MADs. * * This is called by the ib_mad module. +* +* Return: IB_MAD_RESULT_SUCCESS or error */ int rvt_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, const struct ib_wc *in_wc, const struct ib_grh *in_grh,
@@ -75,13 +74,10 @@ int rvt_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, u16 *out_mad_pkey_index) {/* -* Drivers will need to provide a number of things. For exmaple counters -* will need to be maintained by the driver but shoud live in the rvt -* structure. More study will be needed to finalize the interface -* between drivers and rvt for mad packets. -* -*VT-DRIVER-API: ???? -* +* MAD processing is quite different between hfi1 and qib. Therfore this +* is expected to be provided by the driver. Other drivers in the future +* may chose to implement this but it should not be made into a +* requirement. */ if (ibport_num_to_idx (ibdev, port_num) <0 )return -EINVAL ;
@@ -95,6 +91,14 @@ static void rvt_send_mad_handler(struct ib_mad_agent *agent,ib_free_send_mad (mad_send_wc->send_buf); } +/** +* rvt_create_mad_agents - create mad agents +* @rdi: rvt dev struct +* +* If driver needs to be notified of mad agent creation then call back +* +* Return 0 on success +*/ int rvt_create_mad_agents (struct rvt_dev_info *rdi) {struct ib_mad_agent *agent;
@@ -136,6 +140,12 @@ err:return ret; } +/** +* rvt_free_mad_agents - free up mad agents +* @rdi: rvt dev struct +* +* If driver needs notification of mad agent removal make the call back +*/ void rvt_free_mad_agents (struct rvt_dev_info *rdi) {struct ib_mad_agent *agent;
drivers/infiniband/sw/rdmavt/mcast.c +31 -3
@@ -53,6 +53,12 @@#include "mcast.h" +/** +* rvt_driver_mcast - init resources for multicast +* @rdi: rvt dev struct +* +* This is per device that registers with rdmavt +*/ void rvt_driver_mcast_init (struct rvt_dev_info *rdi) {/*
@@ -130,9 +136,9 @@ static void rvt_mcast_free(struct rvt_mcast *mcast)* @ibp: the IB port structure * @mgid: the multicast GID to search for * -* Returns NULL if not found. -* * The caller is responsible for decrementing the reference count if found. +* +* Return: NULL if not found. */ struct rvt_mcast *rvt_mcast_find (struct rvt_ibport *ibp,union ib_gid *mgid) {
@@ -170,7 +176,7 @@ EXPORT_SYMBOL(rvt_mcast_find);* @mcast: the mcast GID table * @mqp: the QP to attach * -* Return zero if both were added. Return EEXIST if the GID was already in +* Return: zero if both were added. Return EEXIST if the GID was already in * the table but the QP was added. Return ESRCH if the QP was already * attached and neither structure was added. */
@@ -247,6 +253,14 @@ bail:return ret; } +/** +* rvt_attach_mcast - attach a qp to a multicast group +* @ibqp: Infiniband qp +* @igd: multicast guid +* @lid: multicast lid +* +* Return: 0 on success +*/ int rvt_attach_mcast (struct ib_qp *ibqp,union ib_gid *gid,u16 lid) {struct rvt_qp *qp =ibqp_to_rvtqp (ibqp);
@@ -298,6 +312,14 @@ bail_mcast:return ret; } +/** +* rvt_detach_mcast - remove a qp from a multicast group +* @ibqp: Infiniband qp +* @igd: multicast guid +* @lid: multicast lid +* +* Return: 0 on success +*/ int rvt_detach_mcast (struct ib_qp *ibqp,union ib_gid *gid,u16 lid) {struct rvt_qp *qp =ibqp_to_rvtqp (ibqp);
@@ -377,6 +399,12 @@ int rvt_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)return 0 ; } +/** +*rvt_mast_tree_empty - determine if any qps are attached to any mcast group +*@rdi: rvt dev struct +* +* Return: in use count +*/ int rvt_mcast_tree_empty (struct rvt_dev_info *rdi) {int i;
drivers/infiniband/sw/rdmavt/mmap.c +21 -7
@@ -51,6 +51,10 @@#include <asm/pgtable.h> #include "mmap.h" +/** +* rvt_mmap_init - init link list and lock for mem map +* @rdi: rvt dev struct +*/ void rvt_mmap_init (struct rvt_dev_info *rdi) {INIT_LIST_HEAD (&rdi->pending_mmaps);
@@ -78,10 +82,6 @@ void rvt_release_mmap_info(struct kref *ref) }EXPORT_SYMBOL (rvt_release_mmap_info); -/* -* open and close keep track of how many times the CQ is mapped, -* to avoid releasing it. -*/ static void rvt_vma_open (struct vm_area_struct *vma) {struct rvt_mmap_info *ip = vma->vm_private_data;
@@ -105,7 +105,8 @@ static const struct vm_operations_struct rvt_vm_ops = {* rvt_mmap - create a new mmap region * @context: the IB user context of the process making the mmap() call * @vma: the VMA to be initialized -* Return zero if the mmap is OK. Otherwise, return an errno. +* +* Return: zero if the mmap is OK. Otherwise, return an errno. */ int rvt_mmap (struct ib_ucontext *context,struct vm_area_struct *vma) {
@@ -147,8 +148,14 @@ done: }EXPORT_SYMBOL (rvt_mmap); -/* -* Allocate information for hfi1_mmap +/** +* rvt_create_mmap_info - allocate information for hfi1_mmap +* @rdi: rvt dev struct +* @size: size in bytes to map +* @context: user context +* @obj: opaque pointer to a cq, wq etc +* +* Return: rvt_mmap struct on success */ struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi, u32 size,
@@ -180,6 +187,13 @@ struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi, }EXPORT_SYMBOL (rvt_create_mmap_info); +/** +* rvt_update_mmap_info - update a mem map +* @rdi: rvt dev struct +* @ip: mmap info pointer +* @size: size to grow by +* @obj: opaque pointer to cq, wq, etc. +*/ void rvt_update_mmap_info (struct rvt_dev_info *rdi,struct rvt_mmap_info *ip,u32 size,void *obj) {
drivers/infiniband/sw/rdmavt/mr.c +25 -13
@@ -52,8 +52,13 @@#include "vt.h" #include "mr.h" -/* +/** +* rvt_driver_mr_init - Init MR resources per driver +* @rdi: rvt dev struct +* * Do any intilization needed when a driver registers with rdmavt. +* +* Return: 0 on success or errno on failure */ int rvt_driver_mr_init (struct rvt_dev_info *rdi) {
@@ -98,7 +103,10 @@ int rvt_driver_mr_init(struct rvt_dev_info *rdi)return 0 ; } -/* +/** +*rvt_mr_exit: clean up MR +*@rdi: rvt dev structure +* * called when drivers have unregistered or perhaps failed to register with us */ void rvt_mr_exit (struct rvt_dev_info *rdi)
@@ -297,7 +305,7 @@ static void __rvt_free_mr(struct rvt_mr *mr)* @pd: protection domain for this memory region * @acc: access flags * -* Returns the memory region on success, otherwise returns an errno. +* Return: the memory region on success, otherwise returns an errno. * Note that all DMA addresses should be created via the * struct ib_dma_mapping_ops functions (see dma.c). */
@@ -348,7 +356,7 @@ bail:* @mr_access_flags: access flags for this memory region * @udata: unused by the driver * -* Returns the memory region on success, otherwise returns an errno. +* Return: the memory region on success, otherwise returns an errno. */ struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt_addr, int mr_access_flags,
@@ -418,10 +426,11 @@ bail_umem:* rvt_dereg_mr - unregister and free a memory region * @ibmr: the memory region to free * -* Returns 0 on success. * * Note that this is called to free MRs created by rvt_get_dma_mr() * or rvt_reg_user_mr(). +* +* Returns 0 on success. */ int rvt_dereg_mr (struct ib_mr *ibmr) {
@@ -456,7 +465,7 @@ out:* @mr_type: mem region type * @max_num_sg: Max number of segments allowed * -* Return the memory region on success, otherwise return an errno. +* Return: the memory region on success, otherwise return an errno. */ struct ib_mr *rvt_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
@@ -480,7 +489,7 @@ struct ib_mr *rvt_alloc_mr(struct ib_pd *pd,* @mr_access_flags: access flags for this memory region * @fmr_attr: fast memory region attributes * -* Returns the memory region on success, otherwise returns an errno. +* Return: the memory region on success, otherwise returns an errno. */ struct ib_fmr *rvt_alloc_fmr (struct ib_pd *pd,int mr_access_flags,struct ib_fmr_attr *fmr_attr)
@@ -537,6 +546,8 @@ bail:* @iova: the virtual address of the start of the fast memory region * * This may be called from interrupt context. +* +* Return: 0 on success */ int rvt_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
@@ -580,7 +591,7 @@ int rvt_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,* rvt_unmap_fmr - unmap fast memory regions * @fmr_list: the list of fast memory regions to unmap * -* Returns 0 on success. +* Return: 0 on success. */ int rvt_unmap_fmr (struct list_head *fmr_list) {
@@ -605,7 +616,7 @@ int rvt_unmap_fmr(struct list_head *fmr_list)* rvt_dealloc_fmr - deallocate a fast memory region * @ibfmr: the fast memory region to deallocate * -* Returns 0 on success. +* Return: 0 on success. */ int rvt_dealloc_fmr (struct ib_fmr *ibfmr) {
@@ -635,12 +646,13 @@ out:* @sge: SGE to check * @acc: access flags * -* Return 1 if valid and successful, otherwise returns 0. +* Check the IB SGE for validity and initialize our internal version +* of it. +* +* Return: 1 if valid and successful, otherwise returns 0. * * increments the reference count upon success * -* Check the IB SGE for validity and initialize our internal version -* of it. */ int rvt_lkey_ok (struct rvt_lkey_table *rkt,struct rvt_pd *pd,struct rvt_sge *isge,struct ib_sge *sge,int acc)
@@ -733,7 +745,7 @@ EXPORT_SYMBOL(rvt_lkey_ok);* @rkey: rkey to check * @acc: access flags * -* Return 1 if successful, otherwise 0. +* Return: 1 if successful, otherwise 0. * * increments the reference count upon success */
drivers/infiniband/sw/rdmavt/pd.c +16 -0
@@ -48,6 +48,16 @@#include <linux/slab.h> #include "pd.h" +/** +* rvt_alloc_pd - allocate a protection domain +* @ibdev: ib device +* @context: optional user context +* @udata: optional user data +* +* Allocate and keep track of a PD. +* +* Return: 0 on success +*/ struct ib_pd *rvt_alloc_pd (struct ib_device *ibdev,struct ib_ucontext *context,struct ib_udata *udata)
@@ -88,6 +98,12 @@ bail:return ret; } +/** +* rvt_dealloc_pd - Free PD +* @ibpd: Free up PD +* +* Return: always 0 +*/ int rvt_dealloc_pd (struct ib_pd *ibpd) {struct rvt_pd *pd =ibpd_to_rvtpd (ibpd);
drivers/infiniband/sw/rdmavt/qp.c +51 -6
143 lines not on this page · raw message
drivers/infiniband/sw/rdmavt/srq.c +20 -1
@@ -51,7 +51,10 @@#include "srq.h" -/* +/** +* rvt_driver_srq_init - init srq resources on a per driver basis +* @rdi: rvt dev structure +* * Do any initialization needed when a driver registers with rdmavt. */ void rvt_driver_srq_init (struct rvt_dev_info *rdi)
@@ -65,6 +68,8 @@ void rvt_driver_srq_init(struct rvt_dev_info *rdi)* @ibpd: the protection domain of the SRQ to create * @srq_init_attr: the attributes of the SRQ * @udata: data from libibverbs when creating a user SRQ +* +* Return: Allocated srq object */ struct ib_srq *rvt_create_srq(struct ib_pd *ibpd, struct ib_srq_init_attr *srq_init_attr,
@@ -168,6 +173,8 @@ bail_srq:* @attr: the new attributes of the SRQ * @attr_mask: indicates which attributes to modify * @udata: user data for libibverbs.so +* +* Return: 0 on success */ int rvt_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, enum ib_srq_attr_mask attr_mask,
@@ -305,6 +312,12 @@ bail_free:return ret; } +/** rvt_query_srq - query srq data +* @ibsrq: srq to query +* @attr: return info in attr +* +* Return: always 0 +*/ int rvt_query_srq (struct ib_srq *ibsrq,struct ib_srq_attr *attr) {struct rvt_srq *srq =ibsrq_to_rvtsrq (ibsrq);
@@ -315,6 +328,12 @@ int rvt_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr)return 0 ; } +/** +* rvt_destroy_srq - destory an srq +* @ibsrq: srq object to destroy +* +* Return always 0 +*/ int rvt_destroy_srq (struct ib_srq *ibsrq) {struct rvt_srq *srq =ibsrq_to_rvtsrq (ibsrq);
drivers/infiniband/sw/rdmavt/vt.c +49 -13
129 lines not on this page · raw message
include/rdma/rdma_vt.h +0 -15
@@ -146,21 +146,6 @@ struct rvt_ibport {* Things that are driver specific, module parameters in hfi1 and qib */ struct rvt_driver_params { -/* -* driver required fields: -* node_guid -* phys_port_cnt -* dma_device -* owner -* driver optional fields (rvt will provide generic value if blank): -* name -* node_desc -* rvt fields, driver value ignored: -* uverbs_abi_ver -* node_type -* num_comp_vectors -* uverbs_cmd_mask -*/ struct ib_device_attr props;/*
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 6/12 IB/rdmavt: Add per verb driver callback checking
In reply to a message not in the archiveFor each verb validate that all requirements for driver callbacks are met. If a function is called without checking for a valid pointer, it is a required function. Also document what each callback function does.
--- drivers/infiniband/sw/rdmavt/vt.c | 441 ++++++++++++++++++++++++++++++++----- include/rdma/rdma_vt.h | 123 +++++++++- 2 files changed, 489 insertions(+), 75 deletions(-)
drivers/infiniband/sw/rdmavt/vt.c +380 -61
@@ -325,12 +325,375 @@ static int rvt_get_port_immutable(struct ib_device *ibdev, u8 port_num,return 0 ; } -/* -* Check driver override. If driver passes a value use it, otherwise we use our -* own value. -*/ -#define CHECK_DRIVER_OVERRIDE (rdi, x) \ - rdi->ibdev.x = rdi->ibdev.x ? : rvt_ ##x +enum { +MISC , +QUERY_DEVICE , +MODIFY_DEVICE , +QUERY_PORT , +MODIFY_PORT , +QUERY_PKEY , +QUERY_GID , +ALLOC_UCONTEXT , +DEALLOC_UCONTEXT , +GET_PORT_IMMUTABLE , +CREATE_QP , +MODIFY_QP , +DESTROY_QP , +QUERY_QP , +POST_SEND , +POST_RECV , +POST_SRQ_RECV , +CREATE_AH , +DESTROY_AH , +MODIFY_AH , +QUERY_AH , +CREATE_SRQ , +MODIFY_SRQ , +DESTROY_SRQ , +QUERY_SRQ , +ATTACH_MCAST , +DETACH_MCAST , +GET_DMA_MR , +REG_USER_MR , +DEREG_MR , +ALLOC_MR , +ALLOC_FMR , +MAP_PHYS_FMR , +UNMAP_FMR , +DEALLOC_FMR , +MMAP , +CREATE_CQ , +DESTROY_CQ , +POLL_CQ , +REQ_NOTFIY_CQ , +RESIZE_CQ , +ALLOC_PD , +DEALLOC_PD , + _VERB_IDX_MAX/* Must always be last! */ +}; + +static inline int check_driver_override (struct rvt_dev_info *rdi, +size_t offset,void *func) +{ +if (!*(void **)((void *)&rdi->ibdev + offset)) { + *(void **)((void *)&rdi->ibdev + offset) = func; +return 0 ; + } + +return 1 ; +} + +static int check_support (struct rvt_dev_info *rdi,int verb) +{ +switch (verb) { +case MISC : +/* +* These functions are not part of verbs specifically but are +* required for rdmavt to function. +*/ +if ((!rdi->driver_f.port_callback) || + (!rdi->driver_f.get_card_name) || + (!rdi->driver_f.get_pci_dev)) +return -EINVAL ; +break ; + +case QUERY_DEVICE : +check_driver_override (rdi, offsetof(struct ib_device , + query_device), + rvt_query_device); +break ; + +case MODIFY_DEVICE : +/* +* rdmavt does not support modify device currently drivers must +* provide. +*/ +if (!check_driver_override (rdi, offsetof(struct ib_device , + modify_device), + rvt_modify_device)) +return -EOPNOTSUPP ; +break ; + +case QUERY_PORT : +if (!check_driver_override (rdi, offsetof(struct ib_device , + query_port), + rvt_query_port)) +if (!rdi->driver_f.query_port_state) +return -EINVAL ; +break ; + +case MODIFY_PORT : +if (!check_driver_override (rdi, offsetof(struct ib_device , + modify_port), + rvt_modify_port)) +if (!rdi->driver_f.cap_mask_chg || + !rdi->driver_f.shut_down_port) +return -EINVAL ; +break ; + +case QUERY_PKEY : +check_driver_override (rdi, offsetof(struct ib_device , + query_pkey), + rvt_query_pkey); +break ; + +case QUERY_GID : +if (!check_driver_override (rdi, offsetof(struct ib_device , + query_gid), + rvt_query_gid)) +if (!rdi->driver_f.get_guid_be) +return -EINVAL ; +break ; + +case ALLOC_UCONTEXT : +check_driver_override (rdi, offsetof(struct ib_device , + alloc_ucontext), + rvt_alloc_ucontext); +break ; + +case DEALLOC_UCONTEXT : +check_driver_override (rdi, offsetof(struct ib_device , + dealloc_ucontext), + rvt_dealloc_ucontext); +break ; + +case GET_PORT_IMMUTABLE : +check_driver_override (rdi, offsetof(struct ib_device , + get_port_immutable), + rvt_get_port_immutable); +break ; + +case CREATE_QP : +if (!check_driver_override (rdi, offsetof(struct ib_device , + create_qp), + rvt_create_qp)) +if (!rdi->driver_f.qp_priv_alloc || + !rdi->driver_f.qp_priv_free || + !rdi->driver_f.notify_qp_reset || + !rdi->driver_f.flush_qp_waiters || + !rdi->driver_f.stop_send_queue || + !rdi->driver_f.quiesce_qp) +return -EINVAL ; +break ; + +case MODIFY_QP : +if (!check_driver_override (rdi, offsetof(struct ib_device , + modify_qp), + rvt_modify_qp)) +if (!rdi->driver_f.notify_qp_reset || + !rdi->driver_f.schedule_send || + !rdi->driver_f.get_pmtu_from_attr || + !rdi->driver_f.flush_qp_waiters || + !rdi->driver_f.stop_send_queue || + !rdi->driver_f.quiesce_qp || + !rdi->driver_f.notify_error_qp || + !rdi->driver_f.mtu_from_qp || + !rdi->driver_f.mtu_to_path_mtu || + !rdi->driver_f.shut_down_port || + !rdi->driver_f.cap_mask_chg) +return -EINVAL ; +break ; + +case DESTROY_QP : +if (!check_driver_override (rdi, offsetof(struct ib_device , + destroy_qp), + rvt_destroy_qp)) +if (!rdi->driver_f.qp_priv_free || + !rdi->driver_f.notify_qp_reset || + !rdi->driver_f.flush_qp_waiters || + !rdi->driver_f.stop_send_queue || + !rdi->driver_f.quiesce_qp) +return -EINVAL ; +break ; + +case QUERY_QP : +check_driver_override (rdi, offsetof(struct ib_device , + query_qp), + rvt_query_qp); +break ; + +case POST_SEND : +if (!check_driver_override (rdi, offsetof(struct ib_device , + post_send), + rvt_post_send)) +if (!rdi->driver_f.schedule_send || + !rdi->driver_f.do_send) +return -EINVAL ; +break ; + +case POST_RECV : +check_driver_override (rdi, offsetof(struct ib_device , + post_recv), + rvt_post_recv); +break ; +case POST_SRQ_RECV : +check_driver_override (rdi, offsetof(struct ib_device , + post_srq_recv), + rvt_post_srq_recv); +break ; + +case CREATE_AH : +check_driver_override (rdi, offsetof(struct ib_device , + create_ah), + rvt_create_ah); +break ; + +case DESTROY_AH : +check_driver_override (rdi, offsetof(struct ib_device , + destroy_ah), + rvt_destroy_ah); +break ; + +case MODIFY_AH : +check_driver_override (rdi, offsetof(struct ib_device , + modify_ah), + rvt_modify_ah); +break ; + +case QUERY_AH : +check_driver_override (rdi, offsetof(struct ib_device , + query_ah), + rvt_query_ah); +break ; + +case CREATE_SRQ : +check_driver_override (rdi, offsetof(struct ib_device , + create_srq), + rvt_create_srq); +break ; + +case MODIFY_SRQ : +check_driver_override (rdi, offsetof(struct ib_device , + modify_srq), + rvt_modify_srq); +break ; + +case DESTROY_SRQ : +check_driver_override (rdi, offsetof(struct ib_device , + destroy_srq), + rvt_destroy_srq); +break ; + +case QUERY_SRQ : +check_driver_override (rdi, offsetof(struct ib_device , + query_srq), + rvt_query_srq); +break ; + +case ATTACH_MCAST : +check_driver_override (rdi, offsetof(struct ib_device , + attach_mcast), + rvt_attach_mcast); +break ; + +case DETACH_MCAST : +check_driver_override (rdi, offsetof(struct ib_device , + detach_mcast), + rvt_detach_mcast); +break ; + +case GET_DMA_MR : +check_driver_override (rdi, offsetof(struct ib_device , + get_dma_mr), + rvt_get_dma_mr); +break ; + +case REG_USER_MR : +check_driver_override (rdi, offsetof(struct ib_device , + reg_user_mr), + rvt_reg_user_mr); +break ; + +case DEREG_MR : +check_driver_override (rdi, offsetof(struct ib_device , + dereg_mr), + rvt_dereg_mr); +break ; + +case ALLOC_FMR : +check_driver_override (rdi, offsetof(struct ib_device , + alloc_fmr), + rvt_alloc_fmr); +break ; + +case ALLOC_MR : +check_driver_override (rdi, offsetof(struct ib_device , + alloc_mr), + rvt_alloc_mr); +break ; + +case MAP_PHYS_FMR : +check_driver_override (rdi, offsetof(struct ib_device , + map_phys_fmr), + rvt_map_phys_fmr); +break ; + +case UNMAP_FMR : +check_driver_override (rdi, offsetof(struct ib_device , + unmap_fmr), + rvt_unmap_fmr); +break ; + +case DEALLOC_FMR : +check_driver_override (rdi, offsetof(struct ib_device , + dealloc_fmr), + rvt_dealloc_fmr); +break ; + +case MMAP : +check_driver_override (rdi, offsetof(struct ib_device , + mmap), + rvt_mmap); +break ; + +case CREATE_CQ : +check_driver_override (rdi, offsetof(struct ib_device , + create_cq), + rvt_create_cq); +break ; + +case DESTROY_CQ : +check_driver_override (rdi, offsetof(struct ib_device , + destroy_cq), + rvt_destroy_cq); +break ; + +case POLL_CQ : +check_driver_override (rdi, offsetof(struct ib_device , + poll_cq), + rvt_poll_cq); +break ; + +case REQ_NOTFIY_CQ : +check_driver_override (rdi, offsetof(struct ib_device , + req_notify_cq), + rvt_req_notify_cq); +break ; + +case RESIZE_CQ : +check_driver_override (rdi, offsetof(struct ib_device , + resize_cq), + rvt_resize_cq); +break ; + +case ALLOC_PD : +check_driver_override (rdi, offsetof(struct ib_device , + alloc_pd), + rvt_alloc_pd); +break ; + +case DEALLOC_PD : +check_driver_override (rdi, offsetof(struct ib_device , + dealloc_pd), + rvt_dealloc_pd); +break ; + +default : +return -EINVAL ; + } + +return 0 ; +}/** * rvt_register_device - register a driver
@@ -343,35 +706,26 @@ static int rvt_get_port_immutable(struct ib_device *ibdev, u8 port_num,*/ int rvt_register_device (struct rvt_dev_info *rdi) { -/* Validate that drivers have provided the right information */ -int ret =0 ; +int ret =0 , i;if (!rdi)return -EINVAL ; -if ((!rdi->driver_f.port_callback) || - (!rdi->driver_f.get_card_name) || - (!rdi->driver_f.get_pci_dev) || - (!rdi->driver_f.check_ah)) { -pr_err ("Driver not supporting req func\n" ); -return -EINVAL ; - } +/* +* Check to ensure drivers have setup the required helpers for the verbs +* they want rdmavt to handle +*/ +for (i =0 ; i < _VERB_IDX_MAX; i++) +if (check_support (rdi, i)) { +pr_err ("Driver support req not met at %d\n" , i); +return -EINVAL ; + } +/* Once we get past here we can use rvt_pr macros and tracepoints */ trace_rvt_dbg (rdi,"Driver attempting registration" );rvt_mmap_init (rdi); -/* Dev Ops */ -CHECK_DRIVER_OVERRIDE (rdi, query_device); -CHECK_DRIVER_OVERRIDE (rdi, modify_device); -CHECK_DRIVER_OVERRIDE (rdi, query_port); -CHECK_DRIVER_OVERRIDE (rdi, modify_port); -CHECK_DRIVER_OVERRIDE (rdi, query_pkey); -CHECK_DRIVER_OVERRIDE (rdi, query_gid); -CHECK_DRIVER_OVERRIDE (rdi, alloc_ucontext); -CHECK_DRIVER_OVERRIDE (rdi, dealloc_ucontext); -CHECK_DRIVER_OVERRIDE (rdi, get_port_immutable); -/* Queue Pairs */ ret =rvt_driver_qp_init (rdi);if (ret) {
@@ -379,33 +733,15 @@ int rvt_register_device(struct rvt_dev_info *rdi)return -EINVAL ; } -CHECK_DRIVER_OVERRIDE (rdi, create_qp); -CHECK_DRIVER_OVERRIDE (rdi, modify_qp); -CHECK_DRIVER_OVERRIDE (rdi, destroy_qp); -CHECK_DRIVER_OVERRIDE (rdi, query_qp); -CHECK_DRIVER_OVERRIDE (rdi, post_send); -CHECK_DRIVER_OVERRIDE (rdi, post_recv); -CHECK_DRIVER_OVERRIDE (rdi, post_srq_recv); -/* Address Handle */ -CHECK_DRIVER_OVERRIDE (rdi, create_ah); -CHECK_DRIVER_OVERRIDE (rdi, destroy_ah); -CHECK_DRIVER_OVERRIDE (rdi, modify_ah); -CHECK_DRIVER_OVERRIDE (rdi, query_ah);spin_lock_init (&rdi->n_ahs_lock); rdi->n_ahs_allocated =0 ;/* Shared Receive Queue */ -CHECK_DRIVER_OVERRIDE (rdi, create_srq); -CHECK_DRIVER_OVERRIDE (rdi, modify_srq); -CHECK_DRIVER_OVERRIDE (rdi, destroy_srq); -CHECK_DRIVER_OVERRIDE (rdi, query_srq);rvt_driver_srq_init (rdi);/* Multicast */ rvt_driver_mcast_init (rdi); -CHECK_DRIVER_OVERRIDE (rdi, attach_mcast); -CHECK_DRIVER_OVERRIDE (rdi, detach_mcast);/* Mem Region */ ret =rvt_driver_mr_init (rdi);
@@ -414,35 +750,18 @@ int rvt_register_device(struct rvt_dev_info *rdi) goto bail_no_mr; } -CHECK_DRIVER_OVERRIDE (rdi, get_dma_mr); -CHECK_DRIVER_OVERRIDE (rdi, reg_user_mr); -CHECK_DRIVER_OVERRIDE (rdi, dereg_mr); -CHECK_DRIVER_OVERRIDE (rdi, alloc_mr); -CHECK_DRIVER_OVERRIDE (rdi, alloc_fmr); -CHECK_DRIVER_OVERRIDE (rdi, map_phys_fmr); -CHECK_DRIVER_OVERRIDE (rdi, unmap_fmr); -CHECK_DRIVER_OVERRIDE (rdi, dealloc_fmr); -CHECK_DRIVER_OVERRIDE (rdi, mmap); -/* Completion queues */ ret =rvt_driver_cq_init (rdi);if (ret) {pr_err ("Error in driver CQ init.\n" ); goto bail_mr; } -CHECK_DRIVER_OVERRIDE (rdi, create_cq); -CHECK_DRIVER_OVERRIDE (rdi, destroy_cq); -CHECK_DRIVER_OVERRIDE (rdi, poll_cq); -CHECK_DRIVER_OVERRIDE (rdi, req_notify_cq); -CHECK_DRIVER_OVERRIDE (rdi, resize_cq);/* DMA Operations */ rdi->ibdev.dma_ops = rdi->ibdev.dma_ops ? : &rvt_default_dma_mapping_ops;/* Protection Domain */ -CHECK_DRIVER_OVERRIDE (rdi, alloc_pd); -CHECK_DRIVER_OVERRIDE (rdi, dealloc_pd);spin_lock_init (&rdi->n_pds_lock); rdi->n_pds_allocated =0 ;
include/rdma/rdma_vt.h +109 -14
171 lines not on this page · raw message
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 7/12 IB/qib: Setup notify free/create mad agent callbacks for rdmavt
In reply to a message not in the archiveQib needs to be notified when mad agents are created and freed, there is some counter maintenance that needs to be performed. Add those callbacks at registration time with rdmavt.
--- drivers/infiniband/hw/qib/qib_verbs.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
drivers/infiniband/hw/qib/qib_verbs.c +4 -0
@@ -1682,6 +1682,10 @@ int qib_register_ib_device(struct qib_devdata *dd) dd->verbs_dev.rdi.driver_f.query_port_state = qib_query_port; dd->verbs_dev.rdi.driver_f.shut_down_port = qib_shut_down_port; dd->verbs_dev.rdi.driver_f.cap_mask_chg = qib_cap_mask_chg; + dd->verbs_dev.rdi.driver_f.notify_create_mad_agent = + qib_notify_create_mad_agent; + dd->verbs_dev.rdi.driver_f.notify_free_mad_agent = + qib_notify_free_mad_agent; dd->verbs_dev.rdi.dparms.max_rdma_atomic =QIB_MAX_RDMA_ATOMIC ; dd->verbs_dev.rdi.driver_f.get_guid_be = qib_get_guid_be;
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 8/12 IB/qib,rdmavt: Move smi_ah to qib
In reply to a message not in the archiveRdmavt adopted an smi_ah from qib which is not needed by hfi1. Move this back to qib and get it out of the common library.
--- drivers/infiniband/hw/qib/qib_iba7322.c | 10 +++++----- drivers/infiniband/hw/qib/qib_verbs.h | 1 + include/rdma/rdma_vt.h | 1 - 3 files changed, 6 insertions(+), 6 deletions(-)
drivers/infiniband/hw/qib/qib_iba7322.c +5 -5
@@ -2910,8 +2910,8 @@ static void qib_setup_7322_cleanup(struct qib_devdata *dd)spin_unlock_irqrestore (&dd->cspec->gpio_lock, flags);qib_qsfp_deinit (&dd->pport[i].cpspec->qsfp_data); } -if (dd->pport[i].ibport_data.rvp.smi_ah) -ib_destroy_ah (&dd->pport[i].ibport_data.rvp.smi_ah->ibah); +if (dd->pport[i].ibport_data.smi_ah) +ib_destroy_ah (&dd->pport[i].ibport_data.smi_ah->ibah); } }
@@ -5507,7 +5507,7 @@ static void try_7322_ipg(struct qib_pportdata *ppd)if (IS_ERR (send_buf)) goto retry; -if (!ibp->rvp.smi_ah) { +if (!ibp->smi_ah) {struct ib_ah *ah; ah =qib_create_qp0_ah (ibp,be16_to_cpu (IB_LID_PERMISSIVE ));
@@ -5515,11 +5515,11 @@ static void try_7322_ipg(struct qib_pportdata *ppd) ret =PTR_ERR (ah); else { send_buf->ah = ah; - ibp->rvp.smi_ah =ibah_to_rvtah (ah); + ibp->smi_ah =ibah_to_rvtah (ah); ret =0 ; } }else { - send_buf->ah = &ibp->rvp.smi_ah->ibah; + send_buf->ah = &ibp->smi_ah->ibah; ret =0 ; }
drivers/infiniband/hw/qib/qib_verbs.h +1 -0
@@ -219,6 +219,7 @@ struct qib_pma_counters {struct qib_ibport {struct rvt_ibport rvp; +struct rvt_ah *smi_ah;__be64 guids[QIB_GUIDS_PER_PORT -1 ];/* writable GUIDs */ struct qib_pma_counters __percpu *pmastats;u64 z_unicast_xmit;/* starting count for PMA */
include/rdma/rdma_vt.h +0 -1
@@ -137,7 +137,6 @@ struct rvt_ibport {u16 *pkey_table;struct rvt_ah *sm_ah; -struct rvt_ah *smi_ah; };#define RVT_CQN_MAX 16/* maximum length of cq name */
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 9/12 IB/rdmavt: Remove RVT_FLAGs
In reply to a message not in the archiveWhile hfi1 and qib were still supporting bits and pieces of core verbs components there needed to be a way to convey if rdmavt should handle allocation and initialize of resources like the queue pair table. Now that all of this is moved into rdmavt there is no need for these flags. They are no longer used in the drivers.
--- drivers/infiniband/sw/rdmavt/cq.c | 5 ----- drivers/infiniband/sw/rdmavt/mr.c | 5 ----- drivers/infiniband/sw/rdmavt/qp.c | 8 -------- include/rdma/rdma_vt.h | 10 ---------- 4 files changed, 0 insertions(+), 28 deletions(-)
drivers/infiniband/sw/rdmavt/cq.c +0 -5
@@ -508,11 +508,6 @@ int rvt_driver_cq_init(struct rvt_dev_info *rdi)int cpu;struct task_struct *task; -if (rdi->flags &RVT_FLAG_CQ_INIT_DRIVER ) { -rvt_pr_info (rdi,"Driver is doing CQ init.\n" ); -return 0 ; - } -if (rdi->worker)return 0 ; rdi->worker =kzalloc (sizeof (*rdi->worker),GFP_KERNEL );
drivers/infiniband/sw/rdmavt/mr.c +0 -5
@@ -66,11 +66,6 @@ int rvt_driver_mr_init(struct rvt_dev_info *rdi)unsigned lk_tab_size;int i; -if (rdi->flags &RVT_FLAG_MR_INIT_DRIVER ) { -rvt_pr_info (rdi,"Driver is doing MR init.\n" ); -return 0 ; - } -/* * The top hfi1_lkey_table_size bits are used to index the * table. The lower 8 bits can be owned by the user (copied from
drivers/infiniband/sw/rdmavt/qp.c +0 -8
@@ -173,11 +173,6 @@ int rvt_driver_qp_init(struct rvt_dev_info *rdi)int i;int ret = -ENOMEM ; -if (rdi->flags &RVT_FLAG_QP_INIT_DRIVER ) { -rvt_pr_info (rdi,"Driver is doing QP init.\n" ); -return 0 ; - } -if (!rdi->dparms.qp_table_size)return -EINVAL ;
@@ -284,9 +279,6 @@ void rvt_qp_exit(struct rvt_dev_info *rdi)if (!rdi->qp_dev)return ; -if (rdi->flags &RVT_FLAG_QP_INIT_DRIVER ) -return ;/* driver did the qp init so nothing else to do */ -kfree (rdi->qp_dev->qp_table);free_qpn_table (&rdi->qp_dev->qpn_table);kfree (rdi->qp_dev);
include/rdma/rdma_vt.h +0 -10
@@ -60,16 +60,6 @@#include <rdma/rdmavt_mr.h> #include <rdma/rdmavt_qp.h> -/* -* For some of the IBTA objects there will likely be some -* initializations required. We need flags to determine whether it is OK -* for rdmavt to do this or not. This does not imply any functions of a -* partiuclar IBTA object are overridden. -*/ -#define RVT_FLAG_MR_INIT_DRIVER BIT(1) -#define RVT_FLAG_QP_INIT_DRIVER BIT(2) -#define RVT_FLAG_CQ_INIT_DRIVER BIT(3) -#define RVT_MAX_PKEY_VALUES 16struct rvt_ibport {
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 10/12 IB/rdmavt: Remove signal_supported and comments
In reply to a message not in the archiveInitially it was intended that rdmavt would support some signaling between the underlying driver and itself. However this turned out to be unnecessary for qib and hfi1. If we need to add something like this in later to support another driver we should do it then. As of now this essentially dead code so remove it.
--- include/rdma/rdma_vt.h | 18 ------------------ 1 files changed, 0 insertions(+), 18 deletions(-)
include/rdma/rdma_vt.h +0 -18
@@ -138,24 +138,6 @@ struct rvt_driver_params {struct ib_device_attr props;/* -* Drivers will need to support a number of notifications to rvt in -* accordance with certain events. This structure should contain a mask -* of the supported events. Such events that the rvt may need to know -* about include: -* port errors -* port active -* lid change -* sm change -* client reregister -* pkey change -* -* There may also be other events that the rvt layers needs to know -* about this is not an exhaustive list. Some events though rvt does not -* need to rely on the driver for such as completion queue error. -*/ -int rvt_signal_supported; - -/* * Anything driver specific that is not covered by props * For instance special module parameters. Goes here. */
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 11/12 IB/rdmavt: Remove unnecessary exported functions
In reply to a message not in the archiveRemove exported functions which are no longer required as the functionality has moved into rdmavt. This also requires re-ordering some of the functions since their prototype no longer appears in a header file. Rather than add forward declarations it is just cleaner to re-order some of the functions.
--- drivers/infiniband/sw/rdmavt/mmap.c | 4 - drivers/infiniband/sw/rdmavt/mmap.h | 8 + drivers/infiniband/sw/rdmavt/qp.c | 252 ++++++++++++++++------------------- drivers/infiniband/sw/rdmavt/srq.c | 1 drivers/infiniband/sw/rdmavt/vt.h | 1 include/rdma/rdma_vt.h | 13 -- include/rdma/rdmavt_qp.h | 4 - 7 files changed, 128 insertions(+), 155 deletions(-)
drivers/infiniband/sw/rdmavt/mmap.c +0 -4
@@ -80,7 +80,6 @@ void rvt_release_mmap_info(struct kref *ref)vfree (ip->obj);kfree (ip); } -EXPORT_SYMBOL (rvt_release_mmap_info);static void rvt_vma_open (struct vm_area_struct *vma) {
@@ -146,7 +145,6 @@ int rvt_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) done:return ret; } -EXPORT_SYMBOL (rvt_mmap);/** * rvt_create_mmap_info - allocate information for hfi1_mmap
@@ -185,7 +183,6 @@ struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi,return ip; } -EXPORT_SYMBOL (rvt_create_mmap_info);/** * rvt_update_mmap_info - update a mem map
@@ -209,4 +206,3 @@ void rvt_update_mmap_info(struct rvt_dev_info *rdi, struct rvt_mmap_info *ip, ip->size = size; ip->obj = obj; } -EXPORT_SYMBOL (rvt_update_mmap_info);
drivers/infiniband/sw/rdmavt/mmap.h +8 -0
@@ -51,5 +51,13 @@#include <rdma/rdma_vt.h> void rvt_mmap_init (struct rvt_dev_info *rdi); +void rvt_release_mmap_info (struct kref *ref); +int rvt_mmap (struct ib_ucontext *context,struct vm_area_struct *vma); +struct rvt_mmap_info *rvt_create_mmap_info (struct rvt_dev_info *rdi, +u32 size, +struct ib_ucontext *context, +void *obj); +void rvt_update_mmap_info (struct rvt_dev_info *rdi,struct rvt_mmap_info *ip, +u32 size,void *obj);#endif /* DEF_RDMAVTMMAP_H */
drivers/infiniband/sw/rdmavt/qp.c +118 -134
290 lines not on this page · raw message
drivers/infiniband/sw/rdmavt/srq.c +1 -0
@@ -50,6 +50,7 @@#include <linux/vmalloc.h> #include "srq.h" +#include "vt.h" /** * rvt_driver_srq_init - init srq resources on a per driver basis
drivers/infiniband/sw/rdmavt/vt.h +1 -0
@@ -60,6 +60,7 @@#include "mmap.h" #include "cq.h" #include "mad.h" +#include "mmap.h" #define rvt_pr_info (rdi, fmt, ...) \ __rvt_pr_info(rdi->driver_f.get_pci_dev(rdi), \
include/rdma/rdma_vt.h +0 -13
@@ -476,19 +476,6 @@ int rvt_rkey_ok(struct rvt_qp *qp, struct rvt_sge *sge, u32 len, u64 vaddr, u32 rkey, int acc);int rvt_lkey_ok (struct rvt_lkey_table *rkt,struct rvt_pd *pd,struct rvt_sge *isge,struct ib_sge *sge,int acc); -int rvt_mmap (struct ib_ucontext *context,struct vm_area_struct *vma); -void rvt_release_mmap_info (struct kref *ref); -struct rvt_mmap_info *rvt_create_mmap_info (struct rvt_dev_info *rdi, -u32 size, -struct ib_ucontext *context, -void *obj); -void rvt_update_mmap_info (struct rvt_dev_info *rdi,struct rvt_mmap_info *ip, -u32 size,void *obj); -int rvt_reg_mr (struct rvt_qp *qp,struct ib_reg_wr *wr);struct rvt_mcast *rvt_mcast_find (struct rvt_ibport *ibp,union ib_gid *mgid); -/* Temporary export */ -void rvt_reset_qp (struct rvt_dev_info *rdi,struct rvt_qp *qp, -enum ib_qp_type type); -#endif /* DEF_RDMA_VT_H */
include/rdma/rdmavt_qp.h +0 -4
@@ -438,10 +438,6 @@ static inline struct rvt_rwqe *rvt_get_rwqe_ptr(struct rvt_rq *rq, unsigned n)extern const int ib_rvt_state_ops[];struct rvt_dev_info ; -void rvt_remove_qp (struct rvt_dev_info *rdi,struct rvt_qp *qp); -void rvt_clear_mr_refs (struct rvt_qp *qp,int clr_sends);int rvt_error_qp (struct rvt_qp *qp,enum ib_wc_status err); -void rvt_free_qpn (struct rvt_qpn_table *qpt,u32 qpn); -void rvt_dec_qp_cnt (struct rvt_dev_info *rdi);#endif /* DEF_RDMAVT_INCQP_H */
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 12/12 IB/qib: Destroy SMI AH before de-allocating the protection domain
In reply to a message not in the archiveFrom: Harish Chegondi <[email protected]>
If SMI AH is not destroyed before de-allocating the PD, it would result in non-zero PD use count when de-allocating the PD, triggering a WARN_ON() at drivers/infiniband/core/verbs.c:284 ib_dealloc_pd+0x69/0xb0 [ib_core]() when unloading the qib driver on systems with dual-port card.
This problem has always been there in qib and was detected only after the commit 7dd78647a2c2 ("IB/core: Make ib_dealloc_pd return void") introduced a WARN_ON in ib_dealloc_pd() that triggers if a PD's use count is non-zero before de-allocating the PD.
Below is the call trace from the dmesg log.
[ 7264.966129] Call Trace: [ 7264.969652] [<ffffffff81338470>] dump_stack+0x44/0x64 [ 7264.976181] [<ffffffff81086bb6>] warn_slowpath_common+0x86/0xc0 [ 7264.983656] [<ffffffff81086cfa>] warn_slowpath_null+0x1a/0x20 [ 7264.990961] [<ffffffffa025c2d9>] ib_dealloc_pd+0x69/0xb0 [ib_core] [ 7264.998717] [<ffffffffa0044de8>] ib_mad_port_close+0xb8/0x120 [ib_mad] [ 7265.006866] [<ffffffffa0044ebf>] ib_mad_remove_device+0x6f/0xc0 [ib_mad] [ 7265.015224] [<ffffffffa025fc87>] ib_unregister_device+0xa7/0x140 [ib_core] [ 7265.023738] [<ffffffffa04b5b79>] rvt_unregister_device+0x29/0x80 [rdmavt] [ 7265.032181] [<ffffffffa088d2a2>] qib_unregister_ib_device+0x22/0x210 [ib_qib] [ 7265.040993] [<ffffffffa085f73f>] qib_remove_one+0x1f/0x250 [ib_qib] [ 7265.048823] [<ffffffff8137a319>] pci_device_remove+0x39/0xc0 [ 7265.055984] [<ffffffff81466a1a>] __device_release_driver+0x9a/0x140 [ 7265.063821] [<ffffffff81466bc8>] driver_detach+0xb8/0xc0 [ 7265.070579] [<ffffffff81465a15>] bus_remove_driver+0x55/0xd0 [ 7265.077717] [<ffffffff8146732c>] driver_unregister+0x2c/0x50 [ 7265.084849] [<ffffffff813789ba>] pci_unregister_driver+0x2a/0x80 [ 7265.092366] [<ffffffffa08921bd>] qib_ib_cleanup+0x37/0x65 [ib_qib] [ 7265.100068] [<ffffffff811096d0>] SyS_delete_module+0x190/0x220 [ 7265.107379] [<ffffffff816a7bae>] entry_SYSCALL_64_fastpath+0x12/0x71
--- drivers/infiniband/hw/qib/qib_iba7322.c | 2 -- drivers/infiniband/hw/qib/qib_mad.c | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-)
drivers/infiniband/hw/qib/qib_iba7322.c +0 -2
@@ -2910,8 +2910,6 @@ static void qib_setup_7322_cleanup(struct qib_devdata *dd)spin_unlock_irqrestore (&dd->cspec->gpio_lock, flags);qib_qsfp_deinit (&dd->pport[i].cpspec->qsfp_data); } -if (dd->pport[i].ibport_data.smi_ah) -ib_destroy_ah (&dd->pport[i].ibport_data.smi_ah->ibah); } }
drivers/infiniband/hw/qib/qib_mad.c +3 -0
@@ -2496,4 +2496,7 @@ void qib_notify_free_mad_agent(struct rvt_dev_info *rdi, int port_idx)if (dd->pport[port_idx].cong_stats.timer.data)del_timer_sync (&dd->pport[port_idx].cong_stats.timer); + +if (dd->pport[port_idx].ibport_data.smi_ah) +ib_destroy_ah (&dd->pport[port_idx].ibport_data.smi_ah->ibah); }
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html