aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorHal Rosenstock <halr@voltaire.com>2005-07-27 14:45:33 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-27 19:26:12 -0400
commitcabe3cbcbb3b09637b9e706c49eadb180fca057e (patch)
tree37c9179b4f43d7a63e7d55ae6a77a9fb44537b0c /drivers/infiniband
parent29bb33dd87dbe8db07c2b19df3fb453d999c96de (diff)
[PATCH] IB: Fix a couple of MAD code paths
Fixed locking to handle error posting MAD send work requests. Fixed handling canceling a MAD with an active work request. Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Hal Rosenstock <halr@voltaire.com> Cc: Roland Dreier <rolandd@cisco.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/mad.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 1d8f26f54ec9..8216af0ba783 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -841,6 +841,7 @@ static int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr)
841{ 841{
842 struct ib_mad_qp_info *qp_info; 842 struct ib_mad_qp_info *qp_info;
843 struct ib_send_wr *bad_send_wr; 843 struct ib_send_wr *bad_send_wr;
844 struct list_head *list;
844 unsigned long flags; 845 unsigned long flags;
845 int ret; 846 int ret;
846 847
@@ -850,22 +851,20 @@ static int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr)
850 mad_send_wr->mad_list.mad_queue = &qp_info->send_queue; 851 mad_send_wr->mad_list.mad_queue = &qp_info->send_queue;
851 852
852 spin_lock_irqsave(&qp_info->send_queue.lock, flags); 853 spin_lock_irqsave(&qp_info->send_queue.lock, flags);
853 if (qp_info->send_queue.count++ < qp_info->send_queue.max_active) { 854 if (qp_info->send_queue.count < qp_info->send_queue.max_active) {
854 list_add_tail(&mad_send_wr->mad_list.list,
855 &qp_info->send_queue.list);
856 spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
857 ret = ib_post_send(mad_send_wr->mad_agent_priv->agent.qp, 855 ret = ib_post_send(mad_send_wr->mad_agent_priv->agent.qp,
858 &mad_send_wr->send_wr, &bad_send_wr); 856 &mad_send_wr->send_wr, &bad_send_wr);
859 if (ret) { 857 list = &qp_info->send_queue.list;
860 printk(KERN_ERR PFX "ib_post_send failed: %d\n", ret);
861 dequeue_mad(&mad_send_wr->mad_list);
862 }
863 } else { 858 } else {
864 list_add_tail(&mad_send_wr->mad_list.list,
865 &qp_info->overflow_list);
866 spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
867 ret = 0; 859 ret = 0;
860 list = &qp_info->overflow_list;
868 } 861 }
862
863 if (!ret) {
864 qp_info->send_queue.count++;
865 list_add_tail(&mad_send_wr->mad_list.list, list);
866 }
867 spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
869 return ret; 868 return ret;
870} 869}
871 870
@@ -2023,8 +2022,7 @@ static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv)
2023} 2022}
2024 2023
2025static struct ib_mad_send_wr_private* 2024static struct ib_mad_send_wr_private*
2026find_send_by_wr_id(struct ib_mad_agent_private *mad_agent_priv, 2025find_send_by_wr_id(struct ib_mad_agent_private *mad_agent_priv, u64 wr_id)
2027 u64 wr_id)
2028{ 2026{
2029 struct ib_mad_send_wr_private *mad_send_wr; 2027 struct ib_mad_send_wr_private *mad_send_wr;
2030 2028
@@ -2047,6 +2045,7 @@ int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms)
2047 struct ib_mad_agent_private *mad_agent_priv; 2045 struct ib_mad_agent_private *mad_agent_priv;
2048 struct ib_mad_send_wr_private *mad_send_wr; 2046 struct ib_mad_send_wr_private *mad_send_wr;
2049 unsigned long flags; 2047 unsigned long flags;
2048 int active;
2050 2049
2051 mad_agent_priv = container_of(mad_agent, struct ib_mad_agent_private, 2050 mad_agent_priv = container_of(mad_agent, struct ib_mad_agent_private,
2052 agent); 2051 agent);
@@ -2057,13 +2056,14 @@ int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms)
2057 return -EINVAL; 2056 return -EINVAL;
2058 } 2057 }
2059 2058
2059 active = (!mad_send_wr->timeout || mad_send_wr->refcount > 1);
2060 if (!timeout_ms) { 2060 if (!timeout_ms) {
2061 mad_send_wr->status = IB_WC_WR_FLUSH_ERR; 2061 mad_send_wr->status = IB_WC_WR_FLUSH_ERR;
2062 mad_send_wr->refcount -= (mad_send_wr->timeout > 0); 2062 mad_send_wr->refcount -= (mad_send_wr->timeout > 0);
2063 } 2063 }
2064 2064
2065 mad_send_wr->send_wr.wr.ud.timeout_ms = timeout_ms; 2065 mad_send_wr->send_wr.wr.ud.timeout_ms = timeout_ms;
2066 if (!mad_send_wr->timeout || mad_send_wr->refcount > 1) 2066 if (active)
2067 mad_send_wr->timeout = msecs_to_jiffies(timeout_ms); 2067 mad_send_wr->timeout = msecs_to_jiffies(timeout_ms);
2068 else 2068 else
2069 ib_reset_mad_timeout(mad_send_wr, timeout_ms); 2069 ib_reset_mad_timeout(mad_send_wr, timeout_ms);