Re: About rwnd_press?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 11/18/2015 10:49 AM, g.o.m.o.n.o.v.y.c.h wrote:
> Hello,
> 
> I would like to ask about asoc->rwnd_press in compared to asoc->rwnd.
> 
> sctp_assoc_rwnd_increase has next if case:
> if (asoc->rwnd_press && asoc->rwnd >= asoc->rwnd_press)
> 
> I want ask community opinion about "asoc->rwnd >= asoc->rwnd_press"
> I observed situation when association buffer was empty but "asoc->rwnd
>> = asoc->rwnd_press"
> returned false.
> Next table shows this issue:
> 1. skb_payload = payload + skb; (skb==232)
> 2. If ulp will read all packets from buffer how much asoc->rwnd will be
> rwnd_r      = (sk_rcvbuf / skb_payload) * payload;
> 3. for current payload size and sk_rcvbuf size how big initialization
> value will be for rwnd_press (in sctp_assoc_rwnd_decrease).
> rwnd_press  = sk_rcvbuf/2 - rwnd_r
> On my laptop skb has sizeof(struct sk_buff) == 232 and sk_rcvbuf equal 212992.
> 
> payload     skb_payload         rwnd_r       rwnd_press
> ...
> 16              248             13744           92752
> //asoc->rwnd>=asoc->rwnd_press - false. but buffer empty.
> 17              249             14552           91944
> 18              250             15336           91160
> 19              251             16131           90365
> 20              252             16920           89576
> 21              253             17682           88814
> 22              254             18458           88038
> 23              255             19228           87268
> 24              256             19968           86528
> 25              257             20725           85771
> 26              258             21476           85020
> 27              259             22221           84275
> 28              260             22960           83536
> 29              261             23693           82803
> 30              262             24390           82106
> 31              263             25110           81386
> 32              264             25824           80672
> ...
> 64              296             46080           60416
> 65              297             46670           59826
> 66              298             47190           59306
> 67              299             47771           58725
> 68              300             48280           58216
> 69              301             48852           57644
> 70              302             49420           57076
> 71              303             49913           56583
> 72              304             50472           56024
> 73              305             51027           55469
> 74              306             51578           54918
> 75              307             52050           54446
> 76              308             52592           53904
> 77              309             53130     <     53366
> 78              310             53664     >     52832
> //asoc->rwnd>=asoc->rwnd_press - true
> 79              311             54115     >     52381
> 80              312             54640     >     51856
> 
> Should it ("asoc->rwnd >= asoc->rwnd_press") stay false even when buffer empty?

I've been thinking about this and yes, it looks like we have an issue.
What you are describing is a condition where our receive buffer fills
up considerably faster then the receive window (due to small data size).
As a result, we might arrive at a situation, where we mark that our window
is under pressure the current available window is larger then consumed.
As a result, when we try to release consumed space, we never fully restore
it.

There is actually another problem with this code.  Simply allowing the
receive to consume all the data will never completely relieve the pressure
condition.

> 
> I tested on my laptop next solution:
> 
> --- a/net/sctp/associola.c    2015-08-15 19:07:16.527696361 +0200
> +++ b/net/sctp/associola.c    2015-08-15 20:08:22.407812656 +0200
> @@ -1458,10 +1458,18 @@ void sctp_assoc_rwnd_increase(struct sct
>       * threshold.  The idea is to recover slowly, but up
>       * to the initial advertised window.
>       */
> -    if (asoc->rwnd_press && asoc->rwnd >= asoc->rwnd_press) {
> -        int change = min(asoc->pathmtu, asoc->rwnd_press);
> -        asoc->rwnd += change;
> -        asoc->rwnd_press -= change;
> +    if (asoc->rwnd_press) {
> +        int fr_count = asoc->base.sk->sk_rcvbuf;
> +        if (asoc->ep->rcvbuf_policy)
> +            fr_count -= atomic_read(&asoc->rmem_alloc);
> +        else
> +            fr_count -= atomic_read(&asoc->base.sk->sk_rmem_alloc);
> +
> +        if (fr_count > 0 && ((fr_count >> 1) >= asoc->rwnd_press)) {

I am trying to understand this solution...  You are computing the 'free count'
here by looking at the current value of allocated memory.  However, since the skb
hasn't been freed yet, the allocated memory amount hasn't changed yet.

So, in effect, (sk_recvbuf - rmem_alloc) >> 1 should be the same as asoc->rwnd
at the time we are trying to increase rwnd.

The above section can be effectively simplified to:
	int old_rwnd = asoc->rwnd;

	... rwnd_over code...

	if (asoc->rwnd_press && old_rwnd && old_rwnd >= asoc->rwnd_press) {


This still doesn't address all the problems.  The correct way to address this
issue is to tie the window to free buffer space.  This was attempted before
and had a very bad performance impact.  At the time we reverted the change,
but the work got dropped.

My wish is for someone to pick that code up and figure out what went wrong.

-vlad

> +            int change = min(asoc->pathmtu, asoc->rwnd_press);
> +            asoc->rwnd += change;
> +            asoc->rwnd_press -= change;
> +        }
>      }
> 
>      pr_debug("%s: asoc:%p rwnd increased by %d to (%u, %u) - %u\n",
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Networking Development]     [Linux OMAP]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux