Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Stop using softnet_lock (fix possible deadlock)



details:   https://anonhg.NetBSD.org/src/rev/fe82fd8ce2b6
branches:  trunk
changeset: 341137:fe82fd8ce2b6
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Tue Oct 20 07:35:15 2015 +0000

description:
Stop using softnet_lock (fix possible deadlock)

Using softnet_lock for mutual exclusion between lltable_free and
arptimer was wrong and had an issue causing a deadlock between
them;  lltable_free waits arptimer completion by calling
callout_halt with softnet_lock that is held in arptimer, however
lltable_free also holds llentry's lock that is also held in
arptimer so arptimer never obtain the lock and both never go
forward eventually.  We have to pass llentry's lock to
callout_halt instead.

diffstat:

 sys/net/if_llatbl.c  |   6 ++----
 sys/netinet/if_arp.c |  15 +++++----------
 2 files changed, 7 insertions(+), 14 deletions(-)

diffs (87 lines):

diff -r 94088612701c -r fe82fd8ce2b6 sys/net/if_llatbl.c
--- a/sys/net/if_llatbl.c       Mon Oct 19 23:31:26 2015 +0000
+++ b/sys/net/if_llatbl.c       Tue Oct 20 07:35:15 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_llatbl.c,v 1.6 2015/09/30 07:12:32 ozaki-r Exp $    */
+/*     $NetBSD: if_llatbl.c,v 1.7 2015/10/20 07:35:15 ozaki-r Exp $    */
 /*
  * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
  * Copyright (c) 2004-2008 Qing Li. All rights reserved.
@@ -364,7 +364,6 @@
 
        lltable_unlink(llt);
 
-       mutex_enter(softnet_lock);
        LIST_INIT(&dchain);
        IF_AFDATA_WLOCK(llt->llt_ifp);
        /* Push all lles to @dchain */
@@ -373,7 +372,7 @@
        IF_AFDATA_WUNLOCK(llt->llt_ifp);
 
        LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) {
-               if (callout_halt(&lle->la_timer, softnet_lock))
+               if (callout_halt(&lle->la_timer, &lle->lle_lock))
                        LLE_REMREF(lle);
 #if defined(__NetBSD__)
                /* XXX should have callback? */
@@ -394,7 +393,6 @@
 #endif
                llentry_free(lle);
        }
-       mutex_exit(softnet_lock);
 
        llt->llt_free_tbl(llt);
 }
diff -r 94088612701c -r fe82fd8ce2b6 sys/netinet/if_arp.c
--- a/sys/netinet/if_arp.c      Mon Oct 19 23:31:26 2015 +0000
+++ b/sys/netinet/if_arp.c      Tue Oct 20 07:35:15 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_arp.c,v 1.189 2015/10/14 11:22:55 roy Exp $ */
+/*     $NetBSD: if_arp.c,v 1.190 2015/10/20 07:35:15 ozaki-r Exp $     */
 
 /*-
  * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.189 2015/10/14 11:22:55 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.190 2015/10/20 07:35:15 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -317,13 +317,11 @@
        struct ifnet *ifp;
        struct rtentry *rt;
 
-       mutex_enter(softnet_lock);
-
        if (lle == NULL)
-               goto out;
+               return;
 
        if (lle->la_flags & LLE_STATIC)
-               goto out;
+               return;
 
        LLE_WLOCK(lle);
        if (callout_pending(&lle->la_timer)) {
@@ -343,7 +341,7 @@
                 * by arpresolve() below.
                 */
                LLE_WUNLOCK(lle);
-               goto out;
+               return;
        }
        ifp = lle->lle_tbl->llt_ifp;
        rt = lle->la_rt;
@@ -374,9 +372,6 @@
        }
 
        IF_AFDATA_UNLOCK(ifp);
-
-out:
-       mutex_exit(softnet_lock);
 }
 
 /*



Home | Main Index | Thread Index | Old Index