From: Markus Armbruster <armbru@redhat.com>
To: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
Cc: jasowang@redhat.com, jiri@resnulli.us, qemu-devel@nongnu.org,
f4bug@amsat.org
Subject: Re: [Qemu-devel] [PATCH v4 3/3] net/rocker: Convert to realize()
Date: Mon, 22 May 2017 08:40:35 +0200 [thread overview]
Message-ID: <87tw4d4cnw.fsf@dusky.pond.sub.org> (raw)
In-Reply-To: <8925c606-5d9c-4c7a-f812-2cb71ec74855@cn.fujitsu.com> (Mao Zhongyi's message of "Mon, 22 May 2017 12:17:11 +0800")
Mao Zhongyi <maozy.fnst@cn.fujitsu.com> writes:
> Hi, Markus
>
> On 05/19/2017 03:20 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().
>>>
>>> .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. After
>>> the patch, effect like this:
>>>
>>> $ x86_64-softmmu/qemu-system-x86_64 -device rocker,name=qemu-rocker
>>> qemu-system-x86_64: -device rocker,name=qemu-rocker: name too long; please shorten to at most 9 chars
>>>
>>> Cc: jasowang@redhat.com
>>> Cc: jiri@resnulli.us
>>> Cc: f4bug@amsat.org
>>> Cc: armbru@redhat.com
>>> Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
>>
>> The conversion to realize() looks good to me, therefore
>> Reviewed-by: Markus Armbruster <armbru@redhat.com>
>>
>> However, I spotted a few issues not related to this patch.
>>
>> 1. Unusual macro names
>>
>> #define ROCKER "rocker"
>>
>> #define to_rocker(obj) \
>> OBJECT_CHECK(Rocker, (obj), ROCKER)
>>
>> Please clean up to
>>
>> #define TYPE_ROCKER "rocker"
>>
>> #define ROCKER(obj) \
>> OBJECT_CHECK(Rocker, (obj), TYPE_ROCKER)
>>
>> in a separate patch.
>
> Thanks, will fix it in the next version.
>
>>
>> 2. Memory leaks on error and unplug
>>
>> Explained inline below.
>>
>>> ---
>>> hw/net/rocker/rocker.c | 27 +++++++++++----------------
>>> 1 file changed, 11 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
>>> index a382a6f..b9a77f1 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 } };
>>> @@ -1319,10 +1317,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,
>>> + "invalid argument requested world %s does not exist",
>>> r->world_name);
>>> - err = -EINVAL;
>>> goto err_world_type_by_name;
>>> }
>>>
>>> @@ -1342,7 +1339,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;
>>> }
>>> @@ -1354,7 +1351,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>> }
>>>
>>> if (rocker_find(r->name)) {
>>> - err = -EEXIST;
>>> + error_setg(errp, "%s already exists", r->name);
>>> goto err_duplicate;
>>> }
>>>
>>> @@ -1368,10 +1365,9 @@ 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,
>>> + "name too long; please shorten to at most %d chars",
>>> MAX_ROCKER_NAME_LEN);
>>> - err = -EINVAL;
>>> goto err_name_too_long;
>>> }
>>>
>>> @@ -1429,7 +1425,7 @@ static int pci_rocker_init(PCIDevice *dev)
>>>
>>> QLIST_INSERT_HEAD(&rockers, r, next);
>>>
>>> - return 0;
>>> + return;
>>>
>>> err_name_too_long:
>>> err_duplicate:
>> rocker_msix_uninit(r);
>> err_msix_init:
>> object_unparent(OBJECT(&r->msix_bar));
>> object_unparent(OBJECT(&r->mmio));
>> err_world_type_by_name:
>> for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
>> if (r->worlds[i]) {
>>> @@ -1443,7 +1439,6 @@ err_world_type_by_name:
>>> world_free(r->worlds[i]);
>>> }
>>> }
>>> - return err;
>>> }
>>>
>>
>> Does this leak r->world_name and r->name?
>
> I think it was leaked neither r->world_name nor r->name, but msix and
> worlds related.
You're right: the two are properties, so the property machinery should
free them.
>> If yes, can you delay their allocation until after the last thing that
>> can fail? That way, you don't have to free them on failure. Simplifies
>> the error paths. Keeping them as simple as practical is desireable,
>> because they're hard to test.
>
> If delay allocation of r->worlds[] until after the last, when r->name and
> r->world_name failed, passing the error message to errp is a good idea. I
> think that's what 'error paths' means, then it is really not need to free
> the memory in the goto label. Because the r->worlds[] has not yet been
> allocated. Is that right? If yes, it's really a perfect solution.
>
> But, this ignores the fact that r->name and r->world_name are depend on
> r->worlds, so r->worlds's allocation must be before them. in this case,
> the previous solution will be lose its meaning.
Delaying allocation until after all error checks is not always
practical. You decide.
[...]
prev parent reply other threads:[~2017-05-22 6:40 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-17 11:12 [Qemu-devel] [PATCH v4 0/3] Convert to realize and fix error handling Mao Zhongyi
2017-05-17 11:12 ` [Qemu-devel] [PATCH v4 1/3] net/rocker: Remove the dead " Mao Zhongyi
2017-05-19 6:24 ` Markus Armbruster
2017-05-22 3:47 ` Mao Zhongyi
2017-05-22 6:35 ` Markus Armbruster
2017-05-22 7:43 ` Mao Zhongyi
2017-05-17 11:12 ` [Qemu-devel] [PATCH v4 2/3] net/rocker: Plug memory leak in pci_rocker_init() Mao Zhongyi
2017-05-17 17:22 ` Philippe Mathieu-Daudé
2017-05-18 9:45 ` Mao Zhongyi
2017-05-19 6:26 ` Markus Armbruster
2017-05-17 11:12 ` [Qemu-devel] [PATCH v4 3/3] net/rocker: Convert to realize() Mao Zhongyi
2017-05-19 7:20 ` Markus Armbruster
2017-05-22 4:17 ` Mao Zhongyi
2017-05-22 6:40 ` Markus Armbruster [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87tw4d4cnw.fsf@dusky.pond.sub.org \
--to=armbru@redhat.com \
--cc=f4bug@amsat.org \
--cc=jasowang@redhat.com \
--cc=jiri@resnulli.us \
--cc=maozy.fnst@cn.fujitsu.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.