From patchwork Tue Mar 23 18:06:05 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hefty, Sean" X-Patchwork-Id: 87724 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 o2NI68MJ006761 for ; Tue, 23 Mar 2010 18:06:08 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754004Ab0CWSGH (ORCPT ); Tue, 23 Mar 2010 14:06:07 -0400 Received: from mga09.intel.com ([134.134.136.24]:9873 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753967Ab0CWSGG (ORCPT ); Tue, 23 Mar 2010 14:06:06 -0400 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 23 Mar 2010 11:03:24 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.51,296,1267430400"; d="scan'208";a="502952311" Received: from unknown (HELO msheftyMOBL2) ([10.254.89.25]) by orsmga002.jf.intel.com with ESMTP; 23 Mar 2010 11:05:12 -0700 From: "Sean Hefty" To: "Hefty, Sean" , "linux-rdma" References: <2F3826558E79459EAD2A457A604221C1@amr.corp.intel.com> Subject: [RFC] [PATCH 9/22] [for 2.6.36] rdma/cm: add support for AF_IB to rdma_resolve_addr Date: Tue, 23 Mar 2010 11:06:05 -0700 Message-ID: <9E248C187E8E4CFBB3C5E20CB92F13E9@amr.corp.intel.com> MIME-Version: 1.0 X-Mailer: Microsoft Office Outlook 11 Thread-Index: AcrKsQISoZCN8VP+SeqPIDQtSiqGcAAAkXvA X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5579 In-Reply-To: <2F3826558E79459EAD2A457A604221C1@amr.corp.intel.com> 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]); Tue, 23 Mar 2010 18:06:08 +0000 (UTC) diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 0bc33cc..c7b6912 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -350,6 +350,62 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv) return ret; } +/* + * Select the source IB device and address to reach the destination IB address. + */ +static int cma_resolve_ib_dev(struct rdma_id_private *id_priv) +{ + struct cma_device *cma_dev, *cur_dev; + struct sockaddr_ib *addr; + union ib_gid gid, sgid, *dgid; + u16 pkey, index; + u8 port, p; + int i; + + cma_dev = NULL; + addr = (struct sockaddr_ib *) &id_priv->id.route.addr.dst_addr; + dgid = (union ib_gid *) &addr->sib_addr; + pkey = ntohs(addr->sib_pkey); + + list_for_each_entry(cur_dev, &dev_list, list) { + if (rdma_node_get_transport(cur_dev->device->node_type) != RDMA_TRANSPORT_IB) + continue; + + for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) { + if (ib_find_cached_pkey(cur_dev->device, p, pkey, &index)) + continue; + + for (i = 0; !ib_get_cached_gid(cur_dev->device, p, i, &gid); i++) { + if (!memcmp(&gid, dgid, sizeof(gid))) { + cma_dev = cur_dev; + sgid = gid; + port = p; + goto found; + } + + if (!cma_dev && (gid.global.subnet_prefix == + dgid->global.subnet_prefix)) { + cma_dev = cur_dev; + sgid = gid; + port = p; + } + } + } + } + + if (!cma_dev) { + return -ENODEV; + } + +found: + cma_attach_to_dev(id_priv, cma_dev); + id_priv->id.port_num = port; + addr = (struct sockaddr_ib *) &id_priv->id.route.addr.src_addr; + memcpy(&addr->sib_addr, &sgid, sizeof sgid); + cma_translate_ib(addr, &id_priv->id.route.addr.dev_addr); + return 0; +} + static void cma_deref_id(struct rdma_id_private *id_priv) { if (atomic_dec_and_test(&id_priv->refcount)) @@ -1930,14 +1986,48 @@ err: return ret; } +static int cma_resolve_ib_addr(struct rdma_id_private *id_priv) +{ + struct cma_work *work; + int ret; + + work = kzalloc(sizeof *work, GFP_KERNEL); + if (!work) + return -ENOMEM; + + if (!id_priv->cma_dev) { + ret = cma_resolve_ib_dev(id_priv); + if (ret) + goto err; + } + + rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, (union ib_gid *) + &(((struct sockaddr_ib *) &id_priv->id.route.addr.dst_addr)->sib_addr)); + + work->id = id_priv; + INIT_WORK(&work->work, cma_work_handler); + work->old_state = CMA_ADDR_QUERY; + work->new_state = CMA_ADDR_RESOLVED; + work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED; + queue_work(cma_wq, &work->work); + return 0; +err: + kfree(work); + return ret; +} + static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, struct sockaddr *dst_addr) { if (!src_addr || !src_addr->sa_family) { src_addr = (struct sockaddr *) &id->route.addr.src_addr; - if ((src_addr->sa_family = dst_addr->sa_family) == AF_INET6) { + src_addr->sa_family = dst_addr->sa_family; + if (dst_addr->sa_family == AF_INET6) { ((struct sockaddr_in6 *) src_addr)->sin6_scope_id = ((struct sockaddr_in6 *) dst_addr)->sin6_scope_id; + } else if (dst_addr->sa_family == AF_IB) { + ((struct sockaddr_ib *) src_addr)->sib_pkey = + ((struct sockaddr_ib *) dst_addr)->sib_pkey; } } return rdma_bind_addr(id, src_addr); @@ -1961,12 +2051,18 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, atomic_inc(&id_priv->refcount); memcpy(&id->route.addr.dst_addr, dst_addr, rdma_addr_size(dst_addr)); - if (cma_any_addr(dst_addr)) + if (cma_any_addr(dst_addr)) { ret = cma_resolve_loopback(id_priv); - else - ret = rdma_resolve_ip(&addr_client, (struct sockaddr *) &id->route.addr.src_addr, - dst_addr, &id->route.addr.dev_addr, - timeout_ms, addr_handler, id_priv); + } else { + if (dst_addr->sa_family == AF_IB) { + ret = cma_resolve_ib_addr(id_priv); + } else { + ret = rdma_resolve_ip(&addr_client, + (struct sockaddr *) &id->route.addr.src_addr, + dst_addr, &id->route.addr.dev_addr, + timeout_ms, addr_handler, id_priv); + } + } if (ret) goto err;