IB/core: Fix handling of multicast response failures
authorRalph Campbell <ralph.campbell@qlogic.com>
Thu, 20 Sep 2007 23:33:44 +0000 (16:33 -0700)
committerRoland Dreier <rolandd@cisco.com>
Wed, 10 Oct 2007 02:59:14 +0000 (19:59 -0700)
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. join operation for member1 receives failures response from SA.
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.

The impact is that the failed join request is tossed.  The second
request is processed, and after it completes, the original request ends
up being retried.

This change also results in join requests being processed in FIFO
order.

Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/core/multicast.c

index 15b4c4d3606dbc4954d399e5ef0f1d5a5d254bb0..1bc1fe60528296251f7ddf86ba85f20dcb65a8d4 100644 (file)
@@ -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);