From patchwork Sat Mar 5 00:05:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hefty, Sean" X-Patchwork-Id: 610541 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 p2506omO027175 for ; Sat, 5 Mar 2011 00:06:50 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760224Ab1CEAGt (ORCPT ); Fri, 4 Mar 2011 19:06:49 -0500 Received: from mga03.intel.com ([143.182.124.21]:29652 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760081Ab1CEAGt convert rfc822-to-8bit (ORCPT ); Fri, 4 Mar 2011 19:06:49 -0500 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga101.ch.intel.com with ESMTP; 04 Mar 2011 16:06:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.62,267,1297065600"; d="scan'208";a="397906828" Received: from orsmsx604.amr.corp.intel.com ([10.22.226.87]) by azsmga001.ch.intel.com with ESMTP; 04 Mar 2011 16:06:08 -0800 Received: from orsmsx601.amr.corp.intel.com (10.22.226.213) by orsmsx604.amr.corp.intel.com (10.22.226.87) with Microsoft SMTP Server (TLS) id 8.2.254.0; Fri, 4 Mar 2011 16:05:51 -0800 Received: from orsmsx501.amr.corp.intel.com ([10.22.226.209]) by orsmsx601.amr.corp.intel.com ([10.22.226.213]) with mapi; Fri, 4 Mar 2011 16:05:51 -0800 From: "Hefty, Sean" To: linux-rdma Date: Fri, 4 Mar 2011 16:05:50 -0800 Subject: [PATCH 6/7] ibacm: Handle port up events Thread-Topic: [PATCH 6/7] ibacm: Handle port up events Thread-Index: AcvaxgSfoktHPkOORD6XfWr1lHcX3gAARaEg Message-ID: 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.6 (demeter1.kernel.org [140.211.167.41]); Sat, 05 Mar 2011 00:06:50 +0000 (UTC) diff --git a/src/acm.c b/src/acm.c index 3590c16..2570fdc 100644 --- a/src/acm.c +++ b/src/acm.c @@ -2499,14 +2499,37 @@ static int acm_init_ep_loopback(struct acm_ep *ep) return 0; } -static int acm_ep_up(struct acm_port *port, struct acm_ep *ep, uint16_t pkey_index) +static struct acm_ep *acm_find_ep(struct acm_port *port, uint16_t pkey) { - struct ibv_qp_init_attr init_attr; - struct ibv_qp_attr attr; - int ret, sq_size; + struct acm_ep *ep, *res = NULL; + DLIST_ENTRY *entry; + + acm_log(2, "pkey 0x%x\n", pkey); + + lock_acquire(&port->lock); + for (entry = port->ep_list.Next; entry != &port->ep_list; entry = entry->Next) { + ep = container_of(entry, struct acm_ep, entry); + if (ep->pkey == pkey) { + res = ep; + break; + } + } + lock_release(&port->lock); + return res; +} + +static struct acm_ep * +acm_alloc_ep(struct acm_port *port, uint16_t pkey, uint16_t pkey_index) +{ + struct acm_ep *ep; acm_log(1, "\n"); + ep = calloc(1, sizeof *ep); + if (!ep) + return NULL; + ep->port = port; + ep->pkey = pkey; ep->pkey_index = pkey_index; ep->resolve_queue.credits = resolve_depth; ep->sa_queue.credits = sa_depth; @@ -2517,15 +2540,36 @@ static int acm_ep_up(struct acm_port *port, struct acm_ep *ep, uint16_t pkey_ind DListInit(&ep->active_queue); DListInit(&ep->wait_queue); lock_init(&ep->lock); + return ep; +} - ret = ibv_query_pkey(port->dev->verbs, port->port_num, pkey_index, &ep->pkey); +static void acm_ep_up(struct acm_port *port, uint16_t pkey_index) +{ + struct acm_ep *ep; + struct ibv_qp_init_attr init_attr; + struct ibv_qp_attr attr; + int ret, sq_size; + uint16_t pkey; + + acm_log(1, "\n"); + ret = ibv_query_pkey(port->dev->verbs, port->port_num, pkey_index, &pkey); if (ret) - return ACM_STATUS_EINVAL; + return; + + if (acm_find_ep(port, pkey)) { + acm_log(2, "endpoint for pkey 0x%x already exists\n", pkey); + return; + } + + acm_log(2, "creating endpoint for pkey 0x%x\n", pkey); + ep = acm_alloc_ep(port, pkey, pkey_index); + if (!ep) + return; ret = acm_assign_ep_names(ep); if (ret) { acm_log(0, "ERROR - unable to assign EP name\n"); - return ret; + goto err0; } sq_size = resolve_depth + sa_depth + send_depth; @@ -2533,7 +2577,7 @@ static int acm_ep_up(struct acm_port *port, struct acm_ep *ep, uint16_t pkey_ind ep, port->dev->channel, 0); if (!ep->cq) { acm_log(0, "ERROR - failed to create CQ\n"); - return -1; + goto err0; } ret = ibv_req_notify_cq(ep->cq, 0); @@ -2593,13 +2637,17 @@ static int acm_ep_up(struct acm_port *port, struct acm_ep *ep, uint16_t pkey_ind acm_log(0, "ERROR - unable to init loopback\n"); goto err2; } - return 0; + lock_acquire(&port->lock); + DListInsertHead(&ep->entry, &port->ep_list); + lock_release(&port->lock); + return; err2: ibv_destroy_qp(ep->qp); err1: ibv_destroy_cq(ep->cq); - return -1; +err0: + free(ep); } static void acm_port_up(struct acm_port *port) @@ -2607,7 +2655,6 @@ static void acm_port_up(struct acm_port *port) struct ibv_port_attr attr; union ibv_gid gid; uint16_t pkey; - struct acm_ep *ep; int i, ret; acm_log(1, "%s %d\n", port->dev->verbs->device->name, port->port_num); @@ -2624,13 +2671,13 @@ static void acm_port_up(struct acm_port *port) port->mtu = attr.active_mtu; port->rate = acm_get_rate(attr.active_width, attr.active_speed); port->subnet_timeout = 1 << (attr.subnet_timeout - 8); - for (;; port->gid_cnt++) { + for (port->gid_cnt = 0;; port->gid_cnt++) { ret = ibv_query_gid(port->dev->verbs, port->port_num, port->gid_cnt, &gid); if (ret || !gid.global.interface_id) break; } - for (;; port->pkey_cnt++) { + for (port->pkey_cnt = 0;; port->pkey_cnt++) { ret = ibv_query_pkey(port->dev->verbs, port->port_num, port->pkey_cnt, &pkey); if (ret || !pkey) break; @@ -2651,25 +2698,12 @@ static void acm_port_up(struct acm_port *port) if (!port->sa_dest.ah) return; - for (i = 0; i < port->pkey_cnt; i++) { - /* TODO: Check if endpoint already exists in port list */ - ep = calloc(1, sizeof *ep); - if (!ep) - break; - - ret = acm_ep_up(port, ep, (uint16_t) i); - if (!ret) { - DListInsertHead(&ep->entry, &port->ep_list); - } else { - acm_log(0, "ERROR - failed to activate EP\n"); - free(ep); - } - } + for (i = 0; i < port->pkey_cnt; i++) + acm_ep_up(port, (uint16_t) i); acm_port_join(port); - lock_acquire(&port->lock); port->state = IBV_PORT_ACTIVE; - lock_release(&port->lock); + acm_log(1, "%s %d is up\n", port->dev->verbs->device->name, port->port_num); } /* @@ -2681,13 +2715,31 @@ static void acm_port_up(struct acm_port *port) static void CDECL_FUNC acm_event_handler(void *context) { struct acm_device *dev = (struct acm_device *) context; - int i; + struct ibv_async_event event; + int i, ret; acm_log(1, "started\n"); for (i = 0; i < dev->port_cnt; i++) { acm_port_up(&dev->port[i]); } - /* TODO: wait for port up/down events */ + + for (;;) { + ret = ibv_get_async_event(dev->verbs, &event); + if (ret) + continue; + + i = event.element.port_num - 1; + switch (event.event_type) { + case IBV_EVENT_PORT_ACTIVE: + if (dev->port[i].state != IBV_PORT_ACTIVE) + acm_port_up(&dev->port[i]); + break; + default: + break; + } + + ibv_ack_async_event(&event); + } } static void acm_activate_devices()