From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from merlin.infradead.org ([205.233.59.134]:49250 "EHLO merlin.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753436AbcJHIMd (ORCPT ); Sat, 8 Oct 2016 04:12:33 -0400 Date: Sat, 8 Oct 2016 10:12:28 +0200 From: Peter Zijlstra To: Jeff Layton Cc: Dmitry Vyukov , Bruce Fields , Al Viro , "linux-fsdevel@vger.kernel.org" , LKML , syzkaller Subject: Re: fs: WARNING in locks_unlink_lock_ctx (not holding proper lock) Message-ID: <20161008081228.GF3142@twins.programming.kicks-ass.net> References: <1475882796.2549.7.camel@poochiereds.net> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1475882796.2549.7.camel@poochiereds.net> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: On Fri, Oct 07, 2016 at 07:26:36PM -0400, Jeff Layton wrote: > Well spotted. Yeah, I think you're right. The assertion is this: > > � � percpu_rwsem_assert_held(&file_rwsem); > > I'm guessing this is probably fallout from the lglock to rwsem > conversion (commit�aba376607383). > > From a quick glance, I think we probably just need to down_read the > file_rwsem in locks_remove_lease, prior to taking the flc_lock, and > release it just afterward. Correct on all that. > I do want to go over the code a little more > closely though to make sure other codepaths aren't missing that lock > though. Urg, sorry for missing these, I went through it again and found the below to be missing. --- Subject: fs/locks: Add missing file_sem locks I overlooked a few code-paths that can lead to locks_delete_global_locks(). Reported-by: Dmitry Vyukov Signed-off-by: Peter Zijlstra (Intel) --- diff --git a/fs/locks.c b/fs/locks.c index 133fb2543d21..c623490863a9 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1604,6 +1604,7 @@ int fcntl_getlease(struct file *filp) ctx = smp_load_acquire(&inode->i_flctx); if (ctx && !list_empty_careful(&ctx->flc_lease)) { + percpu_down_read_preempt_disable(&file_rwsem); spin_lock(&ctx->flc_lock); time_out_leases(file_inode(filp), &dispose); list_for_each_entry(fl, &ctx->flc_lease, fl_list) { @@ -1613,6 +1614,8 @@ int fcntl_getlease(struct file *filp) break; } spin_unlock(&ctx->flc_lock); + percpu_up_read_preempt_enable(&file_rwsem); + locks_dispose_list(&dispose); } return type; @@ -2522,11 +2525,14 @@ locks_remove_lease(struct file *filp, struct file_lock_context *ctx) if (list_empty(&ctx->flc_lease)) return; + percpu_down_read_preempt_disable(&file_rwsem); spin_lock(&ctx->flc_lock); list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) if (filp == fl->fl_file) lease_modify(fl, F_UNLCK, &dispose); spin_unlock(&ctx->flc_lock); + percpu_up_read_preempt_enable(&file_rwsem); + locks_dispose_list(&dispose); }