* [PATCH v4 0/4] use put_device to cleanup resource
@ 2017-12-20 4:26 weiping zhang
2017-12-20 4:26 ` [PATCH v4 1/4] virtio: split device_register into device_initialize and device_add weiping zhang
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: weiping zhang @ 2017-12-20 4:26 UTC (permalink / raw)
To: cohuck, mst, jasowang; +Cc: virtualization
Hi,
The main change is split device_register into 2 sperate calls:
device_initalize() and device_add, and then the caller can use
put_device safety when fail to register_virtio_device.
v3->v4:
* split device_register into device_initialize and devicea_add that
the caller can always use put_device when fail to register virtio
device.
v2->v3:
* virtio: add new helper do get device's status then determine use
put_device or kfree.
v1->v2:
* virtio_pci: add comments in commit message for why using put_device
* virtio_vop: also use put_device int _vop_remove_device
weiping zhang (4):
virtio: split device_register into device_initialize and device_add
virtio_pci: don't kfree device on register failure
virtio_vop: don't kfree device on register failure
virtio_remoteproc: don't kfree device on register failure
drivers/misc/mic/vop/vop_main.c | 20 +++++++++++++-------
drivers/remoteproc/remoteproc_virtio.c | 13 +++++++++++--
drivers/virtio/virtio.c | 18 +++++++++++++++---
drivers/virtio/virtio_pci_common.c | 8 ++++++--
4 files changed, 45 insertions(+), 14 deletions(-)
--
2.9.4
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 1/4] virtio: split device_register into device_initialize and device_add
2017-12-20 4:26 [PATCH v4 0/4] use put_device to cleanup resource weiping zhang
@ 2017-12-20 4:26 ` weiping zhang
2017-12-20 15:53 ` Cornelia Huck
2017-12-20 4:26 ` [PATCH v4 2/4] virtio_pci: don't kfree device on register failure weiping zhang
` (2 subsequent siblings)
3 siblings, 1 reply; 12+ messages in thread
From: weiping zhang @ 2017-12-20 4:26 UTC (permalink / raw)
To: cohuck, mst, jasowang; +Cc: virtualization
In order to make caller do a simple cleanup, we split device_register
into device_initialize and device_add. device_initialize always sucess,
the caller can always use put_device when fail to register virtio_device
no matter fail at ida_simple_get or at device_add.
Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
Suggested-by: Cornelia Huck <cohuck@redhat.com>
---
drivers/virtio/virtio.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index bf7ff39..3c9f211 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -303,11 +303,21 @@ void unregister_virtio_driver(struct virtio_driver *driver)
}
EXPORT_SYMBOL_GPL(unregister_virtio_driver);
+/**
+ * register_virtio_device - register virtio device
+ * @dev : virtio device interested
+ *
+ * If an error occurs, the caller must use put_device, instead of kfree, because
+ * device_initialize and device_add will increase @dev->dev's reference count.
+ *
+ * Returns: 0 on suceess, -error on failure
+ */
int register_virtio_device(struct virtio_device *dev)
{
int err;
dev->dev.bus = &virtio_bus;
+ device_initialize(&dev->dev);
/* Assign a unique device index and hence name. */
err = ida_simple_get(&virtio_index_ida, 0, 0, GFP_KERNEL);
@@ -330,9 +340,11 @@ int register_virtio_device(struct virtio_device *dev)
INIT_LIST_HEAD(&dev->vqs);
- /* device_register() causes the bus infrastructure to look for a
- * matching driver. */
- err = device_register(&dev->dev);
+ /*
+ * device_add() causes the bus infrastructure to look for a matching
+ * driver.
+ */
+ err = device_add(&dev->dev);
if (err)
ida_simple_remove(&virtio_index_ida, dev->index);
out:
--
2.9.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 2/4] virtio_pci: don't kfree device on register failure
2017-12-20 4:26 [PATCH v4 0/4] use put_device to cleanup resource weiping zhang
2017-12-20 4:26 ` [PATCH v4 1/4] virtio: split device_register into device_initialize and device_add weiping zhang
@ 2017-12-20 4:26 ` weiping zhang
2017-12-20 15:55 ` Cornelia Huck
2017-12-20 4:27 ` [PATCH v4 3/4] virtio_vop: " weiping zhang
2017-12-20 4:27 ` [PATCH v4 4/4] virtio_remoteproc: " weiping zhang
3 siblings, 1 reply; 12+ messages in thread
From: weiping zhang @ 2017-12-20 4:26 UTC (permalink / raw)
To: cohuck, mst, jasowang; +Cc: virtualization
As mentioned at drivers/base/core.c:
/*
* NOTE: _Never_ directly free @dev after calling this function, even
* if it returned an error! Always use put_device() to give up the
* reference initialized in this function instead.
*/
so we don't free vp_dev until vp_dev->vdev.dev.release be called.
Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
---
drivers/virtio/virtio_pci_common.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index 1c4797e..48d4d1c 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -513,7 +513,7 @@ static void virtio_pci_release_dev(struct device *_d)
static int virtio_pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *id)
{
- struct virtio_pci_device *vp_dev;
+ struct virtio_pci_device *vp_dev, *reg_dev = NULL;
int rc;
/* allocate our structure and fill it out */
@@ -551,6 +551,7 @@ static int virtio_pci_probe(struct pci_dev *pci_dev,
pci_set_master(pci_dev);
rc = register_virtio_device(&vp_dev->vdev);
+ reg_dev = vp_dev;
if (rc)
goto err_register;
@@ -564,7 +565,10 @@ static int virtio_pci_probe(struct pci_dev *pci_dev,
err_probe:
pci_disable_device(pci_dev);
err_enable_device:
- kfree(vp_dev);
+ if (reg_dev)
+ put_device(&vp_dev->vdev.dev);
+ else
+ kfree(vp_dev);
return rc;
}
--
2.9.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 3/4] virtio_vop: don't kfree device on register failure
2017-12-20 4:26 [PATCH v4 0/4] use put_device to cleanup resource weiping zhang
2017-12-20 4:26 ` [PATCH v4 1/4] virtio: split device_register into device_initialize and device_add weiping zhang
2017-12-20 4:26 ` [PATCH v4 2/4] virtio_pci: don't kfree device on register failure weiping zhang
@ 2017-12-20 4:27 ` weiping zhang
2017-12-20 15:57 ` Cornelia Huck
2017-12-20 4:27 ` [PATCH v4 4/4] virtio_remoteproc: " weiping zhang
3 siblings, 1 reply; 12+ messages in thread
From: weiping zhang @ 2017-12-20 4:27 UTC (permalink / raw)
To: cohuck, mst, jasowang; +Cc: virtualization
As mentioned at drivers/base/core.c:
/*
* NOTE: _Never_ directly free @dev after calling this function, even
* if it returned an error! Always use put_device() to give up the
* reference initialized in this function instead.
*/
so we don't free vdev until vdev->vdev.dev.release be called.
Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
---
drivers/misc/mic/vop/vop_main.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/misc/mic/vop/vop_main.c b/drivers/misc/mic/vop/vop_main.c
index a341938..3633202 100644
--- a/drivers/misc/mic/vop/vop_main.c
+++ b/drivers/misc/mic/vop/vop_main.c
@@ -452,10 +452,12 @@ static irqreturn_t vop_virtio_intr_handler(int irq, void *data)
static void vop_virtio_release_dev(struct device *_d)
{
- /*
- * No need for a release method similar to virtio PCI.
- * Provide an empty one to avoid getting a warning from core.
- */
+ struct virtio_device *vdev =
+ container_of(_d, struct virtio_device, dev);
+ struct _vop_vdev *vop_vdev =
+ container_of(vdev, struct _vop_vdev, vdev);
+
+ kfree(vop_vdev);
}
/*
@@ -466,7 +468,7 @@ static int _vop_add_device(struct mic_device_desc __iomem *d,
unsigned int offset, struct vop_device *vpdev,
int dnode)
{
- struct _vop_vdev *vdev;
+ struct _vop_vdev *vdev, *reg_dev = NULL;
int ret;
u8 type = ioread8(&d->type);
@@ -497,6 +499,7 @@ static int _vop_add_device(struct mic_device_desc __iomem *d,
vdev->c2h_vdev_db = ioread8(&vdev->dc->c2h_vdev_db);
ret = register_virtio_device(&vdev->vdev);
+ reg_dev = vdev;
if (ret) {
dev_err(_vop_dev(vdev),
"Failed to register vop device %u type %u\n",
@@ -512,7 +515,10 @@ static int _vop_add_device(struct mic_device_desc __iomem *d,
free_irq:
vpdev->hw_ops->free_irq(vpdev, vdev->virtio_cookie, vdev);
kfree:
- kfree(vdev);
+ if (reg_dev)
+ put_device(&vdev->vdev.dev);
+ else
+ kfree(vdev);
return ret;
}
@@ -568,7 +574,7 @@ static int _vop_remove_device(struct mic_device_desc __iomem *d,
iowrite8(-1, &dc->h2c_vdev_db);
if (status & VIRTIO_CONFIG_S_DRIVER_OK)
wait_for_completion(&vdev->reset_done);
- kfree(vdev);
+ put_device(&vdev->vdev.dev);
iowrite8(1, &dc->guest_ack);
dev_dbg(&vpdev->dev, "%s %d guest_ack %d\n",
__func__, __LINE__, ioread8(&dc->guest_ack));
--
2.9.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 4/4] virtio_remoteproc: don't kfree device on register failure
2017-12-20 4:26 [PATCH v4 0/4] use put_device to cleanup resource weiping zhang
` (2 preceding siblings ...)
2017-12-20 4:27 ` [PATCH v4 3/4] virtio_vop: " weiping zhang
@ 2017-12-20 4:27 ` weiping zhang
2017-12-20 16:12 ` Cornelia Huck
3 siblings, 1 reply; 12+ messages in thread
From: weiping zhang @ 2017-12-20 4:27 UTC (permalink / raw)
To: cohuck, mst, jasowang; +Cc: virtualization
rproc_virtio_dev_release will be called iff virtio_device.dev's
refer count became to 0. Here we should check if we call device_register
or not, if called, put vdev.dev, and then rproc->dev's cleanup will be
done in rproc_virtio_dev_release, otherwise we do cleanup directly.
Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
---
drivers/remoteproc/remoteproc_virtio.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index 2946348..1073ea3 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -304,7 +304,7 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
{
struct rproc *rproc = rvdev->rproc;
struct device *dev = &rproc->dev;
- struct virtio_device *vdev = &rvdev->vdev;
+ struct virtio_device *vdev = &rvdev->vdev, *reg_dev = NULL;
int ret;
vdev->id.device = id,
@@ -326,15 +326,24 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
kref_get(&rvdev->refcount);
ret = register_virtio_device(vdev);
+ reg_dev = vdev;
if (ret) {
- put_device(&rproc->dev);
dev_err(dev, "failed to register vdev: %d\n", ret);
goto out;
}
dev_info(dev, "registered %s (type %d)\n", dev_name(&vdev->dev), id);
+ return 0;
+
out:
+ if (reg_dev)
+ put_device(&vdev->dev);
+ else {
+ kref_put(&rvdev->refcount, rproc_vdev_release);
+ put_device(&rproc->dev);
+ }
+
return ret;
}
--
2.9.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v4 1/4] virtio: split device_register into device_initialize and device_add
2017-12-20 4:26 ` [PATCH v4 1/4] virtio: split device_register into device_initialize and device_add weiping zhang
@ 2017-12-20 15:53 ` Cornelia Huck
2017-12-21 2:37 ` weiping zhang
0 siblings, 1 reply; 12+ messages in thread
From: Cornelia Huck @ 2017-12-20 15:53 UTC (permalink / raw)
To: weiping zhang; +Cc: virtualization, mst
On Wed, 20 Dec 2017 12:26:25 +0800
weiping zhang <zwp10758@gmail.com> wrote:
[you used a different mail address in your From: than in your s-o-b:;
same for the other patches]
> In order to make caller do a simple cleanup, we split device_register
> into device_initialize and device_add. device_initialize always sucess,
s/success/succeeds/
> the caller can always use put_device when fail to register virtio_device
"so the caller can always use put_device when register_virtio_device
failed,"
> no matter fail at ida_simple_get or at device_add.
"no matter whether it failed..."
>
> Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
> Suggested-by: Cornelia Huck <cohuck@redhat.com>
> ---
> drivers/virtio/virtio.c | 18 +++++++++++++++---
> 1 file changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> index bf7ff39..3c9f211 100644
> --- a/drivers/virtio/virtio.c
> +++ b/drivers/virtio/virtio.c
> @@ -303,11 +303,21 @@ void unregister_virtio_driver(struct virtio_driver *driver)
> }
> EXPORT_SYMBOL_GPL(unregister_virtio_driver);
>
> +/**
> + * register_virtio_device - register virtio device
> + * @dev : virtio device interested
"virtio device to be registered"
> + *
> + * If an error occurs, the caller must use put_device, instead of kfree, because
> + * device_initialize and device_add will increase @dev->dev's reference count.
That's not correct: It's not because of device_add increasing the
reference count (it releases it again on failure), but because another
code path may have obtained a reference.
What about:
"On error, the caller must call put_device on &@dev->dev (and not
kfree), as another code path may have obtained a reference to @dev."
> + *
> + * Returns: 0 on suceess, -error on failure
> + */
> int register_virtio_device(struct virtio_device *dev)
> {
> int err;
>
> dev->dev.bus = &virtio_bus;
> + device_initialize(&dev->dev);
>
> /* Assign a unique device index and hence name. */
> err = ida_simple_get(&virtio_index_ida, 0, 0, GFP_KERNEL);
> @@ -330,9 +340,11 @@ int register_virtio_device(struct virtio_device *dev)
>
> INIT_LIST_HEAD(&dev->vqs);
>
> - /* device_register() causes the bus infrastructure to look for a
> - * matching driver. */
> - err = device_register(&dev->dev);
> + /*
> + * device_add() causes the bus infrastructure to look for a matching
> + * driver.
FWIW, I would just have done s/device_register/device_add/ in the
comment, but this is ok as well.
> + */
> + err = device_add(&dev->dev);
> if (err)
> ida_simple_remove(&virtio_index_ida, dev->index);
> out:
Your code change is fine.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 2/4] virtio_pci: don't kfree device on register failure
2017-12-20 4:26 ` [PATCH v4 2/4] virtio_pci: don't kfree device on register failure weiping zhang
@ 2017-12-20 15:55 ` Cornelia Huck
0 siblings, 0 replies; 12+ messages in thread
From: Cornelia Huck @ 2017-12-20 15:55 UTC (permalink / raw)
To: weiping zhang; +Cc: virtualization, mst
On Wed, 20 Dec 2017 12:26:43 +0800
weiping zhang <zwp10758@gmail.com> wrote:
> As mentioned at drivers/base/core.c:
> /*
> * NOTE: _Never_ directly free @dev after calling this function, even
> * if it returned an error! Always use put_device() to give up the
> * reference initialized in this function instead.
> */
> so we don't free vp_dev until vp_dev->vdev.dev.release be called.
>
> Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
> ---
> drivers/virtio/virtio_pci_common.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
> index 1c4797e..48d4d1c 100644
> --- a/drivers/virtio/virtio_pci_common.c
> +++ b/drivers/virtio/virtio_pci_common.c
> @@ -513,7 +513,7 @@ static void virtio_pci_release_dev(struct device *_d)
> static int virtio_pci_probe(struct pci_dev *pci_dev,
> const struct pci_device_id *id)
> {
> - struct virtio_pci_device *vp_dev;
> + struct virtio_pci_device *vp_dev, *reg_dev = NULL;
Not sure if I would have used a pointer for this purpose, but as that
is what Michael had proposed...
> int rc;
>
> /* allocate our structure and fill it out */
> @@ -551,6 +551,7 @@ static int virtio_pci_probe(struct pci_dev *pci_dev,
> pci_set_master(pci_dev);
>
> rc = register_virtio_device(&vp_dev->vdev);
> + reg_dev = vp_dev;
> if (rc)
> goto err_register;
>
> @@ -564,7 +565,10 @@ static int virtio_pci_probe(struct pci_dev *pci_dev,
> err_probe:
> pci_disable_device(pci_dev);
> err_enable_device:
> - kfree(vp_dev);
> + if (reg_dev)
> + put_device(&vp_dev->vdev.dev);
> + else
> + kfree(vp_dev);
> return rc;
> }
>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 3/4] virtio_vop: don't kfree device on register failure
2017-12-20 4:27 ` [PATCH v4 3/4] virtio_vop: " weiping zhang
@ 2017-12-20 15:57 ` Cornelia Huck
0 siblings, 0 replies; 12+ messages in thread
From: Cornelia Huck @ 2017-12-20 15:57 UTC (permalink / raw)
To: weiping zhang; +Cc: virtualization, mst
On Wed, 20 Dec 2017 12:27:04 +0800
weiping zhang <zwp10758@gmail.com> wrote:
> As mentioned at drivers/base/core.c:
> /*
> * NOTE: _Never_ directly free @dev after calling this function, even
> * if it returned an error! Always use put_device() to give up the
> * reference initialized in this function instead.
> */
> so we don't free vdev until vdev->vdev.dev.release be called.
>
> Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
> ---
> drivers/misc/mic/vop/vop_main.c | 20 +++++++++++++-------
> 1 file changed, 13 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/misc/mic/vop/vop_main.c b/drivers/misc/mic/vop/vop_main.c
> index a341938..3633202 100644
> --- a/drivers/misc/mic/vop/vop_main.c
> +++ b/drivers/misc/mic/vop/vop_main.c
> @@ -452,10 +452,12 @@ static irqreturn_t vop_virtio_intr_handler(int irq, void *data)
>
> static void vop_virtio_release_dev(struct device *_d)
> {
> - /*
> - * No need for a release method similar to virtio PCI.
> - * Provide an empty one to avoid getting a warning from core.
> - */
> + struct virtio_device *vdev =
> + container_of(_d, struct virtio_device, dev);
> + struct _vop_vdev *vop_vdev =
> + container_of(vdev, struct _vop_vdev, vdev);
> +
> + kfree(vop_vdev);
> }
>
> /*
> @@ -466,7 +468,7 @@ static int _vop_add_device(struct mic_device_desc __iomem *d,
> unsigned int offset, struct vop_device *vpdev,
> int dnode)
> {
> - struct _vop_vdev *vdev;
> + struct _vop_vdev *vdev, *reg_dev = NULL;
Similarly, not a fan of that pointer variable, but it's fine.
> int ret;
> u8 type = ioread8(&d->type);
>
> @@ -497,6 +499,7 @@ static int _vop_add_device(struct mic_device_desc __iomem *d,
> vdev->c2h_vdev_db = ioread8(&vdev->dc->c2h_vdev_db);
>
> ret = register_virtio_device(&vdev->vdev);
> + reg_dev = vdev;
> if (ret) {
> dev_err(_vop_dev(vdev),
> "Failed to register vop device %u type %u\n",
> @@ -512,7 +515,10 @@ static int _vop_add_device(struct mic_device_desc __iomem *d,
> free_irq:
> vpdev->hw_ops->free_irq(vpdev, vdev->virtio_cookie, vdev);
> kfree:
> - kfree(vdev);
> + if (reg_dev)
> + put_device(&vdev->vdev.dev);
> + else
> + kfree(vdev);
> return ret;
> }
>
> @@ -568,7 +574,7 @@ static int _vop_remove_device(struct mic_device_desc __iomem *d,
> iowrite8(-1, &dc->h2c_vdev_db);
> if (status & VIRTIO_CONFIG_S_DRIVER_OK)
> wait_for_completion(&vdev->reset_done);
> - kfree(vdev);
> + put_device(&vdev->vdev.dev);
> iowrite8(1, &dc->guest_ack);
> dev_dbg(&vpdev->dev, "%s %d guest_ack %d\n",
> __func__, __LINE__, ioread8(&dc->guest_ack));
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 4/4] virtio_remoteproc: don't kfree device on register failure
2017-12-20 4:27 ` [PATCH v4 4/4] virtio_remoteproc: " weiping zhang
@ 2017-12-20 16:12 ` Cornelia Huck
2017-12-21 3:08 ` weiping zhang
0 siblings, 1 reply; 12+ messages in thread
From: Cornelia Huck @ 2017-12-20 16:12 UTC (permalink / raw)
To: weiping zhang; +Cc: virtualization, mst
On Wed, 20 Dec 2017 12:27:33 +0800
weiping zhang <zwp10758@gmail.com> wrote:
> rproc_virtio_dev_release will be called iff virtio_device.dev's
> refer count became to 0. Here we should check if we call device_register
"reference count drops to 0"
s/call/called/
> or not, if called, put vdev.dev, and then rproc->dev's cleanup will be
> done in rproc_virtio_dev_release, otherwise we do cleanup directly.
>
> Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
> ---
> drivers/remoteproc/remoteproc_virtio.c | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
> index 2946348..1073ea3 100644
> --- a/drivers/remoteproc/remoteproc_virtio.c
> +++ b/drivers/remoteproc/remoteproc_virtio.c
> @@ -304,7 +304,7 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
> {
> struct rproc *rproc = rvdev->rproc;
> struct device *dev = &rproc->dev;
> - struct virtio_device *vdev = &rvdev->vdev;
> + struct virtio_device *vdev = &rvdev->vdev, *reg_dev = NULL;
> int ret;
>
> vdev->id.device = id,
> @@ -326,15 +326,24 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
> kref_get(&rvdev->refcount);
>
> ret = register_virtio_device(vdev);
> + reg_dev = vdev;
> if (ret) {
> - put_device(&rproc->dev);
> dev_err(dev, "failed to register vdev: %d\n", ret);
> goto out;
> }
>
> dev_info(dev, "registered %s (type %d)\n", dev_name(&vdev->dev), id);
>
> + return 0;
> +
> out:
> + if (reg_dev)
> + put_device(&vdev->dev);
> + else {
> + kref_put(&rvdev->refcount, rproc_vdev_release);
> + put_device(&rproc->dev);
> + }
> +
> return ret;
> }
>
I think in this case using the marker makes a straightforward cleanup
way too complicated. There's a single way we can get to the out label,
and that's when register_virtio_device() failed. Switching
put_device(&rproc->dev) to put_device(@vdev->dev) (what your first
patch did) seems like the way to go.
(It also may be good to cc: the maintainers for this driver.)
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 1/4] virtio: split device_register into device_initialize and device_add
2017-12-20 15:53 ` Cornelia Huck
@ 2017-12-21 2:37 ` weiping zhang
2017-12-21 2:43 ` weiping zhang
0 siblings, 1 reply; 12+ messages in thread
From: weiping zhang @ 2017-12-21 2:37 UTC (permalink / raw)
To: Cornelia Huck; +Cc: virtualization, Michael S . Tsirkin
2017-12-20 23:53 GMT+08:00 Cornelia Huck <cohuck@redhat.com>:
> On Wed, 20 Dec 2017 12:26:25 +0800
> weiping zhang <zwp10758@gmail.com> wrote:
>
> [you used a different mail address in your From: than in your s-o-b:;
> same for the other patches]
>
>> In order to make caller do a simple cleanup, we split device_register
>> into device_initialize and device_add. device_initialize always sucess,
>
> s/success/succeeds/
>
>> the caller can always use put_device when fail to register virtio_device
>
> "so the caller can always use put_device when register_virtio_device
> failed,"
>
>> no matter fail at ida_simple_get or at device_add.
>
> "no matter whether it failed..."
>
>> + *
>> + * If an error occurs, the caller must use put_device, instead of kfree, because
>> + * device_initialize and device_add will increase @dev->dev's reference count.
>
> That's not correct: It's not because of device_add increasing the
> reference count (it releases it again on failure), but because another
> code path may have obtained a reference.
>
> What about:
>
> "On error, the caller must call put_device on &@dev->dev (and not
> kfree), as another code path may have obtained a reference to @dev."
>
It's good to understand, further more dev->name may has a bit mem leak.
anyway, I'll correct all comments at V5. Thanks very much.
>> + *
>> + * Returns: 0 on suceess, -error on failure
>> + */
>> int register_virtio_device(struct virtio_device *dev)
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 1/4] virtio: split device_register into device_initialize and device_add
2017-12-21 2:37 ` weiping zhang
@ 2017-12-21 2:43 ` weiping zhang
0 siblings, 0 replies; 12+ messages in thread
From: weiping zhang @ 2017-12-21 2:43 UTC (permalink / raw)
To: Cornelia Huck; +Cc: virtualization, Michael S . Tsirkin
2017-12-21 10:37 GMT+08:00 weiping zhang <zwp10758@gmail.com>:
> 2017-12-20 23:53 GMT+08:00 Cornelia Huck <cohuck@redhat.com>:
>> On Wed, 20 Dec 2017 12:26:25 +0800
>> weiping zhang <zwp10758@gmail.com> wrote:
>>
>> [you used a different mail address in your From: than in your s-o-b:;
>> same for the other patches]
a wrong setting of my email client, correct it next time, thanks.
>>> In order to make caller do a simple cleanup, we split device_register
>>> into device_initialize and device_add. device_initialize always sucess,
>>
>> s/success/succeeds/
>>
>>> the caller can always use put_device when fail to register virtio_device
>>
>> "so the caller can always use put_device when register_virtio_device
>> failed,"
>>
>>> no matter fail at ida_simple_get or at device_add.
>>
>> "no matter whether it failed..."
>>
>>> + *
>>> + * If an error occurs, the caller must use put_device, instead of kfree, because
>>> + * device_initialize and device_add will increase @dev->dev's reference count.
>>
>> That's not correct: It's not because of device_add increasing the
>> reference count (it releases it again on failure), but because another
>> code path may have obtained a reference.
>>
>> What about:
>>
>> "On error, the caller must call put_device on &@dev->dev (and not
>> kfree), as another code path may have obtained a reference to @dev."
>>
> It's good to understand, further more dev->name may has a bit mem leak.
> anyway, I'll correct all comments at V5. Thanks very much.
>>> + *
>>> + * Returns: 0 on suceess, -error on failure
>>> + */
>>> int register_virtio_device(struct virtio_device *dev)
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 4/4] virtio_remoteproc: don't kfree device on register failure
2017-12-20 16:12 ` Cornelia Huck
@ 2017-12-21 3:08 ` weiping zhang
0 siblings, 0 replies; 12+ messages in thread
From: weiping zhang @ 2017-12-21 3:08 UTC (permalink / raw)
To: Cornelia Huck; +Cc: virtualization, Michael S . Tsirkin
2017-12-21 0:12 GMT+08:00 Cornelia Huck <cohuck@redhat.com>:
> On Wed, 20 Dec 2017 12:27:33 +0800
> weiping zhang <zwp10758@gmail.com> wrote:
>
>> rproc_virtio_dev_release will be called iff virtio_device.dev's
>> refer count became to 0. Here we should check if we call device_register
>
> "reference count drops to 0"
>
> s/call/called/
rproc_add_virtio_dev is not like other virtio driver, it always call
register_virtio_device,
so commit message would be:
virtio_remoteproc: correct put_device virtio_device.dev
rproc_virtio_dev_release will be called iff virtio_device.dev's
reference count drops to 0. Here we just put vdev.dev, and then
rproc->dev's cleanup will be done in rproc_virtio_dev_release.
>> or not, if called, put vdev.dev, and then rproc->dev's cleanup will be
>> done in rproc_virtio_dev_release, otherwise we do cleanup directly.
>>
>> Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
>> ---
>> drivers/remoteproc/remoteproc_virtio.c | 13 +++++++++++--
>> 1 file changed, 11 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
>> index 2946348..1073ea3 100644
>> --- a/drivers/remoteproc/remoteproc_virtio.c
>> +++ b/drivers/remoteproc/remoteproc_virtio.c
>> @@ -304,7 +304,7 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
>> {
>> struct rproc *rproc = rvdev->rproc;
>> struct device *dev = &rproc->dev;
>> - struct virtio_device *vdev = &rvdev->vdev;
>> + struct virtio_device *vdev = &rvdev->vdev, *reg_dev = NULL;
>> int ret;
>>
>> vdev->id.device = id,
>> @@ -326,15 +326,24 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
>> kref_get(&rvdev->refcount);
>>
>> ret = register_virtio_device(vdev);
>> + reg_dev = vdev;
>> if (ret) {
>> - put_device(&rproc->dev);
>> dev_err(dev, "failed to register vdev: %d\n", ret);
>> goto out;
>> }
>>
>> dev_info(dev, "registered %s (type %d)\n", dev_name(&vdev->dev), id);
>>
>> + return 0;
>> +
>> out:
>> + if (reg_dev)
>> + put_device(&vdev->dev);
>> + else {
>> + kref_put(&rvdev->refcount, rproc_vdev_release);
>> + put_device(&rproc->dev);
>> + }
>> +
>> return ret;
>> }
>>
>
> I think in this case using the marker makes a straightforward cleanup
> way too complicated. There's a single way we can get to the out label,
> and that's when register_virtio_device() failed. Switching
> put_device(&rproc->dev) to put_device(@vdev->dev) (what your first
> patch did) seems like the way to go.
OK, put it directly at v5.
> (It also may be good to cc: the maintainers for this driver.)
OK, thanks
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2017-12-21 3:08 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-20 4:26 [PATCH v4 0/4] use put_device to cleanup resource weiping zhang
2017-12-20 4:26 ` [PATCH v4 1/4] virtio: split device_register into device_initialize and device_add weiping zhang
2017-12-20 15:53 ` Cornelia Huck
2017-12-21 2:37 ` weiping zhang
2017-12-21 2:43 ` weiping zhang
2017-12-20 4:26 ` [PATCH v4 2/4] virtio_pci: don't kfree device on register failure weiping zhang
2017-12-20 15:55 ` Cornelia Huck
2017-12-20 4:27 ` [PATCH v4 3/4] virtio_vop: " weiping zhang
2017-12-20 15:57 ` Cornelia Huck
2017-12-20 4:27 ` [PATCH v4 4/4] virtio_remoteproc: " weiping zhang
2017-12-20 16:12 ` Cornelia Huck
2017-12-21 3:08 ` weiping zhang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.