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>
References:  <202201182015.20IKFaWL053942@gitrepo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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.



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