From patchwork Thu Aug 27 09:05:30 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 44218 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n7R96pGQ027669 for ; Thu, 27 Aug 2009 09:06:51 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751868AbZH0JFn (ORCPT ); Thu, 27 Aug 2009 05:05:43 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751833AbZH0JFn (ORCPT ); Thu, 27 Aug 2009 05:05:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:32156 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751823AbZH0JFm (ORCPT ); Thu, 27 Aug 2009 05:05:42 -0400 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 n7R95hFm029234; Thu, 27 Aug 2009 05:05:43 -0400 Received: from localhost.localdomain (dhcp-lab-176.englab.brq.redhat.com [10.34.33.176]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n7R95fwM031724; Thu, 27 Aug 2009 05:05:41 -0400 From: Paolo Bonzini To: Davide Libenzi Cc: Avi Kivity , "Michael S. Tsirkin" , gleb@redhat.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 0/2] eventfd: new EFD_STATE flag Date: Thu, 27 Aug 2009 11:05:30 +0200 Message-Id: <1251363930-3916-1-git-send-email-pbonzini@redhat.com> In-Reply-To: References: 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 > Ok, so why not using the eventfd counter as state? > On the device side: > > void write_state(int sfd, int state) { > u64 cnt; > > /* Clear the current state, sfd is in non-blocking mode */ > read(sfd,&cnt, sizeof(cnt)); > /* Writes new state */ > cnt = 1 + !!state; > write(sfd,&cnt, sizeof(cnt)); > } It's interesting [no sarcasm intended, mind] that EFD_SEMAPHORE was added exactly to avoid a read+write combination for the case of decrementing a value. Here it's the same, just it's about the case of writing a *given* value. What about having EFD_STATE simply mean "do not use a counter, just write the value" without affecting the way read works, and use /* Writes new state */ cnt = 1 + !!state; write(sfd,&cnt, sizeof(cnt)); See below? Paolo > On the hypervisor side: > > int read_state(int sfd) { > u64 cnt; > > read(sfd,&cnt, sizeof(cnt)); > return state - 1; > } ------------- 8<-- --------------- Subject: [PATCH] eventfd: new EFD_ABSOLUTE flag This implements a new EFD_ABSOLUTE flag for eventfd. This changes eventfd behaviour so that write simply stores the value written, and is always non-blocking. Untested (I just modified Michael's patch, and given the simpler code I'm not sure it's now worthwhile introducing the inline functions), but otherwise Signed-off-by: Paolo Bonzini --- fs/eventfd.c | 13 ++++++++----- include/linux/eventfd.h | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe kvm" 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/eventfd.c b/fs/eventfd.c index 347a0e0..7b279e3 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c @@ -31,8 +31,6 @@ static inline int eventfd_writeable(struct eventfd_ctx *ctx, u64 n) { - return ULLONG_MAX - n > ctx->count; - return (ctx->flags & EFD_ABSOLUTE) || (ULLONG_MAX - n > ctx->count); } static inline int eventfd_overflow(struct eventfd_ctx *ctx, u64 cnt) @@ -42,10 +40,14 @@ static inline void eventfd_dowrite(struct eventfd_ctx *ctx, u64 ucnt) { - if (eventfd_writeable(ctx, ucnt)) - ucnt = ULLONG_MAX - ctx->count; + if (ctx->flags & EFD_ABSOLUTE) + ctx->count = ucnt; + else { + if (ULLONG_MAX - ctx->count < ucnt) + ucnt = ULLONG_MAX - ctx->count; - ctx->count += ucnt; + ctx->count += ucnt; + } } static inline u64 eventfd_doread(struct eventfd_ctx *ctx) diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h index 3b85ba6..78ff649 100644 --- a/include/linux/eventfd.h +++ b/include/linux/eventfd.h @@ -19,11 +19,12 @@ * shared O_* flags. */ #define EFD_SEMAPHORE (1 << 0) +#define EFD_ABSOLUTE (1 << 1) #define EFD_CLOEXEC O_CLOEXEC #define EFD_NONBLOCK O_NONBLOCK #define EFD_SHARED_FCNTL_FLAGS (O_CLOEXEC | O_NONBLOCK) -#define EFD_FLAGS_SET (EFD_SHARED_FCNTL_FLAGS | EFD_SEMAPHORE) +#define EFD_FLAGS_SET (EFD_SHARED_FCNTL_FLAGS | EFD_SEMAPHORE | EFD_ABSOLUTE) #ifdef CONFIG_EVENTFD -- 1.6.2.5