From: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
To: "Kirill A. Shutemov" <kirill-oKw7cIdHH8eLwutG50LtGA@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
LKML <linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
Cgroups <cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
Davide Libenzi <davidel-AhlLAIvw+VEjIGhXcJzhZg@public.gmane.org>,
Aaron Durbin <adurbin-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>,
Greg Thelen <gthelen-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Subject: Re: [PATCH 3/4] eventfd: make operations on eventfd return -EIDRM if it's hung up
Date: Mon, 4 Feb 2013 11:15:41 +0800 [thread overview]
Message-ID: <510F27DD.8090508@huawei.com> (raw)
In-Reply-To: <20130202161229.GB12939-oKw7cIdHH8eLwutG50LtGA@public.gmane.org>
On 2013/2/3 0:12, Kirill A. Shutemov wrote:
> On Sat, Feb 02, 2013 at 02:51:30PM +0800, Li Zefan wrote:
>> Currently when a cgroup is removed, it calls eventfd_signal() for
>> each registered cgroup event, so userspace can be notified and blocked
>> reads can be unblocked.
>>
>> The problem is, if we have multiple threads blocked on the same eventfd,
>> only one of them will be unlocked.
>>
>> This patch makes sure all operations on the same eventfd can be unbocked.
>>
>> There's another problem, a new cgroup event can be registered while we
>> are removing the cgroup, and then reading the eventfd will be blocked
>> until the thread is killed. This patch also fixes this issue.
>>
>> Signed-off-by: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> ---
>> fs/eventfd.c | 23 +++++++++++++++++++++--
>> kernel/cgroup.c | 1 -
>> 2 files changed, 21 insertions(+), 3 deletions(-)
>>
>> diff --git a/fs/eventfd.c b/fs/eventfd.c
>> index acf15e3..48de15a 100644
>> --- a/fs/eventfd.c
>> +++ b/fs/eventfd.c
>> @@ -35,6 +35,7 @@ struct eventfd_ctx {
>> */
>> __u64 count;
>> unsigned int flags;
>> + bool hung_up;
>> };
>>
>> /**
>> @@ -71,11 +72,19 @@ EXPORT_SYMBOL_GPL(eventfd_signal);
>> * eventfd_signal_hangup - Notify that this eventfd is hung up.
>> * @ctx: [in] Pointer to the eventfd context.
>> *
>> - * Issue a POLLHUP wakeup.
>> + * Issue a POLLHUP wakeup. All current blocked reads, writes and polls on
>> + * this eventfd will return with -EIDRM. Future operations on it will also
>> + * return with -EDIRM.
>> */
>> void eventfd_signal_hangup(struct eventfd_ctx *ctx)
>> {
>> - wake_up_poll(&ctx->wqh, POLLHUP);
>> + unsigned long flags;
>> +
>> + spin_lock_irqsave(&ctx->wqh.lock, flags);
>> + ctx->hung_up = true;
>> + if (waitqueue_active(&ctx->wqh))
>> + wake_up_locked_poll(&ctx->wqh, POLLHUP);
>> + spin_unlock_irqrestore(&ctx->wqh.lock, flags);
>> }
>>
>> static void eventfd_free_ctx(struct eventfd_ctx *ctx)
>> @@ -140,6 +149,8 @@ static unsigned int eventfd_poll(struct file *file, poll_table *wait)
>> events |= POLLERR;
>> if (ULLONG_MAX - 1 > ctx->count)
>> events |= POLLOUT;
>> + if (ctx->hung_up)
>> + events |= POLLHUP;
>> spin_unlock_irqrestore(&ctx->wqh.lock, flags);
>>
>> return events;
>> @@ -208,6 +219,10 @@ ssize_t eventfd_ctx_read(struct eventfd_ctx *ctx, int no_wait, __u64 *cnt)
>> __add_wait_queue(&ctx->wqh, &wait);
>> for (;;) {
>> set_current_state(TASK_INTERRUPTIBLE);
>> + if (ctx->hung_up) {
>> + res = -EIDRM;
>> + break;
>> + }
>
> Shouldn't we just return indicate end-of-file if ctx->hung_up?
>
makes sense
>> if (ctx->count > 0) {
>> res = 0;
>> break;
>> @@ -272,6 +287,10 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c
>> __add_wait_queue(&ctx->wqh, &wait);
>> for (res = 0;;) {
>> set_current_state(TASK_INTERRUPTIBLE);
>> + if (ctx->hung_up) {
>> + res = -EIDRM;
>
> -EPIPE?
>
I wan't sure which errno is most appropriate, but EPIPE seems better.
>> + break;
>> + }
>> if (ULLONG_MAX - ctx->count > ucnt) {
>> res = sizeof(ucnt);
>> break;
>> diff --git a/kernel/cgroup.c b/kernel/cgroup.c
>> index a3d361b..fcb1ab6 100644
>> --- a/kernel/cgroup.c
>> +++ b/kernel/cgroup.c
>> @@ -4373,7 +4373,6 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
>> ctx = eventfd_ctx_get(event->eventfd);
>> spin_unlock(&cgrp->event_list_lock);
>>
>> - eventfd_signal(ctx, 1);
>> eventfd_signal_hangup(ctx);
>> eventfd_ctx_put(ctx);
>>
>> --
>> 1.8.0.2
>> --
>> To unsubscribe from this list: send the line "unsubscribe cgroups" in
>> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
WARNING: multiple messages have this Message-ID (diff)
From: Li Zefan <lizefan@huawei.com>
To: "Kirill A. Shutemov" <kirill@shutemov.name>
Cc: Tejun Heo <tj@kernel.org>, LKML <linux-kernel@vger.kernel.org>,
Cgroups <cgroups@vger.kernel.org>,
Davide Libenzi <davidel@xmailserver.org>,
Aaron Durbin <adurbin@google.com>,
Greg Thelen <gthelen@google.com>
Subject: Re: [PATCH 3/4] eventfd: make operations on eventfd return -EIDRM if it's hung up
Date: Mon, 4 Feb 2013 11:15:41 +0800 [thread overview]
Message-ID: <510F27DD.8090508@huawei.com> (raw)
In-Reply-To: <20130202161229.GB12939@shutemov.name>
On 2013/2/3 0:12, Kirill A. Shutemov wrote:
> On Sat, Feb 02, 2013 at 02:51:30PM +0800, Li Zefan wrote:
>> Currently when a cgroup is removed, it calls eventfd_signal() for
>> each registered cgroup event, so userspace can be notified and blocked
>> reads can be unblocked.
>>
>> The problem is, if we have multiple threads blocked on the same eventfd,
>> only one of them will be unlocked.
>>
>> This patch makes sure all operations on the same eventfd can be unbocked.
>>
>> There's another problem, a new cgroup event can be registered while we
>> are removing the cgroup, and then reading the eventfd will be blocked
>> until the thread is killed. This patch also fixes this issue.
>>
>> Signed-off-by: Li Zefan <lizefan@huawei.com>
>> ---
>> fs/eventfd.c | 23 +++++++++++++++++++++--
>> kernel/cgroup.c | 1 -
>> 2 files changed, 21 insertions(+), 3 deletions(-)
>>
>> diff --git a/fs/eventfd.c b/fs/eventfd.c
>> index acf15e3..48de15a 100644
>> --- a/fs/eventfd.c
>> +++ b/fs/eventfd.c
>> @@ -35,6 +35,7 @@ struct eventfd_ctx {
>> */
>> __u64 count;
>> unsigned int flags;
>> + bool hung_up;
>> };
>>
>> /**
>> @@ -71,11 +72,19 @@ EXPORT_SYMBOL_GPL(eventfd_signal);
>> * eventfd_signal_hangup - Notify that this eventfd is hung up.
>> * @ctx: [in] Pointer to the eventfd context.
>> *
>> - * Issue a POLLHUP wakeup.
>> + * Issue a POLLHUP wakeup. All current blocked reads, writes and polls on
>> + * this eventfd will return with -EIDRM. Future operations on it will also
>> + * return with -EDIRM.
>> */
>> void eventfd_signal_hangup(struct eventfd_ctx *ctx)
>> {
>> - wake_up_poll(&ctx->wqh, POLLHUP);
>> + unsigned long flags;
>> +
>> + spin_lock_irqsave(&ctx->wqh.lock, flags);
>> + ctx->hung_up = true;
>> + if (waitqueue_active(&ctx->wqh))
>> + wake_up_locked_poll(&ctx->wqh, POLLHUP);
>> + spin_unlock_irqrestore(&ctx->wqh.lock, flags);
>> }
>>
>> static void eventfd_free_ctx(struct eventfd_ctx *ctx)
>> @@ -140,6 +149,8 @@ static unsigned int eventfd_poll(struct file *file, poll_table *wait)
>> events |= POLLERR;
>> if (ULLONG_MAX - 1 > ctx->count)
>> events |= POLLOUT;
>> + if (ctx->hung_up)
>> + events |= POLLHUP;
>> spin_unlock_irqrestore(&ctx->wqh.lock, flags);
>>
>> return events;
>> @@ -208,6 +219,10 @@ ssize_t eventfd_ctx_read(struct eventfd_ctx *ctx, int no_wait, __u64 *cnt)
>> __add_wait_queue(&ctx->wqh, &wait);
>> for (;;) {
>> set_current_state(TASK_INTERRUPTIBLE);
>> + if (ctx->hung_up) {
>> + res = -EIDRM;
>> + break;
>> + }
>
> Shouldn't we just return indicate end-of-file if ctx->hung_up?
>
makes sense
>> if (ctx->count > 0) {
>> res = 0;
>> break;
>> @@ -272,6 +287,10 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c
>> __add_wait_queue(&ctx->wqh, &wait);
>> for (res = 0;;) {
>> set_current_state(TASK_INTERRUPTIBLE);
>> + if (ctx->hung_up) {
>> + res = -EIDRM;
>
> -EPIPE?
>
I wan't sure which errno is most appropriate, but EPIPE seems better.
>> + break;
>> + }
>> if (ULLONG_MAX - ctx->count > ucnt) {
>> res = sizeof(ucnt);
>> break;
>> diff --git a/kernel/cgroup.c b/kernel/cgroup.c
>> index a3d361b..fcb1ab6 100644
>> --- a/kernel/cgroup.c
>> +++ b/kernel/cgroup.c
>> @@ -4373,7 +4373,6 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
>> ctx = eventfd_ctx_get(event->eventfd);
>> spin_unlock(&cgrp->event_list_lock);
>>
>> - eventfd_signal(ctx, 1);
>> eventfd_signal_hangup(ctx);
>> eventfd_ctx_put(ctx);
>>
>> --
>> 1.8.0.2
>> --
>> To unsubscribe from this list: send the line "unsubscribe cgroups" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
next prev parent reply other threads:[~2013-02-04 3:15 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-02 6:50 [PATCH 0/4] cgroup: bug fixes for eventfd Li Zefan
2013-02-02 6:50 ` Li Zefan
[not found] ` <510CB733.2080904-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2013-02-02 6:50 ` [PATCH 1/4] eventfd: introduce eventfd_signal_hangup() Li Zefan
2013-02-02 6:50 ` Li Zefan
[not found] ` <510CB744.7000300-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2013-02-02 15:58 ` Kirill A. Shutemov
2013-02-02 15:58 ` Kirill A. Shutemov
[not found] ` <20130202155858.GA13022-oKw7cIdHH8eLwutG50LtGA@public.gmane.org>
2013-02-04 10:15 ` Kirill A. Shutemov
2013-02-04 10:15 ` Kirill A. Shutemov
[not found] ` <20130204101521.GA18322-oKw7cIdHH8eLwutG50LtGA@public.gmane.org>
2013-02-05 3:40 ` Li Zefan
2013-02-05 3:40 ` Li Zefan
[not found] ` <51107F42.1090401-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2013-02-05 8:28 ` Kirill A. Shutemov
2013-02-05 8:28 ` Kirill A. Shutemov
2013-02-06 1:48 ` Li Zefan
[not found] ` <5111B664.5050606-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2013-02-06 14:53 ` Kirill A. Shutemov
2013-02-06 14:53 ` Kirill A. Shutemov
2013-02-02 6:59 ` [PATCH 0/4] cgroup: bug fixes for eventfd Li Zefan
2013-02-02 6:59 ` Li Zefan
2013-02-04 19:27 ` Tejun Heo
2013-02-04 19:27 ` Tejun Heo
2013-02-02 6:51 ` [PATCH 2/4] cgroup: fix cgroup_rmdir() vs close(eventfd) race Li Zefan
[not found] ` <510CB763.3020700-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2013-02-02 15:59 ` Kirill A. Shutemov
2013-02-02 15:59 ` Kirill A. Shutemov
2013-02-02 6:51 ` [PATCH 3/4] eventfd: make operations on eventfd return -EIDRM if it's hung up Li Zefan
2013-02-02 16:12 ` Kirill A. Shutemov
[not found] ` <20130202161229.GB12939-oKw7cIdHH8eLwutG50LtGA@public.gmane.org>
2013-02-04 3:15 ` Li Zefan [this message]
2013-02-04 3:15 ` Li Zefan
2013-02-02 6:51 ` [PATCH 4/4] cgroup: adapt to the new way of detecting cgroup removal Li Zefan
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=510F27DD.8090508@huawei.com \
--to=lizefan-hv44wf8li93qt0dzr+alfa@public.gmane.org \
--cc=adurbin-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org \
--cc=cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=davidel-AhlLAIvw+VEjIGhXcJzhZg@public.gmane.org \
--cc=gthelen-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org \
--cc=kirill-oKw7cIdHH8eLwutG50LtGA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.