All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Zhi Yong Wu <zwu.kernel@gmail.com>
Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org,
	stefanha@linux.vnet.ibm.com, jan.kiszka@siemens.com,
	wuzhy@linux.vnet.ibm.com
Subject: Re: [PATCH v3 16/16] hub: add the support for hub own flow control
Date: Fri, 25 May 2012 12:08:16 +0200	[thread overview]
Message-ID: <4FBF5A10.5090000@redhat.com> (raw)
In-Reply-To: <CAEH94LgCNTGojOMPq4FzYJDurU2QzQHdPiUQU=d6H_0bn6-4xQ@mail.gmail.com>

Il 25/05/2012 09:48, Zhi Yong Wu ha scritto:
>>>  static ssize_t net_hub_receive(NetHub *hub, NetHubPort *source_port,
>>>                                 const uint8_t *buf, size_t len)
>>>  {
>>>      NetHubPort *port;
>>> +    ssize_t ret = 0;
>>>
>>>      QLIST_FOREACH(port, &hub->ports, next) {
>>>          if (port == source_port) {
>>>              continue;
>>>          }
>>>
>>> -        qemu_send_packet(&port->nc, buf, len);
>>> +       ret = qemu_send_packet_async(&port->nc, buf, len,
>>> +                                    net_hub_receive_completed);
>>
>> Just increment nr_packets here:
>>
>>    ret = qemu_send_packet_async
>>    if (ret == 0) {
>>        port->nr_packets++;
>>    }
> This is wrong, if you check the code, sent_cb is only called when the
> send queue is not empty. That is, sent_cb is used for those enqueued
> packets. For those packets which aren't enqueued, The counter will be
> not decreased.

It will also not be incremented, because I'm checking for ret == 0.

>>>      }
>>> -    return len;
>>> +    return ret;
>>
>> You can return len here.  In fact returning ret is wrong because the
>> value comes from a random port (the last one).
> If the return value from the last port doesn't equal to len, you let
> this function return len, it will be also wrong.

But that's the whole point of implementing flow control.  We return len
because we _did_ process the packet; it is now in the port's queues.
However, can_receive will not admit new packets until all ports have
processed the previous one, so that all ports advance to new packets at
the same time.

>>
>>>  }
>>>
>>>  static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
>>> @@ -65,7 +84,8 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
>>>              continue;
>>>          }
>>>
>>> -        ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
>>> +        ret = qemu_sendv_packet_async(&port->nc, iov, iovcnt,
>>> +                                      net_hub_receive_completed);
>>
>> Same here (increment nr_packets)
>>
>>>      }
>>>      return ret;
>>
>> Same here (return len).
> No, it has no such variable called as len, I think that here should
> return ret, not len.
> Do you think that it is necessary to calc len by iov and viocnt?

Yes, for the same reason as above.  Returning "ret" for a random port
(the last one) does not make sense!  But you could just punt: do not
implement net_hub_receive_iov at all...

>> But I think you need to implement this on the hub rather than on the
>> port, and return true only if port->nr_packets == 0 for all ports.
> Can you explain why to need based on hub, not port?

Because the purpose of the counter is to do flow control _on the hub_.
The ports can do their flow control just as well, but the hub has to
reconcile the decisions of the ports.

Taking your example from another message:

>   e.g. guest <---> hubport1 -  hubport2 <--> network backend.
>   hubport1->nr_packets == 0 mean if guest can send packet through
>   hubport1 to outside.
>   while hubport2->nr_packets == 0 mean if network backend can send
>   packet through hubport1 to guest.
>   Their direction is different.
>   So i don't understand why to need
>   "port->nr_packets == 0 for all ports"?

For simplicity.  Yes, this means hubs will be half-duplex.  In practice
I don't think you need to care.

If you want to make it full-duplex, you can keep the per-port counter
and in can_receive check if all ports except this one has a zero
nr_packets count.  In other words, your can_receive method is backwards:
a port can receive a packet if all of its sibling ports are ready to
receive it.

Don't think of it in terms of "directions".  It is not correct, because
it is a star topology.  Think of it in terms of where the packets enter
the hub, and where they are forwarded to.

>> Probably you can move nr_packets to the hub itself rather than the port?
> I think that the counter brings a lot of issues.

I said already that it's not *necessary*.  You're free to find another
solution.  Removing TODO comments and leaving the problem however is not
a solution.

Paolo

WARNING: multiple messages have this Message-ID (diff)
From: Paolo Bonzini <pbonzini@redhat.com>
To: Zhi Yong Wu <zwu.kernel@gmail.com>
Cc: jan.kiszka@siemens.com, wuzhy@linux.vnet.ibm.com,
	qemu-devel@nongnu.org, kvm@vger.kernel.org,
	stefanha@linux.vnet.ibm.com
Subject: Re: [Qemu-devel] [PATCH v3 16/16] hub: add the support for hub own flow control
Date: Fri, 25 May 2012 12:08:16 +0200	[thread overview]
Message-ID: <4FBF5A10.5090000@redhat.com> (raw)
In-Reply-To: <CAEH94LgCNTGojOMPq4FzYJDurU2QzQHdPiUQU=d6H_0bn6-4xQ@mail.gmail.com>

