Hello,

On Fri, May 06, 2022 at 09:50:30PM +0200, Alexander Bluhm wrote:
> Hi,
> 
> When creating network load by forwarding packets, SSH gets unusable
> and ping time gets above 10 seconds.
> 
> Problem is that while multiple forwarding threads are running with
> shared net lock, the exclusive lock cannot be acquired.  This is
> unfair.
> 
> Diff below prevents that a read lock is granted when another thread
> is waiting for the exclusive lock.  With that ping time stays under
> 300 ms.
> 
> Does this read write lock prio change make sense?

    I can confirm this diff helps. And if I understand things right,
    then we basically let all readers to take a slow path via a sleep,
    if there is a writer waiting (think of like putting readers
    behind the waiting writer in queue).

    I was afraid the change can trade writer starvation for reader
    starvation. However I think it is not the case after seeing 
    rw_do_exit(), where we zero out lock after writer does rw_exit().
    this basically gives equal chance to all readers/writers to acquire
    the lock.

not my department, however I would say change looks good to me.

OK sashan@ (given my OK counts in this area)


> 
> bluhm
> 
> Index: kern/kern_rwlock.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/kern/kern_rwlock.c,v
> retrieving revision 1.47
> diff -u -p -r1.47 kern_rwlock.c
> --- kern/kern_rwlock.c        8 Feb 2021 08:18:45 -0000       1.47
> +++ kern/kern_rwlock.c        6 May 2022 12:08:01 -0000
> @@ -81,7 +81,7 @@ static const struct rwlock_op {
>       },
>       {       /* RW_READ */
>               RWLOCK_READ_INCR,
> -             RWLOCK_WRLOCK,
> +             RWLOCK_WRLOCK | RWLOCK_WRWANT,
>               RWLOCK_WAIT,
>               0,
>               PLOCK
> @@ -103,7 +103,7 @@ rw_enter_read(struct rwlock *rwl)
>  {
>       unsigned long owner = rwl->rwl_owner;
>  
> -     if (__predict_false((owner & RWLOCK_WRLOCK) ||
> +     if (__predict_false((owner & (RWLOCK_WRLOCK | RWLOCK_WRWANT)) ||
>           rw_cas(&rwl->rwl_owner, owner, owner + RWLOCK_READ_INCR)))
>               rw_enter(rwl, RW_READ);
>       else {
> 

Reply via email to