diff mbox

[v5,1/4] net/rocker: Remove the dead error handling

Message ID 29c33313efd2ee4f7bf3abb71a4809582891f408.1495508197.git.maozy.fnst@cn.fujitsu.com
State New
Headers show

Commit Message

Mao Zhongyi May 23, 2017, 4:04 a.m. UTC
Memory allocation functions like world_alloc, desc_ring_alloc etc,
they are all wrappers around g_malloc, g_new etc. But g_malloc and 
similar functions doesn't return null. Because they ignore the fact 
that g_malloc() of 0 bytes returns null. So error checks for these
allocation failure are superfluous. Now, remove them entirely.

Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
---
 hw/net/rocker/rocker.c        | 46 -------------------------------------------
 hw/net/rocker/rocker_desc.c   | 10 ----------
 hw/net/rocker/rocker_fp.c     |  4 ----
 hw/net/rocker/rocker_of_dpa.c | 20 -------------------
 hw/net/rocker/rocker_world.c  | 12 +++++------
 5 files changed, 5 insertions(+), 87 deletions(-)

Comments

Markus Armbruster May 23, 2017, 9:27 a.m. UTC | #1
Mao Zhongyi <maozy.fnst@cn.fujitsu.com> writes:

> Memory allocation functions like world_alloc, desc_ring_alloc etc,
> they are all wrappers around g_malloc, g_new etc. But g_malloc and 
> similar functions doesn't return null. Because they ignore the fact 

don't

> that g_malloc() of 0 bytes returns null. So error checks for these
> allocation failure are superfluous. Now, remove them entirely.
>
> Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>

Reviewed-by: Markus Armbruster <armbru@redhat.com>

There's one more cleanup opportunity:

> diff --git a/hw/net/rocker/rocker_desc.c b/hw/net/rocker/rocker_desc.c
> index ac02797..d0df89a 100644
> --- a/hw/net/rocker/rocker_desc.c
> +++ b/hw/net/rocker/rocker_desc.c
> @@ -65,10 +65,6 @@ char *desc_get_buf(DescInfo *info, bool read_only)
>          info->buf_size = size;
>      }
>  
> -    if (!info->buf) {
> -        return NULL;
> -    }
> -
>      if (pci_dma_read(dev, le64_to_cpu(info->desc.buf_addr), info->buf, size)) {
>          return NULL;
>      }

None of the pci_dma_read() calls outside rocker check the return value.
Just as well, because it always returns 0.  Please clean this up in a
separate followup patch.

[...]
Mao Zhongyi May 23, 2017, 10:09 a.m. UTC | #2
Hi, Markus


On 05/23/2017 05:27 PM, Markus Armbruster wrote:
> Mao Zhongyi <maozy.fnst@cn.fujitsu.com> writes:
>
>> Memory allocation functions like world_alloc, desc_ring_alloc etc,
>> they are all wrappers around g_malloc, g_new etc. But g_malloc and
>> similar functions doesn't return null. Because they ignore the fact
>
> don't

Will I need to make a separated patch to fix it? or when you merge to
help me repair?

Thanks a lot.

>
>> that g_malloc() of 0 bytes returns null. So error checks for these
>> allocation failure are superfluous. Now, remove them entirely.
>>
>> Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
>
> Reviewed-by: Markus Armbruster <armbru@redhat.com>

Thanks for your quick review:)

>
> There's one more cleanup opportunity:
>
>> diff --git a/hw/net/rocker/rocker_desc.c b/hw/net/rocker/rocker_desc.c
>> index ac02797..d0df89a 100644
>> --- a/hw/net/rocker/rocker_desc.c
>> +++ b/hw/net/rocker/rocker_desc.c
>> @@ -65,10 +65,6 @@ char *desc_get_buf(DescInfo *info, bool read_only)
>>          info->buf_size = size;
>>      }
>>
>> -    if (!info->buf) {
>> -        return NULL;
>> -    }
>> -
>>      if (pci_dma_read(dev, le64_to_cpu(info->desc.buf_addr), info->buf, size)) {
>>          return NULL;
>>      }
>
> None of the pci_dma_read() calls outside rocker check the return value.
> Just as well, because it always returns 0.  Please clean this up in a
> separate followup patch.

