diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 15:56:07 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 15:56:07 -0400 |
| commit | 5c402355adf8f920531f02099f4ec0d2bccd4c64 (patch) | |
| tree | eba326f8df01efc0d384874839384040401f5b45 | |
| parent | ecc8b655b38a880b578146895e0e1e2d477ca2c0 (diff) | |
| parent | 2cc177364e4746becdf421f926fb967c047ccc32 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
MAINTAINERS: Remove Glenn Streiff from NetEffect entry
mlx4_core: Improve error message when not enough UAR pages are available
IB/mlx4: Add support for memory management extensions and local DMA L_Key
IB/mthca: Keep free count for MTT buddy allocator
mlx4_core: Keep free count for MTT buddy allocator
mlx4_code: Add missing FW status return code
IB/mlx4: Rename struct mlx4_lso_seg to mlx4_wqe_lso_seg
mlx4_core: Add module parameter to enable QoS support
RDMA/iwcm: Remove IB_ACCESS_LOCAL_WRITE from remote QP attributes
IPoIB: Include err code in trace message for ib_sa_path_rec_get() failures
IB/sa_query: Check if sm_ah is NULL in ib_sa_remove_one()
IB/ehca: Release mutex in error path of alloc_small_queue_page()
IB/ehca: Use default value for Local CA ACK Delay if FW returns 0
IB/ehca: Filter PATH_MIG events if QP was never armed
IB/iser: Add support for RDMA_CM_EVENT_ADDR_CHANGE event
RDMA/cma: Add RDMA_CM_EVENT_TIMEWAIT_EXIT event
RDMA/cma: Add RDMA_CM_EVENT_ADDR_CHANGE event
28 files changed, 396 insertions, 49 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 5ecb97e13e59..be05ef9b7b42 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -2937,8 +2937,6 @@ P: Faisal Latif | |||
| 2937 | M: flatif@neteffect.com | 2937 | M: flatif@neteffect.com |
| 2938 | P: Chien Tung | 2938 | P: Chien Tung |
| 2939 | M: ctung@neteffect.com | 2939 | M: ctung@neteffect.com |
| 2940 | P: Glenn Streiff | ||
| 2941 | M: gstreiff@neteffect.com | ||
| 2942 | L: general@lists.openfabrics.org | 2940 | L: general@lists.openfabrics.org |
| 2943 | W: http://www.neteffect.com | 2941 | W: http://www.neteffect.com |
| 2944 | S: Supported | 2942 | S: Supported |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index ae11d5cc74d0..e980ff3335db 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -168,6 +168,12 @@ struct cma_work { | |||
| 168 | struct rdma_cm_event event; | 168 | struct rdma_cm_event event; |
| 169 | }; | 169 | }; |
| 170 | 170 | ||
| 171 | struct cma_ndev_work { | ||
| 172 | struct work_struct work; | ||
| 173 | struct rdma_id_private *id; | ||
| 174 | struct rdma_cm_event event; | ||
| 175 | }; | ||
| 176 | |||
| 171 | union cma_ip_addr { | 177 | union cma_ip_addr { |
| 172 | struct in6_addr ip6; | 178 | struct in6_addr ip6; |
| 173 | struct { | 179 | struct { |
| @@ -914,7 +920,10 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
| 914 | struct rdma_cm_event event; | 920 | struct rdma_cm_event event; |
| 915 | int ret = 0; | 921 | int ret = 0; |
| 916 | 922 | ||
| 917 | if (cma_disable_callback(id_priv, CMA_CONNECT)) | 923 | if ((ib_event->event != IB_CM_TIMEWAIT_EXIT && |
| 924 | cma_disable_callback(id_priv, CMA_CONNECT)) || | ||
| 925 | (ib_event->event == IB_CM_TIMEWAIT_EXIT && | ||
| 926 | cma_disable_callback(id_priv, CMA_DISCONNECT))) | ||
| 918 | return 0; | 927 | return 0; |
| 919 | 928 | ||
| 920 | memset(&event, 0, sizeof event); | 929 | memset(&event, 0, sizeof event); |
| @@ -950,6 +959,8 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
| 950 | event.event = RDMA_CM_EVENT_DISCONNECTED; | 959 | event.event = RDMA_CM_EVENT_DISCONNECTED; |
| 951 | break; | 960 | break; |
| 952 | case IB_CM_TIMEWAIT_EXIT: | 961 | case IB_CM_TIMEWAIT_EXIT: |
| 962 | event.event = RDMA_CM_EVENT_TIMEWAIT_EXIT; | ||
| 963 | break; | ||
| 953 | case IB_CM_MRA_RECEIVED: | 964 | case IB_CM_MRA_RECEIVED: |
| 954 | /* ignore event */ | 965 | /* ignore event */ |
| 955 | goto out; | 966 | goto out; |
| @@ -1598,6 +1609,30 @@ out: | |||
| 1598 | kfree(work); | 1609 | kfree(work); |
| 1599 | } | 1610 | } |
| 1600 | 1611 | ||
| 1612 | static void cma_ndev_work_handler(struct work_struct *_work) | ||
| 1613 | { | ||
| 1614 | struct cma_ndev_work *work = container_of(_work, struct cma_ndev_work, work); | ||
| 1615 | struct rdma_id_private *id_priv = work->id; | ||
| 1616 | int destroy = 0; | ||
| 1617 | |||
| 1618 | mutex_lock(&id_priv->handler_mutex); | ||
| 1619 | if (id_priv->state == CMA_DESTROYING || | ||
| 1620 | id_priv->state == CMA_DEVICE_REMOVAL) | ||
| 1621 | goto out; | ||
| 1622 | |||
| 1623 | if (id_priv->id.event_handler(&id_priv->id, &work->event)) { | ||
| 1624 | cma_exch(id_priv, CMA_DESTROYING); | ||
| 1625 | destroy = 1; | ||
| 1626 | } | ||
| 1627 | |||
| 1628 | out: | ||
| 1629 | mutex_unlock(&id_priv->handler_mutex); | ||
| 1630 | cma_deref_id(id_priv); | ||
| 1631 | if (destroy) | ||
| 1632 | rdma_destroy_id(&id_priv->id); | ||
| 1633 | kfree(work); | ||
| 1634 | } | ||
| 1635 | |||
| 1601 | static int cma_resolve_ib_route(struct rdma_id_private *id_priv, int timeout_ms) | 1636 | static int cma_resolve_ib_route(struct rdma_id_private *id_priv, int timeout_ms) |
| 1602 | { | 1637 | { |
| 1603 | struct rdma_route *route = &id_priv->id.route; | 1638 | struct rdma_route *route = &id_priv->id.route; |
| @@ -2723,6 +2758,65 @@ void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr) | |||
| 2723 | } | 2758 | } |
| 2724 | EXPORT_SYMBOL(rdma_leave_multicast); | 2759 | EXPORT_SYMBOL(rdma_leave_multicast); |
| 2725 | 2760 | ||
| 2761 | static int cma_netdev_change(struct net_device *ndev, struct rdma_id_private *id_priv) | ||
| 2762 | { | ||
| 2763 | struct rdma_dev_addr *dev_addr; | ||
| 2764 | struct cma_ndev_work *work; | ||
| 2765 | |||
| 2766 | dev_addr = &id_priv->id.route.addr.dev_addr; | ||
| 2767 | |||
| 2768 | if ((dev_addr->src_dev == ndev) && | ||
| 2769 | memcmp(dev_addr->src_dev_addr, ndev->dev_addr, ndev->addr_len)) { | ||
| 2770 | printk(KERN_INFO "RDMA CM addr change for ndev %s used by id %p\n", | ||
| 2771 | ndev->name, &id_priv->id); | ||
| 2772 | work = kzalloc(sizeof *work, GFP_KERNEL); | ||
| 2773 | if (!work) | ||
| 2774 | return -ENOMEM; | ||
| 2775 | |||
| 2776 | INIT_WORK(&work->work, cma_ndev_work_handler); | ||
| 2777 | work->id = id_priv; | ||
| 2778 | work->event.event = RDMA_CM_EVENT_ADDR_CHANGE; | ||
| 2779 | atomic_inc(&id_priv->refcount); | ||
| 2780 | queue_work(cma_wq, &work->work); | ||
| 2781 | } | ||
| 2782 | |||
| 2783 | return 0; | ||
| 2784 | } | ||
| 2785 | |||
| 2786 | static int cma_netdev_callback(struct notifier_block *self, unsigned long event, | ||
| 2787 | void *ctx) | ||
| 2788 | { | ||
| 2789 | struct net_device *ndev = (struct net_device *)ctx; | ||
| 2790 | struct cma_device *cma_dev; | ||
| 2791 | struct rdma_id_private *id_priv; | ||
| 2792 | int ret = NOTIFY_DONE; | ||
| 2793 | |||
| 2794 | if (dev_net(ndev) != &init_net) | ||
| 2795 | return NOTIFY_DONE; | ||
| 2796 | |||
| 2797 | if (event != NETDEV_BONDING_FAILOVER) | ||
| 2798 | return NOTIFY_DONE; | ||
| 2799 | |||
| 2800 | if (!(ndev->flags & IFF_MASTER) || !(ndev->priv_flags & IFF_BONDING)) | ||
| 2801 | return NOTIFY_DONE; | ||
| 2802 | |||
| 2803 | mutex_lock(&lock); | ||
| 2804 | list_for_each_entry(cma_dev, &dev_list, list) | ||
| 2805 | list_for_each_entry(id_priv, &cma_dev->id_list, list) { | ||
| 2806 | ret = cma_netdev_change(ndev, id_priv); | ||
| 2807 | if (ret) | ||
| 2808 | goto out; | ||
| 2809 | } | ||
| 2810 | |||
| 2811 | out: | ||
| 2812 | mutex_unlock(&lock); | ||
| 2813 | |||
