Message ID | 20210825090538.4860-2-diana.craciun@oss.nxp.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/2] bus/fsl-mc: Add generic implementation for open/reset/close commands | expand |
On 8/25/2021 12:05 PM, Diana Craciun wrote: > Currently when a fsl-mc device is reset, the entire DPRC container > is reset which is very inefficient because the devices within a > container will be reset multiple times. > Add support for individually resetting a device. > > Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com> > --- > drivers/vfio/fsl-mc/vfio_fsl_mc.c | 45 ++++++++++++++++++++----------- > 1 file changed, 29 insertions(+), 16 deletions(-) > > diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c > index 90cad109583b..46126d41dc32 100644 > --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c > +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c > @@ -155,6 +155,33 @@ static int vfio_fsl_mc_open(struct vfio_device *core_vdev) > return ret; > } > > +static int vfio_fsl_mc_reset_device(struct vfio_fsl_mc_device *vdev) > +{ > + struct fsl_mc_device *mc_dev = vdev->mc_dev; > + int ret = 0; > + > + if (is_fsl_mc_bus_dprc(vdev->mc_dev)) { > + return dprc_reset_container(mc_dev->mc_io, 0, > + mc_dev->mc_handle, > + mc_dev->obj_desc.id, > + DPRC_RESET_OPTION_NON_RECURSIVE); > + } else { > + int err; > + u16 token; > + > + err = fsl_mc_obj_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id, > + mc_dev->obj_desc.type, > + &token); > + if (err) > + return err; > + ret = fsl_mc_obj_reset(mc_dev->mc_io, 0, token); > + err = fsl_mc_obj_close(mc_dev->mc_io, 0, token); > + if (err) > + return err; Error handling here looks a bit atypical to me. Maybe something like this, which will also get rid of the 2nd err var. { ret = fsl_mc_obj_open(...); if (ret) goto out; ret = fsl_mc_obj_reset(...); if (ret) { fsl_mc_obj_close(...); goto out; } ret = fsl_mc_obj_close(...); } out: return ret; --- Best Regards, Laurentiu > + } > + return ret; > +} > + > static void vfio_fsl_mc_release(struct vfio_device *core_vdev) > { > struct vfio_fsl_mc_device *vdev = > @@ -171,10 +198,7 @@ static void vfio_fsl_mc_release(struct vfio_device *core_vdev) > vfio_fsl_mc_regions_cleanup(vdev); > > /* reset the device before cleaning up the interrupts */ > - ret = dprc_reset_container(mc_cont->mc_io, 0, > - mc_cont->mc_handle, > - mc_cont->obj_desc.id, > - DPRC_RESET_OPTION_NON_RECURSIVE); > + ret = vfio_fsl_mc_reset_device(vdev); > > if (ret) { > dev_warn(&mc_cont->dev, "VFIO_FLS_MC: reset device has failed (%d)\n", > @@ -302,18 +326,7 @@ static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev, > } > case VFIO_DEVICE_RESET: > { > - int ret; > - struct fsl_mc_device *mc_dev = vdev->mc_dev; > - > - /* reset is supported only for the DPRC */ > - if (!is_fsl_mc_bus_dprc(mc_dev)) > - return -ENOTTY; > - > - ret = dprc_reset_container(mc_dev->mc_io, 0, > - mc_dev->mc_handle, > - mc_dev->obj_desc.id, > - DPRC_RESET_OPTION_NON_RECURSIVE); > - return ret; > + return vfio_fsl_mc_reset_device(vdev); > > } > default: >
diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c index 90cad109583b..46126d41dc32 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c @@ -155,6 +155,33 @@ static int vfio_fsl_mc_open(struct vfio_device *core_vdev) return ret; } +static int vfio_fsl_mc_reset_device(struct vfio_fsl_mc_device *vdev) +{ + struct fsl_mc_device *mc_dev = vdev->mc_dev; + int ret = 0; + + if (is_fsl_mc_bus_dprc(vdev->mc_dev)) { + return dprc_reset_container(mc_dev->mc_io, 0, + mc_dev->mc_handle, + mc_dev->obj_desc.id, + DPRC_RESET_OPTION_NON_RECURSIVE); + } else { + int err; + u16 token; + + err = fsl_mc_obj_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id, + mc_dev->obj_desc.type, + &token); + if (err) + return err; + ret = fsl_mc_obj_reset(mc_dev->mc_io, 0, token); + err = fsl_mc_obj_close(mc_dev->mc_io, 0, token); + if (err) + return err; + } + return ret; +} + static void vfio_fsl_mc_release(struct vfio_device *core_vdev) { struct vfio_fsl_mc_device *vdev = @@ -171,10 +198,7 @@ static void vfio_fsl_mc_release(struct vfio_device *core_vdev) vfio_fsl_mc_regions_cleanup(vdev); /* reset the device before cleaning up the interrupts */ - ret = dprc_reset_container(mc_cont->mc_io, 0, - mc_cont->mc_handle, - mc_cont->obj_desc.id, - DPRC_RESET_OPTION_NON_RECURSIVE); + ret = vfio_fsl_mc_reset_device(vdev); if (ret) { dev_warn(&mc_cont->dev, "VFIO_FLS_MC: reset device has failed (%d)\n", @@ -302,18 +326,7 @@ static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev, } case VFIO_DEVICE_RESET: { - int ret; - struct fsl_mc_device *mc_dev = vdev->mc_dev; - - /* reset is supported only for the DPRC */ - if (!is_fsl_mc_bus_dprc(mc_dev)) - return -ENOTTY; - - ret = dprc_reset_container(mc_dev->mc_io, 0, - mc_dev->mc_handle, - mc_dev->obj_desc.id, - DPRC_RESET_OPTION_NON_RECURSIVE); - return ret; + return vfio_fsl_mc_reset_device(vdev); } default:
Currently when a fsl-mc device is reset, the entire DPRC container is reset which is very inefficient because the devices within a container will be reset multiple times. Add support for individually resetting a device. Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com> --- drivers/vfio/fsl-mc/vfio_fsl_mc.c | 45 ++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 16 deletions(-)