grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 2/2] ofnet: implement a receive buffer


From: Stanislav Kholmanskikh
Subject: Re: [PATCH 2/2] ofnet: implement a receive buffer
Date: Fri, 18 Nov 2016 16:29:24 +0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0

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.

> 
>> Signed-off-by: Stanislav Kholmanskikh <address@hidden>
>> ---
>>  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.

> 
> 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.

> 
>> +  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.

> 
>> -  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.

> 
>>  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);
>> +}
>> +
>> +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;
>>      }
>> +
>>    card->driver = NULL;
>>    card->data = ofdata;
>>    card->flags = 0;
>> @@ -455,6 +464,13 @@ search_net_devices (struct grub_ieee1275_devalias 
>> *alias)
>>    card->driver = &ofdriver;
>>    grub_net_card_register (card);
>>    return 0;
>> +
>> + fail:
>> +  grub_free (ofdata->path);
>> +  grub_free (ofdata);
>> +  grub_free (card);
>> +  grub_print_error ();
>> +  return 1;
> 
> ...and without full explanation why in #1 commit message it is
> not obvious for what this change is really needed...
> 
> Daniel
> 
> _______________________________________________
> Grub-devel mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/grub-devel
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]