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>
