diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx5/main.c')
| -rw-r--r-- | drivers/infiniband/hw/mlx5/main.c | 106 | 
1 files changed, 69 insertions, 37 deletions
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index c669ef6e47e7..5b988db66b8f 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -1756,13 +1756,9 @@ static int set_ucontext_resp(struct ib_ucontext *uctx,  	struct mlx5_ib_dev *dev = to_mdev(ibdev);  	struct mlx5_ib_ucontext *context = to_mucontext(uctx);  	struct mlx5_bfreg_info *bfregi = &context->bfregi; -	int err;  	if (MLX5_CAP_GEN(dev->mdev, dump_fill_mkey)) { -		err = mlx5_cmd_dump_fill_mkey(dev->mdev, -					      &resp->dump_fill_mkey); -		if (err) -			return err; +		resp->dump_fill_mkey = dev->mkeys.dump_fill_mkey;  		resp->comp_mask |=  			MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_DUMP_FILL_MKEY;  	} @@ -2087,7 +2083,7 @@ static int mlx5_ib_mmap_clock_info_page(struct mlx5_ib_dev *dev,  	if (vma->vm_flags & (VM_WRITE | VM_EXEC))  		return -EPERM; -	vma->vm_flags &= ~VM_MAYWRITE; +	vm_flags_clear(vma, VM_MAYWRITE);  	if (!dev->mdev->clock_info)  		return -EOPNOTSUPP; @@ -2311,7 +2307,7 @@ static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vm  		if (vma->vm_flags & VM_WRITE)  			return -EPERM; -		vma->vm_flags &= ~VM_MAYWRITE; +		vm_flags_clear(vma, VM_MAYWRITE);  		/* Don't expose to user-space information it shouldn't have */  		if (PAGE_SIZE > 4096) @@ -3012,26 +3008,63 @@ static void mlx5_eth_lag_cleanup(struct mlx5_ib_dev *dev)  	}  } -static int mlx5_add_netdev_notifier(struct mlx5_ib_dev *dev, u32 port_num) +static void mlx5_netdev_notifier_register(struct mlx5_roce *roce, +					  struct net_device *netdev)  {  	int err; -	dev->port[port_num].roce.nb.notifier_call = mlx5_netdev_event; -	err = register_netdevice_notifier(&dev->port[port_num].roce.nb); -	if (err) { -		dev->port[port_num].roce.nb.notifier_call = NULL; -		return err; -	} +	if (roce->tracking_netdev) +		return; +	roce->tracking_netdev = netdev; +	roce->nb.notifier_call = mlx5_netdev_event; +	err = register_netdevice_notifier_dev_net(netdev, &roce->nb, &roce->nn); +	WARN_ON(err); +} -	return 0; +static void mlx5_netdev_notifier_unregister(struct mlx5_roce *roce) +{ +	if (!roce->tracking_netdev) +		return; +	unregister_netdevice_notifier_dev_net(roce->tracking_netdev, &roce->nb, +					      &roce->nn); +	roce->tracking_netdev = NULL;  } -static void mlx5_remove_netdev_notifier(struct mlx5_ib_dev *dev, u32 port_num) +static int mlx5e_mdev_notifier_event(struct notifier_block *nb, +				     unsigned long event, void *data)  { -	if (dev->port[port_num].roce.nb.notifier_call) { -		unregister_netdevice_notifier(&dev->port[port_num].roce.nb); -		dev->port[port_num].roce.nb.notifier_call = NULL; +	struct mlx5_roce *roce = container_of(nb, struct mlx5_roce, mdev_nb); +	struct net_device *netdev = data; + +	switch (event) { +	case MLX5_DRIVER_EVENT_UPLINK_NETDEV: +		if (netdev) +			mlx5_netdev_notifier_register(roce, netdev); +		else +			mlx5_netdev_notifier_unregister(roce); +		break; +	default: +		return NOTIFY_DONE;  	} + +	return NOTIFY_OK; +} + +static void mlx5_mdev_netdev_track(struct mlx5_ib_dev *dev, u32 port_num) +{ +	struct mlx5_roce *roce = &dev->port[port_num].roce; + +	roce->mdev_nb.notifier_call = mlx5e_mdev_notifier_event; +	mlx5_blocking_notifier_register(dev->mdev, &roce->mdev_nb); +	mlx5_core_uplink_netdev_event_replay(dev->mdev); +} + +static void mlx5_mdev_netdev_untrack(struct mlx5_ib_dev *dev, u32 port_num) +{ +	struct mlx5_roce *roce = &dev->port[port_num].roce; + +	mlx5_blocking_notifier_unregister(dev->mdev, &roce->mdev_nb); +	mlx5_netdev_notifier_unregister(roce);  }  static int mlx5_enable_eth(struct mlx5_ib_dev *dev) @@ -3138,7 +3171,7 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev,  	if (mpi->mdev_events.notifier_call)  		mlx5_notifier_unregister(mpi->mdev, &mpi->mdev_events);  	mpi->mdev_events.notifier_call = NULL; -	mlx5_remove_netdev_notifier(ibdev, port_num); +	mlx5_mdev_netdev_untrack(ibdev, port_num);  	spin_lock(&port->mp.mpi_lock);  	comps = mpi->mdev_refcnt; @@ -3196,12 +3229,7 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev,  	if (err)  		goto unbind; -	err = mlx5_add_netdev_notifier(ibdev, port_num); -	if (err) { -		mlx5_ib_err(ibdev, "failed adding netdev notifier for port %u\n", -			    port_num + 1); -		goto unbind; -	} +	mlx5_mdev_netdev_track(ibdev, port_num);  	mpi->mdev_events.notifier_call = mlx5_ib_event_slave_port;  	mlx5_notifier_register(mpi->mdev, &mpi->mdev_events); @@ -3634,6 +3662,10 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)  		dev->port[i].roce.last_port_state = IB_PORT_DOWN;  	} +	err = mlx5r_cmd_query_special_mkeys(dev); +	if (err) +		return err; +  	err = mlx5_ib_init_multiport_master(dev);  	if (err)  		return err; @@ -3909,9 +3941,7 @@ static int mlx5_ib_roce_init(struct mlx5_ib_dev *dev)  		port_num = mlx5_core_native_port_num(dev->mdev) - 1;  		/* Register only for native ports */ -		err = mlx5_add_netdev_notifier(dev, port_num); -		if (err) -			return err; +		mlx5_mdev_netdev_track(dev, port_num);  		err = mlx5_enable_eth(dev);  		if (err) @@ -3920,7 +3950,7 @@ static int mlx5_ib_roce_init(struct mlx5_ib_dev *dev)  	return 0;  cleanup: -	mlx5_remove_netdev_notifier(dev, port_num); +	mlx5_mdev_netdev_untrack(dev, port_num);  	return err;  } @@ -3938,7 +3968,7 @@ static void mlx5_ib_roce_cleanup(struct mlx5_ib_dev *dev)  		mlx5_disable_eth(dev);  		port_num = mlx5_core_native_port_num(dev->mdev) - 1; -		mlx5_remove_netdev_notifier(dev, port_num); +		mlx5_mdev_netdev_untrack(dev, port_num);  	}  } @@ -4000,12 +4030,7 @@ static int mlx5_ib_stage_ib_reg_init(struct mlx5_ib_dev *dev)  static void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev)  { -	int err; - -	err = mlx5_mkey_cache_cleanup(dev); -	if (err) -		mlx5_ib_warn(dev, "mr cache cleanup failed\n"); - +	mlx5_mkey_cache_cleanup(dev);  	mlx5r_umr_resource_cleanup(dev);  } @@ -4403,6 +4428,10 @@ static int __init mlx5_ib_init(void)  		return -ENOMEM;  	} +	ret = mlx5_ib_qp_event_init(); +	if (ret) +		goto qp_event_err; +  	mlx5_ib_odp_init();  	ret = mlx5r_rep_init();  	if (ret) @@ -4420,6 +4449,8 @@ drv_err:  mp_err:  	mlx5r_rep_cleanup();  rep_err: +	mlx5_ib_qp_event_cleanup(); +qp_event_err:  	destroy_workqueue(mlx5_ib_event_wq);  	free_page((unsigned long)xlt_emergency_page);  	return ret; @@ -4431,6 +4462,7 @@ static void __exit mlx5_ib_cleanup(void)  	auxiliary_driver_unregister(&mlx5r_mp_driver);  	mlx5r_rep_cleanup(); +	mlx5_ib_qp_event_cleanup();  	destroy_workqueue(mlx5_ib_event_wq);  	free_page((unsigned long)xlt_emergency_page);  }  |