On 2023/06/23 0:04, Petr Mladek wrote: > AFAIK, rt_spin_lock(lock) fulfills exactly the above requirements. > The owner could schedule. The waiter could schedule as well so that > they could be running on the same CPU. Also the current owner gets > higher priority when the is a waiter with the higher priority to avoid > the priority inversion. Excuse me, but that is about multiple threads trying to acquire the same lock, isn't it? Our case is that one thread which makes zonelist_update_seq.seqcount odd acquires zonelist_update_seq.lock but threads spinning at read_seqbegin(zonelist_update_seq.seqcount) from zonelist_iter_begin() do nothing but cpu_relax() busy loop. There is no way to teach that these threads need to give CPU to the thread which made zonelist_update_seq.seqcount odd... > The result would look like: > > in kernel/linux/printk.h: > > static inline void printk_deferred_enter(void) > { > if (!defined(CONFIG_PREEMPT_RT)) > preempt_disable(); > else > migrate_disable(); > > __printk_safe_enter(); > } > > in mm/page_alloc.c > > printk_deferred_enter(); > write_seqlock_irqsafe(&zonelist_update_seq, flags); OK. But for stable, + if (defined(CONFIG_PREEMPT_RT)) + migrate_disable(); /* * Explicitly disable this CPU's interrupts before taking seqlock * to prevent any IRQ handler from calling into the page allocator * (e.g. GFP_ATOMIC) that could hit zonelist_iter_begin and livelock. */ local_irq_save(flags); /* * Explicitly disable this CPU's synchronous printk() before taking * seqlock to prevent any printk() from trying to hold port->lock, for * tty_insert_flip_string_and_push_buffer() on other CPU might be * calling kmalloc(GFP_ATOMIC | __GFP_NOWARN) with port->lock held. */ printk_deferred_enter(); write_seqlock(&zonelist_update_seq); will be easier to apply.