From 3414e7b853864ef158386d596d93fac4eec4efea Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 9 May 2011 22:06:22 -0700 Subject: [PATCH] --- yaml --- r: 245330 b: refs/heads/master c: 30c95c2d495c1c8d4d6a97bb9f4e4eacb91ba1d2 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/infiniband/core/cma.c | 207 ++++++------------- trunk/drivers/infiniband/core/iwcm.c | 2 +- trunk/drivers/infiniband/core/ucma.c | 7 - trunk/drivers/infiniband/hw/cxgb4/cm.c | 16 +- trunk/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 4 +- trunk/drivers/infiniband/hw/cxgb4/qp.c | 1 - trunk/drivers/infiniband/hw/nes/nes_cm.c | 16 +- trunk/drivers/infiniband/hw/nes/nes_verbs.c | 2 +- trunk/include/rdma/iw_cm.h | 11 +- trunk/include/rdma/rdma_cm.h | 10 - trunk/include/rdma/rdma_user_cm.h | 5 +- 12 files changed, 100 insertions(+), 183 deletions(-) diff --git a/[refs] b/[refs] index 265e5e73a487..3e19b0b50fa4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d0c49bf391b2e230a8f3ae4486da7df440f1216d +refs/heads/master: 30c95c2d495c1c8d4d6a97bb9f4e4eacb91ba1d2 diff --git a/trunk/drivers/infiniband/core/cma.c b/trunk/drivers/infiniband/core/cma.c index 99dde874fbbd..5ed9d25d021a 100644 --- a/trunk/drivers/infiniband/core/cma.c +++ b/trunk/drivers/infiniband/core/cma.c @@ -148,7 +148,6 @@ struct rdma_id_private { u32 qp_num; u8 srq; u8 tos; - u8 reuseaddr; }; struct cma_multicast { @@ -713,21 +712,6 @@ static inline int cma_any_addr(struct sockaddr *addr) return cma_zero_addr(addr) || cma_loopback_addr(addr); } -static int cma_addr_cmp(struct sockaddr *src, struct sockaddr *dst) -{ - if (src->sa_family != dst->sa_family) - return -1; - - switch (src->sa_family) { - case AF_INET: - return ((struct sockaddr_in *) src)->sin_addr.s_addr != - ((struct sockaddr_in *) dst)->sin_addr.s_addr; - default: - return ipv6_addr_cmp(&((struct sockaddr_in6 *) src)->sin6_addr, - &((struct sockaddr_in6 *) dst)->sin6_addr); - } -} - static inline __be16 cma_port(struct sockaddr *addr) { if (addr->sa_family == AF_INET) @@ -1580,6 +1564,50 @@ static void cma_listen_on_all(struct rdma_id_private *id_priv) mutex_unlock(&lock); } +int rdma_listen(struct rdma_cm_id *id, int backlog) +{ + struct rdma_id_private *id_priv; + int ret; + + id_priv = container_of(id, struct rdma_id_private, id); + if (id_priv->state == CMA_IDLE) { + ((struct sockaddr *) &id->route.addr.src_addr)->sa_family = AF_INET; + ret = rdma_bind_addr(id, (struct sockaddr *) &id->route.addr.src_addr); + if (ret) + return ret; + } + + if (!cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_LISTEN)) + return -EINVAL; + + id_priv->backlog = backlog; + if (id->device) { + switch (rdma_node_get_transport(id->device->node_type)) { + case RDMA_TRANSPORT_IB: + ret = cma_ib_listen(id_priv); + if (ret) + goto err; + break; + case RDMA_TRANSPORT_IWARP: + ret = cma_iw_listen(id_priv, backlog); + if (ret) + goto err; + break; + default: + ret = -ENOSYS; + goto err; + } + } else + cma_listen_on_all(id_priv); + + return 0; +err: + id_priv->backlog = 0; + cma_comp_exch(id_priv, CMA_LISTEN, CMA_ADDR_BOUND); + return ret; +} +EXPORT_SYMBOL(rdma_listen); + void rdma_set_service_type(struct rdma_cm_id *id, int tos) { struct rdma_id_private *id_priv; @@ -2062,25 +2090,6 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, } EXPORT_SYMBOL(rdma_resolve_addr); -int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse) -{ - struct rdma_id_private *id_priv; - unsigned long flags; - int ret; - - id_priv = container_of(id, struct rdma_id_private, id); - spin_lock_irqsave(&id_priv->lock, flags); - if (id_priv->state == CMA_IDLE) { - id_priv->reuseaddr = reuse; - ret = 0; - } else { - ret = -EINVAL; - } - spin_unlock_irqrestore(&id_priv->lock, flags); - return ret; -} -EXPORT_SYMBOL(rdma_set_reuseaddr); - static void cma_bind_port(struct rdma_bind_list *bind_list, struct rdma_id_private *id_priv) { @@ -2156,71 +2165,41 @@ static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv) return -EADDRNOTAVAIL; } -/* - * Check that the requested port is available. This is called when trying to - * bind to a specific port, or when trying to listen on a bound port. In - * the latter case, the provided id_priv may already be on the bind_list, but - * we still need to check that it's okay to start listening. - */ -static int cma_check_port(struct rdma_bind_list *bind_list, - struct rdma_id_private *id_priv, uint8_t reuseaddr) -{ - struct rdma_id_private *cur_id; - struct sockaddr *addr, *cur_addr; - struct hlist_node *node; - - addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr; - if (cma_any_addr(addr) && !reuseaddr) - return -EADDRNOTAVAIL; - - hlist_for_each_entry(cur_id, node, &bind_list->owners, node) { - if (id_priv == cur_id) - continue; - - if ((cur_id->state == CMA_LISTEN) || - !reuseaddr || !cur_id->reuseaddr) { - cur_addr = (struct sockaddr *) &cur_id->id.route.addr.src_addr; - if (cma_any_addr(cur_addr)) - return -EADDRNOTAVAIL; - - if (!cma_addr_cmp(addr, cur_addr)) - return -EADDRINUSE; - } - } - return 0; -} - static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv) { + struct rdma_id_private *cur_id; + struct sockaddr_in *sin, *cur_sin; struct rdma_bind_list *bind_list; + struct hlist_node *node; unsigned short snum; - int ret; - snum = ntohs(cma_port((struct sockaddr *) &id_priv->id.route.addr.src_addr)); + sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr; + snum = ntohs(sin->sin_port); if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) return -EACCES; bind_list = idr_find(ps, snum); - if (!bind_list) { - ret = cma_alloc_port(ps, id_priv, snum); - } else { - ret = cma_check_port(bind_list, id_priv, id_priv->reuseaddr); - if (!ret) - cma_bind_port(bind_list, id_priv); - } - return ret; -} + if (!bind_list) + return cma_alloc_port(ps, id_priv, snum); -static int cma_bind_listen(struct rdma_id_private *id_priv) -{ - struct rdma_bind_list *bind_list = id_priv->bind_list; - int ret = 0; + /* + * We don't support binding to any address if anyone is bound to + * a specific address on the same port. + */ + if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)) + return -EADDRNOTAVAIL; - mutex_lock(&lock); - if (bind_list->owners.first->next) - ret = cma_check_port(bind_list, id_priv, 0); - mutex_unlock(&lock); - return ret; + hlist_for_each_entry(cur_id, node, &bind_list->owners, node) { + if (cma_any_addr((struct sockaddr *) &cur_id->id.route.addr.src_addr)) + return -EADDRNOTAVAIL; + + cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr; + if (sin->sin_addr.s_addr == cur_sin->sin_addr.s_addr) + return -EADDRINUSE; + } + + cma_bind_port(bind_list, id_priv); + return 0; } static int cma_get_port(struct rdma_id_private *id_priv) @@ -2274,56 +2253,6 @@ static int cma_check_linklocal(struct rdma_dev_addr *dev_addr, return 0; } -int rdma_listen(struct rdma_cm_id *id, int backlog) -{ - struct rdma_id_private *id_priv; - int ret; - - id_priv = container_of(id, struct rdma_id_private, id); - if (id_priv->state == CMA_IDLE) { - ((struct sockaddr *) &id->route.addr.src_addr)->sa_family = AF_INET; - ret = rdma_bind_addr(id, (struct sockaddr *) &id->route.addr.src_addr); - if (ret) - return ret; - } - - if (!cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_LISTEN)) - return -EINVAL; - - if (id_priv->reuseaddr) { - ret = cma_bind_listen(id_priv); - if (ret) - goto err; - } - - id_priv->backlog = backlog; - if (id->device) { - switch (rdma_node_get_transport(id->device->node_type)) { - case RDMA_TRANSPORT_IB: - ret = cma_ib_listen(id_priv); - if (ret) - goto err; - break; - case RDMA_TRANSPORT_IWARP: - ret = cma_iw_listen(id_priv, backlog); - if (ret) - goto err; - break; - default: - ret = -ENOSYS; - goto err; - } - } else - cma_listen_on_all(id_priv); - - return 0; -err: - id_priv->backlog = 0; - cma_comp_exch(id_priv, CMA_LISTEN, CMA_ADDR_BOUND); - return ret; -} -EXPORT_SYMBOL(rdma_listen); - int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) { struct rdma_id_private *id_priv; diff --git a/trunk/drivers/infiniband/core/iwcm.c b/trunk/drivers/infiniband/core/iwcm.c index a9c042345c6f..2a1e9ae134b4 100644 --- a/trunk/drivers/infiniband/core/iwcm.c +++ b/trunk/drivers/infiniband/core/iwcm.c @@ -725,7 +725,7 @@ static int cm_conn_rep_handler(struct iwcm_id_private *cm_id_priv, */ clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_SENT); - if (iw_event->status == 0) { + if (iw_event->status == IW_CM_EVENT_STATUS_ACCEPTED) { cm_id_priv->id.local_addr = iw_event->local_addr; cm_id_priv->id.remote_addr = iw_event->remote_addr; cm_id_priv->state = IW_CM_STATE_ESTABLISHED; diff --git a/trunk/drivers/infiniband/core/ucma.c b/trunk/drivers/infiniband/core/ucma.c index b3fa798525b2..ec1e9da1488b 100644 --- a/trunk/drivers/infiniband/core/ucma.c +++ b/trunk/drivers/infiniband/core/ucma.c @@ -883,13 +883,6 @@ static int ucma_set_option_id(struct ucma_context *ctx, int optname, } rdma_set_service_type(ctx->cm_id, *((u8 *) optval)); break; - case RDMA_OPTION_ID_REUSEADDR: - if (optlen != sizeof(int)) { - ret = -EINVAL; - break; - } - ret = rdma_set_reuseaddr(ctx->cm_id, *((int *) optval) ? 1 : 0); - break; default: ret = -ENOSYS; } diff --git a/trunk/drivers/infiniband/hw/cxgb4/cm.c b/trunk/drivers/infiniband/hw/cxgb4/cm.c index 9d8dcfab2b38..d235810e52df 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/cm.c +++ b/trunk/drivers/infiniband/hw/cxgb4/cm.c @@ -1466,7 +1466,7 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) struct c4iw_qp_attributes attrs; int disconnect = 1; int release = 0; - int closing = 0; + int abort = 0; struct tid_info *t = dev->rdev.lldi.tids; unsigned int tid = GET_TID(hdr); @@ -1507,8 +1507,11 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) case FPDU_MODE: start_ep_timer(ep); __state_set(&ep->com, CLOSING); - closing = 1; + attrs.next_state = C4IW_QP_STATE_CLOSING; + abort = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, + C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); peer_close_upcall(ep); + disconnect = 1; break; case ABORTING: disconnect = 0; @@ -1536,11 +1539,6 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) BUG_ON(1); } mutex_unlock(&ep->com.mutex); - if (closing) { - attrs.next_state = C4IW_QP_STATE_CLOSING; - c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, - C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); - } if (disconnect) c4iw_ep_disconnect(ep, 0, GFP_KERNEL); if (release) @@ -1710,14 +1708,14 @@ static int terminate(struct c4iw_dev *dev, struct sk_buff *skb) ep = lookup_tid(t, tid); BUG_ON(!ep); - if (ep->com.qp) { + if (ep && ep->com.qp) { printk(KERN_WARNING MOD "TERM received tid %u qpid %u\n", tid, ep->com.qp->wq.sq.qid); attrs.next_state = C4IW_QP_STATE_TERMINATE; c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); } else - printk(KERN_WARNING MOD "TERM received tid %u no qp\n", tid); + printk(KERN_WARNING MOD "TERM received tid %u no ep/qp\n", tid); return 0; } diff --git a/trunk/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/trunk/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 9f6166f59268..8e16eb2de91f 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/trunk/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -161,8 +161,8 @@ static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev, } } while (!wr_waitp->done); if (wr_waitp->ret) - printk(KERN_WARNING MOD "%s: FW reply %d tid %u qpid %u\n", - pci_name(rdev->lldi.pdev), wr_waitp->ret, hwtid, qpid); + PDBG("%s: FW reply %d tid %u qpid %u\n", + pci_name(rdev->lldi.pdev), wr_waitp->ret, hwtid, qpid); return wr_waitp->ret; } diff --git a/trunk/drivers/infiniband/hw/cxgb4/qp.c b/trunk/drivers/infiniband/hw/cxgb4/qp.c index 70a5a3c646da..a1824a5f3d76 100644 --- a/trunk/drivers/infiniband/hw/cxgb4/qp.c +++ b/trunk/drivers/infiniband/hw/cxgb4/qp.c @@ -1210,7 +1210,6 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, if (ret) { if (internal) c4iw_get_ep(&qhp->ep->com); - disconnect = abort = 1; goto err; } break; diff --git a/trunk/drivers/infiniband/hw/nes/nes_cm.c b/trunk/drivers/infiniband/hw/nes/nes_cm.c index e74cdf9ef471..33c7eedaba6c 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_cm.c +++ b/trunk/drivers/infiniband/hw/nes/nes_cm.c @@ -2563,7 +2563,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) u16 last_ae; u8 original_hw_tcp_state; u8 original_ibqp_state; - int disconn_status = 0; + enum iw_cm_event_status disconn_status = IW_CM_EVENT_STATUS_OK; int issue_disconn = 0; int issue_close = 0; int issue_flush = 0; @@ -2605,7 +2605,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) { issue_disconn = 1; if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) - disconn_status = -ECONNRESET; + disconn_status = IW_CM_EVENT_STATUS_RESET; } if (((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSED) || @@ -2666,7 +2666,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) cm_id->provider_data = nesqp; /* Send up the close complete event */ cm_event.event = IW_CM_EVENT_CLOSE; - cm_event.status = 0; + cm_event.status = IW_CM_EVENT_STATUS_OK; cm_event.provider_data = cm_id->provider_data; cm_event.local_addr = cm_id->local_addr; cm_event.remote_addr = cm_id->remote_addr; @@ -2966,7 +2966,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) nes_add_ref(&nesqp->ibqp); cm_event.event = IW_CM_EVENT_ESTABLISHED; - cm_event.status = 0; + cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED; cm_event.provider_data = (void *)nesqp; cm_event.local_addr = cm_id->local_addr; cm_event.remote_addr = cm_id->remote_addr; @@ -3377,7 +3377,7 @@ static void cm_event_connected(struct nes_cm_event *event) /* notify OF layer we successfully created the requested connection */ cm_event.event = IW_CM_EVENT_CONNECT_REPLY; - cm_event.status = 0; + cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED; cm_event.provider_data = cm_id->provider_data; cm_event.local_addr.sin_family = AF_INET; cm_event.local_addr.sin_port = cm_id->local_addr.sin_port; @@ -3484,7 +3484,7 @@ static void cm_event_reset(struct nes_cm_event *event) nesqp->cm_id = NULL; /* cm_id->provider_data = NULL; */ cm_event.event = IW_CM_EVENT_DISCONNECT; - cm_event.status = -ECONNRESET; + cm_event.status = IW_CM_EVENT_STATUS_RESET; cm_event.provider_data = cm_id->provider_data; cm_event.local_addr = cm_id->local_addr; cm_event.remote_addr = cm_id->remote_addr; @@ -3495,7 +3495,7 @@ static void cm_event_reset(struct nes_cm_event *event) ret = cm_id->event_handler(cm_id, &cm_event); atomic_inc(&cm_closes); cm_event.event = IW_CM_EVENT_CLOSE; - cm_event.status = 0; + cm_event.status = IW_CM_EVENT_STATUS_OK; cm_event.provider_data = cm_id->provider_data; cm_event.local_addr = cm_id->local_addr; cm_event.remote_addr = cm_id->remote_addr; @@ -3534,7 +3534,7 @@ static void cm_event_mpa_req(struct nes_cm_event *event) cm_node, cm_id, jiffies); cm_event.event = IW_CM_EVENT_CONNECT_REQUEST; - cm_event.status = 0; + cm_event.status = IW_CM_EVENT_STATUS_OK; cm_event.provider_data = (void *)cm_node; cm_event.local_addr.sin_family = AF_INET; diff --git a/trunk/drivers/infiniband/hw/nes/nes_verbs.c b/trunk/drivers/infiniband/hw/nes/nes_verbs.c index 95ca93ceedac..26d8018c0a7c 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_verbs.c +++ b/trunk/drivers/infiniband/hw/nes/nes_verbs.c @@ -1484,7 +1484,7 @@ static int nes_destroy_qp(struct ib_qp *ibqp) (nesqp->ibqp_state == IB_QPS_RTR)) && (nesqp->cm_id)) { cm_id = nesqp->cm_id; cm_event.event = IW_CM_EVENT_CONNECT_REPLY; - cm_event.status = -ETIMEDOUT; + cm_event.status = IW_CM_EVENT_STATUS_TIMEOUT; cm_event.local_addr = cm_id->local_addr; cm_event.remote_addr = cm_id->remote_addr; cm_event.private_data = NULL; diff --git a/trunk/include/rdma/iw_cm.h b/trunk/include/rdma/iw_cm.h index 2d0191c90f9e..cbb822e8d791 100644 --- a/trunk/include/rdma/iw_cm.h +++ b/trunk/include/rdma/iw_cm.h @@ -46,9 +46,18 @@ enum iw_cm_event_type { IW_CM_EVENT_CLOSE /* close complete */ }; +enum iw_cm_event_status { + IW_CM_EVENT_STATUS_OK = 0, /* request successful */ + IW_CM_EVENT_STATUS_ACCEPTED = 0, /* connect request accepted */ + IW_CM_EVENT_STATUS_REJECTED, /* connect request rejected */ + IW_CM_EVENT_STATUS_TIMEOUT, /* the operation timed out */ + IW_CM_EVENT_STATUS_RESET, /* reset from remote peer */ + IW_CM_EVENT_STATUS_EINVAL, /* asynchronous failure for bad parm */ +}; + struct iw_cm_event { enum iw_cm_event_type event; - int status; + enum iw_cm_event_status status; struct sockaddr_in local_addr; struct sockaddr_in remote_addr; void *private_data; diff --git a/trunk/include/rdma/rdma_cm.h b/trunk/include/rdma/rdma_cm.h index 169f7a53fb0c..4fae90304648 100644 --- a/trunk/include/rdma/rdma_cm.h +++ b/trunk/include/rdma/rdma_cm.h @@ -329,14 +329,4 @@ void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr); */ void rdma_set_service_type(struct rdma_cm_id *id, int tos); -/** - * rdma_set_reuseaddr - Allow the reuse of local addresses when binding - * the rdma_cm_id. - * @id: Communication identifier to configure. - * @reuse: Value indicating if the bound address is reusable. - * - * Reuse must be set before an address is bound to the id. - */ -int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse); - #endif /* RDMA_CM_H */ diff --git a/trunk/include/rdma/rdma_user_cm.h b/trunk/include/rdma/rdma_user_cm.h index fc82c1896f75..1d165022c02d 100644 --- a/trunk/include/rdma/rdma_user_cm.h +++ b/trunk/include/rdma/rdma_user_cm.h @@ -221,9 +221,8 @@ enum { /* Option details */ enum { - RDMA_OPTION_ID_TOS = 0, - RDMA_OPTION_ID_REUSEADDR = 1, - RDMA_OPTION_IB_PATH = 1 + RDMA_OPTION_ID_TOS = 0, + RDMA_OPTION_IB_PATH = 1 }; struct rdma_ucm_set_option {