diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index e029401b5680..f3f3051713ef 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -2061,19 +2061,14 @@ void ib_dispatch_event_clients(struct ib_event *event) up_read(&event->device->event_handler_rwsem); } -static int iw_query_port(struct ib_device *device, - u32 port_num, - struct ib_port_attr *port_attr) +static int iw_query_port(struct ib_device *device, u32 port_num, + struct ib_port_attr *port_attr, + struct net_device *netdev) { struct in_device *inetdev; - struct net_device *netdev; memset(port_attr, 0, sizeof(*port_attr)); - netdev = ib_device_get_netdev(device, port_num); - if (!netdev) - return -ENODEV; - port_attr->max_mtu = IB_MTU_4096; port_attr->active_mtu = ib_mtu_int_to_enum(netdev->mtu); @@ -2096,7 +2091,6 @@ static int iw_query_port(struct ib_device *device, rcu_read_unlock(); } - dev_put(netdev); return device->ops.query_port(device, port_num, port_attr); } @@ -2134,13 +2128,27 @@ int ib_query_port(struct ib_device *device, u32 port_num, struct ib_port_attr *port_attr) { + struct net_device *netdev = NULL; + int ret; + if (!rdma_is_port_valid(device, port_num)) return -EINVAL; + if (rdma_protocol_iwarp(device, port_num) || + rdma_protocol_roce(device, port_num)) { + netdev = ib_device_get_netdev(device, port_num); + if (!netdev) + return -ENODEV; + } + if (rdma_protocol_iwarp(device, port_num)) - return iw_query_port(device, port_num, port_attr); + ret = iw_query_port(device, port_num, port_attr, netdev); else - return __ib_query_port(device, port_num, port_attr); + ret = __ib_query_port(device, port_num, port_attr); + if (netdev) + dev_put(netdev); + return ret; + } EXPORT_SYMBOL(ib_query_port); diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 473ee0831307..561fe5704fa8 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1988,11 +1988,11 @@ int ib_get_eth_speed(struct ib_device *dev, u32 port_num, u16 *speed, u8 *width) if (rdma_port_get_link_layer(dev, port_num) != IB_LINK_LAYER_ETHERNET) return -EINVAL; + rtnl_lock(); netdev = ib_device_get_netdev(dev, port_num); if (!netdev) return -ENODEV; - rtnl_lock(); rc = __ethtool_get_link_ksettings(netdev, &lksettings); rtnl_unlock(); diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index 75d1407db52d..c5d439bebc24 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -605,6 +605,7 @@ static int rxe_notify(struct notifier_block *not_blk, switch (event) { case NETDEV_UNREGISTER: + ib_device_set_netdev(&rxe->ib_dev, NULL, 1); ib_unregister_device_queued(&rxe->ib_dev); break; case NETDEV_UP: