From mboxrd@z Thu Jan 1 00:00:00 1970 From: Philippe Gerum Subject: [PATCH 3/8] drivers/udd: fix spurious select() read events Date: Sat, 1 Jun 2019 17:14:57 +0200 Message-Id: <20190601151502.27216-4-rpm@xenomai.org> In-Reply-To: <20190601151502.27216-1-rpm@xenomai.org> References: <20190601151502.27216-1-rpm@xenomai.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Discussions about the Xenomai project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: xenomai@xenomai.org Cc: Jan Kiszka , Philippe Gerum See https://xenomai.org/pipermail/xenomai/2017-July/037494.html Signed-off-by: Philippe Gerum --- include/cobalt/kernel/rtdm/udd.h | 2 +- kernel/drivers/udd/udd.c | 31 ++++++++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/include/cobalt/kernel/rtdm/udd.h b/include/cobalt/kernel/rtdm/udd.h index 550ba9d24..bc2a68db6 100644 --- a/include/cobalt/kernel/rtdm/udd.h +++ b/include/cobalt/kernel/rtdm/udd.h @@ -306,7 +306,7 @@ struct udd_device { /** Reserved to the UDD core. */ struct udd_reserved { rtdm_irq_t irqh; - atomic_t event; + u32 event_count; struct udd_signotify signfy; struct rtdm_event pulse; struct rtdm_driver driver; diff --git a/kernel/drivers/udd/udd.c b/kernel/drivers/udd/udd.c index 972db1225..b086096cc 100644 --- a/kernel/drivers/udd/udd.c +++ b/kernel/drivers/udd/udd.c @@ -117,7 +117,8 @@ static ssize_t udd_read_rt(struct rtdm_fd *fd, struct udd_context *context; struct udd_reserved *ur; struct udd_device *udd; - ssize_t ret; + rtdm_lockctx_t ctx; + ssize_t ret = 0; u32 count; if (len != sizeof(count)) @@ -130,15 +131,20 @@ static ssize_t udd_read_rt(struct rtdm_fd *fd, ur = &udd->__reserved; context = rtdm_fd_to_private(fd); - for (;;) { - if (atomic_read(&ur->event) != context->event_count) - break; + cobalt_atomic_enter(ctx); + + if (ur->event_count != context->event_count) + rtdm_event_clear(&ur->pulse); + else ret = rtdm_event_wait(&ur->pulse); - if (ret) - return ret; - } - count = atomic_read(&ur->event); + count = ur->event_count; + + cobalt_atomic_leave(ctx); + + if (ret) + return ret; + context->event_count = count; ret = rtdm_copy_to_user(fd, buf, &count, sizeof(count)); @@ -404,7 +410,7 @@ int udd_register_device(struct udd_device *udd) } else ur->mapper_name = NULL; - atomic_set(&ur->event, 0); + ur->event_count = 0; rtdm_event_init(&ur->pulse, 0); ur->signfy.pid = -1; @@ -501,12 +507,15 @@ void udd_notify_event(struct udd_device *udd) { struct udd_reserved *ur = &udd->__reserved; union sigval sival; + rtdm_lockctx_t ctx; - atomic_inc(&ur->event); + cobalt_atomic_enter(ctx); + ur->event_count++; rtdm_event_signal(&ur->pulse); + cobalt_atomic_leave(ctx); if (ur->signfy.pid > 0) { - sival.sival_int = atomic_read(&ur->event); + sival.sival_int = (int)ur->event_count; __cobalt_sigqueue(ur->signfy.pid, ur->signfy.sig, &sival); } } -- 2.20.1