Patchwork [v4,16/16] hub: add the support for hub own flow control

login
register
mail settings
Submitter Zhiyong Wu
Date May 25, 2012, 10:52 a.m.
Message ID <1337943134-1107-1-git-send-email-zwu.kernel@gmail.com>
Download mbox | patch
Permalink /patch/161287/
State New
Headers show

Comments

Zhiyong Wu - May 25, 2012, 10:52 a.m.
From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>

Only when all other hub port's *peer* .can_receive() all return 1, the source hub port .can_receive() return 1.

Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
---
 net/hub.c |   27 ++++++++++++++++++++++++---
 1 files changed, 24 insertions(+), 3 deletions(-)
Paolo Bonzini - May 25, 2012, 11:05 a.m.
Il 25/05/2012 12:52, zwu.kernel@gmail.com ha scritto:
> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> 
> Only when all other hub port's *peer* .can_receive() all return 1, the source hub port .can_receive() return 1.
> 
> Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> ---
>  net/hub.c |   27 ++++++++++++++++++++++++---
>  1 files changed, 24 insertions(+), 3 deletions(-)
> 
> diff --git a/net/hub.c b/net/hub.c
> index 357ca87..478cce1 100644
> --- a/net/hub.c
> +++ b/net/hub.c
> @@ -15,6 +15,7 @@
>  #include "monitor.h"
>  #include "net.h"
>  #include "hub.h"
> +#include "iov.h"
>  
>  /*
>   * A hub broadcasts incoming packets to all its ports except the source port.
> @@ -59,16 +60,16 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
>                                     const struct iovec *iov, int iovcnt)
>  {
>      NetHubPort *port;
> -    ssize_t ret = 0;
> +    ssize_t len = iov_size(iov, iovcnt);
>  
>      QLIST_FOREACH(port, &hub->ports, next) {
>          if (port == source_port) {
>              continue;
>          }
>  
> -        ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
> +        qemu_sendv_packet(&port->nc, iov, iovcnt);

I think you still need to apply flow control, otherwise you're cheating.
 But perhaps this is acceptable, I'll leave it to more expert people.

Paolo
Zhiyong Wu - May 25, 2012, 11:10 a.m.
On Fri, May 25, 2012 at 7:05 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:
> Il 25/05/2012 12:52, zwu.kernel@gmail.com ha scritto:
>> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>>
>> Only when all other hub port's *peer* .can_receive() all return 1, the source hub port .can_receive() return 1.
>>
>> Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>> ---
>>  net/hub.c |   27 ++++++++++++++++++++++++---
>>  1 files changed, 24 insertions(+), 3 deletions(-)
>>
>> diff --git a/net/hub.c b/net/hub.c
>> index 357ca87..478cce1 100644
>> --- a/net/hub.c
>> +++ b/net/hub.c
>> @@ -15,6 +15,7 @@
>>  #include "monitor.h"
>>  #include "net.h"
>>  #include "hub.h"
>> +#include "iov.h"
>>
>>  /*
>>   * A hub broadcasts incoming packets to all its ports except the source port.
>> @@ -59,16 +60,16 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
>>                                     const struct iovec *iov, int iovcnt)
>>  {
>>      NetHubPort *port;
>> -    ssize_t ret = 0;
>> +    ssize_t len = iov_size(iov, iovcnt);
>>
>>      QLIST_FOREACH(port, &hub->ports, next) {
>>          if (port == source_port) {
>>              continue;
>>          }
>>
>> -        ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
>> +        qemu_sendv_packet(&port->nc, iov, iovcnt);
>
> I think you still need to apply flow control, otherwise you're cheating.
>  But perhaps this is acceptable, I'll leave it to more expert people.
Great. thanks. any comments for other patches?

>
> Paolo
Stefan Hajnoczi - May 25, 2012, 12:13 p.m.
On Fri, May 25, 2012 at 06:52:14PM +0800, zwu.kernel@gmail.com wrote:
> @@ -59,16 +60,16 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
>                                     const struct iovec *iov, int iovcnt)
>  {
>      NetHubPort *port;
> -    ssize_t ret = 0;
> +    ssize_t len = iov_size(iov, iovcnt);
> 
>      QLIST_FOREACH(port, &hub->ports, next) {
>          if (port == source_port) {
>              continue;
>          }
> 
> -        ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
> +        qemu_sendv_packet(&port->nc, iov, iovcnt);
>      }
> -    return ret;
> +    return len;
>  }

I think this is okay because at this point we've given it our best shot:
we already checked that port peers can receive.  If they error out now
there's not much we can do.  The packet is dropped for that particular
peer but at least we tried to deliver it when they claimed to be ready.

Stefan
Zhiyong Wu - May 26, 2012, 12:32 p.m.
On Fri, May 25, 2012 at 8:13 PM, Stefan Hajnoczi
<stefanha@linux.vnet.ibm.com> wrote:
> On Fri, May 25, 2012 at 06:52:14PM +0800, zwu.kernel@gmail.com wrote:
>> @@ -59,16 +60,16 @@ static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
>>                                     const struct iovec *iov, int iovcnt)
>>  {
>>      NetHubPort *port;
>> -    ssize_t ret = 0;
>> +    ssize_t len = iov_size(iov, iovcnt);
>>
>>      QLIST_FOREACH(port, &hub->ports, next) {
>>          if (port == source_port) {
>>              continue;
>>          }
>>
>> -        ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
>> +        qemu_sendv_packet(&port->nc, iov, iovcnt);
>>      }
>> -    return ret;
>> +    return len;
>>  }
>
> I think this is okay because at this point we've given it our best shot:
> we already checked that port peers can receive.  If they error out now
> there's not much we can do.  The packet is dropped for that particular
> peer but at least we tried to deliver it when they claimed to be ready.
Yeah, i think that he is lack of enough understanding on net subsystem
code. He can't see that his thought brought a lot of issues.

>
> Stefan
>

Patch

diff --git a/net/hub.c b/net/hub.c
index 357ca87..478cce1 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -15,6 +15,7 @@ 
 #include "monitor.h"
 #include "net.h"
 #include "hub.h"
+#include "iov.h"
 
 /*
  * A hub broadcasts incoming packets to all its ports except the source port.
@@ -59,16 +60,16 @@  static ssize_t net_hub_receive_iov(NetHub *hub, NetHubPort *source_port,
                                    const struct iovec *iov, int iovcnt)
 {
     NetHubPort *port;
-    ssize_t ret = 0;
+    ssize_t len = iov_size(iov, iovcnt);
 
     QLIST_FOREACH(port, &hub->ports, next) {
         if (port == source_port) {
             continue;
         }
 
-        ret = qemu_sendv_packet(&port->nc, iov, iovcnt);
+        qemu_sendv_packet(&port->nc, iov, iovcnt);
     }
-    return ret;
+    return len;
 }
 
 static NetHub *net_hub_new(unsigned int id)
@@ -85,6 +86,25 @@  static NetHub *net_hub_new(unsigned int id)
     return hub;
 }
 
+static int net_hub_port_can_receive(NetClientState *nc)
+{
+    NetHubPort *port;
+    NetHubPort *src_port = DO_UPCAST(NetHubPort, nc, nc);
+    NetHub *hub = src_port->hub;
+
+    QLIST_FOREACH(port, &hub->ports, next) {
+        if (port == src_port) {
+            continue;
+        }
+
+        if (!qemu_can_send_packet(&port->nc)) {
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
 static ssize_t net_hub_port_receive(NetClientState *nc,
                                     const uint8_t *buf, size_t len)
 {
@@ -111,6 +131,7 @@  static void net_hub_port_cleanup(NetClientState *nc)
 static NetClientInfo net_hub_port_info = {
     .type = NET_CLIENT_TYPE_HUB,
     .size = sizeof(NetHubPort),
+    .can_receive = net_hub_port_can_receive,
     .receive = net_hub_port_receive,
     .receive_iov = net_hub_port_receive_iov,
     .cleanup = net_hub_port_cleanup,