From nobody Wed Jan 19 22:02:23 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 17097196A91E; Wed, 19 Jan 2022 22:03:19 +0000 (UTC) (envelope-from vladimir@kondratyev.su) Received: from corp.infotel.ru (corp.infotel.ru [195.170.219.3]) by mx1.freebsd.org (Postfix) with ESMTP id 4JfKQZ5Vccz4v4b; Wed, 19 Jan 2022 22:03:18 +0000 (UTC) (envelope-from vladimir@kondratyev.su) Received: from corp (corp.infotel.ru [195.170.219.3]) by corp.infotel.ru (Postfix) with ESMTP id DA98730D965; Thu, 20 Jan 2022 01:03:10 +0300 (MSK) X-Virus-Scanned: amavisd-new at corp.infotel.ru Received: from corp.infotel.ru ([195.170.219.3]) by corp (corp.infotel.ru [195.170.219.3]) (amavisd-new, port 10024) with ESMTP id 4rRIHwvd0XGS; Thu, 20 Jan 2022 01:03:10 +0300 (MSK) Received: from mail.cicgroup.ru (unknown [195.170.219.74]) by corp.infotel.ru (Postfix) with ESMTP id 0B86030DF85; Thu, 20 Jan 2022 01:03:10 +0300 (MSK) Received: from mail.cicgroup.ru (localhost [127.0.0.1]) by mail.cicgroup.ru (Postfix) with ESMTP id F302E42211F; Thu, 20 Jan 2022 01:03:07 +0300 (MSK) Received: from mail.cicgroup.ru ([127.0.0.1]) by mail.cicgroup.ru (mail.cicgroup.ru [127.0.0.1]) (amavisd-new, port 10024) with SMTP id wCOkfpeAvDcq; Thu, 20 Jan 2022 01:03:05 +0300 (MSK) Received: from [127.0.0.1] (localhost [127.0.0.1]) by mail.cicgroup.ru (Postfix) with ESMTPA id 5A88C42211C; Thu, 20 Jan 2022 01:03:05 +0300 (MSK) Message-ID: <3f62b9e2-214b-b1d4-f682-9318f77f315d@kondratyev.su> Date: Thu, 20 Jan 2022 01:02:23 +0300 List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0 Subject: Re: git: 02ea6033020e - main - LinuxKPI: Allow spin_lock_irqsave to be called within a critical section Content-Language: en-US To: Hans Petter Selasky , Konstantin Belousov , Vladimir Kondratyev Cc: src-committers@freebsd.org, dev-commits-src-all@freebsd.org, dev-commits-src-main@freebsd.org References: <202201182015.20IKFaWL053942@gitrepo.freebsd.org> <540a6a93-3101-02e8-b86a-50caa19f9653@kondratyev.su> From: Vladimir Kondratyev In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Rspamd-Queue-Id: 4JfKQZ5Vccz4v4b X-Spamd-Bar: ---- Authentication-Results: mx1.freebsd.org; none X-Spamd-Result: default: False [-4.00 / 15.00]; REPLY(-4.00)[] X-ThisMailContainsUnwantedMimeParts: N On 19.01.2022 12:50, Hans Petter Selasky wrote: > On 1/18/22 22:35, Vladimir Kondratyev wrote: >> >> Any ideas how to avoid it in a generic way? > > Hi, > > On a non-SMP system this will lead to deadlock. > > Is it possible you can pre-lock this spin lock earlier, so that it is already > locked, so instead of > > while(trylock()); > > You have: > > assert (trylock() XXX) > Unfortunately, vulnerable functions are called in too many code paths to patch them all. > Or else, > > convert this particular lock to a native FreeBSD spinlock mutex. > It can be done for wake_up() but not for dma_fence_signal() which suffers from this problem too. Some code that uses that lock expect it to be spinlock_t I think we can just drop critical section in seqlock-related part of dma-buf code and replace it with rwlock as kib@ and mjg@ suggested. Leave seqlock for actual locking to preserve semantics as much as possible and add rwlock to implement reader's blocking. Following snippets show code conversion required for this change: Lock seqlock as reader: retry: seq = read_seqcount_begin(&obj->seq); ... reader payload ... if (read_seqcount_retry(&obj->seq, seq)) { #ifdef __FreeBSD__ /* Wait for rwlock to be released by writer */ rw_rlock(&obj->rwlock); rw_runlock(&obj->rwlock); #endif goto retry; } Lock seqlock as writer: #ifdef __linux__ preempt_disable(); #elif defined (__FreeBSD__) rw_wlock(&obj->rwlock); #endif write_seqcount_begin(&obj->seq); ... writer payload ... write_seqcount_end(&obj->seq); #ifdef __linux__ preempt_enable(); #elif defined (__FreeBSD__) rw_wunlock(&obj->rwlock); #endif -- WBR Vladimir Kondratyev