OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

virtio-dev message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: Re: [PATCH v4 3/6] virtio/vhost-vsock: avoid potential deadlock


On Thu, Mar 31, 2016 at 01:41:35PM +0200, Claudio Imbrenda wrote:
> In some circumstances, like when a RESET packet needs to be sent back,
> both the send and receive locks are held. This makes lockdep unhappy,
> because both locks belong to the same class. In general it is not a good
> idea to hold both the send and receive locks at the same time; this patch
> introduces a reset queue, serviced by the default workqueue. This
> guarantees that the reset packets are sent back with only one lock being
> held, which makes lockdep happy.
> 
> Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
> ---
>  net/vmw_vsock/virtio_transport_common.c | 98 +++++++++++++++++++++++++++++++--
>  1 file changed, 93 insertions(+), 5 deletions(-)
> 
> diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
> index eab1644..fa54359 100644
> --- a/net/vmw_vsock/virtio_transport_common.c
> +++ b/net/vmw_vsock/virtio_transport_common.c
> @@ -8,6 +8,7 @@
>   * This work is licensed under the terms of the GNU GPL, version 2.
>   */
>  #include <linux/spinlock.h>
> +#include <linux/workqueue.h>
>  #include <linux/module.h>
>  #include <linux/ctype.h>
>  #include <linux/list.h>
> @@ -22,6 +23,27 @@
>  #define CREATE_TRACE_POINTS
>  #include <trace/events/vsock_virtio_transport_common.h>
>  
> +enum {
> +	VSOCK_RESET_NOSOCK = 0,
> +	VSOCK_RESET_WITHSOCK,
> +};
> +
> +struct reset_queue {
> +	struct list_head list;
> +	union {
> +		struct virtio_vsock_pkt *pkt;
> +		struct vsock_sock *vsk;
> +	} u;
> +	char type;
> +};
> +
> +static void virtio_transport_send_reset_work(struct work_struct *unused);
> +
> +static DEFINE_SPINLOCK(resetqueue_lock);
> +static LIST_HEAD(queued_resets);
> +static DECLARE_WORK(virtio_transport_resets_wq,
> +			virtio_transport_send_reset_work);
> +
>  static const struct virtio_transport *virtio_transport_get_ops(void)
>  {
>  	const struct vsock_transport *t = vsock_core_get_transport();
> @@ -544,19 +566,61 @@ void virtio_transport_destruct(struct vsock_sock *vsk)
>  }
>  EXPORT_SYMBOL_GPL(virtio_transport_destruct);
>  
> -static int virtio_transport_send_reset(struct vsock_sock *vsk,
> -				       struct virtio_vsock_pkt *pkt)
> +static void virtio_transport_send_reset_work(struct work_struct *unused)
>  {
> +	struct reset_queue *q;
>  	struct virtio_vsock_pkt_info info = {
>  		.op = VIRTIO_VSOCK_OP_RST,
>  		.type = VIRTIO_VSOCK_TYPE_STREAM,
>  	};
>  
> +	spin_lock(&resetqueue_lock);
> +	while (!list_empty(&queued_resets)) {
> +		q = list_first_entry(&queued_resets, struct reset_queue, list);
> +		list_del(&q->list);
> +		spin_unlock(&resetqueue_lock);
> +
> +		/* Since we are now asynchronous, we ignore the return values.
> +		 * After all we don't even know who we should report them to.

I'm a little concerned about adding kmalloc and ignoring return values
because virtio-vsock packets must never be lost.  Unlike TCP there is no
retransmission so the transport must be reliable.

Attachment: signature.asc
Description: PGP signature



[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]