mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
IB/ipoib: Fix deadlock between rmmod and set_mode
am: 1626076b8e
Change-Id: I7df6daf518ff5cdf9ca2cd2babc936b4f12fe91c
This commit is contained in:
@@ -1511,12 +1511,14 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
|
||||
|
||||
ret = ipoib_set_mode(dev, buf);
|
||||
|
||||
rtnl_unlock();
|
||||
/* The assumption is that the function ipoib_set_mode returned
|
||||
* with the rtnl held by it, if not the value -EBUSY returned,
|
||||
* then no need to rtnl_unlock
|
||||
*/
|
||||
if (ret != -EBUSY)
|
||||
rtnl_unlock();
|
||||
|
||||
if (!ret)
|
||||
return count;
|
||||
|
||||
return ret;
|
||||
return (!ret || ret == -EBUSY) ? count : ret;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode);
|
||||
|
||||
@@ -468,8 +468,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf)
|
||||
priv->tx_wr.wr.send_flags &= ~IB_SEND_IP_CSUM;
|
||||
|
||||
ipoib_flush_paths(dev);
|
||||
rtnl_lock();
|
||||
return 0;
|
||||
return (!rtnl_trylock()) ? -EBUSY : 0;
|
||||
}
|
||||
|
||||
if (!strcmp(buf, "datagram\n")) {
|
||||
@@ -478,8 +477,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf)
|
||||
dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu));
|
||||
rtnl_unlock();
|
||||
ipoib_flush_paths(dev);
|
||||
rtnl_lock();
|
||||
return 0;
|
||||
return (!rtnl_trylock()) ? -EBUSY : 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
|
||||
Reference in New Issue
Block a user