From patchwork Wed Jan 6 19:33:48 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Michael S. Tsirkin" X-Patchwork-Id: 71408 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o06Jajwq023113 for ; Wed, 6 Jan 2010 19:36:45 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932314Ab0AFTgn (ORCPT ); Wed, 6 Jan 2010 14:36:43 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756001Ab0AFTgn (ORCPT ); Wed, 6 Jan 2010 14:36:43 -0500 Received: from mx1.redhat.com ([209.132.183.28]:63994 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754622Ab0AFTgm (ORCPT ); Wed, 6 Jan 2010 14:36:42 -0500 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o06JagfU020103 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 6 Jan 2010 14:36:42 -0500 Received: from redhat.com (vpn2-11-128.ams2.redhat.com [10.36.11.128]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id o06Jadgl026250; Wed, 6 Jan 2010 14:36:40 -0500 Date: Wed, 6 Jan 2010 21:33:48 +0200 From: "Michael S. Tsirkin" To: Davide Libenzi Cc: Avi Kivity , kvm@vger.kernel.org Subject: Re: [PATCH 0/2] eventfd: new EFD_STATE flag Message-ID: <20100106193347.GG4001@redhat.com> References: <1251363930-3916-1-git-send-email-pbonzini@redhat.com> <20090827143027.GA22720@redhat.com> <20090827144905.GA22728@redhat.com> <4A9CB318.7030401@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.19 (2009-01-05) X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org diff --git a/fs/eventfd.c b/fs/eventfd.c index d26402f..e350ffd 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c @@ -135,6 +135,17 @@ static unsigned int eventfd_poll(struct file *file, poll_table *wait) return events; } +/* Caller must have wait queue head lock. */ +ssize_t _eventfd_read_ctx(struct eventfd_ctx *ctx, u64 *ucnt) +{ + if (!ctx->count) + return -EAGAIN; + *ucnt = (ctx->flags & EFD_SEMAPHORE) ? 1 : ctx->count; + ctx->count -= *ucnt; + return sizeof *ucnt; +} +EXPORT_SYMBOL_GPL(_eventfd_read_ctx); + static ssize_t eventfd_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -146,17 +157,14 @@ static ssize_t eventfd_read(struct file *file, char __user *buf, size_t count, if (count < sizeof(ucnt)) return -EINVAL; spin_lock_irq(&ctx->wqh.lock); - res = -EAGAIN; - if (ctx->count > 0) - res = sizeof(ucnt); - else if (!(file->f_flags & O_NONBLOCK)) { + res = _eventfd_read_ctx(ctx, &ucnt); + if (res < 0 && !(file->f_flags & O_NONBLOCK)) { __add_wait_queue(&ctx->wqh, &wait); for (res = 0;;) { set_current_state(TASK_INTERRUPTIBLE); - if (ctx->count > 0) { - res = sizeof(ucnt); + res = _eventfd_read_ctx(ctx, &ucnt); + if (res > 0) break; - } if (signal_pending(current)) { res = -ERESTARTSYS; break; @@ -169,8 +177,6 @@ static ssize_t eventfd_read(struct file *file, char __user *buf, size_t count, __set_current_state(TASK_RUNNING); } if (likely(res > 0)) { - ucnt = (ctx->flags & EFD_SEMAPHORE) ? 1 : ctx->count; - ctx->count -= ucnt; if (waitqueue_active(&ctx->wqh)) wake_up_locked_poll(&ctx->wqh, POLLOUT); } diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h index 94dd103..a3d0ce9 100644 --- a/include/linux/eventfd.h +++ b/include/linux/eventfd.h @@ -34,6 +34,7 @@ struct file *eventfd_fget(int fd); struct eventfd_ctx *eventfd_ctx_fdget(int fd); struct eventfd_ctx *eventfd_ctx_fileget(struct file *file); int eventfd_signal(struct eventfd_ctx *ctx, int n); +ssize_t _eventfd_read_ctx(struct eventfd_ctx *ctx, u64 *ucnt); #else /* CONFIG_EVENTFD */ @@ -61,6 +62,11 @@ static inline void eventfd_ctx_put(struct eventfd_ctx *ctx) } +static inline ssize_t _eventfd_read_ctx(struct eventfd_ctx *ctx, u64 *ucnt) +{ + return -ENOSYS; +} + #endif #endif /* _LINUX_EVENTFD_H */