On (25/02/24 09:59), Sebastian Andrzej Siewior wrote: > > +/* > > + * The zspage lock can be held from atomic contexts, but it needs to remain > > + * preemptible when held for reading because it remains held outside of those > > + * atomic contexts, otherwise we unnecessarily lose preemptibility. > > + * > > + * To achieve this, the following rules are enforced on readers and writers: > > + * > > + * - Writers are blocked by both writers and readers, while readers are only > > + * blocked by writers (i.e. normal rwlock semantics). > > + * > > + * - Writers are always atomic (to allow readers to spin waiting for them). > > + * > > + * - Writers always use trylock (as the lock may be held be sleeping readers). > > + * > > + * - Readers may spin on the lock (as they can only wait for atomic writers). > > + * > > + * - Readers may sleep while holding the lock (as writes only use trylock). > > + */ > > +static void zspage_read_lock(struct zspage *zspage) > > +{ > > + struct zspage_lock *zsl = &zspage->zsl; > > + > > + rwsem_acquire_read(zsl_dep_map(zsl), 0, 0, _RET_IP_); > > + > > + spin_lock(&zsl->lock); > > + zsl->cnt++; > > + spin_unlock(&zsl->lock); > > How is this working given that a read_lock always increments the > counter? If it is write_locked then a read_lock makes it UNLOCKED. If zspage is write-locked then zsl->lock is also locked, because write-lock returns with zsl->lock acquired and releases it in write-unlock.