Thanks for the reminder. I just read the code, it's true.
Will fix it right away.

Mao
Markus Armbruster May 23, 2017, 10:52 a.m. UTC | #3
Mao Zhongyi <maozy.fnst@cn.fujitsu.com> writes:

> Hi, Markus
>
>
> On 05/23/2017 05:27 PM, Markus Armbruster wrote:
>> Mao Zhongyi <maozy.fnst@cn.fujitsu.com> writes:
>>
>>> Memory allocation functions like world_alloc, desc_ring_alloc etc,
>>> they are all wrappers around g_malloc, g_new etc. But g_malloc and
>>> similar functions doesn't return null. Because they ignore the fact
>>
>> don't
>
> Will I need to make a separated patch to fix it? or when you merge to
> help me repair?

Perhaps Jason can touch it up on commit.

> Thanks a lot.
>
>>
>>> that g_malloc() of 0 bytes returns null. So error checks for these
>>> allocation failure are superfluous. Now, remove them entirely.
>>>
>>> Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
>>
>> Reviewed-by: Markus Armbruster <armbru@redhat.com>
>
> Thanks for your quick review:)

You're welcome.

>> There's one more cleanup opportunity:
>>
>>> diff --git a/hw/net/rocker/rocker_desc.c b/hw/net/rocker/rocker_desc.c
>>> index ac02797..d0df89a 100644
>>> --- a/hw/net/rocker/rocker_desc.c
>>> +++ b/hw/net/rocker/rocker_desc.c
>>> @@ -65,10 +65,6 @@ char *desc_get_buf(DescInfo *info, bool read_only)
>>>          info->buf_size = size;
>>>      }
>>>
>>> -    if (!info->buf) {
>>> -        return NULL;
>>> -    }
>>> -
>>>      if (pci_dma_read(dev, le64_to_cpu(info->desc.buf_addr), info->buf, size)) {
>>>          return NULL;
>>>      }
>>
>> None of the pci_dma_read() calls outside rocker check the return value.
>> Just as well, because it always returns 0.  Please clean this up in a
>> separate followup patch.
>
> Thanks for the reminder. I just read the code, it's true.
> Will fix it right away.

Thanks!
Philippe Mathieu-Daudé May 24, 2017, 4:43 a.m. UTC | #4
Hi Markus,

On 05/23/2017 06:27 AM, Markus Armbruster wrote:
[...]
> There's one more cleanup opportunity:
>
[...]
>>      if (pci_dma_read(dev, le64_to_cpu(info->desc.buf_addr), info->buf, size)) {
>>          return NULL;
>>      }
>
> None of the pci_dma_read() calls outside rocker check the return value.
> Just as well, because it always returns 0.  Please clean this up in a
> separate followup patch.

It may be the correct way to do it but this sounds like we are missing 
something somewhere... pci_dma_read() calls pci_dma_rw() which always 
returns 0. Why not let it returns void? It is inlined and never used by 
address. Else we should document why returning 0 is correct, and what is 
the reason to not use a void prototype.

pci_dma_rw() calls dma_memory_rw() which does return a boolean value, 
false on success (MEMTX_OK) and true on error (MEMTX_ERROR/DECODE_ERROR)

Regards,

Phil.
Markus Armbruster May 24, 2017, 5:35 a.m. UTC | #5
Philippe Mathieu-Daudé <f4bug@amsat.org> writes:

