[dpdk-dev,v4] vhost: use SMP barriers instead of compiler ones.

Message ID 1458303833-14815-1-git-send-email-i.maximets@samsung.com (mailing list archive)
State Accepted, archived
Delegated to: Thomas Monjalon
Headers

Commit Message

Ilya Maximets March 18, 2016, 12:23 p.m. UTC
  Since commit 4c02e453cc62 ("eal: introduce SMP memory barriers") virtio
uses architecture dependent SMP barriers. vHost should use them too.

Fixes: 4c02e453cc62 ("eal: introduce SMP memory barriers")

Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
---
 lib/librte_vhost/vhost_rxtx.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
  

Comments

Yuanhan Liu March 18, 2016, 12:41 p.m. UTC | #1
On Fri, Mar 18, 2016 at 03:23:53PM +0300, Ilya Maximets wrote:
> Since commit 4c02e453cc62 ("eal: introduce SMP memory barriers") virtio
> uses architecture dependent SMP barriers. vHost should use them too.
> 
> Fixes: 4c02e453cc62 ("eal: introduce SMP memory barriers")
> 
> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
> ---
>  lib/librte_vhost/vhost_rxtx.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
> index b4da665..859c669 100644
> --- a/lib/librte_vhost/vhost_rxtx.c
> +++ b/lib/librte_vhost/vhost_rxtx.c
> @@ -315,7 +315,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
>  			rte_prefetch0(&vq->desc[desc_indexes[i+1]]);
>  	}
>  
> -	rte_compiler_barrier();
> +	rte_smp_wmb();
>  
>  	/* Wait until it's our turn to add our buffer to the used ring. */
>  	while (unlikely(vq->last_used_idx != res_start_idx))
> @@ -565,7 +565,7 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
>  
>  		nr_used = copy_mbuf_to_desc_mergeable(dev, vq, start, end,
>  						      pkts[pkt_idx]);
> -		rte_compiler_barrier();
> +		rte_smp_wmb();
>  
>  		/*
>  		 * Wait until it's our turn to add our buffer
> @@ -923,7 +923,8 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
>  				sizeof(vq->used->ring[used_idx]));
>  	}
>  
> -	rte_compiler_barrier();
> +	rte_smp_wmb();
> +	rte_smp_rmb();

rte_smp_mb?

	--yliu
  
Ilya Maximets March 21, 2016, 4:49 a.m. UTC | #2
On 18.03.2016 15:41, Yuanhan Liu wrote:
> On Fri, Mar 18, 2016 at 03:23:53PM +0300, Ilya Maximets wrote:
>> Since commit 4c02e453cc62 ("eal: introduce SMP memory barriers") virtio
>> uses architecture dependent SMP barriers. vHost should use them too.
>>
>> Fixes: 4c02e453cc62 ("eal: introduce SMP memory barriers")
>>
>> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
>> ---
>>  lib/librte_vhost/vhost_rxtx.c | 7 ++++---
>>  1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
>> index b4da665..859c669 100644
>> --- a/lib/librte_vhost/vhost_rxtx.c
>> +++ b/lib/librte_vhost/vhost_rxtx.c
>> @@ -315,7 +315,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
>>  			rte_prefetch0(&vq->desc[desc_indexes[i+1]]);
>>  	}
>>  
>> -	rte_compiler_barrier();
>> +	rte_smp_wmb();
>>  
>>  	/* Wait until it's our turn to add our buffer to the used ring. */
>>  	while (unlikely(vq->last_used_idx != res_start_idx))
>> @@ -565,7 +565,7 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
>>  
>>  		nr_used = copy_mbuf_to_desc_mergeable(dev, vq, start, end,
>>  						      pkts[pkt_idx]);
>> -		rte_compiler_barrier();
>> +		rte_smp_wmb();
>>  
>>  		/*
>>  		 * Wait until it's our turn to add our buffer
>> @@ -923,7 +923,8 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
>>  				sizeof(vq->used->ring[used_idx]));
>>  	}
>>  
>> -	rte_compiler_barrier();
>> +	rte_smp_wmb();
>> +	rte_smp_rmb();
> 
> rte_smp_mb?

rte_smp_mb() is a real mm_fence() on x86. And we don't need to synchronize reads with
writes here, only reads with reads and writes with writes. It is enough because next
increment uses read and write. Pair of barriers is better because it will not impact
on performance on x86.

Best regards, Ilya Maximets.
  
Ananyev, Konstantin March 21, 2016, 2:07 p.m. UTC | #3
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ilya Maximets
> Sent: Monday, March 21, 2016 4:50 AM
> To: Yuanhan Liu
> Cc: dev@dpdk.org; Xie, Huawei; Dyasly Sergey
> Subject: Re: [dpdk-dev] [PATCH v4] vhost: use SMP barriers instead of compiler ones.
> 
> 
> 
> On 18.03.2016 15:41, Yuanhan Liu wrote:
> > On Fri, Mar 18, 2016 at 03:23:53PM +0300, Ilya Maximets wrote:
> >> Since commit 4c02e453cc62 ("eal: introduce SMP memory barriers") virtio
> >> uses architecture dependent SMP barriers. vHost should use them too.
> >>
> >> Fixes: 4c02e453cc62 ("eal: introduce SMP memory barriers")
> >>
> >> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
> >> ---
> >>  lib/librte_vhost/vhost_rxtx.c | 7 ++++---
> >>  1 file changed, 4 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
> >> index b4da665..859c669 100644
> >> --- a/lib/librte_vhost/vhost_rxtx.c
> >> +++ b/lib/librte_vhost/vhost_rxtx.c
> >> @@ -315,7 +315,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
> >>  			rte_prefetch0(&vq->desc[desc_indexes[i+1]]);
> >>  	}
> >>
> >> -	rte_compiler_barrier();
> >> +	rte_smp_wmb();
> >>
> >>  	/* Wait until it's our turn to add our buffer to the used ring. */
> >>  	while (unlikely(vq->last_used_idx != res_start_idx))
> >> @@ -565,7 +565,7 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
> >>
> >>  		nr_used = copy_mbuf_to_desc_mergeable(dev, vq, start, end,
> >>  						      pkts[pkt_idx]);
> >> -		rte_compiler_barrier();
> >> +		rte_smp_wmb();
> >>
> >>  		/*
> >>  		 * Wait until it's our turn to add our buffer
> >> @@ -923,7 +923,8 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
> >>  				sizeof(vq->used->ring[used_idx]));
> >>  	}
> >>
> >> -	rte_compiler_barrier();
> >> +	rte_smp_wmb();
> >> +	rte_smp_rmb();
> >
> > rte_smp_mb?
> 
> rte_smp_mb() is a real mm_fence() on x86. And we don't need to synchronize reads with
> writes here, only reads with reads and writes with writes. It is enough because next
> increment uses read and write. Pair of barriers is better because it will not impact
> on performance on x86.

Not arguing about that particular patch, just a question:
Why do we have:
#define rte_smp_mb() rte_mb()
for  x86?
Why not just:
#define rte_smp_mb() rte_compiler_barrier()
here?
I meant for situations when we do need real mfence, there is an 'rte_mb' to use.
Konstantin

> 
> Best regards, Ilya Maximets.
  
Huawei Xie March 21, 2016, 5:25 p.m. UTC | #4
On 3/21/2016 10:07 PM, Ananyev, Konstantin wrote:
>
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ilya Maximets
>> Sent: Monday, March 21, 2016 4:50 AM
>> To: Yuanhan Liu
>> Cc: dev@dpdk.org; Xie, Huawei; Dyasly Sergey
>> Subject: Re: [dpdk-dev] [PATCH v4] vhost: use SMP barriers instead of compiler ones.
>>
>>
>>
>> On 18.03.2016 15:41, Yuanhan Liu wrote:
>>> On Fri, Mar 18, 2016 at 03:23:53PM +0300, Ilya Maximets wrote:
>>>> Since commit 4c02e453cc62 ("eal: introduce SMP memory barriers") virtio
>>>> uses architecture dependent SMP barriers. vHost should use them too.
>>>>
>>>> Fixes: 4c02e453cc62 ("eal: introduce SMP memory barriers")
>>>>
>>>> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
>>>> ---
>>>>  lib/librte_vhost/vhost_rxtx.c | 7 ++++---
>>>>  1 file changed, 4 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
>>>> index b4da665..859c669 100644
>>>> --- a/lib/librte_vhost/vhost_rxtx.c
>>>> +++ b/lib/librte_vhost/vhost_rxtx.c
>>>> @@ -315,7 +315,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
>>>>  			rte_prefetch0(&vq->desc[desc_indexes[i+1]]);
>>>>  	}
>>>>
>>>> -	rte_compiler_barrier();
>>>> +	rte_smp_wmb();
>>>>
>>>>  	/* Wait until it's our turn to add our buffer to the used ring. */
>>>>  	while (unlikely(vq->last_used_idx != res_start_idx))
>>>> @@ -565,7 +565,7 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
>>>>
>>>>  		nr_used = copy_mbuf_to_desc_mergeable(dev, vq, start, end,
>>>>  						      pkts[pkt_idx]);
>>>> -		rte_compiler_barrier();
>>>> +		rte_smp_wmb();
>>>>
>>>>  		/*
>>>>  		 * Wait until it's our turn to add our buffer
>>>> @@ -923,7 +923,8 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
>>>>  				sizeof(vq->used->ring[used_idx]));
>>>>  	}
>>>>
>>>> -	rte_compiler_barrier();
>>>> +	rte_smp_wmb();
>>>> +	rte_smp_rmb();
>>> rte_smp_mb?
>> rte_smp_mb() is a real mm_fence() on x86. And we don't need to synchronize reads with
>> writes here, only reads with reads and writes with writes. It is enough because next
>> increment uses read and write. Pair of barriers is better because it will not impact
>> on performance on x86.
> Not arguing about that particular patch, just a question:
> Why do we have:
> #define rte_smp_mb() rte_mb()

Konstantine, actually smp_mb is defined as mfence while smp_r/wmb are
defined as barrier in kernel_src/arch/x86/include/asm/barrier.h.

> for  x86?
> Why not just:
> #define rte_smp_mb() rte_compiler_barrier()
> here?
> I meant for situations when we do need real mfence, there is an 'rte_mb' to use.
> Konstantin
>
>> Best regards, Ilya Maximets.
  
Ananyev, Konstantin March 21, 2016, 5:36 p.m. UTC | #5
> -----Original Message-----
> From: Xie, Huawei
> Sent: Monday, March 21, 2016 5:26 PM
> To: Ananyev, Konstantin; Ilya Maximets; Yuanhan Liu
> Cc: dev@dpdk.org; Dyasly Sergey
> Subject: Re: [dpdk-dev] [PATCH v4] vhost: use SMP barriers instead of compiler ones.
> 
> On 3/21/2016 10:07 PM, Ananyev, Konstantin wrote:
> >
> >> -----Original Message-----
> >> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ilya Maximets
> >> Sent: Monday, March 21, 2016 4:50 AM
> >> To: Yuanhan Liu
> >> Cc: dev@dpdk.org; Xie, Huawei; Dyasly Sergey
> >> Subject: Re: [dpdk-dev] [PATCH v4] vhost: use SMP barriers instead of compiler ones.
> >>
> >>
> >>
> >> On 18.03.2016 15:41, Yuanhan Liu wrote:
> >>> On Fri, Mar 18, 2016 at 03:23:53PM +0300, Ilya Maximets wrote:
> >>>> Since commit 4c02e453cc62 ("eal: introduce SMP memory barriers") virtio
> >>>> uses architecture dependent SMP barriers. vHost should use them too.
> >>>>
> >>>> Fixes: 4c02e453cc62 ("eal: introduce SMP memory barriers")
> >>>>
> >>>> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
> >>>> ---
> >>>>  lib/librte_vhost/vhost_rxtx.c | 7 ++++---
> >>>>  1 file changed, 4 insertions(+), 3 deletions(-)
> >>>>
> >>>> diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
> >>>> index b4da665..859c669 100644
> >>>> --- a/lib/librte_vhost/vhost_rxtx.c
> >>>> +++ b/lib/librte_vhost/vhost_rxtx.c
> >>>> @@ -315,7 +315,7 @@ virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
> >>>>  			rte_prefetch0(&vq->desc[desc_indexes[i+1]]);
> >>>>  	}
> >>>>
> >>>> -	rte_compiler_barrier();
> >>>> +	rte_smp_wmb();
> >>>>
> >>>>  	/* Wait until it's our turn to add our buffer to the used ring. */
> >>>>  	while (unlikely(vq->last_used_idx != res_start_idx))
> >>>> @@ -565,7 +565,7 @@ virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
> >>>>
> >>>>  		nr_used = copy_mbuf_to_desc_mergeable(dev, vq, start, end,
> >>>>  						      pkts[pkt_idx]);
> >>>> -		rte_compiler_barrier();
> >>>> +		rte_smp_wmb();
> >>>>
> >>>>  		/*
> >>>>  		 * Wait until it's our turn to add our buffer
> >>>> @@ -923,7 +923,8 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
> >>>>  				sizeof(vq->used->ring[used_idx]));
> >>>>  	}
> >>>>
> >>>> -	rte_compiler_barrier();
> >>>> +	rte_smp_wmb();
> >>>> +	rte_smp_rmb();
> >>> rte_smp_mb?
> >> rte_smp_mb() is a real mm_fence() on x86. And we don't need to synchronize reads with
> >> writes here, only reads with reads and writes with writes. It is enough because next
> >> increment uses read and write. Pair of barriers is better because it will not impact
> >> on performance on x86.
> > Not arguing about that particular patch, just a question:
> > Why do we have:
> > #define rte_smp_mb() rte_mb()
> 
> Konstantine, actually smp_mb is defined as mfence while smp_r/wmb are
> defined as barrier in kernel_src/arch/x86/include/asm/barrier.h.

I am aware of that, but who said that we should do the same?
Konstantin

> 
> > for  x86?
> > Why not just:
> > #define rte_smp_mb() rte_compiler_barrier()
> > here?
> > I meant for situations when we do need real mfence, there is an 'rte_mb' to use.
> > Konstantin
> >
> >> Best regards, Ilya Maximets.
  
Huawei Xie March 23, 2016, 2:07 p.m. UTC | #6
On 3/18/2016 8:24 PM, Ilya Maximets wrote:
> Since commit 4c02e453cc62 ("eal: introduce SMP memory barriers") virtio
> uses architecture dependent SMP barriers. vHost should use them too.
>
> Fixes: 4c02e453cc62 ("eal: introduce SMP memory barriers")
>
> Signed-off-by: Ilya Maximets <i.maximets@samsung.com>

Acked-by: Huawei Xie <huawei.xie@intel.com>

It fixes the issue for other archs. Will recheck in future.
  
Thomas Monjalon March 31, 2016, 1:46 p.m. UTC | #7
2016-03-23 14:07, Xie, Huawei:
> On 3/18/2016 8:24 PM, Ilya Maximets wrote:
> > Since commit 4c02e453cc62 ("eal: introduce SMP memory barriers") virtio
> > uses architecture dependent SMP barriers. vHost should use them too.
> >
> > Fixes: 4c02e453cc62 ("eal: introduce SMP memory barriers")
> >
> > Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
> 
> Acked-by: Huawei Xie <huawei.xie@intel.com>
> 
> It fixes the issue for other archs. Will recheck in future.

Applied, thanks
  

Patch

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index b4da665..859c669 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -315,7 +315,7 @@  virtio_dev_rx(struct virtio_net *dev, uint16_t queue_id,
 			rte_prefetch0(&vq->desc[desc_indexes[i+1]]);
 	}
 
-	rte_compiler_barrier();
+	rte_smp_wmb();
 
 	/* Wait until it's our turn to add our buffer to the used ring. */
 	while (unlikely(vq->last_used_idx != res_start_idx))
@@ -565,7 +565,7 @@  virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
 
 		nr_used = copy_mbuf_to_desc_mergeable(dev, vq, start, end,
 						      pkts[pkt_idx]);
-		rte_compiler_barrier();
+		rte_smp_wmb();
 
 		/*
 		 * Wait until it's our turn to add our buffer
@@ -923,7 +923,8 @@  rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
 				sizeof(vq->used->ring[used_idx]));
 	}
 
-	rte_compiler_barrier();
+	rte_smp_wmb();
+	rte_smp_rmb();
 	vq->used->idx += i;
 	vhost_log_used_vring(dev, vq, offsetof(struct vring_used, idx),
 			sizeof(vq->used->idx));