RE: [PATCH rdma-next] RDMA/core: Do not invoke init_port on compat devices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: Jason Gunthorpe
> Sent: Friday, May 3, 2019 5:50 PM
> To: Leon Romanovsky <leon@xxxxxxxxxx>
> Cc: Doug Ledford <dledford@xxxxxxxxxx>; Parav Pandit
> <parav@xxxxxxxxxxxx>; RDMA mailing list <linux-rdma@xxxxxxxxxxxxxxx>;
> Mike Marciniszyn <mike.marciniszyn@xxxxxxxxx>; Leon Romanovsky
> <leonro@xxxxxxxxxxxx>
> Subject: Re: [PATCH rdma-next] RDMA/core: Do not invoke init_port on
> compat devices
> 
> On Wed, May 01, 2019 at 08:46:55AM +0300, Leon Romanovsky wrote:
> > From: Parav Pandit <parav@xxxxxxxxxxxx>
> >
> > As compat devices in net namespaces may not need vendor specific
> > control attributes, avoid invoking init_port() on them.
> >
> > This avoids below reported call trace.
> >
> > Call Trace:
> > dump_stack+0x5a/0x73
> > kobject_init+0x74/0x80
> > kobject_init_and_add+0x35/0xb0
> > hfi1_create_port_files+0x6e/0x3c0 [hfi1]
> > ib_setup_port_attrs+0x43b/0x560 [ib_core]
> > add_one_compat_dev+0x16a/0x230 [ib_core]
> > rdma_dev_init_net+0x110/0x160 [ib_core]
> > ops_init+0x38/0xf0
> > setup_net+0xcf/0x1e0
> > copy_net_ns+0xb7/0x130
> > create_new_namespaces+0x11a/0x1b0
> > unshare_nsproxy_namespaces+0x55/0xa0
> > ksys_unshare+0x1a7/0x340
> > __x64_sys_unshare+0xe/0x20
> > do_syscall_64+0x5b/0x180
> > entry_SYSCALL_64_after_hwframe+0x44/0xa9
> >
> > Fixes: 5417783eabb2 ("RDMA/core: Support core port attributes in non
> > init_net")
> > Reported-by: Mike Marciniszyn <mike.marciniszyn@xxxxxxxxx>
> > Tested-by: Mike Marciniszyn <mike.marciniszyn@xxxxxxxxx>
> > Signed-off-by: Parav Pandit <parav@xxxxxxxxxxxx>
> > Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx>
> > ---
> >  drivers/infiniband/core/core_priv.h |  2 +-
> >  drivers/infiniband/core/sysfs.c     | 13 +++++++------
> >  2 files changed, 8 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/infiniband/core/core_priv.h
> > b/drivers/infiniband/core/core_priv.h
> > index 2764647056d8..77956c42358e 100644
> > --- a/drivers/infiniband/core/core_priv.h
> > +++ b/drivers/infiniband/core/core_priv.h
> > @@ -342,7 +342,7 @@ struct net_device
> > *rdma_read_gid_attr_ndev_rcu(const struct ib_gid_attr *attr);
> >
> >  void ib_free_port_attrs(struct ib_core_device *coredev);  int
> > ib_setup_port_attrs(struct ib_core_device *coredev,
> > -			bool alloc_hw_stats);
> > +			bool init_port_alloc_stats);
> 
> Yuk this name is ugly. I reworked it a bit and put this in the wip branch,
> please check it:
>
Patch looks good.
I kept the flag to keep door open in case if user requires stats in ns.
But its fine, we can work through it at later point if required.

 
> commit eb15c78b05bd9fbac45ee5b56aaf29b2570b5238
> Author: Parav Pandit <parav@xxxxxxxxxxxx>
> Date:   Wed May 1 08:46:55 2019 +0300
> 
>     RDMA/core: Do not invoke init_port on compat devices
> 
>     The driver interface cannot manipulate the sysfs of the compat device,
>     only of the full device so we must avoid calling the driver sysfs APIs on
>     compat devices.
> 
>     This prevents an oops:
> 
>      Call Trace:
>      dump_stack+0x5a/0x73
>      kobject_init+0x74/0x80
>      kobject_init_and_add+0x35/0xb0
>      hfi1_create_port_files+0x6e/0x3c0 [hfi1]
>      ib_setup_port_attrs+0x43b/0x560 [ib_core]
>      add_one_compat_dev+0x16a/0x230 [ib_core]
>      rdma_dev_init_net+0x110/0x160 [ib_core]
>      ops_init+0x38/0xf0
>      setup_net+0xcf/0x1e0
>      copy_net_ns+0xb7/0x130
>      create_new_namespaces+0x11a/0x1b0
>      unshare_nsproxy_namespaces+0x55/0xa0
>      ksys_unshare+0x1a7/0x340
>      __x64_sys_unshare+0xe/0x20
>      do_syscall_64+0x5b/0x180
>      entry_SYSCALL_64_after_hwframe+0x44/0xa9
> 
>     Fixes: 5417783eabb2 ("RDMA/core: Support core port attributes in non
> init_net")
>     Reported-by: Mike Marciniszyn <mike.marciniszyn@xxxxxxxxx>
>     Tested-by: Mike Marciniszyn <mike.marciniszyn@xxxxxxxxx>
>     Signed-off-by: Parav Pandit <parav@xxxxxxxxxxxx>
>     Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx>
>     Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxxxx>
> 
> diff --git a/drivers/infiniband/core/core_priv.h
> b/drivers/infiniband/core/core_priv.h
> index 2764647056d8fd..ff40a450b5d28e 100644
> --- a/drivers/infiniband/core/core_priv.h
> +++ b/drivers/infiniband/core/core_priv.h
> @@ -341,8 +341,7 @@ int roce_resolve_route_from_path(struct
> sa_path_rec *rec,  struct net_device *rdma_read_gid_attr_ndev_rcu(const
> struct ib_gid_attr *attr);
> 
>  void ib_free_port_attrs(struct ib_core_device *coredev); -int
> ib_setup_port_attrs(struct ib_core_device *coredev,
> -			bool alloc_hw_stats);
> +int ib_setup_port_attrs(struct ib_core_device *coredev);
> 
>  int rdma_compatdev_set(u8 enable);
> 
> diff --git a/drivers/infiniband/core/device.c
> b/drivers/infiniband/core/device.c
> index 76088655f06ef7..2123cc693a2959 100644
> --- a/drivers/infiniband/core/device.c
> +++ b/drivers/infiniband/core/device.c
> @@ -870,7 +870,7 @@ static int add_one_compat_dev(struct ib_device
> *device,
>  	ret = device_add(&cdev->dev);
>  	if (ret)
>  		goto add_err;
> -	ret = ib_setup_port_attrs(cdev, false);
> +	ret = ib_setup_port_attrs(cdev);
>  	if (ret)
>  		goto port_err;
> 
> diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
> index 2fe89754e59207..7a599c5e455fa9 100644
> --- a/drivers/infiniband/core/sysfs.c
> +++ b/drivers/infiniband/core/sysfs.c
> @@ -1015,10 +1015,10 @@ static void setup_hw_stats(struct ib_device
> *device, struct ib_port *port,
>  	return;
>  }
> 
> -static int add_port(struct ib_core_device *coredev,
> -		    int port_num, bool alloc_stats)
> +static int add_port(struct ib_core_device *coredev, int port_num)
>  {
>  	struct ib_device *device = rdma_device_to_ibdev(&coredev->dev);
> +	bool is_full_dev = &device->coredev == coredev;
>  	struct ib_port *p;
>  	struct ib_port_attr attr;
>  	int i;
> @@ -1057,7 +1057,7 @@ static int add_port(struct ib_core_device *coredev,
>  		goto err_put;
>  	}
> 
> -	if (device->ops.process_mad && alloc_stats) {
> +	if (device->ops.process_mad && is_full_dev) {
>  		p->pma_table = get_counter_table(device, port_num);
>  		ret = sysfs_create_group(&p->kobj, p->pma_table);
>  		if (ret)
> @@ -1113,7 +1113,7 @@ static int add_port(struct ib_core_device *coredev,
>  	if (ret)
>  		goto err_free_pkey;
> 
> -	if (device->ops.init_port) {
> +	if (device->ops.init_port && is_full_dev) {
>  		ret = device->ops.init_port(device, port_num, &p->kobj);
>  		if (ret)
>  			goto err_remove_pkey;
> @@ -1124,7 +1124,7 @@ static int add_port(struct ib_core_device *coredev,
>  	 * port, so holder should be device. Therefore skip per port conunter
>  	 * initialization.
>  	 */
> -	if (device->ops.alloc_hw_stats && port_num && alloc_stats)
> +	if (device->ops.alloc_hw_stats && port_num && is_full_dev)
>  		setup_hw_stats(device, p, port_num);
> 
>  	list_add_tail(&p->kobj.entry, &coredev->port_list); @@ -1308,7
> +1308,7 @@ void ib_free_port_attrs(struct ib_core_device *coredev)
>  	kobject_put(coredev->ports_kobj);
>  }
> 
> -int ib_setup_port_attrs(struct ib_core_device *coredev, bool alloc_stats)
> +int ib_setup_port_attrs(struct ib_core_device *coredev)
>  {
>  	struct ib_device *device = rdma_device_to_ibdev(&coredev->dev);
>  	unsigned int port;
> @@ -1320,7 +1320,7 @@ int ib_setup_port_attrs(struct ib_core_device
> *coredev, bool alloc_stats)
>  		return -ENOMEM;
> 
>  	rdma_for_each_port (device, port) {
> -		ret = add_port(coredev, port, alloc_stats);
> +		ret = add_port(coredev, port);
>  		if (ret)
>  			goto err_put;
>  	}
> @@ -1336,7 +1336,7 @@ int ib_device_register_sysfs(struct ib_device
> *device)  {
>  	int ret;
> 
> -	ret = ib_setup_port_attrs(&device->coredev, true);
> +	ret = ib_setup_port_attrs(&device->coredev);
>  	if (ret)
>  		return ret;
> 




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux