From e9feb2e8182c62b3435c975301d00917fad0a3e4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 6 Aug 2009 09:12:37 +0000 Subject: [PATCH] - Refactoring: split srpt_ch_qp_rtr_rts() into two functions, namely srpt_ch_qp_rtr() and srpt_ch_qp_rts(). - Replaced dynamic memory allocation (kmalloc()/kfree()) in the aforementioned two functions by stack allocation. - Compiles again on pre-2.6.22 kernels (RHEL / CentOS systems). git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1015 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- srpt/src/ib_srpt.c | 66 +++++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index 18a936a97..bf0493d26 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -784,39 +784,54 @@ static int srpt_init_ch_qp(struct srpt_rdma_ch *ch, struct ib_qp *qp) } /** - * Change the state of a channel to 'ready to receive' or 'ready to send'. + * Change the state of a channel to 'ready to receive' (RTR). * @ch: channel of the queue pair. - * @qp: queue pair whose attributes should be modified. - * @qp_state: new state of the queue pair; either IB_QPS_RTS or IB_QPS_RTR - * (RTS = ready to send; RTR = ready to receive). + * @qp: queue pair to change the state of. * * Returns zero upon success and a negative value upon failure. */ -static int srpt_ch_qp_rtr_rts(struct srpt_rdma_ch *ch, struct ib_qp *qp, - enum ib_qp_state qp_state) +static int srpt_ch_qp_rtr(struct srpt_rdma_ch *ch, struct ib_qp *qp) { - struct ib_qp_attr *qp_attr; + struct ib_qp_attr qp_attr; int attr_mask; int ret; - qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL); - if (!qp_attr) - return -ENOMEM; - - qp_attr->qp_state = qp_state; - ret = ib_cm_init_qp_attr(ch->cm_id, qp_attr, &attr_mask); + qp_attr.qp_state = IB_QPS_RTR; + ret = ib_cm_init_qp_attr(ch->cm_id, &qp_attr, &attr_mask); if (ret) goto out; - if (qp_state == IB_QPS_RTR) - qp_attr->max_dest_rd_atomic = 4; - else - qp_attr->max_rd_atomic = 4; + qp_attr.max_dest_rd_atomic = 4; - ret = ib_modify_qp(qp, qp_attr, attr_mask); + ret = ib_modify_qp(qp, &qp_attr, attr_mask); + +out: + return ret; +} + +/** + * Change the state of a channel to 'ready to send' (RTS). + * @ch: channel of the queue pair. + * @qp: queue pair to change the state of. + * + * Returns zero upon success and a negative value upon failure. + */ +static int srpt_ch_qp_rts(struct srpt_rdma_ch *ch, struct ib_qp *qp) +{ + struct ib_qp_attr qp_attr; + int attr_mask; + int ret; + + qp_attr.qp_state = IB_QPS_RTS; + ret = ib_cm_init_qp_attr(ch->cm_id, &qp_attr, &attr_mask); + if (ret) + goto out; + + qp_attr.max_rd_atomic = 4; + + ret = ib_modify_qp(qp, &qp_attr, attr_mask); out: - kfree(qp_attr); return ret; } @@ -1637,7 +1652,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, goto free_ch; } - ret = srpt_ch_qp_rtr_rts(ch, ch->qp, IB_QPS_RTR); + ret = srpt_ch_qp_rtr(ch, ch->qp); if (ret) { rej->reason = cpu_to_be32(SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); TRACE_DBG("Reject failed qp to rtr/rts ret=%d", ret); @@ -1764,7 +1779,7 @@ static int srpt_cm_rtu_recv(struct ib_cm_id *cm_id) RDMA_CHANNEL_LIVE)) { struct srpt_ioctx *ioctx, *ioctx_tmp; - ret = srpt_ch_qp_rtr_rts(ch, ch->qp, IB_QPS_RTS); + ret = srpt_ch_qp_rts(ch, ch->qp); list_for_each_entry_safe(ioctx, ioctx_tmp, &ch->cmd_wait_list, wait_list) { @@ -2758,7 +2773,16 @@ static void srpt_remove_one(struct ib_device *device) * finished if it is running. */ for (i = 0; i < sdev->device->phys_port_cnt; i++) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) cancel_work_sync(&sdev->port[i].work); +#else + /* + * cancel_work_sync() was introduced in kernel 2.6.22. Older + * kernels do not have a facility to cancel scheduled work. + */ + printk(KERN_ERR PFX + "your kernel does not provide cancel_work_sync().\n"); +#endif scst_unregister(sdev->scst_tgt); sdev->scst_tgt = NULL;