qeth: avoid duplicate deletion of multicast addresses
authorUrsula Braun <braunu@de.ibm.com>
Fri, 5 Oct 2007 14:45:46 +0000 (16:45 +0200)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 10 Oct 2007 23:54:41 +0000 (16:54 -0700)
if qeth_set_multicast_list() is performed on 2 CPUs in parallel,
card->ip_list may end corrupted.
Solution: In function __qeth_delete_all_mc()
          remove card->ip_list entry before invoking
          qeth_deregister_addr_entry(). Thus a 2nd invocation of
          qeth_set_multicast_list() cannot try to remove the
          same entry twice.

Signed-off-by Ursula Braun <braunu@de.ibm.com>

Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/s390/net/qeth_main.c

index fe6164795edaf720cc482cf938741f0331d7feab..6d7b79e2ba928a523ea0ecf1f0b4f74b45018540 100644 (file)
@@ -823,14 +823,15 @@ __qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags)
 again:
        list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) {
                if (addr->is_multicast) {
+                       list_del(&addr->entry);
                        spin_unlock_irqrestore(&card->ip_lock, *flags);
                        rc = qeth_deregister_addr_entry(card, addr);
                        spin_lock_irqsave(&card->ip_lock, *flags);
                        if (!rc) {
-                               list_del(&addr->entry);
                                kfree(addr);
                                goto again;
-                       }
+                       } else
+                               list_add(&addr->entry, &card->ip_list);
                }
        }
 }