Il 25/05/2012 09:48, Zhi Yong Wu ha scritto:
>>>  static ssize_t net_hub_receive(NetHub *hub, NetHubPort *source_port,
>>>                                 const uint8_t *buf, size_t len)
>>>  {
>>>      NetHubPort *port;
>>> +    ssize_t ret = 0;
>>>
>>>      QLIST_FOREACH(port, &hub->ports, next) {
>>>          if (port == source_port) {
>>>              continue;
>>>          }
>>>
>>> -        qemu_send_packet(&port->nc, buf, len);
>>> +       ret = qemu_send_packet_async(&port->nc, buf, len,
>>> +                                    net_hub_receive_completed);
>>
>> Just increment nr_packets here:
>>
>>    ret = qemu_send_packet_async
>>    if (ret == 0) {
>>        port->nr_packets++;
>>    }
> This is wrong, if you check the code, sent_cb is only called when the
> send queue is not empty. That is, sent_cb is used for those enqueued
> packets. For those packets which aren't enqueued, The counter will be
> not decreased.

It will also not be incremented, because I'm checking for ret == 0.

>>>      }
>>> -    return len;
>>> +    return ret;
>>
>> You can return len here.  In fact returning ret is wrong because the
>> value comes from a random port (the last one).
> If the return value from the last port doesn't equal to len, you let
> this function return len, it will be also wrong.

But that's the whole point of implementing flow control.  We return len
because we _did_ process the packet; it is now in the port's queues.
However, can_receive will not admit new packets until all ports have
processed the previous one, so that all ports advance to new packets at
the same time.

>>
>>>  }
>>>
>>>  static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
>>> @@ -65,7 +84,8 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
>>>              continue;
>>>          }
>>>
>>> -        ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
>>> +        ret = qemu_sendv_packet_async(&port->nc, iov, iovcnt,
>>> +                                      net_hub_receive_completed);
>>
>> Same here (increment nr_packets)
>>
>>>      }
>>>      return ret;
>>
>> Same here (return len).
> No, it has no such variable called as len, I think that here should
> return ret, not len.
> Do you think that it is necessary to calc len by iov and viocnt?

Yes, for the same reason as above.  Returning "ret" for a random port
(the last one) does not make sense!  But you could just punt: do not
implement net_hub_receive_iov at all...

>> But I think you need to implement this on the hub rather than on the
>> port, and return true only if port->nr_packets == 0 for all ports.
> Can you explain why to need based on hub, not port?

Because the purpose of the counter is to do flow control _on the hub_.
The ports can do their flow control just as well, but the hub has to
reconcile the decisions of the ports.

Taking your example from another message:

>   e.g. guest <---> hubport1 -  hubport2 <--> network backend.
>   hubport1->nr_packets == 0 mean if guest can send packet through
>   hubport1 to outside.
>   while hubport2->nr_packets == 0 mean if network backend can send
>   packet through hubport1 to guest.
>   Their direction is different.
>   So i don't understand why to need
>   "port->nr_packets == 0 for all ports"?

For simplicity.  Yes, this means hubs will be half-duplex.  In practice
I don't think you need to care.

If you want to make it full-duplex, you can keep the per-port counter
and in can_receive check if all ports except this one has a zero
nr_packets count.  In other words, your can_receive method is backwards:
a port can receive a packet if all of its sibling ports are ready to
receive it.

Don't think of it in terms of "directions".  It is not correct, because
it is a star topology.  Think of it in terms of where the packets enter
the hub, and where they are forwarded to.

>> Probably you can move nr_packets to the hub itself rather than the port?
> I think that the counter brings a lot of issues.

I said already that it's not *necessary*.  You're free to find another
solution.  Removing TODO comments and leaving the problem however is not
a solution.

