mp->br = br;
        mp->addr = *group;
-       setup_timer(&mp->timer, br_multicast_group_expired,
-                   (unsigned long)mp);
 
        hlist_add_head_rcu(&mp->hlist[mdb->ver], &mdb->mhash[hash]);
        mdb->size++;
        struct net_bridge_mdb_entry *mp;
        struct net_bridge_port_group *p;
        struct net_bridge_port_group __rcu **pp;
-       unsigned long now = jiffies;
        int err;
 
        spin_lock(&br->multicast_lock);
 
        if (!port) {
                mp->mglist = true;
-               mod_timer(&mp->timer, now + br->multicast_membership_interval);
                goto out;
        }
 
             (p = mlock_dereference(*pp, br)) != NULL;
             pp = &p->next) {
                if (p->port == port)
-                       goto found;
+                       goto out;
                if ((unsigned long)p->port < (unsigned long)port)
                        break;
        }
        rcu_assign_pointer(*pp, p);
        br_mdb_notify(br->dev, port, group, RTM_NEWMDB);
 
-found:
-       mod_timer(&p->timer, now + br->multicast_membership_interval);
 out:
        err = 0;
 
        if (!mp)
                goto out;
 
+       setup_timer(&mp->timer, br_multicast_group_expired, (unsigned long)mp);
+       mod_timer(&mp->timer, now + br->multicast_membership_interval);
+       mp->timer_armed = true;
+
        max_delay *= br->multicast_last_member_count;
 
        if (mp->mglist &&
        if (!mp)
                goto out;
 
+       setup_timer(&mp->timer, br_multicast_group_expired, (unsigned long)mp);
+       mod_timer(&mp->timer, now + br->multicast_membership_interval);
+       mp->timer_armed = true;
+
        max_delay *= br->multicast_last_member_count;
        if (mp->mglist &&
            (timer_pending(&mp->timer) ?
                        call_rcu_bh(&p->rcu, br_multicast_free_pg);
                        br_mdb_notify(br->dev, port, group, RTM_DELMDB);
 
-                       if (!mp->ports && !mp->mglist &&
+                       if (!mp->ports && !mp->mglist && mp->timer_armed &&
                            netif_running(br->dev))
                                mod_timer(&mp->timer, jiffies);
                }
                     br->multicast_last_member_interval;
 
        if (!port) {
-               if (mp->mglist &&
+               if (mp->mglist && mp->timer_armed &&
                    (timer_pending(&mp->timer) ?
                     time_after(mp->timer.expires, time) :
                     try_to_del_timer_sync(&mp->timer) >= 0)) {
                        mod_timer(&mp->timer, time);
                }
-
-               goto out;
-       }
-
-       for (p = mlock_dereference(mp->ports, br);
-            p != NULL;
-            p = mlock_dereference(p->next, br)) {
-               if (p->port != port)
-                       continue;
-
-               if (!hlist_unhashed(&p->mglist) &&
-                   (timer_pending(&p->timer) ?
-                    time_after(p->timer.expires, time) :
-                    try_to_del_timer_sync(&p->timer) >= 0)) {
-                       mod_timer(&p->timer, time);
-               }
-
-               break;
        }
 
 out:
                hlist_for_each_entry_safe(mp, n, &mdb->mhash[i],
                                          hlist[ver]) {
                        del_timer(&mp->timer);
+                       mp->timer_armed = false;
                        call_rcu_bh(&mp->rcu, br_multicast_free_group);
                }
        }