> Hi Markus,
>
> On 05/23/2017 06:27 AM, Markus Armbruster wrote:
> [...]
>> There's one more cleanup opportunity:
>>
> [...]
>>>      if (pci_dma_read(dev, le64_to_cpu(info->desc.buf_addr), info->buf, size)) {
>>>          return NULL;
>>>      }
>>
>> None of the pci_dma_read() calls outside rocker check the return value.
>> Just as well, because it always returns 0.  Please clean this up in a
>> separate followup patch.
>
> It may be the correct way to do it but this sounds like we are missing
> something somewhere... pci_dma_read() calls pci_dma_rw() which always
> returns 0. Why not let it returns void? It is inlined and never used
> by address. Else we should document why returning 0 is correct, and
> what is the reason to not use a void prototype.
>
> pci_dma_rw() calls dma_memory_rw() which does return a boolean value,
> false on success (MEMTX_OK) and true on error
> (MEMTX_ERROR/DECODE_ERROR)

PCI question.  Michael, Marcel?
Marcel Apfelbaum May 24, 2017, 12:01 p.m. UTC | #6
----- Original Message -----
> From: "Markus Armbruster" <armbru@redhat.com>
> To: "Philippe Mathieu-Daudé" <f4bug@amsat.org>
> Cc: qemu-devel@nongnu.org, "Mao Zhongyi" <maozy.fnst@cn.fujitsu.com>, jiri@resnulli.us, jasowang@redhat.com, "Michael
> S. Tsirkin" <mst@redhat.com>, "Marcel Apfelbaum" <marcel@redhat.com>
> Sent: Wednesday, May 24, 2017 8:35:04 AM
> Subject: Re: [Qemu-devel] [PATCH v5 1/4] net/rocker: Remove the dead error handling
> 
> Philippe Mathieu-Daudé <f4bug@amsat.org> writes:
> 
> > Hi Markus,
> >
> > On 05/23/2017 06:27 AM, Markus Armbruster wrote:
> > [...]
> >> There's one more cleanup opportunity:
> >>
> > [...]
> >>>      if (pci_dma_read(dev, le64_to_cpu(info->desc.buf_addr), info->buf,
> >>>      size)) {
> >>>          return NULL;
> >>>      }
> >>
> >> None of the pci_dma_read() calls outside rocker check the return value.
> >> Just as well, because it always returns 0.  Please clean this up in a
> >> separate followup patch.
> >
> > It may be the correct way to do it but this sounds like we are missing
> > something somewhere... pci_dma_read() calls pci_dma_rw() which always
> > returns 0. Why not let it returns void? It is inlined and never used
> > by address. Else we should document why returning 0 is correct, and
> > what is the reason to not use a void prototype.
> >
> > pci_dma_rw() calls dma_memory_rw() which does return a boolean value,
> > false on success (MEMTX_OK) and true on error
> > (MEMTX_ERROR/DECODE_ERROR)
> 
> PCI question.  Michael, Marcel?
> 

Hi Markus,

Looking at the git history, pci_dma_rw used to call cpu_physical_memory_rw
which, at that time (commit ec17457), returned void. Since the interface dictated
to return int, 0 is returned as "always OK".

The callers to pci_dma_read did not bother to check it for obvious reasons (even if they should).

In the meantime the memory API has changed to allow returning errors, but since the callers of
pci_dma_rw don't check the return value, why bother to update the PCI DMA?

History aside (and my speculations above), it seems  the right move is to update
the return value and check it by callers, but honestly I don't have any idea
if the emulated devices expect pci dma to fail.
Adding Paolo and David for more insights.

Thanks,
Marcel
David Gibson May 25, 2017, 1:02 a.m. UTC | #7
On Wed, 24 May 2017 08:01:47 -0400 (EDT)
Marcel Apfelbaum <marcel@redhat.com> wrote:

