On Thu, Aug 27, 2009 at 11:05:30AM +0200, Paolo Bonzini wrote: > > 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)); That would work for kvm. > 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 <pbonzini@xxxxxxxxxx> > --- > fs/eventfd.c | 13 ++++++++----- > include/linux/eventfd.h | 4 ++-- > 2 files changed, 10 insertions(+), 7 deletions(-) > > 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 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html