Re: [RFC PATCH 07/13] vsock: handle buffer_size sockopts in the core

2019-10-11 Thread Stefano Garzarella
On Fri, Oct 11, 2019 at 09:27:14AM +0100, Stefan Hajnoczi wrote:
> On Thu, Oct 10, 2019 at 11:32:54AM +0200, Stefano Garzarella wrote:
> > On Wed, Oct 09, 2019 at 01:30:26PM +0100, Stefan Hajnoczi wrote:
> > > On Fri, Sep 27, 2019 at 01:26:57PM +0200, Stefano Garzarella wrote:
> > > Another issue is that this patch drops the VIRTIO_VSOCK_MAX_BUF_SIZE
> > > limit that used to be enforced by virtio_transport_set_buffer_size().
> > > Now the limit is only applied at socket init time.  If the buffer size
> > > is changed later then VIRTIO_VSOCK_MAX_BUF_SIZE can be exceeded.  If
> > > that doesn't matter, why even bother with VIRTIO_VSOCK_MAX_BUF_SIZE
> > > here?
> > > 
> > 
> > The .notify_buffer_size() should avoid this issue, since it allows the
> > transport to limit the buffer size requested after the initialization.
> > 
> > But again the min set by the user can not be respected and in the
> > previous implementation we forced it to VIRTIO_VSOCK_MAX_BUF_SIZE.
> > 
> > Now we don't limit the min, but we guarantee only that vsk->buffer_size
> > is lower than VIRTIO_VSOCK_MAX_BUF_SIZE.
> > 
> > Can that be an acceptable compromise?
> 
> I think so.
> 
> Setting buffer sizes was never tested or used much by userspace
> applications that I'm aware of.  We should probably include tests for
> changing buffer sizes in the test suite.

Good idea! We should add a test to check if min/max are respected,
playing a bit with these sockopt.

I'll do it in the test series!

Thanks,
Stefano


Re: [RFC PATCH 07/13] vsock: handle buffer_size sockopts in the core

2019-10-11 Thread Stefan Hajnoczi
On Thu, Oct 10, 2019 at 11:32:54AM +0200, Stefano Garzarella wrote:
> On Wed, Oct 09, 2019 at 01:30:26PM +0100, Stefan Hajnoczi wrote:
> > On Fri, Sep 27, 2019 at 01:26:57PM +0200, Stefano Garzarella wrote:
> > Another issue is that this patch drops the VIRTIO_VSOCK_MAX_BUF_SIZE
> > limit that used to be enforced by virtio_transport_set_buffer_size().
> > Now the limit is only applied at socket init time.  If the buffer size
> > is changed later then VIRTIO_VSOCK_MAX_BUF_SIZE can be exceeded.  If
> > that doesn't matter, why even bother with VIRTIO_VSOCK_MAX_BUF_SIZE
> > here?
> > 
> 
> The .notify_buffer_size() should avoid this issue, since it allows the
> transport to limit the buffer size requested after the initialization.
> 
> But again the min set by the user can not be respected and in the
> previous implementation we forced it to VIRTIO_VSOCK_MAX_BUF_SIZE.
> 
> Now we don't limit the min, but we guarantee only that vsk->buffer_size
> is lower than VIRTIO_VSOCK_MAX_BUF_SIZE.
> 
> Can that be an acceptable compromise?

I think so.

Setting buffer sizes was never tested or used much by userspace
applications that I'm aware of.  We should probably include tests for
changing buffer sizes in the test suite.

Stefan


signature.asc
Description: PGP signature


Re: [RFC PATCH 07/13] vsock: handle buffer_size sockopts in the core

2019-10-10 Thread Stefano Garzarella
On Wed, Oct 09, 2019 at 01:30:26PM +0100, Stefan Hajnoczi wrote:
> On Fri, Sep 27, 2019 at 01:26:57PM +0200, Stefano Garzarella wrote:
> > @@ -140,18 +145,11 @@ struct vsock_transport {
> > struct vsock_transport_send_notify_data *);
> > int (*notify_send_post_enqueue)(struct vsock_sock *, ssize_t,
> > struct vsock_transport_send_notify_data *);
> > +   int (*notify_buffer_size)(struct vsock_sock *, u64 *);
> 
> Is ->notify_buffer_size() called under lock_sock(sk)?  If yes, please
> document it.

Yes, it is. I'll document it!