> ----- Original Message -----
> > From: "Markus Armbruster" <armbru@redhat.com>
> > To: "Philippe Mathieu-Daudé" <f4bug@amsat.org>
> > Cc: qemu-devel@nongnu.org, "Mao Zhongyi" <maozy.fnst@cn.fujitsu.com>, jiri@resnulli.us, jasowang@redhat.com, "Michael
> > S. Tsirkin" <mst@redhat.com>, "Marcel Apfelbaum" <marcel@redhat.com>
> > Sent: Wednesday, May 24, 2017 8:35:04 AM
> > Subject: Re: [Qemu-devel] [PATCH v5 1/4] net/rocker: Remove the dead error handling
> > 
> > Philippe Mathieu-Daudé <f4bug@amsat.org> writes:
> >   
> > > Hi Markus,
> > >
> > > On 05/23/2017 06:27 AM, Markus Armbruster wrote:
> > > [...]  
> > >> There's one more cleanup opportunity:
> > >>  
> > > [...]  
> > >>>      if (pci_dma_read(dev, le64_to_cpu(info->desc.buf_addr), info->buf,
> > >>>      size)) {
> > >>>          return NULL;
> > >>>      }  
> > >>
> > >> None of the pci_dma_read() calls outside rocker check the return value.
> > >> Just as well, because it always returns 0.  Please clean this up in a
> > >> separate followup patch.  
> > >
> > > It may be the correct way to do it but this sounds like we are missing
> > > something somewhere... pci_dma_read() calls pci_dma_rw() which always
> > > returns 0. Why not let it returns void? It is inlined and never used
> > > by address. Else we should document why returning 0 is correct, and
> > > what is the reason to not use a void prototype.
> > >
> > > pci_dma_rw() calls dma_memory_rw() which does return a boolean value,
> > > false on success (MEMTX_OK) and true on error
> > > (MEMTX_ERROR/DECODE_ERROR)  
> > 
> > PCI question.  Michael, Marcel?
> >   
> 
> Hi Markus,
> 
> Looking at the git history, pci_dma_rw used to call cpu_physical_memory_rw
> which, at that time (commit ec17457), returned void. Since the interface dictated
> to return int, 0 is returned as "always OK".
> 
> The callers to pci_dma_read did not bother to check it for obvious reasons (even if they should).
> 
> In the meantime the memory API has changed to allow returning errors, but since the callers of
> pci_dma_rw don't check the return value, why bother to update the PCI DMA?
> 
> History aside (and my speculations above), it seems  the right move is to update
> the return value and check it by callers, but honestly I don't have any idea
> if the emulated devices expect pci dma to fail.
> Adding Paolo and David for more insights.

It seems to me that PCI DMA transfers ought to be able to fail, and
devices ought to be able to handle that (to a limited extent).

After all, what will happen if you try to DMA to PCI addresses that
simply aren't mapped.  Or which are in the domain of a vIOMMU which
wither hasn't mapped those addreses, or has them mapped read-only
(meaning host-to-device only in this context).
diff mbox

Patch

diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
index 6e70fdd..d01ba9d 100644
--- a/hw/net/rocker/rocker.c
+++ b/hw/net/rocker/rocker.c
@@ -239,10 +239,6 @@  static int tx_consume(Rocker *r, DescInfo *info)
         }
         iov[iovcnt].iov_len = frag_len;
         iov[iovcnt].iov_base = g_malloc(frag_len);
