All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Kiper <dkiper@net-space.pl>
To: stanislav.kholmanskikh@oracle.com, grub-devel@gnu.org
Cc: vasily.isaenko@oracle.com
Subject: Re: [PATCH 2/2] ofnet: implement a receive buffer
Date: Mon, 21 Nov 2016 22:48:03 +0100	[thread overview]
Message-ID: <20161121214803.GD22877@router-fw-old.local.net-space.pl> (raw)
In-Reply-To: <582F0234.1080400@oracle.com>

On Fri, Nov 18, 2016 at 04:29:24PM +0300, Stanislav Kholmanskikh wrote:
> On 11/16/2016 01:34 AM, Daniel Kiper wrote:
> > On Tue, Apr 12, 2016 at 03:39:56PM +0300, Stanislav Kholmanskikh wrote:
> >> get_card_packet() from ofnet.c allocates a netbuff based on the device's MTU:
> >>
> >>   nb = grub_netbuff_alloc (dev->mtu + 64 + 2);
> >>
> >> In the case when the MTU is large, and the received packet is
> >> relatively small, this leads to allocation of significantly more memory,
> >> than it's required. An example could be transmission of TFTP packets
> >> with 0x400 blksize via a network card with 0x10000 MTU.
> >>
> >> This patch implements a per-card receive buffer in a way similar to efinet.c,
> >> and makes get_card_packet() allocate a netbuff of the received data size.
> >
> > Have you checked performance impact of this patch? It should not be
> > meaningful but it is good to know.
>
> No. I didn't do performance testing.

Please do.

> >> Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
> >> ---
> >>  grub-core/net/drivers/ieee1275/ofnet.c |  100 ++++++++++++++++++-------------
> >>  1 files changed, 58 insertions(+), 42 deletions(-)
> >>
> >> diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c
> >> index 6bd3b92..09ec77e 100644
> >> --- a/grub-core/net/drivers/ieee1275/ofnet.c
> >> +++ b/grub-core/net/drivers/ieee1275/ofnet.c
> >> @@ -85,24 +85,35 @@ get_card_packet (struct grub_net_card *dev)
> >>    grub_uint64_t start_time;
> >>    struct grub_net_buff *nb;
> >>
> >> -  nb = grub_netbuff_alloc (dev->mtu + 64 + 2);
> >> +  start_time = grub_get_time_ms ();
> >> +  do
> >> +    rc = grub_ieee1275_read (data->handle, dev->rcvbuf, dev->rcvbufsize, &actual);
> >> +  while ((actual <= 0 || rc < 0) && (grub_get_time_ms () - start_time < 200));
> >
> > Why 200? Please avoid using plain numbers if possible. Use constants. If it does
> > not make sense then put comment which explains why this figure not another.
>
> The whole 'do while' construction is from the existing code, I only
> modify the destination for the grub_ieee1275_read() call.

OK but if you move such code around anyway do not leave it unreadable. Improve it
by constants or comments.

> > Additionally, are we sure that whole packet can be always stored in dev->rcvbuf?
>
> Code in search_net_devices() allocates the buffer to be of size:
>
> ALIGN_UP (card->mtu, 64) + 256;
>
> so, yes, it's capable to handle any valid packet size.

Great but why this numbers?

> >> +  if (actual <= 0)
> >> +    return NULL;
> >> +
> >> +  nb = grub_netbuff_alloc (actual + 2);
> >>    if (!nb)
> >>      return NULL;
> >> +
> >>    /* Reserve 2 bytes so that 2 + 14/18 bytes of ethernet header is divisible
> >>       by 4. So that IP header is aligned on 4 bytes. */
> >> -  grub_netbuff_reserve (nb, 2);
> >> +  if (grub_netbuff_reserve (nb, 2))
> >> +    {
> >> +      grub_netbuff_free (nb);
> >> +      return NULL;
> >> +    }
> >
> > This smells like separate fix not belonging to this patch.
>
> Ok. I can move this change into a separate patch.

Thanks a lot!

> >> -  start_time = grub_get_time_ms ();
> >> -  do
> >> -    rc = grub_ieee1275_read (data->handle, nb->data, dev->mtu + 64, &actual);
> >> -  while ((actual <= 0 || rc < 0) && (grub_get_time_ms () - start_time < 200));
> >> -  if (actual > 0)
> >> +  grub_memcpy (nb->data, dev->rcvbuf, actual);
> >> +
> >> +  if (grub_netbuff_put (nb, actual))
> >>      {
> >> -      grub_netbuff_put (nb, actual);
> >> -      return nb;
> >> +      grub_netbuff_free (nb);
> >> +      return NULL;
> >>      }
> >
> > Why not...
>
> Ok.
>
> >
> >   if (!grub_netbuff_put (nb, actual))
> >     return nb;
> >
> >> -  grub_netbuff_free (nb);
> >> -  return NULL;
> >> +
> >> +  return nb;
> >
> > ...then you do not need these changes too...
> >
> >>  }
> >
> > It looks that everything below belongs to patch #1...
>
> No. Patch 1 is about two supplementary funcions for "alloc-mem",
> "free-mem". The changes below setup the transmit/receive buffers for a
> network card. The changes above use this receive buffer. So, in my
> opinion, this all is logically coupled and should be in one patch.

