From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.nokia.com ([131.228.20.170] helo=mgw-ext11.nokia.com) by canuck.infradead.org with esmtps (Exim 4.63 #1 (Red Hat Linux)) id 1HTiek-00018L-KS for linux-mtd@lists.infradead.org; Tue, 20 Mar 2007 14:02:00 -0400 Subject: Re: JFFS2: BUG: sleeping function called from invalid context From: Artem Bityutskiy To: Adrian Hunter In-Reply-To: <45FFBCC6.8010800@nokia.com> References: <45FFBCC6.8010800@nokia.com> Content-Type: text/plain; charset=UTF-8 Date: Tue, 20 Mar 2007 20:01:37 +0200 Message-Id: <1174413697.17249.126.camel@sauron> Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Cc: David Woodhouse , linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org Reply-To: dedekind@infradead.org List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , On Tue, 2007-03-20 at 12:51 +0200, Adrian Hunter wrote: > BUG: sleeping function called from invalid context at include/linux/write= back.h:76 > in_atomic():1, irqs_disabled():0 > 2 locks held by jffs2_gcd_mtd0/5710: > #0: (&c->wbuf_sem){----}, at: [] jffs2_flash_writev+0x67/0x5c= 0 [jffs2] > #1: (&c->erase_completion_lock){--..}, at: [] jffs2_wbuf_reco= ver+0xb03/0x11f1 [jffs2] > [] show_trace_log_lvl+0x1a/0x30 > [] show_trace+0x12/0x14 > [] dump_stack+0x16/0x18 > [] __might_sleep+0xb8/0xcb > [] ifind_fast+0x48/0x86 > [] iget_locked+0x2a/0x133 > [] jffs2_gc_fetch_inode+0x18e/0x229 [jffs2] > [] jffs2_wbuf_recover+0xd5e/0x11f1 [jffs2] > [] __jffs2_flush_wbuf+0x3b6/0x791 [jffs2] > [] jffs2_flash_writev+0x367/0x5c0 [jffs2] > [] jffs2_write_dnode+0x180/0x403 [jffs2] > [] jffs2_garbage_collect_dnode+0x7d3/0x8cd [jffs2] > [] jffs2_garbage_collect_live+0x242/0x31e [jffs2] > [] jffs2_garbage_collect_pass+0x99b/0xac9 [jffs2] > [] jffs2_garbage_collect_thread+0x341/0x396 [jffs2] > [] kernel_thread_helper+0x7/0x14 > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D This function seems to be completely broken. JFF2 calls iget() while holding c->erase_completion_lock spinlock. This is one problem. Iget can sleep. The other one is that JFFS2 calls jffs2_gc_fetch_inode() while holding c->alloc_sem and c->wbuf_sem semaphores. What happens if JFFS2 races with pdflush, and pdflush wins, clears inode, then VFS calls read_inode() to satisfy JFFS2's iget() request. It is a _deadlock_ because the in read_inode JFFS2 will try to lock the above semaphores again. The wbuf recovery function has to be re-worked or just disabled - because returning error is better then fall into a deadlock. David, comments, ideas? --=20 Best regards, Artem Bityutskiy (=D0=91=D0=B8=D1=82=D1=8E=D1=86=D0=BA=D0=B8=D0=B9 =D0=90= =D1=80=D1=82=D1=91=D0=BC)