diff mbox

[net-next,8/8] vhost_net: use lockless peeking for skb array during busy polling

Message ID 1490069087-4783-9-git-send-email-jasowang@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jason Wang March 21, 2017, 4:04 a.m. UTC
For the socket that exports its skb array, we can use lockless polling
to avoid touching spinlock during busy polling.

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 drivers/vhost/net.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

Comments

Michael S. Tsirkin March 29, 2017, 12:07 p.m. UTC | #1
On Tue, Mar 21, 2017 at 12:04:47PM +0800, Jason Wang wrote:
> For the socket that exports its skb array, we can use lockless polling
> to avoid touching spinlock during busy polling.
> 
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
>  drivers/vhost/net.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index 53f09f2..41153a3 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -551,10 +551,13 @@ static int peek_head_len(struct vhost_net_virtqueue *rvq, struct sock *sk)
>  	return len;
>  }
>  
> -static int sk_has_rx_data(struct sock *sk)
> +static int sk_has_rx_data(struct vhost_net_virtqueue *rvq, struct sock *sk)
>  {
>  	struct socket *sock = sk->sk_socket;
>  
> +	if (rvq->rx_array)
> +		return !__skb_array_empty(rvq->rx_array);
> +
>  	if (sock->ops->peek_len)
>  		return sock->ops->peek_len(sock);
>  

I don't see which patch adds __skb_array_empty.

> @@ -579,7 +582,7 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net,
>  		endtime = busy_clock() + vq->busyloop_timeout;
>  
>  		while (vhost_can_busy_poll(&net->dev, endtime) &&
> -		       !sk_has_rx_data(sk) &&
> +		       !sk_has_rx_data(rvq, sk) &&
>  		       vhost_vq_avail_empty(&net->dev, vq))
>  			cpu_relax();
>  
> -- 
> 2.7.4
Jason Wang March 30, 2017, 2:16 a.m. UTC | #2
On 2017年03月29日 20:07, Michael S. Tsirkin wrote:
> On Tue, Mar 21, 2017 at 12:04:47PM +0800, Jason Wang wrote:
>> For the socket that exports its skb array, we can use lockless polling
>> to avoid touching spinlock during busy polling.
>>
>> Signed-off-by: Jason Wang <jasowang@redhat.com>
>> ---
>>   drivers/vhost/net.c | 7 +++++--
>>   1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
>> index 53f09f2..41153a3 100644
>> --- a/drivers/vhost/net.c
>> +++ b/drivers/vhost/net.c
>> @@ -551,10 +551,13 @@ static int peek_head_len(struct vhost_net_virtqueue *rvq, struct sock *sk)
>>   	return len;
>>   }
>>   
>> -static int sk_has_rx_data(struct sock *sk)
>> +static int sk_has_rx_data(struct vhost_net_virtqueue *rvq, struct sock *sk)
>>   {
>>   	struct socket *sock = sk->sk_socket;
>>   
>> +	if (rvq->rx_array)
>> +		return !__skb_array_empty(rvq->rx_array);
>> +
>>   	if (sock->ops->peek_len)
>>   		return sock->ops->peek_len(sock);
>>   
> I don't see which patch adds __skb_array_empty.

This is not something new, it was introduced by ad69f35d1dc0a 
("skb_array: array based FIFO for skbs").

Thanks

>
>> @@ -579,7 +582,7 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net,
>>   		endtime = busy_clock() + vq->busyloop_timeout;
>>   
>>   		while (vhost_can_busy_poll(&net->dev, endtime) &&
>> -		       !sk_has_rx_data(sk) &&
>> +		       !sk_has_rx_data(rvq, sk) &&
>>   		       vhost_vq_avail_empty(&net->dev, vq))
>>   			cpu_relax();
>>   
>> -- 
>> 2.7.4
Michael S. Tsirkin March 30, 2017, 2:33 a.m. UTC | #3
On Thu, Mar 30, 2017 at 10:16:15AM +0800, Jason Wang wrote:
> 
> 
> On 2017年03月29日 20:07, Michael S. Tsirkin wrote:
> > On Tue, Mar 21, 2017 at 12:04:47PM +0800, Jason Wang wrote:
> > > For the socket that exports its skb array, we can use lockless polling
> > > to avoid touching spinlock during busy polling.
> > > 
> > > Signed-off-by: Jason Wang <jasowang@redhat.com>
> > > ---
> > >   drivers/vhost/net.c | 7 +++++--
> > >   1 file changed, 5 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> > > index 53f09f2..41153a3 100644
> > > --- a/drivers/vhost/net.c
> > > +++ b/drivers/vhost/net.c
> > > @@ -551,10 +551,13 @@ static int peek_head_len(struct vhost_net_virtqueue *rvq, struct sock *sk)
> > >   	return len;
> > >   }
> > > -static int sk_has_rx_data(struct sock *sk)
> > > +static int sk_has_rx_data(struct vhost_net_virtqueue *rvq, struct sock *sk)
> > >   {
> > >   	struct socket *sock = sk->sk_socket;
> > > +	if (rvq->rx_array)
> > > +		return !__skb_array_empty(rvq->rx_array);
> > > +
> > >   	if (sock->ops->peek_len)
> > >   		return sock->ops->peek_len(sock);
> > I don't see which patch adds __skb_array_empty.
> 
> This is not something new, it was introduced by ad69f35d1dc0a ("skb_array:
> array based FIFO for skbs").
> 
> Thanks

Same comment about a compiler barrier applies then.

> > 
> > > @@ -579,7 +582,7 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net,
> > >   		endtime = busy_clock() + vq->busyloop_timeout;
> > >   		while (vhost_can_busy_poll(&net->dev, endtime) &&
> > > -		       !sk_has_rx_data(sk) &&
> > > +		       !sk_has_rx_data(rvq, sk) &&
> > >   		       vhost_vq_avail_empty(&net->dev, vq))
> > >   			cpu_relax();
> > > -- 
> > > 2.7.4
Jason Wang March 30, 2017, 3:53 a.m. UTC | #4
On 2017年03月30日 10:33, Michael S. Tsirkin wrote:
> On Thu, Mar 30, 2017 at 10:16:15AM +0800, Jason Wang wrote:
>>
>> On 2017年03月29日 20:07, Michael S. Tsirkin wrote:
>>> On Tue, Mar 21, 2017 at 12:04:47PM +0800, Jason Wang wrote:
>>>> For the socket that exports its skb array, we can use lockless polling
>>>> to avoid touching spinlock during busy polling.
>>>>
>>>> Signed-off-by: Jason Wang <jasowang@redhat.com>
>>>> ---
>>>>    drivers/vhost/net.c | 7 +++++--
>>>>    1 file changed, 5 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
>>>> index 53f09f2..41153a3 100644
>>>> --- a/drivers/vhost/net.c
>>>> +++ b/drivers/vhost/net.c
>>>> @@ -551,10 +551,13 @@ static int peek_head_len(struct vhost_net_virtqueue *rvq, struct sock *sk)
>>>>    	return len;
>>>>    }
>>>> -static int sk_has_rx_data(struct sock *sk)
>>>> +static int sk_has_rx_data(struct vhost_net_virtqueue *rvq, struct sock *sk)
>>>>    {
>>>>    	struct socket *sock = sk->sk_socket;
>>>> +	if (rvq->rx_array)
>>>> +		return !__skb_array_empty(rvq->rx_array);
>>>> +
>>>>    	if (sock->ops->peek_len)
>>>>    		return sock->ops->peek_len(sock);
>>> I don't see which patch adds __skb_array_empty.
>> This is not something new, it was introduced by ad69f35d1dc0a ("skb_array:
>> array based FIFO for skbs").
>>
>> Thanks
> Same comment about a compiler barrier applies then.

Ok, rethink about this, since skb_array could be resized, using lockless 
version seems wrong.

For the comment of using compiler barrier, caller 
(vhost_net_rx_peek_head_len) uses cpu_relax(). But I haven't figured out 
why a compiler barrier is needed here. Could you please explain?

Thanks

>
>>>> @@ -579,7 +582,7 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net,
>>>>    		endtime = busy_clock() + vq->busyloop_timeout;
>>>>    		while (vhost_can_busy_poll(&net->dev, endtime) &&
>>>> -		       !sk_has_rx_data(sk) &&
>>>> +		       !sk_has_rx_data(rvq, sk) &&
>>>>    		       vhost_vq_avail_empty(&net->dev, vq))
>>>>    			cpu_relax();
>>>> -- 
>>>> 2.7.4
diff mbox

Patch

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 53f09f2..41153a3 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -551,10 +551,13 @@  static int peek_head_len(struct vhost_net_virtqueue *rvq, struct sock *sk)
 	return len;
 }
 
-static int sk_has_rx_data(struct sock *sk)
+static int sk_has_rx_data(struct vhost_net_virtqueue *rvq, struct sock *sk)
 {
 	struct socket *sock = sk->sk_socket;
 
+	if (rvq->rx_array)
+		return !__skb_array_empty(rvq->rx_array);
+
 	if (sock->ops->peek_len)
 		return sock->ops->peek_len(sock);
 
@@ -579,7 +582,7 @@  static int vhost_net_rx_peek_head_len(struct vhost_net *net,
 		endtime = busy_clock() + vq->busyloop_timeout;
 
 		while (vhost_can_busy_poll(&net->dev, endtime) &&
-		       !sk_has_rx_data(sk) &&
+		       !sk_has_rx_data(rvq, sk) &&
 		       vhost_vq_avail_empty(&net->dev, vq))
 			cpu_relax();