* [Qemu-devel] [PATCH v3] net/rocker: Convert to realize
@ 2017-05-16 12:37 Mao Zhongyi
2017-05-16 15:29 ` Markus Armbruster
0 siblings, 1 reply; 5+ messages in thread
From: Mao Zhongyi @ 2017-05-16 12:37 UTC (permalink / raw)
To: qemu-devel; +Cc: jiri, jasowang, f4bug
The rocker device still implements the old PCIDeviceClass .init()
instead of the new .realize(). All devices need to be converted to
.realize().
.init() reports errors with fprintf() and return 0 on success, negative
number on failure. Meanwhile, when -device rocker fails, it first report
a specific error, then a generic one, like this:
$ x86_64-softmmu/qemu-system-x86_64 -device rocker,name=qemu-rocker
rocker: name too long; please shorten to at most 9 chars
qemu-system-x86_64: -device rocker,name=qemu-rocker: Device initialization failed
Now, convert it to .realize() that passes errors to its callers via its
errp argument. Also avoid the superfluous second error message.
Cc: jiri@resnulli.us
Cc: jasowang@redhat.com
Cc: f4bug@amsat.org
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
---
hw/net/rocker/rocker.c | 35 +++++++++++++++++------------------
1 file changed, 17 insertions(+), 18 deletions(-)
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
index 6e70fdd..c446cda 100644
--- a/hw/net/rocker/rocker.c
+++ b/hw/net/rocker/rocker.c
@@ -1252,20 +1252,18 @@ rollback:
return err;
}
-static int rocker_msix_init(Rocker *r)
+static int rocker_msix_init(Rocker *r, Error **errp)
{
PCIDevice *dev = PCI_DEVICE(r);
int err;
- Error *local_err = NULL;
err = msix_init(dev, ROCKER_MSIX_VEC_COUNT(r->fp_ports),
&r->msix_bar,
ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_TABLE_OFFSET,
&r->msix_bar,
ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_PBA_OFFSET,
- 0, &local_err);
+ 0, errp);
if (err) {
- error_report_err(local_err);
return err;
}
@@ -1301,7 +1299,7 @@ static World *rocker_world_type_by_name(Rocker *r, const char *name)
return NULL;
}
-static int pci_rocker_init(PCIDevice *dev)
+static void pci_rocker_realize(PCIDevice *dev, Error **errp)
{
Rocker *r = to_rocker(dev);
const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } };
@@ -1315,7 +1313,7 @@ static int pci_rocker_init(PCIDevice *dev)
for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
if (!r->worlds[i]) {
- err = -ENOMEM;
+ error_setg(errp, "rocker: memory allocation for worlds failed");
goto err_world_alloc;
}
}
@@ -1326,10 +1324,9 @@ static int pci_rocker_init(PCIDevice *dev)
r->world_dflt = rocker_world_type_by_name(r, r->world_name);
if (!r->world_dflt) {
- fprintf(stderr,
- "rocker: requested world \"%s\" does not exist\n",
+ error_setg(errp,
+ "rocker: invalid argument, requested world %s does not exist",
r->world_name);
- err = -EINVAL;
goto err_world_type_by_name;
}
@@ -1349,7 +1346,7 @@ static int pci_rocker_init(PCIDevice *dev)
/* MSI-X init */
- err = rocker_msix_init(r);
+ err = rocker_msix_init(r, errp);
if (err) {
goto err_msix_init;
}
@@ -1361,7 +1358,7 @@ static int pci_rocker_init(PCIDevice *dev)
}
if (rocker_find(r->name)) {
- err = -EEXIST;
+ error_setg(errp, "rocker: %s already exists", r->name);
goto err_duplicate;
}
@@ -1375,10 +1372,10 @@ static int pci_rocker_init(PCIDevice *dev)
#define ROCKER_IFNAMSIZ 16
#define MAX_ROCKER_NAME_LEN (ROCKER_IFNAMSIZ - 1 - 3 - 3)
if (strlen(r->name) > MAX_ROCKER_NAME_LEN) {
- fprintf(stderr,
- "rocker: name too long; please shorten to at most %d chars\n",
+ error_setg(errp,
+ "rocker: name too long; please shorten to at most %d chars",
MAX_ROCKER_NAME_LEN);
- return -EINVAL;
+ goto err_name_too_long;
}
if (memcmp(&r->fp_start_macaddr, &zero, sizeof(zero)) == 0) {
@@ -1397,6 +1394,7 @@ static int pci_rocker_init(PCIDevice *dev)
r->rings = g_new(DescRing *, rocker_pci_ring_count(r));
if (!r->rings) {
+ error_setg(errp, "rocker: memory allocation for rings failed");
goto err_rings_alloc;
}
@@ -1410,11 +1408,11 @@ static int pci_rocker_init(PCIDevice *dev)
* .....
*/
- err = -ENOMEM;
for (i = 0; i < rocker_pci_ring_count(r); i++) {
DescRing *ring = desc_ring_alloc(r, i);
if (!ring) {
+ error_setg(errp, "rocker: memory allocation for ring failed");
goto err_ring_alloc;
}
@@ -1438,6 +1436,7 @@ static int pci_rocker_init(PCIDevice *dev)
i, &r->fp_ports_peers[i]);
if (!port) {
+ error_setg(errp, "rocker: memory allocation for port failed");
goto err_port_alloc;
}
@@ -1447,7 +1446,7 @@ static int pci_rocker_init(PCIDevice *dev)
QLIST_INSERT_HEAD(&rockers, r, next);
- return 0;
+ return;
err_port_alloc:
for (--i; i >= 0; i--) {
@@ -1461,6 +1460,7 @@ err_ring_alloc:
}
g_free(r->rings);
err_rings_alloc:
+err_name_too_long:
err_duplicate:
rocker_msix_uninit(r);
err_msix_init:
@@ -1473,7 +1473,6 @@ err_world_alloc:
world_free(r->worlds[i]);
}
}
- return err;
}
static void pci_rocker_uninit(PCIDevice *dev)
@@ -1558,7 +1557,7 @@ static void rocker_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_rocker_init;
+ k->realize = pci_rocker_realize;
k->exit = pci_rocker_uninit;
k->vendor_id = PCI_VENDOR_ID_REDHAT;
k->device_id = PCI_DEVICE_ID_REDHAT_ROCKER;
--
2.9.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v3] net/rocker: Convert to realize
2017-05-16 12:37 [Qemu-devel] [PATCH v3] net/rocker: Convert to realize Mao Zhongyi
@ 2017-05-16 15:29 ` Markus Armbruster
2017-05-17 3:58 ` Mao Zhongyi
0 siblings, 1 reply; 5+ messages in thread
From: Markus Armbruster @ 2017-05-16 15:29 UTC (permalink / raw)
To: Mao Zhongyi; +Cc: qemu-devel, jasowang, jiri, f4bug
Mao Zhongyi <maozy.fnst@cn.fujitsu.com> writes:
> The rocker device still implements the old PCIDeviceClass .init()
> instead of the new .realize(). All devices need to be converted to
> .realize().
Thanks for chipping in!
> .init() reports errors with fprintf() and return 0 on success, negative
> number on failure. Meanwhile, when -device rocker fails, it first report
> a specific error, then a generic one, like this:
>
> $ x86_64-softmmu/qemu-system-x86_64 -device rocker,name=qemu-rocker
> rocker: name too long; please shorten to at most 9 chars
> qemu-system-x86_64: -device rocker,name=qemu-rocker: Device initialization failed
>
> Now, convert it to .realize() that passes errors to its callers via its
> errp argument. Also avoid the superfluous second error message.
Recommend to show the error message after your patch here:
qemu-system-x86_64: -device rocker,name=qemu-rocker: rocker: name too long; please shorten to at most 9 chars
Not least because that makes it blatantly obvious that keeping the
"rocker: " is not a good idea :)
> Cc: jiri@resnulli.us
> Cc: jasowang@redhat.com
> Cc: f4bug@amsat.org
> Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
> ---
> hw/net/rocker/rocker.c | 35 +++++++++++++++++------------------
> 1 file changed, 17 insertions(+), 18 deletions(-)
>
> diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
> index 6e70fdd..c446cda 100644
> --- a/hw/net/rocker/rocker.c
> +++ b/hw/net/rocker/rocker.c
> @@ -1252,20 +1252,18 @@ rollback:
> return err;
> }
>
> -static int rocker_msix_init(Rocker *r)
> +static int rocker_msix_init(Rocker *r, Error **errp)
> {
> PCIDevice *dev = PCI_DEVICE(r);
> int err;
> - Error *local_err = NULL;
>
> err = msix_init(dev, ROCKER_MSIX_VEC_COUNT(r->fp_ports),
> &r->msix_bar,
> ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_TABLE_OFFSET,
> &r->msix_bar,
> ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_PBA_OFFSET,
> - 0, &local_err);
> + 0, errp);
> if (err) {
> - error_report_err(local_err);
> return err;
> }
>
> @@ -1301,7 +1299,7 @@ static World *rocker_world_type_by_name(Rocker *r, const char *name)
> return NULL;
> }
>
> -static int pci_rocker_init(PCIDevice *dev)
> +static void pci_rocker_realize(PCIDevice *dev, Error **errp)
> {
> Rocker *r = to_rocker(dev);
> const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } };
> @@ -1315,7 +1313,7 @@ static int pci_rocker_init(PCIDevice *dev)
>
> for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
> if (!r->worlds[i]) {
> - err = -ENOMEM;
> + error_setg(errp, "rocker: memory allocation for worlds failed");
r->worlds[i] is null when of_dpa_world_alloc() returns null. It's a
wrapper around world_alloc(), which returns null only when g_malloc()
does. It doesn't. Please remove the dead error handling. Ideally in a
separate cleanup patch before this one, to facilitate review.
Recommend to drop the "rocker: " prefix. Same for all the other error
messages.
> goto err_world_alloc;
> }
> }
> @@ -1326,10 +1324,9 @@ static int pci_rocker_init(PCIDevice *dev)
>
> r->world_dflt = rocker_world_type_by_name(r, r->world_name);
> if (!r->world_dflt) {
> - fprintf(stderr,
> - "rocker: requested world \"%s\" does not exist\n",
> + error_setg(errp,
> + "rocker: invalid argument, requested world %s does not exist",
> r->world_name);
> - err = -EINVAL;
> goto err_world_type_by_name;
> }
>
> @@ -1349,7 +1346,7 @@ static int pci_rocker_init(PCIDevice *dev)
>
> /* MSI-X init */
>
> - err = rocker_msix_init(r);
> + err = rocker_msix_init(r, errp);
> if (err) {
> goto err_msix_init;
> }
> @@ -1361,7 +1358,7 @@ static int pci_rocker_init(PCIDevice *dev)
> }
>
> if (rocker_find(r->name)) {
> - err = -EEXIST;
> + error_setg(errp, "rocker: %s already exists", r->name);
> goto err_duplicate;
> }
>
> @@ -1375,10 +1372,10 @@ static int pci_rocker_init(PCIDevice *dev)
> #define ROCKER_IFNAMSIZ 16
> #define MAX_ROCKER_NAME_LEN (ROCKER_IFNAMSIZ - 1 - 3 - 3)
> if (strlen(r->name) > MAX_ROCKER_NAME_LEN) {
> - fprintf(stderr,
> - "rocker: name too long; please shorten to at most %d chars\n",
> + error_setg(errp,
> + "rocker: name too long; please shorten to at most %d chars",
> MAX_ROCKER_NAME_LEN);
> - return -EINVAL;
> + goto err_name_too_long;
Is this a bug fix?
> }
>
> if (memcmp(&r->fp_start_macaddr, &zero, sizeof(zero)) == 0) {
> @@ -1397,6 +1394,7 @@ static int pci_rocker_init(PCIDevice *dev)
>
> r->rings = g_new(DescRing *, rocker_pci_ring_count(r));
> if (!r->rings) {
> + error_setg(errp, "rocker: memory allocation for rings failed");
> goto err_rings_alloc;
> }
g_new() can't fail. Please remove the dead error handling.
>
> @@ -1410,11 +1408,11 @@ static int pci_rocker_init(PCIDevice *dev)
> * .....
> */
>
> - err = -ENOMEM;
> for (i = 0; i < rocker_pci_ring_count(r); i++) {
> DescRing *ring = desc_ring_alloc(r, i);
>
> if (!ring) {
> + error_setg(errp, "rocker: memory allocation for ring failed");
> goto err_ring_alloc;
> }
>
desc_ring_alloc() returns null only when g_new0() does. It doesn't.
Please remove the dead error handling here and in desc_ring_alloc().
> @@ -1438,6 +1436,7 @@ static int pci_rocker_init(PCIDevice *dev)
> i, &r->fp_ports_peers[i]);
>
> if (!port) {
> + error_setg(errp, "rocker: memory allocation for port failed");
> goto err_port_alloc;
> }
>
Likewise for fp_port_alloc().
I recommend you search all of rocker/ for similarly dead error checking
after g_malloc() & friends.
> @@ -1447,7 +1446,7 @@ static int pci_rocker_init(PCIDevice *dev)
>
> QLIST_INSERT_HEAD(&rockers, r, next);
>
> - return 0;
> + return;
>
> err_port_alloc:
> for (--i; i >= 0; i--) {
> @@ -1461,6 +1460,7 @@ err_ring_alloc:
> }
> g_free(r->rings);
> err_rings_alloc:
> +err_name_too_long:
> err_duplicate:
> rocker_msix_uninit(r);
> err_msix_init:
> @@ -1473,7 +1473,6 @@ err_world_alloc:
> world_free(r->worlds[i]);
> }
> }
> - return err;
> }
>
> static void pci_rocker_uninit(PCIDevice *dev)
> @@ -1558,7 +1557,7 @@ static void rocker_class_init(ObjectClass *klass, void *data)
> DeviceClass *dc = DEVICE_CLASS(klass);
> PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>
> - k->init = pci_rocker_init;
> + k->realize = pci_rocker_realize;
> k->exit = pci_rocker_uninit;
> k->vendor_id = PCI_VENDOR_ID_REDHAT;
> k->device_id = PCI_DEVICE_ID_REDHAT_ROCKER;
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v3] net/rocker: Convert to realize
2017-05-16 15:29 ` Markus Armbruster
@ 2017-05-17 3:58 ` Mao Zhongyi
2017-05-17 7:04 ` Markus Armbruster
0 siblings, 1 reply; 5+ messages in thread
From: Mao Zhongyi @ 2017-05-17 3:58 UTC (permalink / raw)
To: Markus Armbruster; +Cc: qemu-devel, jasowang, jiri, f4bug
Hi, Markus
On 05/16/2017 11:29 PM, Markus Armbruster wrote:
> Mao Zhongyi <maozy.fnst@cn.fujitsu.com> writes:
>
>> The rocker device still implements the old PCIDeviceClass .init()
>> instead of the new .realize(). All devices need to be converted to
>> .realize().
>
> Thanks for chipping in!
>
>> .init() reports errors with fprintf() and return 0 on success, negative
>> number on failure. Meanwhile, when -device rocker fails, it first report
>> a specific error, then a generic one, like this:
>>
>> $ x86_64-softmmu/qemu-system-x86_64 -device rocker,name=qemu-rocker
>> rocker: name too long; please shorten to at most 9 chars
>> qemu-system-x86_64: -device rocker,name=qemu-rocker: Device initialization failed
>>
>> Now, convert it to .realize() that passes errors to its callers via its
>> errp argument. Also avoid the superfluous second error message.
>
> Recommend to show the error message after your patch here:
>
> qemu-system-x86_64: -device rocker,name=qemu-rocker: rocker: name too long; please shorten to at most 9 chars
Thanks, I think I got it.
>
> Not least because that makes it blatantly obvious that keeping the
> "rocker: " is not a good idea :)
Actually, I was always curious about why there are 2 "rocker" strings
in the report, it's superfluous. But in order to keep a consistent log
format, so inherited the original style.
Will remove it in the next version.
>
>> Cc: jiri@resnulli.us
>> Cc: jasowang@redhat.com
>> Cc: f4bug@amsat.org
>> Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
>> ---
>> hw/net/rocker/rocker.c | 35 +++++++++++++++++------------------
>> 1 file changed, 17 insertions(+), 18 deletions(-)
>>
>> diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
>> index 6e70fdd..c446cda 100644
>> --- a/hw/net/rocker/rocker.c
>> +++ b/hw/net/rocker/rocker.c
>> @@ -1252,20 +1252,18 @@ rollback:
>> return err;
>> }
>>
>> -static int rocker_msix_init(Rocker *r)
>> +static int rocker_msix_init(Rocker *r, Error **errp)
>> {
>> PCIDevice *dev = PCI_DEVICE(r);
>> int err;
>> - Error *local_err = NULL;
>>
>> err = msix_init(dev, ROCKER_MSIX_VEC_COUNT(r->fp_ports),
>> &r->msix_bar,
>> ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_TABLE_OFFSET,
>> &r->msix_bar,
>> ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_PBA_OFFSET,
>> - 0, &local_err);
>> + 0, errp);
>> if (err) {
>> - error_report_err(local_err);
>> return err;
>> }
>>
>> @@ -1301,7 +1299,7 @@ static World *rocker_world_type_by_name(Rocker *r, const char *name)
>> return NULL;
>> }
>>
>> -static int pci_rocker_init(PCIDevice *dev)
>> +static void pci_rocker_realize(PCIDevice *dev, Error **errp)
>> {
>> Rocker *r = to_rocker(dev);
>> const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } };
>> @@ -1315,7 +1313,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>
>> for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
>> if (!r->worlds[i]) {
>> - err = -ENOMEM;
>> + error_setg(errp, "rocker: memory allocation for worlds failed");
>
> r->worlds[i] is null when of_dpa_world_alloc() returns null. It's a
> wrapper around world_alloc(), which returns null only when g_malloc()
> does. It doesn't. Please remove the dead error handling. Ideally in a
> separate cleanup patch before this one, to facilitate review.
>
Thanks very much for your detailed explanation.
After reading g_malloc0(), I am aware of this: g_malloc0(size_t size)
returns null only when size is 0. But it is a wrapper around
g_malloc0_n(1, size) that ignore the fact that g_malloc0() of 0 bytes
returns null. So it doesn't return null. Am I right?
> Recommend to drop the "rocker: " prefix. Same for all the other error
> messages.
>
Thanks, will dorp it entirely.
>> goto err_world_alloc;
>> }
>> }
>> @@ -1326,10 +1324,9 @@ static int pci_rocker_init(PCIDevice *dev)
>>
>> r->world_dflt = rocker_world_type_by_name(r, r->world_name);
>> if (!r->world_dflt) {
>> - fprintf(stderr,
>> - "rocker: requested world \"%s\" does not exist\n",
>> + error_setg(errp,
>> + "rocker: invalid argument, requested world %s does not exist",
>> r->world_name);
>> - err = -EINVAL;
>> goto err_world_type_by_name;
>> }
>>
>> @@ -1349,7 +1346,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>
>> /* MSI-X init */
>>
>> - err = rocker_msix_init(r);
>> + err = rocker_msix_init(r, errp);
>> if (err) {
>> goto err_msix_init;
>> }
>> @@ -1361,7 +1358,7 @@ static int pci_rocker_init(PCIDevice *dev)
>> }
>>
>> if (rocker_find(r->name)) {
>> - err = -EEXIST;
>> + error_setg(errp, "rocker: %s already exists", r->name);
>> goto err_duplicate;
>> }
>>
>> @@ -1375,10 +1372,10 @@ static int pci_rocker_init(PCIDevice *dev)
>> #define ROCKER_IFNAMSIZ 16
>> #define MAX_ROCKER_NAME_LEN (ROCKER_IFNAMSIZ - 1 - 3 - 3)
>> if (strlen(r->name) > MAX_ROCKER_NAME_LEN) {
>> - fprintf(stderr,
>> - "rocker: name too long; please shorten to at most %d chars\n",
>> + error_setg(errp,
>> + "rocker: name too long; please shorten to at most %d chars",
>> MAX_ROCKER_NAME_LEN);
>> - return -EINVAL;
>> + goto err_name_too_long;
>
> Is this a bug fix?
Before the patch, it will return a negative value when the name more
than 9 chars. But it doesn't free the memory of world and msix that
has allocated previously.
After the patch, I think the cleanup is more entire. doesn't it?
>
>> }
>>
>> if (memcmp(&r->fp_start_macaddr, &zero, sizeof(zero)) == 0) {
>> @@ -1397,6 +1394,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>
>> r->rings = g_new(DescRing *, rocker_pci_ring_count(r));
>> if (!r->rings) {
>> + error_setg(errp, "rocker: memory allocation for rings failed");
>> goto err_rings_alloc;
>> }
>
> g_new() can't fail. Please remove the dead error handling.
Thanks, will drop it.
>
>>
>> @@ -1410,11 +1408,11 @@ static int pci_rocker_init(PCIDevice *dev)
>> * .....
>> */
>>
>> - err = -ENOMEM;
>> for (i = 0; i < rocker_pci_ring_count(r); i++) {
>> DescRing *ring = desc_ring_alloc(r, i);
>>
>> if (!ring) {
>> + error_setg(errp, "rocker: memory allocation for ring failed");
>> goto err_ring_alloc;
>> }
>>
>
> desc_ring_alloc() returns null only when g_new0() does. It doesn't.
> Please remove the dead error handling here and in desc_ring_alloc().
>
I got it, will remove it in the next version.
Thanks
>> @@ -1438,6 +1436,7 @@ static int pci_rocker_init(PCIDevice *dev)
>> i, &r->fp_ports_peers[i]);
>>
>> if (!port) {
>> + error_setg(errp, "rocker: memory allocation for port failed");
>> goto err_port_alloc;
>> }
>>
>
> Likewise for fp_port_alloc().
>
> I recommend you search all of rocker/ for similarly dead error checking
> after g_malloc() & friends.
I'll search and fix similar error checking.
>
>> @@ -1447,7 +1446,7 @@ static int pci_rocker_init(PCIDevice *dev)
[...]
Thanks for your quick review:), will do the fix right away.
Mao
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v3] net/rocker: Convert to realize
2017-05-17 3:58 ` Mao Zhongyi
@ 2017-05-17 7:04 ` Markus Armbruster
2017-05-17 7:46 ` Mao Zhongyi
0 siblings, 1 reply; 5+ messages in thread
From: Markus Armbruster @ 2017-05-17 7:04 UTC (permalink / raw)
To: Mao Zhongyi; +Cc: jasowang, jiri, qemu-devel, f4bug
Mao Zhongyi <maozy.fnst@cn.fujitsu.com> writes:
> Hi, Markus
>
> On 05/16/2017 11:29 PM, Markus Armbruster wrote:
>> Mao Zhongyi <maozy.fnst@cn.fujitsu.com> writes:
>>
>>> The rocker device still implements the old PCIDeviceClass .init()
>>> instead of the new .realize(). All devices need to be converted to
>>> .realize().
>>
>> Thanks for chipping in!
>>
>>> .init() reports errors with fprintf() and return 0 on success, negative
>>> number on failure. Meanwhile, when -device rocker fails, it first report
>>> a specific error, then a generic one, like this:
>>>
>>> $ x86_64-softmmu/qemu-system-x86_64 -device rocker,name=qemu-rocker
>>> rocker: name too long; please shorten to at most 9 chars
>>> qemu-system-x86_64: -device rocker,name=qemu-rocker: Device initialization failed
>>>
>>> Now, convert it to .realize() that passes errors to its callers via its
>>> errp argument. Also avoid the superfluous second error message.
>>
>> Recommend to show the error message after your patch here:
>>
>> qemu-system-x86_64: -device rocker,name=qemu-rocker: rocker: name too long; please shorten to at most 9 chars
>
> Thanks, I think I got it.
>
>>
>> Not least because that makes it blatantly obvious that keeping the
>> "rocker: " is not a good idea :)
>
> Actually, I was always curious about why there are 2 "rocker" strings
> in the report, it's superfluous. But in order to keep a consistent log
> format, so inherited the original style.
>
> Will remove it in the next version.
>
>>
>>> Cc: jiri@resnulli.us
>>> Cc: jasowang@redhat.com
>>> Cc: f4bug@amsat.org
>>> Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
>>> ---
>>> hw/net/rocker/rocker.c | 35 +++++++++++++++++------------------
>>> 1 file changed, 17 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
>>> index 6e70fdd..c446cda 100644
>>> --- a/hw/net/rocker/rocker.c
>>> +++ b/hw/net/rocker/rocker.c
>>> @@ -1252,20 +1252,18 @@ rollback:
>>> return err;
>>> }
>>>
>>> -static int rocker_msix_init(Rocker *r)
>>> +static int rocker_msix_init(Rocker *r, Error **errp)
>>> {
>>> PCIDevice *dev = PCI_DEVICE(r);
>>> int err;
>>> - Error *local_err = NULL;
>>>
>>> err = msix_init(dev, ROCKER_MSIX_VEC_COUNT(r->fp_ports),
>>> &r->msix_bar,
>>> ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_TABLE_OFFSET,
>>> &r->msix_bar,
>>> ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_PBA_OFFSET,
>>> - 0, &local_err);
>>> + 0, errp);
>>> if (err) {
>>> - error_report_err(local_err);
>>> return err;
>>> }
>>>
>>> @@ -1301,7 +1299,7 @@ static World *rocker_world_type_by_name(Rocker *r, const char *name)
>>> return NULL;
>>> }
>>>
>>> -static int pci_rocker_init(PCIDevice *dev)
>>> +static void pci_rocker_realize(PCIDevice *dev, Error **errp)
>>> {
>>> Rocker *r = to_rocker(dev);
>>> const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } };
>>> @@ -1315,7 +1313,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>>
>>> for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
>>> if (!r->worlds[i]) {
>>> - err = -ENOMEM;
>>> + error_setg(errp, "rocker: memory allocation for worlds failed");
>>
>> r->worlds[i] is null when of_dpa_world_alloc() returns null. It's a
>> wrapper around world_alloc(), which returns null only when g_malloc()
>> does. It doesn't. Please remove the dead error handling. Ideally in a
>> separate cleanup patch before this one, to facilitate review.
>>
>
> Thanks very much for your detailed explanation.
>
> After reading g_malloc0(), I am aware of this: g_malloc0(size_t size)
> returns null only when size is 0. But it is a wrapper around
> g_malloc0_n(1, size) that ignore the fact that g_malloc0() of 0 bytes
> returns null. So it doesn't return null. Am I right?
Correct, it can't return null here.
Aside: even when it does return null for zero size, that null is *not*
an error!
>> Recommend to drop the "rocker: " prefix. Same for all the other error
>> messages.
>>
>
> Thanks, will dorp it entirely.
>
>>> goto err_world_alloc;
>>> }
>>> }
>>> @@ -1326,10 +1324,9 @@ static int pci_rocker_init(PCIDevice *dev)
>>>
>>> r->world_dflt = rocker_world_type_by_name(r, r->world_name);
>>> if (!r->world_dflt) {
>>> - fprintf(stderr,
>>> - "rocker: requested world \"%s\" does not exist\n",
>>> + error_setg(errp,
>>> + "rocker: invalid argument, requested world %s does not exist",
>>> r->world_name);
>>> - err = -EINVAL;
>>> goto err_world_type_by_name;
>>> }
>>>
>>> @@ -1349,7 +1346,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>>
>>> /* MSI-X init */
>>>
>>> - err = rocker_msix_init(r);
>>> + err = rocker_msix_init(r, errp);
>>> if (err) {
>>> goto err_msix_init;
>>> }
>>> @@ -1361,7 +1358,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>> }
>>>
>>> if (rocker_find(r->name)) {
>>> - err = -EEXIST;
>>> + error_setg(errp, "rocker: %s already exists", r->name);
>>> goto err_duplicate;
>>> }
>>>
>>> @@ -1375,10 +1372,10 @@ static int pci_rocker_init(PCIDevice *dev)
>>> #define ROCKER_IFNAMSIZ 16
>>> #define MAX_ROCKER_NAME_LEN (ROCKER_IFNAMSIZ - 1 - 3 - 3)
>>> if (strlen(r->name) > MAX_ROCKER_NAME_LEN) {
>>> - fprintf(stderr,
>>> - "rocker: name too long; please shorten to at most %d chars\n",
>>> + error_setg(errp,
>>> + "rocker: name too long; please shorten to at most %d chars",
>>> MAX_ROCKER_NAME_LEN);
>>> - return -EINVAL;
>>> + goto err_name_too_long;
>>
>> Is this a bug fix?
>
> Before the patch, it will return a negative value when the name more
> than 9 chars. But it doesn't free the memory of world and msix that
> has allocated previously.
>
> After the patch, I think the cleanup is more entire. doesn't it?
Sounds like you're plugging a memory leak. I recommend to plug it in a
separate patch before this one, because that way your bug fix is
properly visible in the commit log.
>>> }
>>>
>>> if (memcmp(&r->fp_start_macaddr, &zero, sizeof(zero)) == 0) {
>>> @@ -1397,6 +1394,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>>
>>> r->rings = g_new(DescRing *, rocker_pci_ring_count(r));
>>> if (!r->rings) {
>>> + error_setg(errp, "rocker: memory allocation for rings failed");
>>> goto err_rings_alloc;
>>> }
>>
>> g_new() can't fail. Please remove the dead error handling.
>
> Thanks, will drop it.
>
>>
>>>
>>> @@ -1410,11 +1408,11 @@ static int pci_rocker_init(PCIDevice *dev)
>>> * .....
>>> */
>>>
>>> - err = -ENOMEM;
>>> for (i = 0; i < rocker_pci_ring_count(r); i++) {
>>> DescRing *ring = desc_ring_alloc(r, i);
>>>
>>> if (!ring) {
>>> + error_setg(errp, "rocker: memory allocation for ring failed");
>>> goto err_ring_alloc;
>>> }
>>>
>>
>> desc_ring_alloc() returns null only when g_new0() does. It doesn't.
>> Please remove the dead error handling here and in desc_ring_alloc().
>>
>
> I got it, will remove it in the next version.
> Thanks
>
>>> @@ -1438,6 +1436,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>> i, &r->fp_ports_peers[i]);
>>>
>>> if (!port) {
>>> + error_setg(errp, "rocker: memory allocation for port failed");
>>> goto err_port_alloc;
>>> }
>>>
>>
>> Likewise for fp_port_alloc().
>>
>> I recommend you search all of rocker/ for similarly dead error checking
>> after g_malloc() & friends.
>
> I'll search and fix similar error checking.
>
>>
>>> @@ -1447,7 +1446,7 @@ static int pci_rocker_init(PCIDevice *dev)
> [...]
>
> Thanks for your quick review:), will do the fix right away.
Looking forward to v2 :)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v3] net/rocker: Convert to realize
2017-05-17 7:04 ` Markus Armbruster
@ 2017-05-17 7:46 ` Mao Zhongyi
0 siblings, 0 replies; 5+ messages in thread
From: Mao Zhongyi @ 2017-05-17 7:46 UTC (permalink / raw)
To: Markus Armbruster; +Cc: jasowang, jiri, qemu-devel, f4bug
Hi, Markus
On 05/17/2017 03:04 PM, Markus Armbruster wrote:
> Mao Zhongyi <maozy.fnst@cn.fujitsu.com> writes:
>
>>
>>
>> On 05/16/2017 11:29 PM, Markus Armbruster wrote:
>>> Mao Zhongyi <maozy.fnst@cn.fujitsu.com> writes:
>>>
>>>> The rocker device still implements the old PCIDeviceClass .init()
>>>> instead of the new .realize(). All devices need to be converted to
>>>> .realize().
>>>
>>> Thanks for chipping in!
>>>
>>>> .init() reports errors with fprintf() and return 0 on success, negative
>>>> number on failure. Meanwhile, when -device rocker fails, it first report
>>>> a specific error, then a generic one, like this:
>>>>
>>>> $ x86_64-softmmu/qemu-system-x86_64 -device rocker,name=qemu-rocker
>>>> rocker: name too long; please shorten to at most 9 chars
>>>> qemu-system-x86_64: -device rocker,name=qemu-rocker: Device initialization failed
>>>>
>>>> Now, convert it to .realize() that passes errors to its callers via its
>>>> errp argument. Also avoid the superfluous second error message.
>>>
>>> Recommend to show the error message after your patch here:
>>>
>>> qemu-system-x86_64: -device rocker,name=qemu-rocker: rocker: name too long; please shorten to at most 9 chars
>>
>> Thanks, I think I got it.
>>
>>>
>>> Not least because that makes it blatantly obvious that keeping the
>>> "rocker: " is not a good idea :)
>>
>> Actually, I was always curious about why there are 2 "rocker" strings
>> in the report, it's superfluous. But in order to keep a consistent log
>> format, so inherited the original style.
>>
>> Will remove it in the next version.
>>
>>>
>>>> Cc: jiri@resnulli.us
>>>> Cc: jasowang@redhat.com
>>>> Cc: f4bug@amsat.org
>>>> Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
>>>> ---
>>>> hw/net/rocker/rocker.c | 35 +++++++++++++++++------------------
>>>> 1 file changed, 17 insertions(+), 18 deletions(-)
>>>>
>>>> diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
>>>> index 6e70fdd..c446cda 100644
>>>> --- a/hw/net/rocker/rocker.c
>>>> +++ b/hw/net/rocker/rocker.c
>>>> @@ -1252,20 +1252,18 @@ rollback:
>>>> return err;
>>>> }
>>>>
>>>> -static int rocker_msix_init(Rocker *r)
>>>> +static int rocker_msix_init(Rocker *r, Error **errp)
>>>> {
>>>> PCIDevice *dev = PCI_DEVICE(r);
>>>> int err;
>>>> - Error *local_err = NULL;
>>>>
>>>> err = msix_init(dev, ROCKER_MSIX_VEC_COUNT(r->fp_ports),
>>>> &r->msix_bar,
>>>> ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_TABLE_OFFSET,
>>>> &r->msix_bar,
>>>> ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_PBA_OFFSET,
>>>> - 0, &local_err);
>>>> + 0, errp);
>>>> if (err) {
>>>> - error_report_err(local_err);
>>>> return err;
>>>> }
>>>>
>>>> @@ -1301,7 +1299,7 @@ static World *rocker_world_type_by_name(Rocker *r, const char *name)
>>>> return NULL;
>>>> }
>>>>
>>>> -static int pci_rocker_init(PCIDevice *dev)
>>>> +static void pci_rocker_realize(PCIDevice *dev, Error **errp)
>>>> {
>>>> Rocker *r = to_rocker(dev);
>>>> const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } };
>>>> @@ -1315,7 +1313,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>>>
>>>> for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
>>>> if (!r->worlds[i]) {
>>>> - err = -ENOMEM;
>>>> + error_setg(errp, "rocker: memory allocation for worlds failed");
>>>
>>> r->worlds[i] is null when of_dpa_world_alloc() returns null. It's a
>>> wrapper around world_alloc(), which returns null only when g_malloc()
>>> does. It doesn't. Please remove the dead error handling. Ideally in a
>>> separate cleanup patch before this one, to facilitate review.
>>>
>>
>> Thanks very much for your detailed explanation.
>>
>> After reading g_malloc0(), I am aware of this: g_malloc0(size_t size)
>> returns null only when size is 0. But it is a wrapper around
>> g_malloc0_n(1, size) that ignore the fact that g_malloc0() of 0 bytes
>> returns null. So it doesn't return null. Am I right?
>
> Correct, it can't return null here.
>
> Aside: even when it does return null for zero size, that null is *not*
> an error!
Thanks, I see.
>
>>> Recommend to drop the "rocker: " prefix. Same for all the other error
>>> messages.
>>>
>>
>> Thanks, will dorp it entirely.
>>
>>>> goto err_world_alloc;
>>>> }
>>>> }
>>>> @@ -1326,10 +1324,9 @@ static int pci_rocker_init(PCIDevice *dev)
>>>>
>>>> r->world_dflt = rocker_world_type_by_name(r, r->world_name);
>>>> if (!r->world_dflt) {
>>>> - fprintf(stderr,
>>>> - "rocker: requested world \"%s\" does not exist\n",
>>>> + error_setg(errp,
>>>> + "rocker: invalid argument, requested world %s does not exist",
>>>> r->world_name);
>>>> - err = -EINVAL;
>>>> goto err_world_type_by_name;
>>>> }
>>>>
>>>> @@ -1349,7 +1346,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>>>
>>>> /* MSI-X init */
>>>>
>>>> - err = rocker_msix_init(r);
>>>> + err = rocker_msix_init(r, errp);
>>>> if (err) {
>>>> goto err_msix_init;
>>>> }
>>>> @@ -1361,7 +1358,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>>> }
>>>>
>>>> if (rocker_find(r->name)) {
>>>> - err = -EEXIST;
>>>> + error_setg(errp, "rocker: %s already exists", r->name);
>>>> goto err_duplicate;
>>>> }
>>>>
>>>> @@ -1375,10 +1372,10 @@ static int pci_rocker_init(PCIDevice *dev)
>>>> #define ROCKER_IFNAMSIZ 16
>>>> #define MAX_ROCKER_NAME_LEN (ROCKER_IFNAMSIZ - 1 - 3 - 3)
>>>> if (strlen(r->name) > MAX_ROCKER_NAME_LEN) {
>>>> - fprintf(stderr,
>>>> - "rocker: name too long; please shorten to at most %d chars\n",
>>>> + error_setg(errp,
>>>> + "rocker: name too long; please shorten to at most %d chars",
>>>> MAX_ROCKER_NAME_LEN);
>>>> - return -EINVAL;
>>>> + goto err_name_too_long;
>>>
>>> Is this a bug fix?
>>
>> Before the patch, it will return a negative value when the name more
>> than 9 chars. But it doesn't free the memory of world and msix that
>> has allocated previously.
>>
>> After the patch, I think the cleanup is more entire. doesn't it?
>
> Sounds like you're plugging a memory leak. I recommend to plug it in a
> separate patch before this one, because that way your bug fix is
> properly visible in the commit log.
Thanks for your kind recommendation:), that's what I plan to do.
>
>>>> }
>>>>
>>>> if (memcmp(&r->fp_start_macaddr, &zero, sizeof(zero)) == 0) {
>>>> @@ -1397,6 +1394,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>>>
>>>> r->rings = g_new(DescRing *, rocker_pci_ring_count(r));
>>>> if (!r->rings) {
>>>> + error_setg(errp, "rocker: memory allocation for rings failed");
>>>> goto err_rings_alloc;
>>>> }
>>>
>>> g_new() can't fail. Please remove the dead error handling.
>>
>> Thanks, will drop it.
>>
>>>
>>>>
>>>> @@ -1410,11 +1408,11 @@ static int pci_rocker_init(PCIDevice *dev)
>>>> * .....
>>>> */
>>>>
>>>> - err = -ENOMEM;
>>>> for (i = 0; i < rocker_pci_ring_count(r); i++) {
>>>> DescRing *ring = desc_ring_alloc(r, i);
>>>>
>>>> if (!ring) {
>>>> + error_setg(errp, "rocker: memory allocation for ring failed");
>>>> goto err_ring_alloc;
>>>> }
>>>>
>>>
>>> desc_ring_alloc() returns null only when g_new0() does. It doesn't.
>>> Please remove the dead error handling here and in desc_ring_alloc().
>>>
>>
>> I got it, will remove it in the next version.
>> Thanks
>>
>>>> @@ -1438,6 +1436,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>>> i, &r->fp_ports_peers[i]);
>>>>
>>>> if (!port) {
>>>> + error_setg(errp, "rocker: memory allocation for port failed");
>>>> goto err_port_alloc;
>>>> }
>>>>
>>>
>>> Likewise for fp_port_alloc().
>>>
>>> I recommend you search all of rocker/ for similarly dead error checking
>>> after g_malloc() & friends.
>>
>> I'll search and fix similar error checking.
>>
>>>
>>>> @@ -1447,7 +1446,7 @@ static int pci_rocker_init(PCIDevice *dev)
>> [...]
>>
>> Thanks for your quick review:), will do the fix right away.
>
> Looking forward to v2 :)
>
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-05-17 7:46 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-16 12:37 [Qemu-devel] [PATCH v3] net/rocker: Convert to realize Mao Zhongyi
2017-05-16 15:29 ` Markus Armbruster
2017-05-17 3:58 ` Mao Zhongyi
2017-05-17 7:04 ` Markus Armbruster
2017-05-17 7:46 ` Mao Zhongyi
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.