ret = ipoib_set_mode(dev, buf);
 
-       rtnl_unlock();
-
-       if (!ret)
-               return count;
+       /* 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();
 
-       return ret;
+       return (!ret || ret == -EBUSY) ? count : ret;
 }
 
 static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode);
 
                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")) {
                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;