-        if (!iov[iovcnt].iov_base) {
-            err = -ROCKER_ENOMEM;
-            goto err_no_mem;
-        }
 
         if (pci_dma_read(dev, frag_addr, iov[iovcnt].iov_base,
                      iov[iovcnt].iov_len)) {
@@ -262,7 +258,6 @@  static int tx_consume(Rocker *r, DescInfo *info)
 
 err_too_many_frags:
 err_bad_io:
-err_no_mem:
 err_bad_attr:
     for (i = 0; i < ROCKER_TX_FRAGS_MAX; i++) {
         g_free(iov[i].iov_base);
@@ -674,10 +669,6 @@  int rx_produce(World *world, uint32_t pport,
      */
 
     data = g_malloc(data_size);
-    if (!data) {
-        err = -ROCKER_ENOMEM;
-        goto out;
-    }
     iov_to_buf(iov, iovcnt, 0, data, data_size);
     pci_dma_write(dev, frag_addr, data, data_size);
     g_free(data);
@@ -722,11 +713,6 @@  static void rocker_test_dma_ctrl(Rocker *r, uint32_t val)
 
     buf = g_malloc(r->test_dma_size);
 
-    if (!buf) {
-        DPRINTF("test dma buffer alloc failed");
-        return;
-    }
-
     switch (val) {
     case ROCKER_TEST_DMA_CTRL_CLEAR:
         memset(buf, 0, r->test_dma_size);
@@ -1313,13 +1299,6 @@  static int pci_rocker_init(PCIDevice *dev)
 
     r->worlds[ROCKER_WORLD_TYPE_OF_DPA] = of_dpa_world_alloc(r);
 
-    for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
-        if (!r->worlds[i]) {
-            err = -ENOMEM;
-            goto err_world_alloc;
-        }
-    }
-
     if (!r->world_name) {
         r->world_name = g_strdup(world_name(r->worlds[ROCKER_WORLD_TYPE_OF_DPA]));
     }
@@ -1396,9 +1375,6 @@  static int pci_rocker_init(PCIDevice *dev)
     }
 
     r->rings = g_new(DescRing *, rocker_pci_ring_count(r));
-    if (!r->rings) {
-        goto err_rings_alloc;
-    }
 
     /* Rings are ordered like this:
      * - command ring
@@ -1410,14 +1386,9 @@  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) {
-            goto err_ring_alloc;
-        }
-
         if (i == ROCKER_RING_CMD) {
             desc_ring_set_consume(ring, cmd_consume, ROCKER_MSIX_VEC_CMD);
         } else if (i == ROCKER_RING_EVENT) {
@@ -1437,10 +1408,6 @@  static int pci_rocker_init(PCIDevice *dev)
             fp_port_alloc(r, r->name, &r->fp_start_macaddr,
                           i, &r->fp_ports_peers[i]);
 
-        if (!port) {
-            goto err_port_alloc;
-        }
-
         r->fp_port[i] = port;
         fp_port_set_world(port, r->world_dflt);
     }
@@ -1449,25 +1416,12 @@  static int pci_rocker_init(PCIDevice *dev)
 
     return 0;
 
-err_port_alloc:
-    for (--i; i >= 0; i--) {
-        FpPort *port = r->fp_port[i];
-        fp_port_free(port);
-    }
-    i = rocker_pci_ring_count(r);
-err_ring_alloc:
-    for (--i; i >= 0; i--) {
-        desc_ring_free(r->rings[i]);
-    }
-    g_free(r->rings);
-err_rings_alloc:
 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:
-err_world_alloc:
     for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
         if (r->worlds[i]) {
             world_free(r->worlds[i]);
diff --git a/hw/net/rocker/rocker_desc.c b/hw/net/rocker/rocker_desc.c
index ac02797..d0df89a 100644
--- a/hw/net/rocker/rocker_desc.c
+++ b/hw/net/rocker/rocker_desc.c
@@ -65,10 +65,6 @@  char *desc_get_buf(DescInfo *info, bool read_only)
         info->buf_size = size;
     }
 
-    if (!info->buf) {
-        return NULL;
-    }
-
     if (pci_dma_read(dev, le64_to_cpu(info->desc.buf_addr), info->buf, size)) {
         return NULL;
     }
@@ -144,9 +140,6 @@  bool desc_ring_set_size(DescRing *ring, uint32_t size)
     ring->head = ring->tail = 0;
 
     ring->info = g_renew(DescInfo, ring->info, size);
-    if (!ring->info) {
-        return false;
-    }
 
     memset(ring->info, 0, size * sizeof(DescInfo));
 
@@ -347,9 +340,6 @@  DescRing *desc_ring_alloc(Rocker *r, int index)
     DescRing *ring;
 
     ring = g_new0(DescRing, 1);
-    if (!ring) {
-        return NULL;
-    }
 
     ring->r = r;
     ring->index = index;
diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c
index 1305ac3..4b3c984 100644
--- a/hw/net/rocker/rocker_fp.c
+++ b/hw/net/rocker/rocker_fp.c
@@ -226,10 +226,6 @@  FpPort *fp_port_alloc(Rocker *r, char *sw_name,
 {
     FpPort *port = g_new0(FpPort, 1);
 
-    if (!port) {
-        return NULL;
-    }
-
     port->r = r;
     port->index = index;
     port->pport = index + 1;
diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
index 9b1e0d2..191a58e 100644
--- a/hw/net/rocker/rocker_of_dpa.c
+++ b/hw/net/rocker/rocker_of_dpa.c
@@ -368,9 +368,6 @@  static OfDpaFlow *of_dpa_flow_alloc(uint64_t cookie)
     int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) / 1000;
 
     flow = g_new0(OfDpaFlow, 1);
-    if (!flow) {
-        return NULL;
-    }
 
     flow->cookie = cookie;
     flow->mask.tbl_id = 0xffffffff;
@@ -813,10 +810,6 @@  static OfDpaGroup *of_dpa_group_alloc(uint32_t id)
 {
     OfDpaGroup *group = g_new0(OfDpaGroup, 1);
 
-    if (!group) {
-        return NULL;
-    }
-
     group->id = id;
 
     return group;
@@ -1867,9 +1860,6 @@  static int of_dpa_cmd_flow_add(OfDpa *of_dpa, uint64_t cookie,
     }
 
     flow = of_dpa_flow_alloc(cookie);
-    if (!flow) {
-        return -ROCKER_ENOMEM;
-    }
 
     err = of_dpa_cmd_flow_add_mod(of_dpa, flow, flow_tlvs);
     if (err) {
@@ -2040,17 +2030,10 @@  static int of_dpa_cmd_add_l2_flood(OfDpa *of_dpa, OfDpaGroup *group,
         rocker_tlv_get_le16(group_tlvs[ROCKER_TLV_OF_DPA_GROUP_COUNT]);
 
     tlvs = g_new0(RockerTlv *, group->l2_flood.group_count + 1);
-    if (!tlvs) {
-        return -ROCKER_ENOMEM;
-    }
 
     g_free(group->l2_flood.group_ids);
     group->l2_flood.group_ids =
         g_new0(uint32_t, group->l2_flood.group_count);
-    if (!group->l2_flood.group_ids) {
-        err = -ROCKER_ENOMEM;
-        goto err_out;
-    }
 
     rocker_tlv_parse_nested(tlvs, group->l2_flood.group_count,
                             group_tlvs[ROCKER_TLV_OF_DPA_GROUP_IDS]);
@@ -2157,9 +2140,6 @@  static int of_dpa_cmd_group_add(OfDpa *of_dpa, uint32_t group_id,
     }
 
     group = of_dpa_group_alloc(group_id);
-    if (!group) {
-        return -ROCKER_ENOMEM;
-    }
 
     err = of_dpa_cmd_group_do(of_dpa, group_id, group, group_tlvs);
     if (err) {
diff --git a/hw/net/rocker/rocker_world.c b/hw/net/rocker/rocker_world.c
index 89777e9..f73c534 100644
--- a/hw/net/rocker/rocker_world.c
+++ b/hw/net/rocker/rocker_world.c
@@ -51,13 +51,11 @@  World *world_alloc(Rocker *r, size_t sizeof_private,
 {
     World *w = g_malloc0(sizeof(World) + sizeof_private);
 
-    if (w) {
-        w->r = r;
-        w->type = type;
-        w->ops = ops;
-        if (w->ops->init) {
-            w->ops->init(w);
-        }
+    w->r = r;
+    w->type = type;
+    w->ops = ops;
+    if (w->ops->init) {
+        w->ops->init(w);
     }
 
     return w;