OSDN Git Service

fakelb: fix schedule while atomic
authorAlexander Aring <aar@pengutronix.de>
Thu, 1 Sep 2016 09:24:57 +0000 (11:24 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Mar 2017 01:57:15 +0000 (09:57 +0800)
commit bdca1fd9a6df745857e23c6056494b7fe062b4e6 upstream.

This patch changes the spinlock to mutex for the available fakelb phy
list. When holding the spinlock the ieee802154_unregister_hw is called
which holding the rtnl_mutex, in that case we get a "BUG: sleeping function
called from invalid context" error. We simple change the spinlock to
mutex which allows to hold the rtnl lock there.

Signed-off-by: Alexander Aring <aar@pengutronix.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ieee802154/fakelb.c

index 860d4ae..43617de 100644 (file)
@@ -30,7 +30,7 @@
 static int numlbs = 2;
 
 static LIST_HEAD(fakelb_phys);
-static DEFINE_SPINLOCK(fakelb_phys_lock);
+static DEFINE_MUTEX(fakelb_phys_lock);
 
 static LIST_HEAD(fakelb_ifup_phys);
 static DEFINE_RWLOCK(fakelb_ifup_phys_lock);
@@ -180,9 +180,9 @@ static int fakelb_add_one(struct device *dev)
        if (err)
                goto err_reg;
 
-       spin_lock(&fakelb_phys_lock);
+       mutex_lock(&fakelb_phys_lock);
        list_add_tail(&phy->list, &fakelb_phys);
-       spin_unlock(&fakelb_phys_lock);
+       mutex_unlock(&fakelb_phys_lock);
 
        return 0;
 
@@ -214,10 +214,10 @@ static int fakelb_probe(struct platform_device *pdev)
        return 0;
 
 err_slave:
-       spin_lock(&fakelb_phys_lock);
+       mutex_lock(&fakelb_phys_lock);
        list_for_each_entry_safe(phy, tmp, &fakelb_phys, list)
                fakelb_del(phy);
-       spin_unlock(&fakelb_phys_lock);
+       mutex_unlock(&fakelb_phys_lock);
        return err;
 }
 
@@ -225,10 +225,10 @@ static int fakelb_remove(struct platform_device *pdev)
 {
        struct fakelb_phy *phy, *tmp;
 
-       spin_lock(&fakelb_phys_lock);
+       mutex_lock(&fakelb_phys_lock);
        list_for_each_entry_safe(phy, tmp, &fakelb_phys, list)
                fakelb_del(phy);
-       spin_unlock(&fakelb_phys_lock);
+       mutex_unlock(&fakelb_phys_lock);
        return 0;
 }