> 
> > +static void vsock_update_buffer_size(struct vsock_sock *vsk,
> > +const struct vsock_transport *transport,
> > +u64 val)
> > +{
> > +   if (val > vsk->buffer_max_size)
> > +   val = vsk->buffer_max_size;
> > +
> > +   if (val < vsk->buffer_min_size)
> > +   val = vsk->buffer_min_size;
> > +
> > +   if (val != vsk->buffer_size &&
> > +   transport && transport->notify_buffer_size)
> > +   transport->notify_buffer_size(vsk, );
> 
> Why does this function return an int if we don't check the return value?
> 

Copy and past :-(
I'll fix it returning void since I don't think it can fail.

> > diff --git a/net/vmw_vsock/virtio_transport_common.c 
> > b/net/vmw_vsock/virtio_transport_common.c
> > index fc046c071178..bac9e7430a2e 100644
> > --- a/net/vmw_vsock/virtio_transport_common.c
> > +++ b/net/vmw_vsock/virtio_transport_common.c
> > @@ -403,17 +403,13 @@ int virtio_transport_do_socket_init(struct vsock_sock 
> > *vsk,
> > if (psk) {
> > struct virtio_vsock_sock *ptrans = psk->trans;
> >  
> > -   vvs->buf_size   = ptrans->buf_size;
> > -   vvs->buf_size_min = ptrans->buf_size_min;
> > -   vvs->buf_size_max = ptrans->buf_size_max;
> > vvs->peer_buf_alloc = ptrans->peer_buf_alloc;
> > -   } else {
> > -   vvs->buf_size = VIRTIO_VSOCK_DEFAULT_BUF_SIZE;
> > -   vvs->buf_size_min = VIRTIO_VSOCK_DEFAULT_MIN_BUF_SIZE;
> > -   vvs->buf_size_max = VIRTIO_VSOCK_DEFAULT_MAX_BUF_SIZE;
> > }
> >  
> > -   vvs->buf_alloc = vvs->buf_size;
> > +   if (vsk->buffer_size > VIRTIO_VSOCK_MAX_BUF_SIZE)
> > +   vsk->buffer_size = VIRTIO_VSOCK_MAX_BUF_SIZE;
> 
> Hmm...this could be outside the [min, max] range.  I'm not sure how much
> it matters.

The core guarantees that vsk->buffer_size is <= of the max, so since we are
lowering it, the max should be respected. For the min you are right,
but I think this limit is stricter than the min set by the user.

> 
> Another issue is that this patch drops the VIRTIO_VSOCK_MAX_BUF_SIZE
> limit that used to be enforced by virtio_transport_set_buffer_size().
> Now the limit is only applied at socket init time.  If the buffer size
> is changed later then VIRTIO_VSOCK_MAX_BUF_SIZE can be exceeded.  If
> that doesn't matter, why even bother with VIRTIO_VSOCK_MAX_BUF_SIZE
> here?
> 

The .notify_buffer_size() should avoid this issue, since it allows the
transport to limit the buffer size requested after the initialization.

But again the min set by the user can not be respected and in the
previous implementation we forced it to VIRTIO_VSOCK_MAX_BUF_SIZE.

Now we don't limit the min, but we guarantee only that vsk->buffer_size
is lower than VIRTIO_VSOCK_MAX_BUF_SIZE.

Can that be an acceptable compromise?

Thanks,
Stefano


Re: [RFC PATCH 07/13] vsock: handle buffer_size sockopts in the core

2019-10-09 Thread Stefan Hajnoczi
On Fri, Sep 27, 2019 at 01:26:57PM +0200, Stefano Garzarella wrote:
> @@ -140,18 +145,11 @@ struct vsock_transport {
>   struct vsock_transport_send_notify_data *);
>   int (*notify_send_post_enqueue)(struct vsock_sock *, ssize_t,
>   struct vsock_transport_send_notify_data *);
> + int (*notify_buffer_size)(struct vsock_sock *, u64 *);

Is ->notify_buffer_size() called under lock_sock(sk)?  If yes, please
document it.

> +static void vsock_update_buffer_size(struct vsock_sock *vsk,
> +  const struct vsock_transport *transport,
> +  u64 val)
> +{
> + if (val > vsk->buffer_max_size)
> + val = vsk->buffer_max_size;
> +
> + if (val < vsk->buffer_min_size)
> + val = vsk->buffer_min_size;
> +
> + if (val != vsk->buffer_size &&
> + transport && transport->notify_buffer_size)
> + transport->notify_buffer_size(vsk, );

Why does this function return an int if we don't check the return value?

> diff --git a/net/vmw_vsock/virtio_transport_common.c 
> b/net/vmw_vsock/virtio_transport_common.c
> index fc046c071178..bac9e7430a2e 100644
> --- a/net/vmw_vsock/virtio_transport_common.c
> +++ b/net/vmw_vsock/virtio_transport_common.c
> @@ -403,17 +403,13 @@ int virtio_transport_do_socket_init(struct vsock_sock 
> *vsk,
>   if (psk) {
>   struct virtio_vsock_sock *ptrans = psk->trans;
>  
> - vvs->buf_size   = ptrans->buf_size;
> - vvs->buf_size_min = ptrans->buf_size_min;
> - vvs->buf_size_max = ptrans->buf_size_max;
>   vvs->peer_buf_alloc = ptrans->peer_buf_alloc;
> - } else {
> - vvs->buf_size = VIRTIO_VSOCK_DEFAULT_BUF_SIZE;
> - vvs->buf_size_min = VIRTIO_VSOCK_DEFAULT_MIN_BUF_SIZE;
> - vvs->buf_size_max = VIRTIO_VSOCK_DEFAULT_MAX_BUF_SIZE;
>   }
>  
> - vvs->buf_alloc = vvs->buf_size;
> + if (vsk->buffer_size > VIRTIO_VSOCK_MAX_BUF_SIZE)
> + vsk->buffer_size = VIRTIO_VSOCK_MAX_BUF_SIZE;

Hmm...this could be outside the [min, max] range.  I'm not sure how much
it matters.

Another issue is that this patch drops the VIRTIO_VSOCK_MAX_BUF_SIZE
limit that used to be enforced by virtio_transport_set_buffer_size().
Now the limit is only applied at socket init time.  If the buffer size
is changed later then VIRTIO_VSOCK_MAX_BUF_SIZE can be exceeded.  If
that doesn't matter, why even bother with VIRTIO_VSOCK_MAX_BUF_SIZE
here?



signature.asc
Description: PGP signature


RE: [RFC PATCH 07/13] vsock: handle buffer_size sockopts in the core

2019-10-03 Thread Dexuan Cui
> From: Stefano Garzarella 
> Sent: Friday, September 27, 2019 4:27 AM
> To: net...@vger.kernel.org
> 
> virtio_transport and vmci_transport handle the buffer_size
> sockopts in a very similar way.
> 
> In order to support multiple transports, this patch moves this
> handling in the core to allow the user to change the options
> also if the socket is not yet assigned to any transport.
> 
> This patch also adds the '.notify_buffer_size' callback in the
> 'struct virtio_transport' in order to inform the transport,
> when the buffer_size is changed by the user. It is also useful
> to limit the 'buffer_size' requested (e.g. virtio transports).
> 
> Signed-off-by: Stefano Garzarella 
> ---
>  drivers/vhost/vsock.c   |  7 +-
>  include/linux/virtio_vsock.h| 15 +
>  include/net/af_vsock.h  | 14 ++--
>  net/vmw_vsock/af_vsock.c| 43 ++---
>  net/vmw_vsock/hyperv_transport.c| 36 ---
>  net/vmw_vsock/virtio_transport.c|  8 +--
>  net/vmw_vsock/virtio_transport_common.c | 78 --
>  net/vmw_vsock/vmci_transport.c  | 86 +++--
>  net/vmw_vsock/vmci_transport.h  |  3 -
>  9 files changed, 64 insertions(+), 226 deletions(-)
> 

The hv_sock part (hyperv_transport.c) looks good to me.

Acked-by: Dexuan Cui 



[RFC PATCH 07/13] vsock: handle buffer_size sockopts in the core

2019-09-27 Thread Stefano Garzarella
virtio_transport and vmci_transport handle the buffer_size
sockopts in a very similar way.

In order to support multiple transports, this patch moves this
handling in the core to allow the user to change the options
also if the socket is not yet assigned to any transport.

This patch also adds the '.notify_buffer_size' callback in the
'struct virtio_transport' in order to inform the transport,
when the buffer_size is changed by the user. It is also useful
to limit the 'buffer_size' requested (e.g. virtio transports).

Signed-off-by: Stefano Garzarella 
---
 drivers/vhost/vsock.c   |  7 +-
 include/linux/virtio_vsock.h| 15 +
 include/net/af_vsock.h  | 14 ++--
 net/vmw_vsock/af_vsock.c| 43 ++---
 net/vmw_vsock/hyperv_transport.c| 36 ---
 net/vmw_vsock/virtio_transport.c|  8 +--
 net/vmw_vsock/virtio_transport_common.c | 78 --
 net/vmw_vsock/vmci_transport.c  | 86 +++--
 net/vmw_vsock/vmci_transport.h  |  3 -
 9 files changed, 64 insertions(+), 226 deletions(-)

diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 92ab3852c954..6d7e4f022748 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -418,13 +418,8 @@ static struct virtio_transport vhost_transport = {
.notify_send_pre_block= 
virtio_transport_notify_send_pre_block,
.notify_send_pre_enqueue  = 
virtio_transport_notify_send_pre_enqueue,
.notify_send_post_enqueue = 
virtio_transport_notify_send_post_enqueue,
+   .notify_buffer_size   = virtio_transport_notify_buffer_size,
 
-   .set_buffer_size  = virtio_transport_set_buffer_size,
-   .set_min_buffer_size  = 
virtio_transport_set_min_buffer_size,
-   .set_max_buffer_size  = 
virtio_transport_set_max_buffer_size,
-   .get_buffer_size  = virtio_transport_get_buffer_size,
-   .get_min_buffer_size  = 
virtio_transport_get_min_buffer_size,
-   .get_max_buffer_size  = 
virtio_transport_get_max_buffer_size,
},
 
.send_pkt = vhost_transport_send_pkt,
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 96d8132acbd7..ab02d119fe79 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -7,9 +7,6 @@
 #include 
 #include 
 
-#define VIRTIO_VSOCK_DEFAULT_MIN_BUF_SIZE  128
-#define VIRTIO_VSOCK_DEFAULT_BUF_SIZE  (1024 * 256)
-#define VIRTIO_VSOCK_DEFAULT_MAX_BUF_SIZE  (1024 * 256)
 #define VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE   (1024 * 4)
 #define VIRTIO_VSOCK_MAX_BUF_SIZE  0xUL
 #define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE  (1024 * 64)
@@ -25,11 +22,6 @@ enum {
 struct virtio_vsock_sock {
struct vsock_sock *vsk;
 
-   /* Protected by lock_sock(sk_vsock(trans->vsk)) */
-   u32 buf_size;
-   u32 buf_size_min;
-   u32 buf_size_max;
-
spinlock_t tx_lock;
spinlock_t rx_lock;
 
@@ -93,12 +85,6 @@ s64 virtio_transport_stream_has_space(struct vsock_sock 
*vsk);
 
 int virtio_transport_do_socket_init(struct vsock_sock *vsk,
 struct vsock_sock *psk);
-u64 virtio_transport_get_buffer_size(struct vsock_sock *vsk);
-u64 virtio_transport_get_min_buffer_size(struct vsock_sock *vsk);
-u64 virtio_transport_get_max_buffer_size(struct vsock_sock *vsk);
-void virtio_transport_set_buffer_size(struct vsock_sock *vsk, u64 val);
-void virtio_transport_set_min_buffer_size(struct vsock_sock *vsk, u64 val);
-void virtio_transport_set_max_buffer_size(struct vsock_sock *vs, u64 val);
 int
 virtio_transport_notify_poll_in(struct vsock_sock *vsk,
size_t target,
@@ -125,6 +111,7 @@ int virtio_transport_notify_send_pre_enqueue(struct 
vsock_sock *vsk,
struct vsock_transport_send_notify_data *data);
 int virtio_transport_notify_send_post_enqueue(struct vsock_sock *vsk,
ssize_t written, struct vsock_transport_send_notify_data *data);
+int virtio_transport_notify_buffer_size(struct vsock_sock *vsk, u64 *val);
 
 u64 virtio_transport_stream_rcvhiwat(struct vsock_sock *vsk);
 bool virtio_transport_stream_is_active(struct vsock_sock *vsk);
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index 2ca67d048de4..86f8f463e01a 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -65,6 +65,11 @@ struct vsock_sock {
bool sent_request;
bool ignore_connecting_rst;
 
+   /* Protected by lock_sock(sk) */
+   u64 buffer_size;
+   u64 buffer_min_size;
+   u64 buffer_max_size;
+
/* Private to transport. */
void *trans;
 };
@@ -140,18 +145,11 @@ struct vsock_transport {
struct vsock_transport_send_notify_data *);
int (*notify_send_post_enqueue)(struct vsock_sock *, ssize_t,
struct