To allow canceling all packets of a connection. Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com> Signed-off-by: Peng Tao <bergwolf at gmail.com> --- drivers/vhost/vsock.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/net/af_vsock.h | 3 +++ 2 files changed, 44 insertions(+) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index a504e2e0..db64d51 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -218,6 +218,46 @@ vhost_transport_send_pkt(struct virtio_vsock_pkt *pkt) return len; } +static int +vhost_transport_cancel_pkt(struct vsock_sock *vsk) +{ + struct vhost_vsock *vsock; + struct virtio_vsock_pkt *pkt, *n; + int cnt = 0; + LIST_HEAD(freeme); + + /* Find the vhost_vsock according to guest context id */ + vsock = vhost_vsock_get(vsk->remote_addr.svm_cid); + if (!vsock) + return -ENODEV; + + spin_lock_bh(&vsock->send_pkt_list_lock); + list_for_each_entry_safe(pkt, n, &vsock->send_pkt_list, list) { + if (pkt->cancel_token != (void *)vsk) + continue; + list_move(&pkt->list, &freeme); + } + spin_unlock_bh(&vsock->send_pkt_list_lock); + + list_for_each_entry_safe(pkt, n, &freeme, list) { + if (pkt->reply) + cnt++; + list_del(&pkt->list); + virtio_transport_free_pkt(pkt); + } + + if (cnt) { + struct vhost_virtqueue *tx_vq = &vsock->vqs[VSOCK_VQ_TX]; + int new_cnt; + + new_cnt = atomic_sub_return(cnt, &vsock->queued_replies); + if (new_cnt + cnt >= tx_vq->num && new_cnt < tx_vq->num) + vhost_poll_queue(&tx_vq->poll); + } + + return 0; +} + static struct virtio_vsock_pkt * vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq, unsigned int out, unsigned int in) @@ -664,6 +704,7 @@ static struct virtio_transport vhost_transport = { .release = virtio_transport_release, .connect = virtio_transport_connect, .shutdown = virtio_transport_shutdown, + .cancel_pkt = vhost_transport_cancel_pkt, .dgram_enqueue = virtio_transport_dgram_enqueue, .dgram_dequeue = virtio_transport_dgram_dequeue, diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index f275896..ce5f100 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h @@ -100,6 +100,9 @@ struct vsock_transport { void (*destruct)(struct vsock_sock *); void (*release)(struct vsock_sock *); + /* Cancel packets belonging the same vsock */ + int (*cancel_pkt)(struct vsock_sock *vsk); + /* Connections. */ int (*connect)(struct vsock_sock *); -- 2.7.4
Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com> Signed-off-by: Peng Tao <bergwolf at gmail.com> --- net/vmw_vsock/virtio_transport.c | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c index 936d7ee..95c1162 100644 --- a/net/vmw_vsock/virtio_transport.c +++ b/net/vmw_vsock/virtio_transport.c @@ -170,6 +170,47 @@ virtio_transport_send_pkt(struct virtio_vsock_pkt *pkt) return len; } +static int +virtio_transport_cancel_pkt(struct vsock_sock *vsk) +{ + struct virtio_vsock *vsock; + struct virtio_vsock_pkt *pkt, *n; + int cnt = 0; + LIST_HEAD(freeme); + + vsock = virtio_vsock_get(); + if (!vsock) { + return -ENODEV; + } + + spin_lock_bh(&vsock->send_pkt_list_lock); + list_for_each_entry_safe(pkt, n, &vsock->send_pkt_list, list) { + if (pkt->cancel_token != (void *)vsk) + continue; + list_move(&pkt->list, &freeme); + } + spin_unlock_bh(&vsock->send_pkt_list_lock); + + list_for_each_entry_safe(pkt, n, &freeme, list) { + if (pkt->reply) + cnt++; + list_del(&pkt->list); + virtio_transport_free_pkt(pkt); + } + + if (cnt) { + struct virtqueue *rx_vq = vsock->vqs[VSOCK_VQ_RX]; + int new_cnt; + + new_cnt = atomic_sub_return(cnt, &vsock->queued_replies); + if (new_cnt + cnt >= virtqueue_get_vring_size(rx_vq) && + new_cnt < virtqueue_get_vring_size(rx_vq)) + queue_work(virtio_vsock_workqueue, &vsock->rx_work); + } + + return 0; +} + static void virtio_vsock_rx_fill(struct virtio_vsock *vsock) { int buf_len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE; @@ -419,6 +460,7 @@ static struct virtio_transport virtio_transport = { .release = virtio_transport_release, .connect = virtio_transport_connect, .shutdown = virtio_transport_shutdown, + .cancel_pkt = virtio_transport_cancel_pkt, .dgram_bind = virtio_transport_dgram_bind, .dgram_dequeue = virtio_transport_dgram_dequeue, -- 2.7.4
Peng Tao
2016-Dec-08 17:12 UTC
[PATCH v3 4/4] vsock: cancel packets when failing to connect
Otherwise we'll leave the packets queued until releasing vsock device. E.g., if guest is slow to start up, resulting ETIMEDOUT on connect, guest will get the connect requests from failed host sockets. Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com> Signed-off-by: Peng Tao <bergwolf at gmail.com> --- net/vmw_vsock/af_vsock.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 8a398b3..c73b03a 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1101,10 +1101,19 @@ static const struct proto_ops vsock_dgram_ops = { .sendpage = sock_no_sendpage, }; +static int vsock_transport_cancel_pkt(struct vsock_sock *vsk) +{ + if (!transport->cancel_pkt) + return -EOPNOTSUPP; + + return transport->cancel_pkt(vsk); +} + static void vsock_connect_timeout(struct work_struct *work) { struct sock *sk; struct vsock_sock *vsk; + int cancel = 0; vsk = container_of(work, struct vsock_sock, dwork.work); sk = sk_vsock(vsk); @@ -1115,8 +1124,11 @@ static void vsock_connect_timeout(struct work_struct *work) sk->sk_state = SS_UNCONNECTED; sk->sk_err = ETIMEDOUT; sk->sk_error_report(sk); + cancel = 1; } release_sock(sk); + if (cancel) + vsock_transport_cancel_pkt(vsk); sock_put(sk); } @@ -1223,11 +1235,13 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr, err = sock_intr_errno(timeout); sk->sk_state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED; + vsock_transport_cancel_pkt(vsk); goto out_wait; } else if (timeout == 0) { err = -ETIMEDOUT; sk->sk_state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED; + vsock_transport_cancel_pkt(vsk); goto out_wait; } -- 2.7.4
Stefan Hajnoczi
2016-Dec-09 10:15 UTC
[PATCH v3 2/4] vhost-vsock: add pkt cancel capability
On Fri, Dec 09, 2016 at 01:12:34AM +0800, Peng Tao wrote:> To allow canceling all packets of a connection. > > Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com> > Signed-off-by: Peng Tao <bergwolf at gmail.com> > --- > drivers/vhost/vsock.c | 41 +++++++++++++++++++++++++++++++++++++++++ > include/net/af_vsock.h | 3 +++ > 2 files changed, 44 insertions(+) > > diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c > index a504e2e0..db64d51 100644 > --- a/drivers/vhost/vsock.c > +++ b/drivers/vhost/vsock.c > @@ -218,6 +218,46 @@ vhost_transport_send_pkt(struct virtio_vsock_pkt *pkt) > return len; > } > > +static int > +vhost_transport_cancel_pkt(struct vsock_sock *vsk) > +{ > + struct vhost_vsock *vsock; > + struct virtio_vsock_pkt *pkt, *n; > + int cnt = 0; > + LIST_HEAD(freeme); > + > + /* Find the vhost_vsock according to guest context id */ > + vsock = vhost_vsock_get(vsk->remote_addr.svm_cid); > + if (!vsock) > + return -ENODEV; > + > + spin_lock_bh(&vsock->send_pkt_list_lock); > + list_for_each_entry_safe(pkt, n, &vsock->send_pkt_list, list) { > + if (pkt->cancel_token != (void *)vsk)It's not necessary to cast to void* in C. All pointers cast to void* automatically without compiler warnings. The warnings and explicit casts are a C++ thing. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 455 bytes Desc: not available URL: <http://lists.linuxfoundation.org/pipermail/virtualization/attachments/20161209/5ae4a01d/attachment-0001.sig>
On Fri, Dec 09, 2016 at 01:12:35AM +0800, Peng Tao wrote:> Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com> > Signed-off-by: Peng Tao <bergwolf at gmail.com> > --- > net/vmw_vsock/virtio_transport.c | 42 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > > diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c > index 936d7ee..95c1162 100644 > --- a/net/vmw_vsock/virtio_transport.c > +++ b/net/vmw_vsock/virtio_transport.c > @@ -170,6 +170,47 @@ virtio_transport_send_pkt(struct virtio_vsock_pkt *pkt) > return len; > } > > +static int > +virtio_transport_cancel_pkt(struct vsock_sock *vsk) > +{ > + struct virtio_vsock *vsock; > + struct virtio_vsock_pkt *pkt, *n; > + int cnt = 0; > + LIST_HEAD(freeme); > + > + vsock = virtio_vsock_get(); > + if (!vsock) { > + return -ENODEV; > + } > + > + spin_lock_bh(&vsock->send_pkt_list_lock); > + list_for_each_entry_safe(pkt, n, &vsock->send_pkt_list, list) { > + if (pkt->cancel_token != (void *)vsk)The cast is unnecessary here. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 455 bytes Desc: not available URL: <http://lists.linuxfoundation.org/pipermail/virtualization/attachments/20161209/c074c031/attachment.sig>
Jorgen S. Hansen
2016-Dec-12 10:37 UTC
[PATCH v3 2/4] vhost-vsock: add pkt cancel capability
> On Dec 8, 2016, at 6:12 PM, Peng Tao <bergwolf at gmail.com> wrote: > > --- a/include/net/af_vsock.h > +++ b/include/net/af_vsock.h > @@ -100,6 +100,9 @@ struct vsock_transport { > void (*destruct)(struct vsock_sock *); > void (*release)(struct vsock_sock *); > > + /* Cancel packets belonging the same vsock */How about ?/* Cancel all pending packets sent on vsock. */? ?> + int (*cancel_pkt)(struct vsock_sock *vsk); > + > /* Connections. */ > int (*connect)(struct vsock_sock *); > > -- > 2.7.4 >Thanks, J?rgen
On Mon, Dec 12, 2016 at 6:37 PM, Jorgen S. Hansen <jhansen at vmware.com> wrote:> >> On Dec 8, 2016, at 6:12 PM, Peng Tao <bergwolf at gmail.com> wrote: >> >> --- a/include/net/af_vsock.h >> +++ b/include/net/af_vsock.h >> @@ -100,6 +100,9 @@ struct vsock_transport { >> void (*destruct)(struct vsock_sock *); >> void (*release)(struct vsock_sock *); >> >> + /* Cancel packets belonging the same vsock */ > > How about ?/* Cancel all pending packets sent on vsock. */? ? >Sure. I'll update it. Thanks, Tao
Possibly Parallel Threads
- [PATCH v3 4/4] vsock: cancel packets when failing to connect
- [PATCH v4 2/4] vhost-vsock: add pkt cancel capability
- [PATCH v4 2/4] vhost-vsock: add pkt cancel capability
- [PATCH v3 2/4] vhost-vsock: add pkt cancel capability
- [PATCH v3 2/4] vhost-vsock: add pkt cancel capability