diff options
| -rw-r--r-- | drivers/infiniband/core/mad.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 16549add8e8f..f7854b65fd55 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
| @@ -2364,8 +2364,12 @@ static void timeout_sends(void *data) | |||
| 2364 | static void ib_mad_thread_completion_handler(struct ib_cq *cq, void *arg) | 2364 | static void ib_mad_thread_completion_handler(struct ib_cq *cq, void *arg) |
| 2365 | { | 2365 | { |
| 2366 | struct ib_mad_port_private *port_priv = cq->cq_context; | 2366 | struct ib_mad_port_private *port_priv = cq->cq_context; |
| 2367 | unsigned long flags; | ||
| 2367 | 2368 | ||
| 2368 | queue_work(port_priv->wq, &port_priv->work); | 2369 | spin_lock_irqsave(&ib_mad_port_list_lock, flags); |
| 2370 | if (!list_empty(&port_priv->port_list)) | ||
| 2371 | queue_work(port_priv->wq, &port_priv->work); | ||
| 2372 | spin_unlock_irqrestore(&ib_mad_port_list_lock, flags); | ||
| 2369 | } | 2373 | } |
| 2370 | 2374 | ||
| 2371 | /* | 2375 | /* |
| @@ -2677,18 +2681,23 @@ static int ib_mad_port_open(struct ib_device *device, | |||
| 2677 | } | 2681 | } |
| 2678 | INIT_WORK(&port_priv->work, ib_mad_completion_handler, port_priv); | 2682 | INIT_WORK(&port_priv->work, ib_mad_completion_handler, port_priv); |
| 2679 | 2683 | ||
| 2684 | spin_lock_irqsave(&ib_mad_port_list_lock, flags); | ||
| 2685 | list_add_tail(&port_priv->port_list, &ib_mad_port_list); | ||
| 2686 | spin_unlock_irqrestore(&ib_mad_port_list_lock, flags); | ||
| 2687 | |||
| 2680 | ret = ib_mad_port_start(port_priv); | 2688 | ret = ib_mad_port_start(port_priv); |
| 2681 | if (ret) { | 2689 | if (ret) { |
| 2682 | printk(KERN_ERR PFX "Couldn't start port\n"); | 2690 | printk(KERN_ERR PFX "Couldn't start port\n"); |
| 2683 | goto error9; | 2691 | goto error9; |
| 2684 | } | 2692 | } |
| 2685 | 2693 | ||
| 2686 | spin_lock_irqsave(&ib_mad_port_list_lock, flags); | ||
| 2687 | list_add_tail(&port_priv->port_list, &ib_mad_port_list); | ||
| 2688 | spin_unlock_irqrestore(&ib_mad_port_list_lock, flags); | ||
| 2689 | return 0; | 2694 | return 0; |
| 2690 | 2695 | ||
| 2691 | error9: | 2696 | error9: |
| 2697 | spin_lock_irqsave(&ib_mad_port_list_lock, flags); | ||
| 2698 | list_del_init(&port_priv->port_list); | ||
| 2699 | spin_unlock_irqrestore(&ib_mad_port_list_lock, flags); | ||
| 2700 | |||
| 2692 | destroy_workqueue(port_priv->wq); | 2701 | destroy_workqueue(port_priv->wq); |
| 2693 | error8: | 2702 | error8: |
| 2694 | destroy_mad_qp(&port_priv->qp_info[1]); | 2703 | destroy_mad_qp(&port_priv->qp_info[1]); |
| @@ -2725,11 +2734,9 @@ static int ib_mad_port_close(struct ib_device *device, int port_num) | |||
| 2725 | printk(KERN_ERR PFX "Port %d not found\n", port_num); | 2734 | printk(KERN_ERR PFX "Port %d not found\n", port_num); |
| 2726 | return -ENODEV; | 2735 | return -ENODEV; |
| 2727 | } | 2736 | } |
| 2728 | list_del(&port_priv->port_list); | 2737 | list_del_init(&port_priv->port_list); |
| 2729 | spin_unlock_irqrestore(&ib_mad_port_list_lock, flags); | 2738 | spin_unlock_irqrestore(&ib_mad_port_list_lock, flags); |
| 2730 | 2739 | ||
| 2731 | /* Stop processing completions. */ | ||
| 2732 | flush_workqueue(port_priv->wq); | ||
| 2733 | destroy_workqueue(port_priv->wq); | 2740 | destroy_workqueue(port_priv->wq); |
| 2734 | destroy_mad_qp(&port_priv->qp_info[1]); | 2741 | destroy_mad_qp(&port_priv->qp_info[1]); |
| 2735 | destroy_mad_qp(&port_priv->qp_info[0]); | 2742 | destroy_mad_qp(&port_priv->qp_info[0]); |
