fs/dcache: disable preemption on i_dir_seq's write side
i_dir_seq is a sequence counter with a lock which is represented by the lowest bit. The writer atomically updates the counter which ensures that it can be modified by only one writer at a time. The commit introducing this change claims that the lock has been integrated into the counter for space reasons within the inode struct. The i_dir_seq member is within a union which shares also a pointer. That means by using seqlock_t we would have a sequence counter and a lock without increasing the size of the data structure on 64bit and 32bit would grow by 4 bytes. With lockdep enabled the size would grow and on PREEMPT_RT the spinlock_t is also larger. In order to keep this construct working on PREEMPT_RT, the writer needs to disable preemption while obtaining the lock on the sequence counter / starting the write critical section. The writer acquires an otherwise unrelated spinlock_t which serves the same purpose on !PREEMPT_RT. With enabled preemption a high priority reader could preempt the writer and live lock the system while waiting for the locked bit to disappear. Another solution would be to have global spinlock_t which is always acquired by the writer. The reader would then acquire the lock if the sequence count is odd and by doing so force the writer out of the critical section. The global spinlock_t could be replaced by a hashed lock based on the address of the inode to lower the lock contention. For now, manually disable preemption on PREEMPT_RT to avoid live locks. Reported-by:<Oleg.Karfich@wago.com> Signed-off-by:
Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Loading
Please register or sign in to comment