[ofa-general] [PATCH] IB/core - possible bug in handling link down in ib_sa_join_multicast()

Ralph Campbell ralph.campbell at qlogic.com
Thu Sep 20 16:33:44 PDT 2007


I was looking at the code for multicast.c and noticed that
ib_sa_join_multicast() calls queue_join() which puts the
request at the front of the group->pending_list.  If this
is a second request, it seems like it would interfere with
process_join_error() since group->last_join won't point
to the member at the head of the pending_list. The sequence
would thus be:

1. ib_sa_join_multicast()
   // puts member1 on head of pending_list and starts work thread
2. mcast_work_handler()
   // calls send_join() which sets group->last_join to member1
3. ib_sa_join_multicast()
   // puts member2 on head of pending_list
4. IB_EVENT_PORT_ERR event calls mcast_groups_lost()
   // sets group->state to MCAST_ERROR
5. join_handler() is called with error status
6. process_join_error() fails to process member1 since
   it doesn't match the first entry in the group->pending_list.

Signed-off-by: Ralph Campbell <ralph.campbell at qlogic.com>

diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c
index 15b4c4d..1bc1fe6 100644
--- a/drivers/infiniband/core/multicast.c
+++ b/drivers/infiniband/core/multicast.c
@@ -196,7 +196,7 @@ static void queue_join(struct mcast_member *member)
 	unsigned long flags;
 
 	spin_lock_irqsave(&group->lock, flags);
-	list_add(&member->list, &group->pending_list);
+	list_add_tail(&member->list, &group->pending_list);
 	if (group->state == MCAST_IDLE) {
 		group->state = MCAST_BUSY;
 		atomic_inc(&group->refcount);





More information about the general mailing list