From: Jeff Moyer <jmoyer@redhat.com>
To: Sergey Temerkhanov <temerkhanov@cifronik.ru>
Cc: LKML <linux-kernel@vger.kernel.org>, linux-aio <linux-aio@kvack.org>
Subject: Re: [PATCH 1/2] AIO: Fix reference counting in io_cancel and aio_cancel_all
Date: Tue, 16 Mar 2010 10:46:10 -0400 [thread overview]
Message-ID: <x494okguxxp.fsf@segfault.boston.devel.redhat.com> (raw)
In-Reply-To: <201003161418.16959.temerkhanov@cifronik.ru> (Sergey Temerkhanov's message of "Tue, 16 Mar 2010 14:18:16 +0300")
Sergey Temerkhanov <temerkhanov@cifronik.ru> writes:
> io_cancel() and aio_cancel_all() have inconsistent reference counting
> (ki_users field of struct kiocb) which leads to unkillable processes upon
> io_cancel() or io_destroy() syscalls. This patch fixes the undesired behavior.
Hi, Sergey,
Thanks for the patch. Would you mind resubmitting it to make it a bit
easier to review? The way you've done things, it is difficult to tell
if you just moved the aio_cancel_all function or if you moved it and
made changes. Please have the patch that moves it separated out from
other changes, or at least mention in the changelog that the function
was unchanged. Next, if you could tell what sorts of testing you've
performed, that would be great. Finally, it would be a good idea to CC
linux-aio@kvack.org on aio patches.
Thanks!
Jeff
>
> Regards, Sergey Temerkhanov, Cifronic ZAO
> diff -r b290b47c0880 fs/aio.c
> --- a/fs/aio.c Tue Mar 16 13:51:13 2010 +0300
> +++ b/fs/aio.c Tue Mar 16 14:11:36 2010 +0300
> @@ -63,6 +63,8 @@
> static void aio_kick_handler(struct work_struct *);
> static void aio_queue_work(struct kioctx *);
>
> +static void aio_cancel_all(struct kioctx *ctx);
> +
> /* aio_setup
> * Creates the slab caches used by the aio routines, panic on
> * failure as this is done early during the boot sequence.
> @@ -315,33 +317,6 @@
> return ctx;
> }
>
> -/* aio_cancel_all
> - * Cancels all outstanding aio requests on an aio context. Used
> - * when the processes owning a context have all exited to encourage
> - * the rapid destruction of the kioctx.
> - */
> -static void aio_cancel_all(struct kioctx *ctx)
> -{
> - int (*cancel)(struct kiocb *, struct io_event *);
> - struct io_event res;
> - spin_lock_irq(&ctx->ctx_lock);
> - ctx->dead = 1;
> - while (!list_empty(&ctx->active_reqs)) {
> - struct list_head *pos = ctx->active_reqs.next;
> - struct kiocb *iocb = list_kiocb(pos);
> - list_del_init(&iocb->ki_list);
> - cancel = iocb->ki_cancel;
> - kiocbSetCancelled(iocb);
> - if (cancel) {
> - iocb->ki_users++;
> - spin_unlock_irq(&ctx->ctx_lock);
> - cancel(iocb, &res);
> - spin_lock_irq(&ctx->ctx_lock);
> - }
> - }
> - spin_unlock_irq(&ctx->ctx_lock);
> -}
> -
> static void wait_for_all_aios(struct kioctx *ctx)
> {
> struct task_struct *tsk = current;
> @@ -1038,6 +1013,36 @@
> return ret;
> }
>
> +/* aio_cancel_all
> + * Cancels all outstanding aio requests on an aio context. Used
> + * when the processes owning a context have all exited to encourage
> + * the rapid destruction of the kioctx.
> + */
> +static void aio_cancel_all(struct kioctx *ctx)
> +{
> + int (*cancel)(struct kiocb *, struct io_event *);
> + struct io_event res;
> + spin_lock_irq(&ctx->ctx_lock);
> + ctx->dead = 1;
> + while (!list_empty(&ctx->active_reqs)) {
> + struct list_head *pos = ctx->active_reqs.next;
> + struct kiocb *iocb = list_kiocb(pos);
> + list_del_init(&iocb->ki_list);
> + cancel = iocb->ki_cancel;
> + kiocbSetCancelled(iocb);
> + if (cancel) {
> + iocb->ki_users++;
> + spin_unlock_irq(&ctx->ctx_lock);
> + cancel(iocb, &res);
> + spin_lock_irq(&ctx->ctx_lock);
> + dprintk("aio_cancel_all: iocb->ki_users: %d\n", iocb->ki_users);
> + __aio_put_req(ctx, iocb);
> + }
> + __aio_put_req(ctx, iocb);
> + }
> + spin_unlock_irq(&ctx->ctx_lock);
> +}
> +
> /* aio_read_evt
> * Pull an event off of the ioctx's event ring. Returns the number of
> * events fetched (0 or 1 ;-)
> @@ -1787,9 +1792,11 @@
> if (copy_to_user(result, &tmp, sizeof(tmp)))
> ret = -EFAULT;
> }
> + aio_put_req(kiocb);
> } else
> ret = -EINVAL;
>
> + aio_put_req(kiocb);
> put_ioctx(ctx);
>
> return ret;
next prev parent reply other threads:[~2010-03-16 14:46 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-16 11:18 Sergey Temerkhanov
2010-03-16 11:29 ` [PATCH 2/2] AIO: Change pr_debug statements to dprintk in fs/aio.c Sergey Temerkhanov
2010-03-16 14:49 ` Jeff Moyer
2010-03-16 14:46 ` Jeff Moyer [this message]
2010-03-16 16:26 ` [PATCH resubmit 2/3] AIO: Fix reference counting in io_cancel and aio_cancel_all Сергей Темерханов
2010-03-16 16:30 ` [PATCH resubmit 3/3] AIO: Change dprintk statements to pr_debug Сергей Темерханов
2010-03-16 16:30 ` [PATCH resubmit 1/3] AIO: Move aio_cancel_all() Сергей Темерханов
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=x494okguxxp.fsf@segfault.boston.devel.redhat.com \
--to=jmoyer@redhat.com \
--cc=linux-aio@kvack.org \
--cc=linux-kernel@vger.kernel.org \
--cc=temerkhanov@cifronik.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®