Message ID | 20161008081228.GF3142@twins.programming.kicks-ass.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Sat, 2016-10-08 at 10:12 +0200, Peter Zijlstra wrote: > 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 <dvyukov@google.com> > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> > --- > > 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); > } > Looks correct to me. Peter, do you need me to pick this patch up or do you plan to get it to Linus another way? Thanks, and: Reviewed-by: Jeff Layton <jlayton@poochiereds.net> -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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); }