Date: Tue, 18 Jan 2022 20:15:36 GMT From: Vladimir Kondratyev <wulf@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 02ea6033020e - main - LinuxKPI: Allow spin_lock_irqsave to be called within a critical section Message-ID: <202201182015.20IKFaWL053942@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 { \
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202201182015.20IKFaWL053942>