On 2025-08-12 14:39:29 [+0900], Yunseong Kim wrote: > While testing with PREEMPT_RT enabled, I encountered a potential issue in > gfs2_quota_init() where preemption is disabled via bit_spin_lock(), but a > subsequent call eventually reaches a sleepable lock. > > Below is the simplified call flow: > [PREEMPT_RT] … > At the moment, two possible approaches come to mind: > > 1. Avoid using the bit-spinlock in this path entirely > - Rework the bucket protection so we do not call into code that may sleep > while preemption is disabled. > - no sleeping while preemption-disabled. > - May require reworking bucket protection/race re-check logic. So this would add 4096 spinlocks for RT. Given that those a bit bigger than the other ones, it will use a bit more than 16KiB of memory. Maybe fewer could be used assuming lock sharing is fine here but I haven't checked the code > 2. Replace the inner lock with a non-sleeping primitive > - (e.g., use a raw_spinlock_t for lockref->lock) so it can be taken while > preemption is disabled. > - Since lockref does not currently support raw_spinlock_t, this would require > additional rework of the lockref structure. > - Minimal structural change; avoids sleeping in the problematic context. This is something. Looking at the layout of struct lockref USE_CMPXCHG_LOCKREF can only work if the spinlock is the raw_spinlock_t without lockdep. So it expects the lock to be unlocked and does a 64bit cmpxchg() to inc/ dec the counter that follows. I was confused why lockref_mark_dead() works for dcache given that the lock is not released outside of lockref.c except for lockref_put_or_lock(). But then I noticed d_lock. So making the lock raw_spinlock_t breaks the few lockref_put_or_lock() users. The impact on dcache is huge and I noticed some waitqueue handling which would break. So there is that. Based on this I think it should be handled somehow within gfs2. > I can help test patches for this on both PREEMPT_RT and NON-RT kernels. > > > Thanks, > Yunseong Kim Sebastian