Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Jan 2022 22:22:04 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Vladimir Kondratyev <wulf@freebsd.org>
Cc:        src-committers@freebsd.org, dev-commits-src-all@freebsd.org, dev-commits-src-main@freebsd.org
Subject:   Re: git: 02ea6033020e - main - LinuxKPI: Allow spin_lock_irqsave to be called within a critical section
Message-ID:  <YechbCTSWuUs%2BNr5@kib.kiev.ua>
In-Reply-To: <202201182015.20IKFaWL053942@gitrepo.freebsd.org>

index | next in thread | previous in thread | raw e-mail

On Tue, Jan 18, 2022 at 08:15:36PM +0000, Vladimir Kondratyev wrote:
> The branch main has been updated by wulf:
> 
> URL: https://cgit.FreeBSD.org/src/commit/?id=02ea6033020e11afec6472bf560b0ddebd0fa97a
> 
> commit 02ea6033020e11afec6472bf560b0ddebd0fa97a
> Author:     Vladimir Kondratyev <wulf@FreeBSD.org>
> AuthorDate: 2022-01-18 20:14:12 +0000
> Commit:     Vladimir Kondratyev <wulf@FreeBSD.org>
> CommitDate: 2022-01-18 20:14:12 +0000
> 
>     LinuxKPI: Allow spin_lock_irqsave to be called within a critical section
>     
>     with spinning on spin_trylock. dma-buf part of drm-kmod depends on this
>     property and absence of it support results in "mi_switch: switch in a
>     critical section" assertions [1][2].
>     
>     [1] https://github.com/freebsd/drm-kmod/issues/116
>     [2] https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=261166
>     
>     MFC after:      1 week
>     Reviewed by:    manu
>     Differential Revision:  https://reviews.freebsd.org/D33887
> ---
>  .../linuxkpi/common/include/linux/spinlock.h       | 27 ++++++++++++++++++----
>  1 file changed, 23 insertions(+), 4 deletions(-)
> 
> diff --git a/sys/compat/linuxkpi/common/include/linux/spinlock.h b/sys/compat/linuxkpi/common/include/linux/spinlock.h
> index a87cb7180b28..31d47fa73986 100644
> --- a/sys/compat/linuxkpi/common/include/linux/spinlock.h
> +++ b/sys/compat/linuxkpi/common/include/linux/spinlock.h
> @@ -37,6 +37,7 @@
>  #include <sys/lock.h>
>  #include <sys/mutex.h>
>  #include <sys/kdb.h>
> +#include <sys/proc.h>
>  
>  #include <linux/compiler.h>
>  #include <linux/rwlock.h>
> @@ -117,14 +118,32 @@ typedef struct {
>  	local_bh_disable();			\
>  } while (0)
>  
> -#define	spin_lock_irqsave(_l, flags) do {	\
> -	(flags) = 0;				\
> -	spin_lock(_l);				\
> +#define	__spin_trylock_nested(_l, _n) ({		\
> +	int __ret;					\
> +	if (SPIN_SKIP()) {				\
> +		__ret = 1;				\
> +	} else {					\
> +		__ret = mtx_trylock_flags(&(_l)->m, MTX_DUPOK);	\
> +		if (likely(__ret != 0))			\
> +			local_bh_disable();		\
> +	}						\
> +	__ret;						\
> +})
> +
> +#define	spin_lock_irqsave(_l, flags) do {		\
> +	(flags) = 0;					\
> +	if (unlikely(curthread->td_critnest != 0))	\
> +		while (!spin_trylock(_l)) {}		\
> +	else						\
> +		spin_lock(_l);				\
>  } while (0)
>  
>  #define	spin_lock_irqsave_nested(_l, flags, _n) do {	\
>  	(flags) = 0;					\
> -	spin_lock_nested(_l, _n);			\
> +	if (unlikely(curthread->td_critnest != 0))	\
> +		while (!__spin_trylock_nested(_l, _n)) {}	\
> +	else						\
> +		spin_lock_nested(_l, _n);		\
>  } while (0)
>  
>  #define	spin_unlock_irqrestore(_l, flags) do {		\
You are spin-waiting for blockable mutex, am I right?  This means a deadlock.
Just for example, on UP machine the spinning thread could starve the thread
that owns the mutex, which never gets to the CPU.


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?YechbCTSWuUs%2BNr5>