> -----Original Message----- > From: Leon Romanovsky [mailto:leon@xxxxxxxxxx] > Sent: Tuesday, December 18, 2018 4:16 AM > To: Doug Ledford <dledford@xxxxxxxxxx>; Jason Gunthorpe > <jgg@xxxxxxxxxxxx> > Cc: Leon Romanovsky <leonro@xxxxxxxxxxxx>; RDMA mailing list <linux- > rdma@xxxxxxxxxxxxxxx>; Weiny, Ira <ira.weiny@xxxxxxxxx>; Jack Morgenstein > <jackm@xxxxxxxxxxxxxxxxxx>; Parav Pandit <parav@xxxxxxxxxxxx> > Subject: [PATCH rdma-next 2/6] IB/umad: Avoid destroying device while it is > accessed > > From: Parav Pandit <parav@xxxxxxxxxxxx> > > ib_umad_reg_agent2() and ib_umad_reg_agent() access the device name > while doing dev_notice(). During such access, ib_umad_kill_port() can > destroy the device using device_destroy(). > > cpu-0 cpu-1 > ----- ----- > ib_umad_ioctl() > [...] ib_umad_kill_port() > device_destroy(dev) > > ib_umad_reg_agent() > dev_notice(dev) > > Therefore, first mark ib_dev as NULL inside the port mutex, thus blocking any > further access by file ops. Then, unregister the mad agent and destroy the > device after the mutex is unlocked. > > This ensures that device doesn't get destroyed while it is being accessed. Reviewed-by: Ira Weiny <ira.weiny@xxxxxxxxx> > > Fixes: 0f29b46d49b0 ("IB/mad: add new ioctl to ABI to support new > registration option") > Signed-off-by: Parav Pandit <parav@xxxxxxxxxxxx> > Reviewed-by: Jack Morgenstein <jackm@xxxxxxxxxxxxxxxxxx> > Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx> > --- > drivers/infiniband/core/user_mad.c | 20 +++++++++++--------- > 1 file changed, 11 insertions(+), 9 deletions(-) > > diff --git a/drivers/infiniband/core/user_mad.c > b/drivers/infiniband/core/user_mad.c > index 6ca5b517a944..491a537efac5 100644 > --- a/drivers/infiniband/core/user_mad.c > +++ b/drivers/infiniband/core/user_mad.c > @@ -1238,17 +1238,9 @@ static void ib_umad_kill_port(struct > ib_umad_port *port) > struct ib_umad_file *file; > int id; > > - dev_set_drvdata(port->dev, NULL); > - dev_set_drvdata(port->sm_dev, NULL); > - > - device_destroy(umad_class, port->cdev.dev); > - device_destroy(umad_class, port->sm_cdev.dev); > - > - cdev_del(&port->cdev); > - cdev_del(&port->sm_cdev); > - > mutex_lock(&port->file_mutex); > > + /* Mark ib_dev NULL which blocks file ops to progress further. */ > port->ib_dev = NULL; > > list_for_each_entry(file, &port->file_list, port_list) { @@ -1262,6 > +1254,16 @@ static void ib_umad_kill_port(struct ib_umad_port *port) > } > > mutex_unlock(&port->file_mutex); > + > + dev_set_drvdata(port->dev, NULL); > + dev_set_drvdata(port->sm_dev, NULL); > + > + device_destroy(umad_class, port->cdev.dev); > + device_destroy(umad_class, port->sm_cdev.dev); > + > + cdev_del(&port->cdev); > + cdev_del(&port->sm_cdev); > + > ida_free(&umad_ida, port->dev_num); > } > > -- > 2.19.1