On 6/30/23 08:40, Eelco Chaudron wrote:
> 
> 
> On 29 Jun 2023, at 17:54, Ilya Maximets wrote:
> 
>> On 6/29/23 17:43, Eelco Chaudron wrote:
>>>
>>>
>>> On 22 Jun 2023, at 0:32, Ilya Maximets wrote:
>>>
>>>> Current implementation of meters in the userspace datapath takes
>>>> the meter lock for every packet batch.  If more than one thread
>>>> hits the flow with the same meter, they will lock each other.
>>>>
>>>> Replace the critical section with atomic operations to avoid
>>>> interlocking.  Meters themselves are RCU-protected, so it's safe
>>>> to access them without holding a lock.
>>>>
>>>> Implementation does the following:
>>>>
>>>>  1. Tries to advance the 'used' timer of the meter with atomic
>>>>     compare+exchange if it's smaller than 'now'.
>>>>  2. If the timer change succeeds, atomically update band buckets.
>>>>  3. Atomically update packet statistics for a meter.
>>>>  4. Go over buckets and try to atomically subtract the amount of
>>>>     packets or bytes, recording the highest exceeded band.
>>>>  5. Atomically update band statistics and drop packets.
>>>>
>>>> Bucket manipulations are implemented with atomic compare+exchange
>>>> operations with extra checks, because bucket size should never
>>>> exceed the maximum and it should never go below zero.
>>>>
>>>> Packet statistics may be momentarily inconsistent, i.e., number
>>>> of packets and the number of bytes may reflect different sets
>>>> of packets.  But it should be eventually consistent.  And the
>>>> difference at any given time should be in just few packets.
>>>>
>>>> For the sake of reduced code complexity PKTPS meter tries to push
>>>> packets through the band one by one, even though they all have
>>>> the same weight.  This is also more fair if more than one thread
>>>> is passing packets through the same band at the same time.
>>>> Trying to predict the number of packets that can pass may also
>>>> cause extra atomic operations reducing the performance.
>>>>
>>>> This implementation shows similar performance to the previous one,
>>>> but should scale better with more threads hiting the same meter.
>>>
>>> This works looks great!! Some small comments below. Did limited testing and 
>>> seems to work fine.
>>>
>>> Cheers,
>>>
>>> Eelco
>>>
>>>> Signed-off-by: Ilya Maximets <[email protected]>
>>>> ---
>>>>
>>>> @Lin Huang, if you can try this change on your setup, that
>>>> would be great.
>>>>
>>>>  NEWS              |   2 +
>>>>  lib/dpif-netdev.c | 250 +++++++++++++++++++++++++---------------------
>>>>  2 files changed, 140 insertions(+), 112 deletions(-)
>>>>

...

>>>
>>>> +
>>>>      size_t j;
>>>>      DP_PACKET_BATCH_REFILL_FOR_EACH (j, cnt, packet, packets_) {
>>>> -        if (exceeded_band[j] >= 0) {
>>>> +        uint32_t m = exceeded_band[j];
>>>> +
>>>> +        if (m != UINT32_MAX) {
>>>>              /* Meter drop packet. */
>>>> -            band = &meter->bands[exceeded_band[j]];
>>>> -            band->packet_count += 1;
>>>> -            band->byte_count += dp_packet_size(packet);
>>>> -            COVERAGE_INC(datapath_drop_meter);
>>>> +            band = &meter->bands[m];
>>>> +            band_packets[m]++;
>>>> +            band_bytes[m] += dp_packet_size(packet);
>>>
>>>
>>> This code now looks like this (the diff is a mess to comment on):
>>>
>>>         if (m != UINT32_MAX) {
>>>             /* Meter drop packet. */
>>>             band = &meter->bands[m];
>>>
>>> !           ^^^ This line can be removed as band is not used.
>>
>> True.  Can remove.
> 
> Thanks, now I see that even shows up with clang-analyze.
> 
> I guess this is the only real change needed. So if you roll it in during 
> commit time:
> 
> Acked-by: Eelco Chaudron <[email protected]>

Thanks Simon and Eelco for review!  And thanks Lin and Zhang for testing!

I removed the unused assignment and applied the change.

Best regards, Ilya Maximets.
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to