diff --git a/[refs] b/[refs] index 67257abc39cb..358f152e4f20 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2f5de1512884da8c74bec2c76e8f114b972ab4be +refs/heads/master: 5b673b71c8ca0fbdb99dc1b1434cfb554212d6ff diff --git a/trunk/drivers/infiniband/core/cma.c b/trunk/drivers/infiniband/core/cma.c index e980ff3335db..ae11d5cc74d0 100644 --- a/trunk/drivers/infiniband/core/cma.c +++ b/trunk/drivers/infiniband/core/cma.c @@ -168,12 +168,6 @@ struct cma_work { struct rdma_cm_event event; }; -struct cma_ndev_work { - struct work_struct work; - struct rdma_id_private *id; - struct rdma_cm_event event; -}; - union cma_ip_addr { struct in6_addr ip6; struct { @@ -920,10 +914,7 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) struct rdma_cm_event event; int ret = 0; - if ((ib_event->event != IB_CM_TIMEWAIT_EXIT && - cma_disable_callback(id_priv, CMA_CONNECT)) || - (ib_event->event == IB_CM_TIMEWAIT_EXIT && - cma_disable_callback(id_priv, CMA_DISCONNECT))) + if (cma_disable_callback(id_priv, CMA_CONNECT)) return 0; memset(&event, 0, sizeof event); @@ -959,8 +950,6 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) event.event = RDMA_CM_EVENT_DISCONNECTED; break; case IB_CM_TIMEWAIT_EXIT: - event.event = RDMA_CM_EVENT_TIMEWAIT_EXIT; - break; case IB_CM_MRA_RECEIVED: /* ignore event */ goto out; @@ -1609,30 +1598,6 @@ static void cma_work_handler(struct work_struct *_work) kfree(work); } -static void cma_ndev_work_handler(struct work_struct *_work) -{ - struct cma_ndev_work *work = container_of(_work, struct cma_ndev_work, work); - struct rdma_id_private *id_priv = work->id; - int destroy = 0; - - mutex_lock(&id_priv->handler_mutex); - if (id_priv->state == CMA_DESTROYING || - id_priv->state == CMA_DEVICE_REMOVAL) - goto out; - - if (id_priv->id.event_handler(&id_priv->id, &work->event)) { - cma_exch(id_priv, CMA_DESTROYING); - destroy = 1; - } - -out: - mutex_unlock(&id_priv->handler_mutex); - cma_deref_id(id_priv); - if (destroy) - rdma_destroy_id(&id_priv->id); - kfree(work); -} - static int cma_resolve_ib_route(struct rdma_id_private *id_priv, int timeout_ms) { struct rdma_route *route = &id_priv->id.route; @@ -2758,65 +2723,6 @@ void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr) } EXPORT_SYMBOL(rdma_leave_multicast); -static int cma_netdev_change(struct net_device *ndev, struct rdma_id_private *id_priv) -{ - struct rdma_dev_addr *dev_addr; - struct cma_ndev_work *work; - - dev_addr = &id_priv->id.route.addr.dev_addr; - - if ((dev_addr->src_dev == ndev) && - memcmp(dev_addr->src_dev_addr, ndev->dev_addr, ndev->addr_len)) { - printk(KERN_INFO "RDMA CM addr change for ndev %s used by id %p\n", - ndev->name, &id_priv->id); - work = kzalloc(sizeof *work, GFP_KERNEL); - if (!work) - return -ENOMEM; - - INIT_WORK(&work->work, cma_ndev_work_handler); - work->id = id_priv; - work->event.event = RDMA_CM_EVENT_ADDR_CHANGE; - atomic_inc(&id_priv->refcount); - queue_work(cma_wq, &work->work); - } - - return 0; -} - -static int cma_netdev_callback(struct notifier_block *self, unsigned long event, - void *ctx) -{ - struct net_device *ndev = (struct net_device *)ctx; - struct cma_device *cma_dev; - struct rdma_id_private *id_priv; - int ret = NOTIFY_DONE; - - if (dev_net(ndev) != &init_net) - return NOTIFY_DONE; - - if (event != NETDEV_BONDING_FAILOVER) - return NOTIFY_DONE; - - if (!(ndev->flags & IFF_MASTER) || !(ndev->priv_flags & IFF_BONDING)) - return NOTIFY_DONE; - - mutex_lock(&lock); - list_for_each_entry(cma_dev, &dev_list, list) - list_for_each_entry(id_priv, &cma_dev->id_list, list) { - ret = cma_netdev_change(ndev, id_priv); - if (ret) - goto out; - } - -out: - mutex_unlock(&lock); - return ret; -} - -static struct notifier_block cma_nb = { - .notifier_call = cma_netdev_callback -}; - static void cma_add_one(struct ib_device *device) { struct cma_device *cma_dev; @@ -2925,7 +2831,6 @@ static int cma_init(void) ib_sa_register_client(&sa_client); rdma_addr_register_client(&addr_client); - register_netdevice_notifier(&cma_nb); ret = ib_register_client(&cma_client); if (ret) @@ -2933,7 +2838,6 @@ static int cma_init(void) return 0; err: - unregister_netdevice_notifier(&cma_nb); rdma_addr_unregister_client(&addr_client); ib_sa_unregister_client(&sa_client); destroy_workqueue(cma_wq); @@ -2943,7 +2847,6 @@ static int cma_init(void) static void cma_cleanup(void) { ib_unregister_client(&cma_client); - unregister_netdevice_notifier(&cma_nb); rdma_addr_unregister_client(&addr_client); ib_sa_unregister_client(&sa_client); destroy_workqueue(cma_wq); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_classes.h b/trunk/drivers/infiniband/hw/ehca/ehca_classes.h index 1e9e99a13933..0b0618edd645 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/trunk/drivers/infiniband/hw/ehca/ehca_classes.h @@ -194,6 +194,7 @@ struct ehca_qp { u32 packet_count; atomic_t nr_events; /* events seen */ wait_queue_head_t wait_completion; + int mig_armed; }; #define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ) diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_irq.c b/trunk/drivers/infiniband/hw/ehca/ehca_irq.c index 0792d930c481..99642a6e17c4 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_irq.c @@ -178,6 +178,10 @@ static void dispatch_qp_event(struct ehca_shca *shca, struct ehca_qp *qp, { struct ib_event event; + /* PATH_MIG without the QP ever having been armed is false alarm */ + if (event_type == IB_EVENT_PATH_MIG && !qp->mig_armed) + return; + event.device = &shca->ib_device; event.event = event_type; diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c index 3f59587338ea..ea13efddf175 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c @@ -1460,6 +1460,8 @@ static int internal_modify_qp(struct ib_qp *ibqp, goto modify_qp_exit2; } mqpcb->path_migration_state = attr->path_mig_state + 1; + if (attr->path_mig_state == IB_MIG_REARM) + my_qp->mig_armed = 1; update_mask |= EHCA_BMASK_SET(MQPCB_MASK_PATH_MIGRATION_STATE, 1); } diff --git a/trunk/drivers/infiniband/ulp/iser/iser_verbs.c b/trunk/drivers/infiniband/ulp/iser/iser_verbs.c index 63462ecca147..3a917c1f796f 100644 --- a/trunk/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/trunk/drivers/infiniband/ulp/iser/iser_verbs.c @@ -483,7 +483,6 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve break; case RDMA_CM_EVENT_DISCONNECTED: case RDMA_CM_EVENT_DEVICE_REMOVAL: - case RDMA_CM_EVENT_ADDR_CHANGE: iser_disconnected_handler(cma_id); break; default: diff --git a/trunk/include/rdma/rdma_cm.h b/trunk/include/rdma/rdma_cm.h index df7faf09d66f..22bb2e7bab1a 100644 --- a/trunk/include/rdma/rdma_cm.h +++ b/trunk/include/rdma/rdma_cm.h @@ -57,9 +57,7 @@ enum rdma_cm_event_type { RDMA_CM_EVENT_DISCONNECTED, RDMA_CM_EVENT_DEVICE_REMOVAL, RDMA_CM_EVENT_MULTICAST_JOIN, - RDMA_CM_EVENT_MULTICAST_ERROR, - RDMA_CM_EVENT_ADDR_CHANGE, - RDMA_CM_EVENT_TIMEWAIT_EXIT + RDMA_CM_EVENT_MULTICAST_ERROR }; enum rdma_port_space {