netpoll: make __netpoll_cleanup non-block
[pandora-kernel.git] / net / bridge / br_device.c
index 929e48a..f41ba40 100644 (file)
@@ -127,9 +127,9 @@ static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev,
                const struct br_cpu_netstats *bstats
                        = per_cpu_ptr(br->stats, cpu);
                do {
-                       start = u64_stats_fetch_begin(&bstats->syncp);
+                       start = u64_stats_fetch_begin_bh(&bstats->syncp);
                        memcpy(&tmp, bstats, sizeof(tmp));
-               } while (u64_stats_fetch_retry(&bstats->syncp, start));
+               } while (u64_stats_fetch_retry_bh(&bstats->syncp, start));
                sum.tx_bytes   += tmp.tx_bytes;
                sum.tx_packets += tmp.tx_packets;
                sum.rx_bytes   += tmp.rx_bytes;
@@ -213,7 +213,8 @@ static void br_netpoll_cleanup(struct net_device *dev)
        }
 }
 
-static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
+static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni,
+                           gfp_t gfp)
 {
        struct net_bridge *br = netdev_priv(dev);
        struct net_bridge_port *p, *n;
@@ -222,8 +223,7 @@ static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
        list_for_each_entry_safe(p, n, &br->port_list, list) {
                if (!p->dev)
                        continue;
-
-               err = br_netpoll_enable(p);
+               err = br_netpoll_enable(p, gfp);
                if (err)
                        goto fail;
        }
@@ -236,20 +236,17 @@ fail:
        goto out;
 }
 
-int br_netpoll_enable(struct net_bridge_port *p)
+int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp)
 {
        struct netpoll *np;
        int err = 0;
 
-       np = kzalloc(sizeof(*p->np), GFP_KERNEL);
+       np = kzalloc(sizeof(*p->np), gfp);
        err = -ENOMEM;
        if (!np)
                goto out;
 
-       np->dev = p->dev;
-       strlcpy(np->dev_name, p->dev->name, IFNAMSIZ);
-
-       err = __netpoll_setup(np);
+       err = __netpoll_setup(np, p->dev, gfp);
        if (err) {
                kfree(np);
                goto out;
@@ -270,11 +267,7 @@ void br_netpoll_disable(struct net_bridge_port *p)
 
        p->np = NULL;
 
-       /* Wait for transmitting packets to finish before freeing. */
-       synchronize_rcu_bh();
-
-       __netpoll_cleanup(np);
-       kfree(np);
+       __netpoll_free_rcu(np);
 }
 
 #endif