From patchwork Wed May 26 20:14:28 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Heinz X-Patchwork-Id: 102496 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o4QKEcrT017826 for ; Wed, 26 May 2010 20:14:39 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756825Ab0EZUOi (ORCPT ); Wed, 26 May 2010 16:14:38 -0400 Received: from avexcashub1.qlogic.com ([198.70.193.61]:25844 "EHLO avexcashub1.qlogic.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755120Ab0EZUOh convert rfc822-to-8bit (ORCPT ); Wed, 26 May 2010 16:14:37 -0400 Received: from avexcashub2.qlogic.org (10.1.4.116) by avexcashub1.qlogic.org (10.1.4.161) with Microsoft SMTP Server (TLS) id 8.1.375.2; Wed, 26 May 2010 13:14:36 -0700 Received: from MNEXCASHUB2.qlogic.org (10.33.2.104) by avexcashub2.qlogic.org (10.1.4.162) with Microsoft SMTP Server (TLS) id 8.1.375.2; Wed, 26 May 2010 13:14:36 -0700 Received: from MNEXMB1.qlogic.org ([fe80::c6b:fda:afec:79a1]) by MNEXCASHUB2.qlogic.org ([::1]) with mapi; Wed, 26 May 2010 15:14:35 -0500 From: Mike Heinz To: "linux-rdma@vger.kernel.org" , Roland Dreier Date: Wed, 26 May 2010 15:14:28 -0500 Subject: [PATCH] IB/core User RMPP patch Thread-Topic: [PATCH] IB/core User RMPP patch Thread-Index: Acr9EAtKD/028Ag3RWu6iemg4gN1Tg== Message-ID: <4C2744E8AD2982428C5BFE523DF8CDCB49A488D528@MNEXMB1.qlogic.org> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-cr-hashedpuzzle: Fm89 F5n7 GOt5 GZXo Hjh+ IExK IjDz KuL/ MLz3 OM4x PPbT QFJE SeYP Uch/ U3V6 VAZZ; 2; bABpAG4AdQB4AC0AcgBkAG0AYQBAAHYAZwBlAHIALgBrAGUAcgBuAGUAbAAuAG8AcgBnADsAcgBkAHIAZQBpAGUAcgBAAGMAaQBzAGMAbwAuAGMAbwBtAA==; Sosha1_v1; 7; {BBF4D866-E6D6-4072-9774-AB73E771F744}; bQBpAGMAaABhAGUAbAAuAGgAZQBpAG4AegBAAHEAbABvAGcAaQBjAC4AYwBvAG0A; Wed, 26 May 2010 20:14:28 GMT; WwBQAEEAVABDAEgAXQAgAEkAQgAvAGMAbwByAGUAIABVAHMAZQByACAAUgBNAFAAUAAgAHAAYQB0AGMAaAA= x-cr-puzzleid: {BBF4D866-E6D6-4072-9774-AB73E771F744} acceptlanguage: en-US MIME-Version: 1.0 Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 26 May 2010 20:14:39 +0000 (UTC) diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 80282f1..b3457ae 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -1830,25 +1830,39 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, if (ib_response_mad(mad_recv_wc->recv_buf.mad)) { spin_lock_irqsave(&mad_agent_priv->lock, flags); mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc); - if (!mad_send_wr) { + if (mad_send_wr) { + ib_mark_mad_done(mad_send_wr); spin_unlock_irqrestore(&mad_agent_priv->lock, flags); - ib_free_recv_mad(mad_recv_wc); - deref_mad_agent(mad_agent_priv); - return; - } - ib_mark_mad_done(mad_send_wr); - spin_unlock_irqrestore(&mad_agent_priv->lock, flags); - /* Defined behavior is to complete response before request */ - mad_recv_wc->wc->wr_id = (unsigned long) &mad_send_wr->send_buf; - mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, - mad_recv_wc); - atomic_dec(&mad_agent_priv->refcount); + /* Defined behavior is to complete response before request */ + mad_recv_wc->wc->wr_id = (unsigned long) &mad_send_wr->send_buf; + mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, + mad_recv_wc); + atomic_dec(&mad_agent_priv->refcount); - mad_send_wc.status = IB_WC_SUCCESS; - mad_send_wc.vendor_err = 0; - mad_send_wc.send_buf = &mad_send_wr->send_buf; - ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc); + mad_send_wc.status = IB_WC_SUCCESS; + mad_send_wc.vendor_err = 0; + mad_send_wc.send_buf = &mad_send_wr->send_buf; + ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc); + } else { + if ( !mad_agent_priv->agent.rmpp_version + && ib_is_mad_class_rmpp(mad_recv_wc->recv_buf.mad->mad_hdr.mgmt_class) + && (ib_get_rmpp_flags(&((struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad)->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) { + // user rmpp is in effect + spin_unlock_irqrestore(&mad_agent_priv->lock, flags); + + mad_recv_wc->wc->wr_id = 0; + mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, + mad_recv_wc); + atomic_dec(&mad_agent_priv->refcount); + } else { + // not user rmpp, revert to normal behavior and drop the mad + spin_unlock_irqrestore(&mad_agent_priv->lock, flags); + ib_free_recv_mad(mad_recv_wc); + deref_mad_agent(mad_agent_priv); + return; + } + } } else { mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, mad_recv_wc); diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 36f815c..f9cacbc 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -508,7 +508,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class); - if (!ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)) { + if (!agent->rmpp_version || !ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)) { copy_offset = IB_MGMT_MAD_HDR; rmpp_active = 0; } else { @@ -560,14 +560,22 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, rmpp_mad->mad_hdr.tid = *tid; } - spin_lock_irq(&file->send_lock); - ret = is_duplicate(file, packet); - if (!ret) + if ( !agent->rmpp_version + && ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class) + && (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) { + spin_lock_irq(&file->send_lock); list_add_tail(&packet->list, &file->send_list); - spin_unlock_irq(&file->send_lock); - if (ret) { - ret = -EINVAL; - goto err_msg; + spin_unlock_irq(&file->send_lock); + } else { + spin_lock_irq(&file->send_lock); + ret = is_duplicate(file, packet); + if (!ret) + list_add_tail(&packet->list, &file->send_list); + spin_unlock_irq(&file->send_lock); + if (ret) { + ret = -EINVAL; + goto err_msg; + } } ret = ib_post_send_mad(packet->msg, NULL);