From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nick Piggin Subject: Re: [patch] fs: aio fix rcu lookup Date: Sat, 15 Jan 2011 02:00:25 +1100 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: Andrew Morton , linux-fsdevel , linux-kernel@vger.kernel.org To: Jeff Moyer Return-path: Received: from mail-wy0-f194.google.com ([74.125.82.194]:56283 "EHLO mail-wy0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752447Ab1ANPA1 convert rfc822-to-8bit (ORCPT ); Fri, 14 Jan 2011 10:00:27 -0500 In-Reply-To: Sender: linux-fsdevel-owner@vger.kernel.org List-ID: On Sat, Jan 15, 2011 at 1:52 AM, Jeff Moyer wrote: > Nick Piggin writes: > >> Hi, >> >> While hunting down a bug in NFS's AIO, I believe I found this >> buggy code... >> >> fs: aio fix rcu ioctx lookup >> >> aio-dio-invalidate-failure GPFs in aio_put_req from io_submit. >> >> lookup_ioctx doesn't implement the rcu lookup pattern properly. >> rcu_read_lock does not prevent refcount going to zero, so we >> might take a refcount on a zero count ioctx. > > So, does this patch fix the problem? =A0You didn't actually say.... No, it seemd to be an NFS AIO problem, although it was a slightly older kernel so I'll re test after -rc1 if I haven't heard back about it. Do you agree with the theoretical problem? I didn't try to write a racer to break it yet. Inserting a delay before the get_ioctx might do the trick. >> Signed-off-by: Nick Piggin >> >> Index: linux-2.6/fs/aio.c >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> --- linux-2.6.orig/fs/aio.c =A0 2011-01-14 00:29:00.000000000 +1100 >> +++ linux-2.6/fs/aio.c =A0 =A0 =A0 =A02011-01-14 11:31:47.000000000 = +1100 >> @@ -239,15 +239,23 @@ static void __put_ioctx(struct kioctx *c >> =A0 =A0 =A0 call_rcu(&ctx->rcu_head, ctx_rcu_free); >> =A0} >> >> -#define get_ioctx(kioctx) do { =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 \ >> - =A0 =A0 BUG_ON(atomic_read(&(kioctx)->users) <=3D 0); =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 \ >> - =A0 =A0 atomic_inc(&(kioctx)->users); =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 \ >> -} while (0) >> -#define put_ioctx(kioctx) do { =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 \ >> - =A0 =A0 BUG_ON(atomic_read(&(kioctx)->users) <=3D 0); =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 \ >> - =A0 =A0 if (unlikely(atomic_dec_and_test(&(kioctx)->users))) =A0 =A0= =A0 =A0 =A0 =A0\ >> - =A0 =A0 =A0 =A0 =A0 =A0 __put_ioctx(kioctx); =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0\ >> -} while (0) >> +static inline void get_ioctx(struct kioctx *kioctx) >> +{ >> + =A0 =A0 BUG_ON(atomic_read(&kioctx->users) <=3D 0); >> + =A0 =A0 atomic_inc(&kioctx->users); >> +} >> + >> +static inline int try_get_ioctx(struct kioctx *kioctx) >> +{ >> + =A0 =A0 return atomic_inc_not_zero(&kioctx->users); >> +} >> + >> +static inline void put_ioctx(struct kioctx *kioctx) >> +{ >> + =A0 =A0 BUG_ON(atomic_read(&kioctx->users) <=3D 0); >> + =A0 =A0 if (unlikely(atomic_dec_and_test(&kioctx->users))) >> + =A0 =A0 =A0 =A0 =A0 =A0 __put_ioctx(kioctx); >> +} > > Why did you switch from macros? =A0Personal preference? =A0Can you at= least > mention it in the changelog? Yeah, I couldn't bring myself to add another macro :) I can mention it, sure. -- 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