From patchwork Mon Dec 27 15:18:08 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Walukiewicz, Miroslaw" X-Patchwork-Id: 434261 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oBRKCV91025997 for ; Mon, 27 Dec 2010 20:16:43 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754051Ab0L0PSO (ORCPT ); Mon, 27 Dec 2010 10:18:14 -0500 Received: from mga11.intel.com ([192.55.52.93]:13853 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754022Ab0L0PSN convert rfc822-to-8bit (ORCPT ); Mon, 27 Dec 2010 10:18:13 -0500 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 27 Dec 2010 07:18:13 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.60,234,1291622400"; d="scan'208";a="640772007" Received: from irsmsx601.ger.corp.intel.com ([163.33.7.164]) by fmsmga002.fm.intel.com with ESMTP; 27 Dec 2010 07:18:12 -0800 Received: from irsmsx501.ger.corp.intel.com (163.33.7.70) by irsmsx601.ger.corp.intel.com (163.33.7.164) with Microsoft SMTP Server (TLS) id 8.2.254.0; Mon, 27 Dec 2010 15:18:11 +0000 Received: from irsmsx503.ger.corp.intel.com ([163.33.7.254]) by irsmsx501.ger.corp.intel.com ([163.33.7.70]) with mapi; Mon, 27 Dec 2010 15:18:11 +0000 From: "Walukiewicz, Miroslaw" To: Or Gerlitz , Jason Gunthorpe CC: Roland Dreier , "Hefty, Sean" , "linux-rdma@vger.kernel.org" Date: Mon, 27 Dec 2010 15:18:08 +0000 Subject: RE: ibv_post_send/recv kernel path optimizations Thread-Topic: ibv_post_send/recv kernel path optimizations Thread-Index: AculwxfX0JSeTF2MSp6P/vzNV59K0AAFHP1w Message-ID: References: <20101013091312.GB6060@bicker> <20101123071025.GI1522@bicker> <20101124221845.GH2369@obsidianresearch.com> <20101125041337.GA11049@obsidianresearch.com> <4CEE7A22.2040706@voltaire.com> <4CF60343.7050602@voltaire.com> <20101214181735.GA2506@obsidianresearch.com> <4D1888CB.2010101@Voltaire.com> In-Reply-To: <4D1888CB.2010101@Voltaire.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: 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 (demeter1.kernel.org [140.211.167.41]); Mon, 27 Dec 2010 20:16:43 +0000 (UTC) diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 3520182..234324f 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -269,6 +269,54 @@ static void put_xrcd_read(struct ib_uobject *uobj) put_uobj_read(uobj); } +#define RAW_QP_HASH(h) ((((h) >> 24) ^ ((h) >> 16) ^ \ + ((h) >> 8) ^ (h)) & (MAX_RAW_QP_HASH - 1)) + +static void init_raw_qp_hash(struct ib_ucontext *ucontext) { + int idx; + + for (idx = 0; idx < MAX_RAW_QP_HASH; idx++) + INIT_LIST_HEAD(&ucontext->raw_qp_hash[idx]); +} + +static void raw_qp_hash_add(struct ib_ucontext *ucontext, + u32 qp_handle, + struct ib_qp *qp) +{ + int key; + + if (qp->qp_type != IB_QPT_RAW_ETH) + return; + + key = RAW_QP_HASH(qp_handle); + list_add(&qp->uobject->raw_qp_list, &ucontext->raw_qp_hash[key]); } + +static void raw_qp_hash_del(struct ib_qp *qp) { + if (qp->qp_type != IB_QPT_RAW_ETH) + return; + + list_del(&qp->uobject->raw_qp_list); +} + +static struct ib_qp *raw_qp_lookup(u32 qp_handle, struct ib_ucontext +*ucontext) { + int key; + struct ib_qp *qp; + struct ib_uobject *uobj, *tmp; + + key = RAW_QP_HASH(qp_handle); + list_for_each_entry_safe(uobj, tmp, + &ucontext->raw_qp_hash[key], raw_qp_list) { + qp = uobj->object; + if (qp->uobject->id == qp_handle) + return qp; + } + return NULL; +} + ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, const char __user *buf, int in_len, int out_len) @@ -313,6 +361,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, INIT_LIST_HEAD(&ucontext->srq_list); INIT_LIST_HEAD(&ucontext->ah_list); INIT_LIST_HEAD(&ucontext->xrc_domain_list); + init_raw_qp_hash(ucontext); ucontext->closing = 0; resp.num_comp_vectors = file->device->num_comp_vectors; @@ -1155,6 +1204,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, mutex_lock(&file->mutex); list_add_tail(&obj->uevent.uobject.list, &file->ucontext->qp_list); + raw_qp_hash_add(file->ucontext, obj->uevent.uobject.id, qp); mutex_unlock(&file->mutex); obj->uevent.uobject.live = 1; @@ -1412,6 +1462,7 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, mutex_lock(&file->mutex); list_del(&uobj->list); + raw_qp_hash_del(qp); mutex_unlock(&file->mutex); ib_uverbs_release_uevent(file, &obj->uevent); @@ -1450,6 +1501,25 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, if (cmd.wqe_size < sizeof (struct ib_uverbs_send_wr)) return -EINVAL; + mutex_lock(&file->mutex); + qp = raw_qp_lookup(cmd.qp_handle, file->ucontext); + mutex_unlock(&file->mutex); + if (qp) { + if (qp->qp_type == IB_QPT_RAW_ETH) { + resp.bad_wr = 0; + ret = qp->device->post_send(qp, NULL, &bad_wr); + if (ret) + resp.bad_wr = cmd.wr_count; + + if (copy_to_user((void __user *) (unsigned long) + cmd.response, + &resp, + sizeof resp)) + ret = -EFAULT; + goto out_raw_qp; + } + } + user_wr = kmalloc(cmd.wqe_size, GFP_KERNEL); if (!user_wr) return -ENOMEM; @@ -1579,7 +1649,7 @@ out_put: out: kfree(user_wr); - +out_raw_qp: return ret ? ret : in_len; } @@ -1664,7 +1734,6 @@ err: kfree(wr); wr = next; } - return ERR_PTR(ret); } @@ -1681,6 +1750,25 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; + mutex_lock(&file->mutex); + qp = raw_qp_lookup(cmd.qp_handle, file->ucontext); + mutex_unlock(&file->mutex); + if (qp) { + if (qp->qp_type == IB_QPT_RAW_ETH) { + resp.bad_wr = 0; + ret = qp->device->post_recv(qp, NULL, &bad_wr); + if (ret) + resp.bad_wr = cmd.wr_count; + + if (copy_to_user((void __user *) (unsigned long) + cmd.response, + &resp, + sizeof resp)) + ret = -EFAULT; + goto out_raw_qp; + } + } + wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd, in_len - sizeof cmd, cmd.wr_count, cmd.sge_count, cmd.wqe_size); @@ -1713,7 +1801,7 @@ out: kfree(wr); wr = next; } - +out_raw_qp: return ret ? ret : in_len; } diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index f5b054a..adf1dd8 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -838,6 +838,8 @@ struct ib_fmr_attr { u8 page_shift; }; +#define MAX_RAW_QP_HASH 8 + struct ib_ucontext { struct ib_device *device; struct list_head pd_list; @@ -848,6 +850,7 @@ struct ib_ucontext { struct list_head srq_list; struct list_head ah_list; struct list_head xrc_domain_list; + struct list_head raw_qp_hash[MAX_RAW_QP_HASH]; int closing; }; @@ -859,6 +862,7 @@ struct ib_uobject { int id; /* index into kernel idr */ struct kref ref; struct rw_semaphore mutex; /* protects .live */ + struct list_head raw_qp_list; /* raw qp hash */ int live; };