summaryrefslogtreecommitdiff
path: root/target/linux/generic/files/drivers
diff options
context:
space:
mode:
authorPavel Kubelun <be.dissent@gmail.com>2016-11-28 15:21:42 +0300
committerJohn Crispin <john@phrozen.org>2016-12-01 15:47:43 +0100
commiteb049d3777ce6e50ae830a41f9308c270cb26858 (patch)
tree3c5461d4120545f05e7987758cde12078ed55447 /target/linux/generic/files/drivers
parent65b20d8b64bb5c6d8b9375d3952899b6aaaa302e (diff)
downloadmtk-20170518-eb049d3777ce6e50ae830a41f9308c270cb26858.zip
mtk-20170518-eb049d3777ce6e50ae830a41f9308c270cb26858.tar.gz
mtk-20170518-eb049d3777ce6e50ae830a41f9308c270cb26858.tar.bz2
net: ar8216: hold ar8xxx_dev_list_lock during use_count--
Import from https://chromium.googlesource.com/chromiumos/third_party/kernel/+/c3fd96a7b87da23979d8569ce45447f8419ca303%5E%21/#F0 Signed-off-by: Pavel Kubelun <be.dissent@gmail.com> CHROMIUM: drivers: ar8216: hold ar8xxx_dev_list_lock during use_count-- It is possible for the remove() callback to run twice in parallel, which could result into --use_count returning only 1 in both cases and the rest of the unregistration path to never be reached. This case has never been observed in practice, but we will fix preventively to make the code more robust. BUG=chrome-os-partner:33096 TEST=none Change-Id: If09abe27fdb2037f514f8674418bafaab3cbdef6 Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org> Reviewed-on: https://chromium-review.googlesource.com/232870 Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Reviewed-by: Toshi Kikuchi <toshik@chromium.org> Tested-by: Toshi Kikuchi <toshik@chromium.org>
Diffstat (limited to 'target/linux/generic/files/drivers')
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8216.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c
index 7398d7e..d575043 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
@@ -2241,10 +2241,14 @@ ar8xxx_phy_remove(struct phy_device *phydev)
return;
phydev->priv = NULL;
- if (--priv->use_count > 0)
- return;
mutex_lock(&ar8xxx_dev_list_lock);
+
+ if (--priv->use_count > 0) {
+ mutex_unlock(&ar8xxx_dev_list_lock);
+ return;
+ }
+
list_del(&priv->list);
mutex_unlock(&ar8xxx_dev_list_lock);
@@ -2294,4 +2298,3 @@ ar8xxx_exit(void)
module_init(ar8xxx_init);
module_exit(ar8xxx_exit);
MODULE_LICENSE("GPL");
-