Paolo

  reply	other threads:[~2012-05-25 10:08 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-24 17:59 [PATCH v3 00/16] net: hub-based networking zwu.kernel
2012-05-24 17:59 ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 01/16] net: Add a hub net client zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 02/16] net: Use hubs for the vlan feature zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 03/16] net: Look up 'vlan' net clients using hubs zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 04/16] hub: Check that hubs are configured correctly zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 05/16] net: Drop vlan argument to qemu_new_net_client() zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 06/16] net: Remove vlan qdev property zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 07/16] net: Remove vlan code from net.c zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 08/16] net: Remove VLANState zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 09/16] net: Rename non_vlan_clients to net_clients zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 10/16] net: Rename VLANClientState to NetClientState zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 11/16] net: Rename vc local variables to nc zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 12/16] net: Rename qemu_del_vlan_client() to qemu_del_net_client() zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 13/16] net: Make the monitor output more reasonable hub info zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 20:34   ` Jan Kiszka
2012-05-24 20:34     ` [Qemu-devel] " Jan Kiszka
2012-05-25  0:48     ` Zhi Yong Wu
2012-05-25  0:48       ` [Qemu-devel] " Zhi Yong Wu
2012-05-25 12:00     ` Zhi Yong Wu
2012-05-25 12:00       ` [Qemu-devel] " Zhi Yong Wu
2012-05-25 13:49       ` Jan Kiszka
2012-05-25 13:49         ` [Qemu-devel] " Jan Kiszka
2012-05-25 13:58         ` Zhi Yong Wu
2012-05-25 13:58           ` [Qemu-devel] " Zhi Yong Wu
2012-05-24 17:59 ` [PATCH v3 14/16] net: cleanup deliver/deliver_iov func pointers zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 15/16] net: determine if packets can be sent before net queue deliver packets zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-24 17:59 ` [PATCH v3 16/16] hub: add the support for hub own flow control zwu.kernel
2012-05-24 17:59   ` [Qemu-devel] " zwu.kernel
2012-05-25  7:04   ` Paolo Bonzini
2012-05-25  7:04     ` [Qemu-devel] " Paolo Bonzini
2012-05-25  7:48     ` Zhi Yong Wu
2012-05-25  7:48       ` [Qemu-devel] " Zhi Yong Wu
2012-05-25 10:08       ` Paolo Bonzini [this message]
2012-05-25 10:08         ` Paolo Bonzini
2012-05-25 10:54         ` Zhi Yong Wu
2012-05-25 10:54           ` [Qemu-devel] " Zhi Yong Wu
2012-05-25  8:04     ` Zhi Yong Wu
2012-05-25  8:04       ` [Qemu-devel] " Zhi Yong Wu
2012-05-25  8:18     ` Zhi Yong Wu
2012-05-25  8:18       ` [Qemu-devel] " Zhi Yong Wu
2012-05-24 20:53 ` [Qemu-devel] [PATCH v3 00/16] net: hub-based networking Luiz Capitulino
2012-05-24 20:53   ` Luiz Capitulino
2012-05-25  0:47   ` Zhi Yong Wu
2012-05-25  0:47     ` [Qemu-devel] " Zhi Yong Wu
2012-05-25 12:49     ` Luiz Capitulino
2012-05-25 12:49       ` Luiz Capitulino
2012-05-25 10:07   ` Stefan Hajnoczi
2012-05-25 10:07     ` [Qemu-devel] " Stefan Hajnoczi
2012-05-25 11:18     ` Markus Armbruster
2012-05-25 11:18       ` [Qemu-devel] " Markus Armbruster
2012-05-25 12:01       ` Stefan Hajnoczi
2012-05-25 12:01         ` Stefan Hajnoczi
2012-05-25 12:30         ` Markus Armbruster
2012-05-25 12:53         ` Luiz Capitulino
2012-05-25 12:53           ` Luiz Capitulino
2012-05-25 12:59           ` Paolo Bonzini
2012-05-25 12:59             ` Paolo Bonzini
2012-05-25 13:07             ` Luiz Capitulino
2012-05-25 13:07               ` [Qemu-devel] " Luiz Capitulino
2012-05-25 13:14               ` Paolo Bonzini
2012-05-25 13:14                 ` Paolo Bonzini
2012-05-25 13:18                 ` Luiz Capitulino
2012-05-25 13:18                   ` Luiz Capitulino
2012-05-25 13:19                   ` Paolo Bonzini
2012-05-25 13:19                     ` Paolo Bonzini
2012-05-25 13:30                     ` Luiz Capitulino
2012-05-25 13:30                       ` Luiz Capitulino
2012-05-25 13:37                       ` Paolo Bonzini
2012-05-25 13:37                         ` Paolo Bonzini
2012-05-25 13:43                         ` Luiz Capitulino
2012-05-25 13:43                           ` Luiz Capitulino
2012-05-25 13:47                           ` Paolo Bonzini
2012-05-25 13:47                             ` [Qemu-devel] " Paolo Bonzini
2012-05-25 13:56                             ` Luiz Capitulino
2012-05-25 13:56                               ` Luiz Capitulino
2012-05-28 11:17                               ` Stefan Hajnoczi
2012-05-28 11:17                                 ` Stefan Hajnoczi
2012-05-28 13:25                                 ` Luiz Capitulino
2012-05-28 13:25                                   ` Luiz Capitulino
2012-05-29  8:14                                   ` Markus Armbruster
2012-06-04  4:48                                     ` Anthony Liguori
2012-06-04  4:48                                       ` Anthony Liguori
2012-06-04  7:24                                       ` Markus Armbruster
2012-06-04  4:56           ` Anthony Liguori
2012-06-04  4:56             ` [Qemu-devel] " Anthony Liguori
2012-06-04 13:09             ` Luiz Capitulino
2012-06-04 13:09               ` Luiz Capitulino

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=4FBF5A10.5090000@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=jan.kiszka@siemens.com \
    --cc=kvm@vger.kernel.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@linux.vnet.ibm.com \
    --cc=wuzhy@linux.vnet.ibm.com \
    --cc=zwu.kernel@gmail.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.