Skip to content

Commit 6a0c435

Browse files
Hal RosenstockLinus Torvalds
authored andcommitted
[PATCH] IB: Fix timeout/cancelled MAD handling
Fixes an issue processing a sent MAD after it has timed out or been canceled. The race occurs when a response MAD matches with the send request. The request could time out or be canceled after the response MAD matches with the request, but before the request completion can be processed. Signed-off-by: Sean Hefty <[email protected]> Signed-off-by: Hal Rosenstock <[email protected]> Cc: Roland Dreier <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent d760ce8 commit 6a0c435

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

drivers/infiniband/core/mad.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
341341
spin_lock_init(&mad_agent_priv->lock);
342342
INIT_LIST_HEAD(&mad_agent_priv->send_list);
343343
INIT_LIST_HEAD(&mad_agent_priv->wait_list);
344+
INIT_LIST_HEAD(&mad_agent_priv->done_list);
344345
INIT_WORK(&mad_agent_priv->timed_work, timeout_sends, mad_agent_priv);
345346
INIT_LIST_HEAD(&mad_agent_priv->local_list);
346347
INIT_WORK(&mad_agent_priv->local_work, local_completions,
@@ -1559,6 +1560,16 @@ find_send_req(struct ib_mad_agent_private *mad_agent_priv,
15591560
return NULL;
15601561
}
15611562

1563+
static void ib_mark_req_done(struct ib_mad_send_wr_private *mad_send_wr)
1564+
{
1565+
mad_send_wr->timeout = 0;
1566+
if (mad_send_wr->refcount == 1) {
1567+
list_del(&mad_send_wr->agent_list);
1568+
list_add_tail(&mad_send_wr->agent_list,
1569+
&mad_send_wr->mad_agent_priv->done_list);
1570+
}
1571+
}
1572+
15621573
static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
15631574
struct ib_mad_recv_wc *mad_recv_wc)
15641575
{
@@ -1580,8 +1591,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
15801591
wake_up(&mad_agent_priv->wait);
15811592
return;
15821593
}
1583-
/* Timeout = 0 means that we won't wait for a response */
1584-
mad_send_wr->timeout = 0;
1594+
ib_mark_req_done(mad_send_wr);
15851595
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
15861596

15871597
/* Defined behavior is to complete response before request */

drivers/infiniband/core/mad_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct ib_mad_agent_private {
9292
spinlock_t lock;
9393
struct list_head send_list;
9494
struct list_head wait_list;
95+
struct list_head done_list;
9596
struct work_struct timed_work;
9697
unsigned long timeout;
9798
struct list_head local_list;

0 commit comments

Comments
 (0)