Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet Don't pass rwlock to callout_halt



details:   https://anonhg.NetBSD.org/src/rev/80771f5ea8a9
branches:  trunk
changeset: 358388:80771f5ea8a9
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Wed Dec 27 08:35:20 2017 +0000

description:
Don't pass rwlock to callout_halt

diffstat:

 sys/netinet/in.c |  26 ++++++++++++++++++++++----
 1 files changed, 22 insertions(+), 4 deletions(-)

diffs (61 lines):

diff -r d6a991910b2f -r 80771f5ea8a9 sys/netinet/in.c
--- a/sys/netinet/in.c  Wed Dec 27 08:29:02 2017 +0000
+++ b/sys/netinet/in.c  Wed Dec 27 08:35:20 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in.c,v 1.212 2017/12/25 04:41:48 ozaki-r Exp $ */
+/*     $NetBSD: in.c,v 1.213 2017/12/27 08:35:20 ozaki-r Exp $ */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.212 2017/12/25 04:41:48 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.213 2017/12/27 08:35:20 ozaki-r Exp $");
 
 #include "arp.h"
 
@@ -1953,6 +1953,7 @@
 {
        struct ifnet *ifp __diagused;
        size_t pkts_dropped;
+       bool locked = false;
 
        LLE_WLOCK_ASSERT(lle);
        KASSERT(llt != NULL);
@@ -1962,15 +1963,32 @@
                ifp = llt->llt_ifp;
                IF_AFDATA_WLOCK_ASSERT(ifp);
                lltable_unlink_entry(llt, lle);
+               locked = true;
        }
 
+       /*
+        * We need to release the lock here to lle_timer proceeds;
+        * lle_timer should stop immediately if LLE_LINKED isn't set.
+        * Note that we cannot pass lle->lle_lock to callout_halt
+        * because it's a rwlock.
+        */
+       LLE_ADDREF(lle);
+       LLE_WUNLOCK(lle);
+       if (locked)
+               IF_AFDATA_WUNLOCK(ifp);
+
        /* cancel timer */
-       if (callout_halt(&lle->lle_timer, &lle->lle_lock))
-               LLE_REMREF(lle);
+       callout_halt(&lle->lle_timer, NULL);
+
+       LLE_WLOCK(lle);
+       LLE_REMREF(lle);
 
        /* Drop hold queue */
        pkts_dropped = llentry_free(lle);
        arp_stat_add(ARP_STAT_DFRDROPPED, (uint64_t)pkts_dropped);
+
+       if (locked)
+               IF_AFDATA_WLOCK(ifp);
 }
 
 static int



Home | Main Index | Thread Index | Old Index