* [PATCH v3 1/5] virtio: add helper virtio_get_status
2017-12-17 13:45 [PATCH v3 0/5] proper cleanup if fail to register_virtio_device weiping zhang
@ 2017-12-17 13:45 ` weiping zhang
2017-12-17 13:46 ` [PATCH v3 2/5] virtio_pci: don't kfree device on register failure weiping zhang
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: weiping zhang @ 2017-12-17 13:45 UTC (permalink / raw)
To: cohuck, mst, jasowang; +Cc: virtualization
add helper function to simplify dev->config->get_status().
Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
---
drivers/virtio/virtio.c | 6 ++++++
include/linux/virtio_config.h | 2 ++
2 files changed, 8 insertions(+)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index bf7ff39..c5b057bd 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -165,6 +165,12 @@ void virtio_add_status(struct virtio_device *dev, unsigned int status)
}
EXPORT_SYMBOL_GPL(virtio_add_status);
+unsigned int virtio_get_status(struct virtio_device *dev)
+{
+ return dev->config->get_status(dev);
+}
+EXPORT_SYMBOL_GPL(virtio_get_status);
+
int virtio_finalize_features(struct virtio_device *dev)
{
int ret = dev->config->finalize_features(dev);
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 5559a2d..30972c4 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -429,6 +429,8 @@ static inline void virtio_cwrite64(struct virtio_device *vdev,
vdev->config->set(vdev, offset, &val, sizeof(val));
}
+unsigned int virtio_get_status(struct virtio_device *dev);
+
/* Conditional config space accessors. */
#define virtio_cread_feature(vdev, fbit, structname, member, ptr) \
({ \
--
2.9.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v3 2/5] virtio_pci: don't kfree device on register failure
2017-12-17 13:45 [PATCH v3 0/5] proper cleanup if fail to register_virtio_device weiping zhang
2017-12-17 13:45 ` [PATCH v3 1/5] virtio: add helper virtio_get_status weiping zhang
@ 2017-12-17 13:46 ` weiping zhang
2017-12-17 13:47 ` [PATCH v3 3/5] virtio_vop: " weiping zhang
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: weiping zhang @ 2017-12-17 13:46 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 | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index 1c4797e..21a2ce0 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -564,7 +564,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 (VIRTIO_CONFIG_S_ACKNOWLEDGE & virtio_get_status(&vp_dev->vdev))
+ put_device(&vp_dev->vdev.dev);
+ else
+ kfree(vp_dev);
return rc;
}
--
2.9.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v3 3/5] virtio_vop: don't kfree device on register failure
2017-12-17 13:45 [PATCH v3 0/5] proper cleanup if fail to register_virtio_device weiping zhang
2017-12-17 13:45 ` [PATCH v3 1/5] virtio: add helper virtio_get_status weiping zhang
2017-12-17 13:46 ` [PATCH v3 2/5] virtio_pci: don't kfree device on register failure weiping zhang
@ 2017-12-17 13:47 ` weiping zhang
2017-12-17 13:47 ` [PATCH v3 4/5] virtio_remoteproc: " weiping zhang
2017-12-17 13:48 ` [PATCH v3 5/5] virtio: add comments for virtio_register_device weiping zhang
4 siblings, 0 replies; 8+ messages in thread
From: weiping zhang @ 2017-12-17 13:47 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 | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/misc/mic/vop/vop_main.c b/drivers/misc/mic/vop/vop_main.c
index a341938..53eaa9d 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);
}
/*
@@ -512,7 +514,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 (VIRTIO_CONFIG_S_ACKNOWLEDGE & virtio_get_status(&vdev->vdev))
+ put_device(&vdev->vdev.dev);
+ else
+ kfree(vdev);
return ret;
}
@@ -568,7 +573,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] 8+ messages in thread* [PATCH v3 4/5] virtio_remoteproc: don't kfree device on register failure
2017-12-17 13:45 [PATCH v3 0/5] proper cleanup if fail to register_virtio_device weiping zhang
` (2 preceding siblings ...)
2017-12-17 13:47 ` [PATCH v3 3/5] virtio_vop: " weiping zhang
@ 2017-12-17 13:47 ` weiping zhang
2017-12-17 13:48 ` [PATCH v3 5/5] virtio: add comments for virtio_register_device weiping zhang
4 siblings, 0 replies; 8+ messages in thread
From: weiping zhang @ 2017-12-17 13:47 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 | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index 2946348..ad5d6d1 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -327,14 +327,22 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
ret = register_virtio_device(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 (VIRTIO_CONFIG_S_ACKNOWLEDGE & virtio_get_status(vdev))
+ 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] 8+ messages in thread* [PATCH v3 5/5] virtio: add comments for virtio_register_device
2017-12-17 13:45 [PATCH v3 0/5] proper cleanup if fail to register_virtio_device weiping zhang
` (3 preceding siblings ...)
2017-12-17 13:47 ` [PATCH v3 4/5] virtio_remoteproc: " weiping zhang
@ 2017-12-17 13:48 ` weiping zhang
2017-12-19 11:11 ` Cornelia Huck
4 siblings, 1 reply; 8+ messages in thread
From: weiping zhang @ 2017-12-17 13:48 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.
*/
virtio_register_device may fail before/after call device_register, the
caller should do a proper cleanup. Caller cann't use kfree directly,
if virtio_register_device has already called device_register. Caller
cann't use put_device directly, if virtio_register_device has not yet
call device_register, because kobject_put may give a warning cause
dev->kobj has not been initialized.
Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
---
drivers/virtio/virtio.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index c5b057bd..4f0718b 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -309,6 +309,19 @@ void unregister_virtio_driver(struct virtio_driver *driver)
}
EXPORT_SYMBOL_GPL(unregister_virtio_driver);
+/**
+ * register_virtio_device - register virtio device
+ *
+ * @dev : virtio device interested
+ *
+ * This funciton may fail after call device_register, as mentioned at
+ * drivers/base/core.c we must use put_device(), _never_ directly free @dev.
+ * The caller should take care of the status of @dev and determine to use
+ * put_device or kfree. If @dev in VIRTIO_CONFIG_S_ACKNOWLEDGE status that
+ * means caller should use put_device otherwise use kfree directly.
+ *
+ * Returns: 0 on success, error on failure.
+ */
int register_virtio_device(struct virtio_device *dev)
{
int err;
--
2.9.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v3 5/5] virtio: add comments for virtio_register_device
2017-12-17 13:48 ` [PATCH v3 5/5] virtio: add comments for virtio_register_device weiping zhang
@ 2017-12-19 11:11 ` Cornelia Huck
2017-12-19 15:23 ` weiping zhang
0 siblings, 1 reply; 8+ messages in thread
From: Cornelia Huck @ 2017-12-19 11:11 UTC (permalink / raw)
To: weiping zhang; +Cc: virtualization, mst
On Sun, 17 Dec 2017 21:48:05 +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.
> */
> virtio_register_device may fail before/after call device_register, the
> caller should do a proper cleanup. Caller cann't use kfree directly,
> if virtio_register_device has already called device_register. Caller
> cann't use put_device directly, if virtio_register_device has not yet
> call device_register, because kobject_put may give a warning cause
> dev->kobj has not been initialized.
This comment makes me inclined to think that we should also rethink
register_virtio_device(). On failure, we cannot do kfree() due to
driver core interaction; but we cannot do a put_device() either, since
the refcount may not yet have been initialized -- unless we check the
device status, which triggers I/O (at least on s390).
We really want to do the same cleanup on error in every case. What
about splitting device_register() into device_initialize() and
device_add()? If we move device_initialize() before getting an index,
we should be fine with doing put_device() on error in every case.
>
> Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
> ---
> drivers/virtio/virtio.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> index c5b057bd..4f0718b 100644
> --- a/drivers/virtio/virtio.c
> +++ b/drivers/virtio/virtio.c
> @@ -309,6 +309,19 @@ void unregister_virtio_driver(struct virtio_driver *driver)
> }
> EXPORT_SYMBOL_GPL(unregister_virtio_driver);
>
> +/**
> + * register_virtio_device - register virtio device
> + *
> + * @dev : virtio device interested
> + *
> + * This funciton may fail after call device_register, as mentioned at
> + * drivers/base/core.c we must use put_device(), _never_ directly free @dev.
> + * The caller should take care of the status of @dev and determine to use
> + * put_device or kfree. If @dev in VIRTIO_CONFIG_S_ACKNOWLEDGE status that
> + * means caller should use put_device otherwise use kfree directly.
> + *
> + * Returns: 0 on success, error on failure.
> + */
> int register_virtio_device(struct virtio_device *dev)
> {
> int err;
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v3 5/5] virtio: add comments for virtio_register_device
2017-12-19 11:11 ` Cornelia Huck
@ 2017-12-19 15:23 ` weiping zhang
0 siblings, 0 replies; 8+ messages in thread
From: weiping zhang @ 2017-12-19 15:23 UTC (permalink / raw)
To: Cornelia Huck; +Cc: virtualization, Michael S . Tsirkin
2017-12-19 19:11 GMT+08:00 Cornelia Huck <cohuck@redhat.com>:
> On Sun, 17 Dec 2017 21:48:05 +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.
>> */
>> virtio_register_device may fail before/after call device_register, the
>> caller should do a proper cleanup. Caller cann't use kfree directly,
>> if virtio_register_device has already called device_register. Caller
>> cann't use put_device directly, if virtio_register_device has not yet
>> call device_register, because kobject_put may give a warning cause
>> dev->kobj has not been initialized.
>
> This comment makes me inclined to think that we should also rethink
> register_virtio_device(). On failure, we cannot do kfree() due to
> driver core interaction; but we cannot do a put_device() either, since
> the refcount may not yet have been initialized -- unless we check the
> device status, which triggers I/O (at least on s390).
>
> We really want to do the same cleanup on error in every case. What
> about splitting device_register() into device_initialize() and
> device_add()? If we move device_initialize() before getting an index,
> we should be fine with doing put_device() on error in every case.
>
Good idea (^_^), I''ll apply it at V4.
^ permalink raw reply [flat|nested] 8+ messages in thread