Re: [PATCH] mm/page_alloc: Use write_seqlock_irqsave() instead write_seqlock() + local_irq_save().

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2023-06-23 00:43:00 [+0900], Tetsuo Handa wrote:
> 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...

For !RT there is no spinning because interrupts are disabled.
For RT there is no spinning because the reader blocks on lock owned by
writer.

> > 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.

I would prefer not to worry about stable-RT but about upstream and then
we backport what is needed into the stable-RT trees once we settled on
something. This does not affect !RT.

Sebastian




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux