]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/core/netpoll.c
Merge tag 'riscv-for-linus-4.20-rc4' of git://git.kernel.org/pub/scm/linux/kernel...
[linux.git] / net / core / netpoll.c
index 3ae899805f8b674b4ffb7d791330f836d38eff7d..2b9fdbc43205f3d8cf826b2074493aa5e72401fb 100644 (file)
@@ -57,7 +57,6 @@ DEFINE_STATIC_SRCU(netpoll_srcu);
         MAX_UDP_CHUNK)
 
 static void zap_completion_queue(void);
-static void netpoll_async_cleanup(struct work_struct *work);
 
 static unsigned int carrier_timeout = 4;
 module_param(carrier_timeout, uint, 0644);
@@ -589,7 +588,6 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
 
        np->dev = ndev;
        strlcpy(np->dev_name, ndev->name, IFNAMSIZ);
-       INIT_WORK(&np->cleanup_work, netpoll_async_cleanup);
 
        if (ndev->priv_flags & IFF_DISABLE_NETPOLL) {
                np_err(np, "%s doesn't support polling, aborting\n",
@@ -719,7 +717,8 @@ int netpoll_setup(struct netpoll *np)
 
                                read_lock_bh(&idev->lock);
                                list_for_each_entry(ifp, &idev->addr_list, if_list) {
-                                       if (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)
+                                       if (!!(ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL) !=
+                                           !!(ipv6_addr_type(&np->remote_ip.in6) & IPV6_ADDR_LINKLOCAL))
                                                continue;
                                        np->local_ip.in6 = ifp->addr;
                                        err = 0;
@@ -788,10 +787,6 @@ void __netpoll_cleanup(struct netpoll *np)
 {
        struct netpoll_info *npinfo;
 
-       /* rtnl_dereference would be preferable here but
-        * rcu_cleanup_netpoll path can put us in here safely without
-        * holding the rtnl, so plain rcu_dereference it is
-        */
        npinfo = rtnl_dereference(np->dev->npinfo);
        if (!npinfo)
                return;
@@ -812,21 +807,16 @@ void __netpoll_cleanup(struct netpoll *np)
 }
 EXPORT_SYMBOL_GPL(__netpoll_cleanup);
 
-static void netpoll_async_cleanup(struct work_struct *work)
+void __netpoll_free(struct netpoll *np)
 {
-       struct netpoll *np = container_of(work, struct netpoll, cleanup_work);
+       ASSERT_RTNL();
 
-       rtnl_lock();
+       /* Wait for transmitting packets to finish before freeing. */
+       synchronize_rcu_bh();
        __netpoll_cleanup(np);
-       rtnl_unlock();
        kfree(np);
 }
-
-void __netpoll_free_async(struct netpoll *np)
-{
-       schedule_work(&np->cleanup_work);
-}
-EXPORT_SYMBOL_GPL(__netpoll_free_async);
+EXPORT_SYMBOL_GPL(__netpoll_free);
 
 void netpoll_cleanup(struct netpoll *np)
 {