Hello,
On Sun, May 08, 2022 at 07:31:46PM +0200, Alexandr Nedvedicky wrote:
> 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.
> 

    I was perhaps too fast in my judgement. I think we should also
    look more closely at rw_do_exit(): 

335 /* membar_exit_before_atomic() has to precede call of this function. */
336 void
337 rw_do_exit(struct rwlock *rwl, unsigned long wrlock)
338 {
339         unsigned long owner, set;
340
341         do {
342                 owner = rwl->rwl_owner;
343                 if (wrlock)
344                         set = 0;
345                 else
346                         set = (owner - RWLOCK_READ_INCR) &
347                                 ~(RWLOCK_WAIT|RWLOCK_WRWANT);
348         } while (__predict_false(rw_cas(&rwl->rwl_owner, owner, set)));
349
350         if (owner & RWLOCK_WAIT)
351                 wakeup(rwl);
352

    my question is why do we reset RWLOCK_WAIT and RWLOCK_WRWANT flags?
    I think those flags should be reset the last reader gone. Perhaps
    the else branch for reader requires this:

        else {
                set = (owner - RWLOCK_READ_INCR) &
                    ~(RWLOCK_WAIT|RWLOCK_WRWANT)
                if (set != 0)
                        set |= (owner & RWLOCK_MASK);
        }


thanks and
regards
sashan

Reply via email to