raw/skeleton: fix segmentation fault on rawdev_autotest
Checks
Commit Message
segmentation fault ocured as vdev->device.driver->name did not
return correct value.
Test2 failed as dummy_value was freed before it was used.
Signed-off-by: Kallio Marko <marko.kallio@cavium.comm>
Signed-off-by: Harman Kalra <hkalra@marvell.com>
---
drivers/raw/skeleton_rawdev/skeleton_rawdev.c | 3 ++-
drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
Comments
On Tuesday 11 December 2018 06:44 PM, Harman Kalra wrote:
> segmentation fault ocured as vdev->device.driver->name did not
> return correct value.
> Test2 failed as dummy_value was freed before it was used.
>
> Signed-off-by: Kallio Marko <marko.kallio@cavium.comm>
> Signed-off-by: Harman Kalra <hkalra@marvell.com>
> ---
> drivers/raw/skeleton_rawdev/skeleton_rawdev.c | 3 ++-
> drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c | 4 ++--
> 2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
> index d7630fc69..c957ced11 100644
> --- a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
> +++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c
> @@ -585,7 +585,8 @@ skeleton_rawdev_create(const char *name,
>
> rawdev->dev_ops = &skeleton_rawdev_ops;
> rawdev->device = &vdev->device;
> - rawdev->driver_name = vdev->device.driver->name;
> +
> + rawdev->driver_name = rawdev->name;
This is not right. rawdev->name is name of the device and not that of a
driver.
But, this also highlights a much bigger issue here:
----
$ master+* ± grep driver_name * -rn
dpaa2_cmdif/dpaa2_cmdif.c:214: rawdev->driver_name =
vdev->device.driver->name;
dpaa2_qdma/dpaa2_qdma.c:958: rawdev->driver_name =
dpaa2_drv->driver.name;
ifpga_rawdev/ifpga_rawdev.c:421: rawdev->driver_name =
pci_dev->device.driver->name;
skeleton_rawdev/skeleton_rawdev.c:588: rawdev->driver_name =
vdev->device.driver->name;
----
So, it seems that all rawdev drivers are assuming that even before probe
is over (this assignment is path of probe within driver), they can
assign the name to the 'device.driver'.
Here is the snippet from bus/pci/pci_common.c
--->8---
ret = dr->probe(dr, dev);
...
if (ret) {
/* Error case */
...
} else {
dev->device.driver = &dr->driver;
}
--->8---
And from bus/vdev/vdev.c
--->8---
ret = driver->probe(dev);
if (ret == 0)
dev->device.driver = &driver->driver;
--->8---
So, the bus is actually assigning device.driver part *after* probe is
successfully complete.
So, if your's segfaulted, there is a high probability others too would
encounter the same.
This needs investigation.
>
> skeldev = skeleton_rawdev_get_priv(rawdev);
>
> diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
> index 359c9e296..788c3f1b9 100644
> --- a/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
> +++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev_test.c
> @@ -294,14 +294,14 @@ test_rawdev_attr_set_get(void)
> "Attribute (Test1) not set correctly (%" PRIu64 ")",
> ret_value);
>
> - free(dummy_value);
> -
> ret_value = 0;
> ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test2", &ret_value);
> RTE_TEST_ASSERT_EQUAL(*((int *)(uintptr_t)ret_value), 200,
> "Attribute (Test2) not set correctly (%" PRIu64 ")",
> ret_value);
>
> + free(dummy_value);
> +
The issue that you report is correct - that dummy_value is being
released before next test - causing segfault.
The problem here is that if free(dummy_value) is called *after* "Test2",
coverity reports error [See: 88d0e47880ec ("raw/skeleton: fix memory
leak on test failure"] - and rightly so because RTE_TES_ASSERT_EQUAL()
returns in case of error.
I will try and find a way out of this.
> return TEST_SUCCESS;
> }
>
>
@@ -585,7 +585,8 @@ skeleton_rawdev_create(const char *name,
rawdev->dev_ops = &skeleton_rawdev_ops;
rawdev->device = &vdev->device;
- rawdev->driver_name = vdev->device.driver->name;
+
+ rawdev->driver_name = rawdev->name;
skeldev = skeleton_rawdev_get_priv(rawdev);
@@ -294,14 +294,14 @@ test_rawdev_attr_set_get(void)
"Attribute (Test1) not set correctly (%" PRIu64 ")",
ret_value);
- free(dummy_value);
-
ret_value = 0;
ret = rte_rawdev_get_attr(TEST_DEV_ID, "Test2", &ret_value);
RTE_TEST_ASSERT_EQUAL(*((int *)(uintptr_t)ret_value), 200,
"Attribute (Test2) not set correctly (%" PRIu64 ")",
ret_value);
+ free(dummy_value);
+
return TEST_SUCCESS;
}