I have checked code below once again. First of all I think that
grub_ieee1275_alloc_mem() and grub_ieee1275_free_mem() have to live
in this file not in grub-core/kern/ieee1275/openfw.c. I see no
other callers for both of them. Additionally, patch #1 should
introduce grub_ieee1275_alloc_mem(), ofnet_alloc_netbuf() and
search_net_devices() should call ofnet_alloc_netbuf(). No more
no less. Do not forget to mention in commit message why patch #1
is needed. Then patch #2 should introduce rest of the code below.

> >>  static struct grub_net_card_driver ofdriver =
> >> @@ -294,6 +305,24 @@ grub_ieee1275_net_config_real (const char *devpath, char **device, char **path,
> >>    }
> >>  }
> >>
> >> +static void *
> >> +ofnet_alloc_netbuf (grub_size_t len)
> >> +{
> >> +  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN))
> >> +    return grub_ieee1275_alloc_mem (len);
> >> +  else
> >> +    return grub_malloc (len);

It looks that it should be grub_zalloc() instead of grub_malloc() here.

> >> +}
> >> +
> >> +static void
> >> +ofnet_free_netbuf (void *addr, grub_size_t len)
> >> +{
> >> +  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN))
> >> +    grub_ieee1275_free_mem (addr, len);
> >> +  else
> >> +    grub_free (addr);
> >> +}
> >> +
> >>  static int
> >>  search_net_devices (struct grub_ieee1275_devalias *alias)
> >>  {
> >> @@ -409,41 +438,21 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
> >>    card->default_address = lla;
> >>
> >>    card->txbufsize = ALIGN_UP (card->mtu, 64) + 256;
> >> +  card->rcvbufsize = ALIGN_UP (card->mtu, 64) + 256;
> >>
> >> -  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN))
> >> -    {
> >> -      struct alloc_args
> >> -      {
> >> -	struct grub_ieee1275_common_hdr common;
> >> -	grub_ieee1275_cell_t method;
> >> -	grub_ieee1275_cell_t len;
> >> -	grub_ieee1275_cell_t catch;
> >> -	grub_ieee1275_cell_t result;
> >> -      }
> >> -      args;
> >> -      INIT_IEEE1275_COMMON (&args.common, "interpret", 2, 2);
> >> -      args.len = card->txbufsize;
> >> -      args.method = (grub_ieee1275_cell_t) "alloc-mem";
> >> -
> >> -      if (IEEE1275_CALL_ENTRY_FN (&args) == -1
> >> -	  || args.catch)
> >> -	{
> >> -	  card->txbuf = 0;
> >> -	  grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
> >> -	}
> >> -      else
> >> -	card->txbuf = (void *) args.result;
> >> -    }
> >> -  else
> >> -    card->txbuf = grub_zalloc (card->txbufsize);
> >> +  card->txbuf = ofnet_alloc_netbuf (card->txbufsize);
> >>    if (!card->txbuf)
> >> +    goto fail;
> >> +
> >> +  card->rcvbuf = ofnet_alloc_netbuf (card->rcvbufsize);
> >> +  if (!card->rcvbuf)
> >>      {
> >> -      grub_free (ofdata->path);
> >> -      grub_free (ofdata);
> >> -      grub_free (card);
> >> -      grub_print_error ();
> >> -      return 0;
> >> +      grub_error_push ();
> >> +      ofnet_free_netbuf(card->txbuf, card->txbufsize);
> >> +      grub_error_pop ();
> >> +      goto fail;
> >>      }

Should not we free card->rcvbuf and/or card->txbuf if module is
unloaded or something like that?

Daniel


  reply	other threads:[~2016-11-21 21:48 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-12 12:39 [PATCH 1/2] ieee1275: alloc-mem and free-mem Stanislav Kholmanskikh
2016-04-12 12:39 ` [PATCH 2/2] ofnet: implement a receive buffer Stanislav Kholmanskikh
2016-05-10 10:45   ` Stanislav Kholmanskikh
2016-07-13 14:35     ` Stanislav Kholmanskikh
2016-10-13  8:13       ` Stanislav Kholmanskikh
2016-11-15 22:34   ` Daniel Kiper
2016-11-18 13:29     ` Stanislav Kholmanskikh
2016-11-21 21:48       ` Daniel Kiper [this message]
2016-11-22 14:08         ` Stanislav Kholmanskikh
2016-11-23 11:16           ` Daniel Kiper
2016-11-23 15:09             ` Stanislav Kholmanskikh
2016-11-24  9:25               ` Daniel Kiper
2016-11-30 15:27               ` Stanislav Kholmanskikh
2016-11-15 21:22 ` [PATCH 1/2] ieee1275: alloc-mem and free-mem Daniel Kiper
2016-11-18 12:32   ` Stanislav Kholmanskikh
2017-05-11  1:51     ` Vladimir 'phcoder' Serbinenko

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=20161121214803.GD22877@router-fw-old.local.net-space.pl \
    --to=dkiper@net-space.pl \
    --cc=grub-devel@gnu.org \
    --cc=stanislav.kholmanskikh@oracle.com \
    --cc=vasily.isaenko@oracle.com \
    /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.