[haiku-commits] haiku: hrev51071 - src/add-ons/kernel/network/stack

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 6 Apr 2017 18:20:57 +0200 (CEST)

hrev51071 adds 1 changeset to branch 'master'
old head: ceff2b88ae26f78af0f954d8836ab50765ff7733
new head: f17488662a661029abeba1594c92904f7670c406
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=f17488662a66+%5Eceff2b88ae26

----------------------------------------------------------------------------

f17488662a66: network stack: Fixed double mutex lock.
  
  * device_removed() no longer uses get_device_interface() to avoid
    the double locking.
  * Introduced net_device_interface::busy member to avoid locking in
    device_removed() for too long.
  * This should fix #7252.

                                   [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev51071
Commit:      f17488662a661029abeba1594c92904f7670c406
URL:         http://cgit.haiku-os.org/haiku/commit/?id=f17488662a66
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Thu Apr  6 16:14:52 2017 UTC

Ticket:      https://dev.haiku-os.org/ticket/7252

----------------------------------------------------------------------------

2 files changed, 23 insertions(+), 7 deletions(-)
.../kernel/network/stack/device_interfaces.cpp   | 25 ++++++++++++++++----
.../kernel/network/stack/device_interfaces.h     |  5 ++--

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/network/stack/device_interfaces.cpp 
b/src/add-ons/kernel/network/stack/device_interfaces.cpp
index 0143360..27dc784 100644
--- a/src/add-ons/kernel/network/stack/device_interfaces.cpp
+++ b/src/add-ons/kernel/network/stack/device_interfaces.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2017, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -152,6 +152,7 @@ domain_receive_adapter(void* cookie, net_device* device, 
net_buffer* buffer)
 static net_device_interface*
 find_device_interface(const char* name)
 {
+       ASSERT_LOCKED_MUTEX(&sLock);
        DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
 
        while (net_device_interface* interface = iterator.Next()) {
@@ -182,6 +183,7 @@ allocate_device_interface(net_device* device, 
net_device_module_info* module)
        interface->device = device;
        interface->up_count = 0;
        interface->ref_count = 1;
+       interface->busy = false;
        interface->monitor_count = 0;
        interface->deframe_func = NULL;
        interface->deframe_ref_count = 0;
@@ -409,6 +411,9 @@ get_device_interface(uint32 index)
        DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
        while (net_device_interface* interface = iterator.Next()) {
                if (interface->device->index == index) {
+                       if (interface->busy)
+                               break;
+
                        if (atomic_add(&interface->ref_count, 1) != 0)
                                return interface;
                }
@@ -428,6 +433,9 @@ get_device_interface(const char* name, bool create)
 
        net_device_interface* interface = find_device_interface(name);
        if (interface != NULL) {
+               if (interface->busy)
+                       return NULL;
+
                if (atomic_add(&interface->ref_count, 1) != 0)
                        return interface;
 
@@ -763,11 +771,17 @@ device_removed(net_device* device)
 {
        MutexLocker locker(sLock);
 
-       // hold a reference to the device interface being removed
-       // so our put_() will (eventually) do the final cleanup
-       net_device_interface* interface = get_device_interface(device->name, 
false);
+       net_device_interface* interface = find_device_interface(device->name);
        if (interface == NULL)
                return B_DEVICE_NOT_FOUND;
+       if (interface->busy)
+               return B_BUSY;
+
+       // Acquire a reference to the device interface being removed
+       // so our put_() will (eventually) do the final cleanup
+       atomic_add(&interface->ref_count, 1);
+       interface->busy = true;
+       locker.Unlock();
 
        // Propagate the loss of the device throughout the stack.
 
@@ -776,8 +790,9 @@ device_removed(net_device* device)
 
        // By now all of the monitors must have removed themselves. If they
        // didn't, they'll probably wait forever to be callback'ed again.
-       recursive_lock_lock(&interface->monitor_lock);
+       RecursiveLocker monitorLocker(interface->monitor_lock);
        interface->monitor_funcs.RemoveAll();
+       monitorLocker.Unlock();
 
        // All of the readers should be gone as well since we are out of
        // interfaces and put_domain_datalink_protocols() is called for
diff --git a/src/add-ons/kernel/network/stack/device_interfaces.h 
b/src/add-ons/kernel/network/stack/device_interfaces.h
index 958448e..fef47f5 100644
--- a/src/add-ons/kernel/network/stack/device_interfaces.h
+++ b/src/add-ons/kernel/network/stack/device_interfaces.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2017, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -32,12 +32,13 @@ struct net_device_interface : 
DoublyLinkedListLinkImpl<net_device_interface> {
        uint32                          up_count;
                // a device can be brought up by more than one interface
        int32                           ref_count;
+       bool                            busy;
 
        net_deframe_func        deframe_func;
        int32                           deframe_ref_count;
 
        int32                           monitor_count;
-       recursive_lock                  monitor_lock;
+       recursive_lock          monitor_lock;
        DeviceMonitorList       monitor_funcs;
 
        DeviceHandlerList       receive_funcs;


Other related posts:

  • » [haiku-commits] haiku: hrev51071 - src/add-ons/kernel/network/stack - axeld