You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/12/28 14:45:31 UTC

[nuttx] branch master updated (cbe4cb2056 -> d36b7fea45)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


    from cbe4cb2056 net: Add set/getsockopt options compatible with iptables.
     new c7eca3d176 timerfd/eventfd: using file_allocate to replace register_driver
     new d36b7fea45 timerfd: remove timeout work and do notify in isr

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 fs/vfs/Kconfig      |  12 ---
 fs/vfs/fs_eventfd.c | 128 ++++++++--------------
 fs/vfs/fs_timerfd.c | 297 +++++++++++++++-------------------------------------
 3 files changed, 126 insertions(+), 311 deletions(-)


[nuttx] 01/02: timerfd/eventfd: using file_allocate to replace register_driver

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit c7eca3d176baef559dc2ca6c921c231a1fad7f75
Author: dongjiuzhu1 <do...@xiaomi.com>
AuthorDate: Thu Dec 22 22:15:40 2022 +0800

    timerfd/eventfd: using file_allocate to replace register_driver
    
    Signed-off-by: dongjiuzhu1 <do...@xiaomi.com>
---
 fs/vfs/Kconfig      |  12 -----
 fs/vfs/fs_eventfd.c | 128 +++++++++++++++++-----------------------------------
 fs/vfs/fs_timerfd.c | 119 ++++++++++++++----------------------------------
 3 files changed, 76 insertions(+), 183 deletions(-)

diff --git a/fs/vfs/Kconfig b/fs/vfs/Kconfig
index b722b09903..9b3c63ec6a 100644
--- a/fs/vfs/Kconfig
+++ b/fs/vfs/Kconfig
@@ -11,12 +11,6 @@ config EVENT_FD
 
 if EVENT_FD
 
-config EVENT_FD_VFS_PATH
-	string "Path to eventfd storage"
-	default "/var/event"
-	---help---
-		The path to where eventfd will exist in the VFS namespace.
-
 config EVENT_FD_POLL
 	bool "EventFD poll support"
 	default y
@@ -40,12 +34,6 @@ config TIMER_FD
 
 if TIMER_FD
 
-config TIMER_FD_VFS_PATH
-	string "Path to timerfd storage"
-	default "/var/timer"
-	---help---
-		The path to where timerfd will exist in the VFS namespace.
-
 config TIMER_FD_POLL
 	bool "TimerFD poll support"
 	default y
diff --git a/fs/vfs/fs_eventfd.c b/fs/vfs/fs_eventfd.c
index 1f2ef29a83..30321d20bc 100644
--- a/fs/vfs/fs_eventfd.c
+++ b/fs/vfs/fs_eventfd.c
@@ -43,20 +43,18 @@
 typedef struct eventfd_waiter_sem_s
 {
   sem_t sem;
-  struct eventfd_waiter_sem_s *next;
+  FAR struct eventfd_waiter_sem_s *next;
 } eventfd_waiter_sem_t;
 
 /* This structure describes the internal state of the driver */
 
 struct eventfd_priv_s
 {
-  mutex_t                   lock;            /* Enforces device exclusive access */
-  FAR eventfd_waiter_sem_t *rdsems;          /* List of blocking readers */
-  FAR eventfd_waiter_sem_t *wrsems;          /* List of blocking writers */
-  eventfd_t                 counter;         /* eventfd counter */
-  unsigned int              minor;           /* eventfd minor number */
-  uint8_t                   crefs;           /* References counts on eventfd (max: 255) */
-  bool                      mode_semaphore;  /* eventfd mode (semaphore or counter) */
+  mutex_t                   lock;    /* Enforces device exclusive access */
+  FAR eventfd_waiter_sem_t *rdsems;  /* List of blocking readers */
+  FAR eventfd_waiter_sem_t *wrsems;  /* List of blocking writers */
+  eventfd_t                 counter; /* eventfd counter */
+  uint8_t                   crefs;   /* References counts on eventfd (max: 255) */
 
   /* The following is a list if poll structures of threads waiting for
    * driver events.
@@ -87,9 +85,6 @@ static int eventfd_blocking_io(FAR struct eventfd_priv_s *dev,
                                FAR eventfd_waiter_sem_t  *sem,
                                FAR eventfd_waiter_sem_t **slist);
 
-static unsigned int eventfd_get_unique_minor(void);
-static void eventfd_release_minor(unsigned int minor);
-
 static FAR struct eventfd_priv_s *eventfd_allocdev(void);
 static void eventfd_destroy(FAR struct eventfd_priv_s *dev);
 
@@ -115,6 +110,18 @@ static const struct file_operations g_eventfd_fops =
 #endif
 };
 
+static struct inode g_eventfd_inode =
+{
+  NULL,                   /* i_parent */
+  NULL,                   /* i_peer */
+  NULL,                   /* i_child */
+  1,                      /* i_crefs */
+  FSNODEFLAG_TYPE_DRIVER, /* i_flags */
+  {
+    &g_eventfd_fops       /* u */
+  }
+};
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -138,25 +145,14 @@ static FAR struct eventfd_priv_s *eventfd_allocdev(void)
 
 static void eventfd_destroy(FAR struct eventfd_priv_s *dev)
 {
+  nxmutex_unlock(&dev->lock);
   nxmutex_destroy(&dev->lock);
   kmm_free(dev);
 }
 
-static unsigned int eventfd_get_unique_minor(void)
-{
-  static unsigned int minor;
-
-  return minor++;
-}
-
-static void eventfd_release_minor(unsigned int minor)
-{
-}
-
 static int eventfd_do_open(FAR struct file *filep)
 {
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct eventfd_priv_s *priv = inode->i_private;
+  FAR struct eventfd_priv_s *priv = filep->f_priv;
   int ret;
 
   /* Get exclusive access to the device structures */
@@ -167,8 +163,6 @@ static int eventfd_do_open(FAR struct file *filep)
       return ret;
     }
 
-  finfo("crefs: %d <%s>\n", priv->crefs, inode->i_name);
-
   if (priv->crefs >= 255)
     {
       /* More than 255 opens; uint8_t would overflow to zero */
@@ -189,13 +183,8 @@ static int eventfd_do_open(FAR struct file *filep)
 
 static int eventfd_do_close(FAR struct file *filep)
 {
+  FAR struct eventfd_priv_s *priv = filep->f_priv;
   int ret;
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct eventfd_priv_s *priv = inode->i_private;
-
-  /* devpath: EVENT_FD_VFS_PATH + /efd (4) + %u (10) + null char (1) */
-
-  char devpath[sizeof(CONFIG_EVENT_FD_VFS_PATH) + 4 + 10 + 1];
 
   /* Get exclusive access to the device structures */
 
@@ -205,8 +194,6 @@ static int eventfd_do_close(FAR struct file *filep)
       return ret;
     }
 
-  finfo("crefs: %d <%s>\n", priv->crefs, inode->i_name);
-
   /* Decrement the references to the driver.  If the reference count will
    * decrement to 0, then uninitialize the driver.
    */
@@ -223,16 +210,8 @@ static int eventfd_do_close(FAR struct file *filep)
   /* Re-create the path to the driver. */
 
   finfo("destroy\n");
-  sprintf(devpath, CONFIG_EVENT_FD_VFS_PATH "/efd%u", priv->minor);
-
-  /* Will be unregistered later after close is done */
-
-  unregister_driver(devpath);
 
-  DEBUGASSERT(nxmutex_is_locked(&priv->lock));
-  eventfd_release_minor(priv->minor);
   eventfd_destroy(priv);
-
   return OK;
 }
 
@@ -241,6 +220,7 @@ static int eventfd_blocking_io(FAR struct eventfd_priv_s *dev,
                                FAR eventfd_waiter_sem_t **slist)
 {
   int ret;
+
   sem->next = *slist;
   *slist = sem;
 
@@ -287,8 +267,7 @@ static int eventfd_blocking_io(FAR struct eventfd_priv_s *dev,
 static ssize_t eventfd_do_read(FAR struct file *filep, FAR char *buffer,
                                size_t len)
 {
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct eventfd_priv_s *dev = inode->i_private;
+  FAR struct eventfd_priv_s *dev = filep->f_priv;
   FAR eventfd_waiter_sem_t *cur_sem;
   ssize_t ret;
 
@@ -332,7 +311,7 @@ static ssize_t eventfd_do_read(FAR struct file *filep, FAR char *buffer,
 
   /* Device ready for read */
 
-  if (dev->mode_semaphore)
+  if ((filep->f_oflags & EFD_SEMAPHORE) != 0)
     {
       *(FAR eventfd_t *)buffer = 1;
       dev->counter -= 1;
@@ -367,11 +346,10 @@ static ssize_t eventfd_do_read(FAR struct file *filep, FAR char *buffer,
 static ssize_t eventfd_do_write(FAR struct file *filep,
                                 FAR const char *buffer, size_t len)
 {
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct eventfd_priv_s *dev = inode->i_private;
+  FAR struct eventfd_priv_s *dev = filep->f_priv;
   FAR eventfd_waiter_sem_t *cur_sem;
-  ssize_t ret;
   eventfd_t new_counter;
+  ssize_t ret;
 
   if (len < sizeof(eventfd_t) || buffer == NULL ||
       (*(FAR eventfd_t *)buffer == (eventfd_t)-1) ||
@@ -443,10 +421,9 @@ static ssize_t eventfd_do_write(FAR struct file *filep,
 
 #ifdef CONFIG_EVENT_FD_POLL
 static int eventfd_do_poll(FAR struct file *filep, FAR struct pollfd *fds,
-                        bool setup)
+                           bool setup)
 {
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct eventfd_priv_s *dev = inode->i_private;
+  FAR struct eventfd_priv_s *dev = filep->f_priv;
   int ret;
   int i;
   pollevent_t eventset;
@@ -528,13 +505,15 @@ out:
 
 int eventfd(unsigned int count, int flags)
 {
-  int ret;
-  int new_fd;
   FAR struct eventfd_priv_s *new_dev;
+  int new_fd;
+  int ret;
 
-  /* devpath: EVENT_FD_VFS_PATH + /efd (4) + %u (10) + null char (1) */
-
-  char devpath[sizeof(CONFIG_EVENT_FD_VFS_PATH) + 4 + 10 + 1];
+  if ((flags & ~(EFD_NONBLOCK | EFD_SEMAPHORE | EFD_CLOEXEC)) != 0)
+    {
+      ret = -EINVAL;
+      goto exit_set_errno;
+    }
 
   /* Allocate instance data for this driver */
 
@@ -548,46 +527,21 @@ int eventfd(unsigned int count, int flags)
     }
 
   new_dev->counter = count;
-  new_dev->mode_semaphore = !!(flags & EFD_SEMAPHORE);
-
-  /* Request a unique minor device number */
-
-  new_dev->minor = eventfd_get_unique_minor();
-
-  /* Get device path */
-
-  sprintf(devpath, CONFIG_EVENT_FD_VFS_PATH "/efd%u", new_dev->minor);
-
-  /* Register the driver */
-
-  ret = register_driver(devpath, &g_eventfd_fops, 0666, new_dev);
-  if (ret < 0)
+  new_fd = file_allocate(&g_eventfd_inode, O_RDWR | flags,
+                         0, new_dev, 0, true);
+  if (new_fd < 0)
     {
-      ferr("Failed to register new device %s: %d\n", devpath, ret);
-      goto exit_release_minor;
+      ret = new_fd;
+      goto exit_with_dev;
     }
 
   /* Device is ready for use */
 
   nxmutex_unlock(&new_dev->lock);
 
-  /* Try open new device */
-
-  new_fd = nx_open(devpath, O_RDWR |
-    (flags & (EFD_NONBLOCK | EFD_SEMAPHORE | EFD_CLOEXEC)));
-
-  if (new_fd < 0)
-    {
-      ret = new_fd;
-      goto exit_unregister_driver;
-    }
-
   return new_fd;
 
-exit_unregister_driver:
-  unregister_driver(devpath);
-exit_release_minor:
-  eventfd_release_minor(new_dev->minor);
+exit_with_dev:
   eventfd_destroy(new_dev);
 exit_set_errno:
   set_errno(-ret);
diff --git a/fs/vfs/fs_timerfd.c b/fs/vfs/fs_timerfd.c
index d6c5460aa6..6fe502c6d0 100644
--- a/fs/vfs/fs_timerfd.c
+++ b/fs/vfs/fs_timerfd.c
@@ -55,7 +55,7 @@
 typedef struct timerfd_waiter_sem_s
 {
   sem_t sem;
-  struct timerfd_waiter_sem_s *next;
+  FAR struct timerfd_waiter_sem_s *next;
 } timerfd_waiter_sem_t;
 
 /* This structure describes the internal state of the driver */
@@ -71,7 +71,6 @@ struct timerfd_priv_s
   struct work_s             work;    /* For deferred timeout operations */
   timerfd_t                 counter; /* timerfd counter */
   spinlock_t                splock;  /* timerfd counter specific lock */
-  unsigned int              minor;   /* timerfd minor number */
   uint8_t                   crefs;   /* References counts on timerfd (max: 255) */
 
   /* The following is a list if poll structures of threads waiting for
@@ -101,9 +100,6 @@ static int timerfd_blocking_io(FAR struct timerfd_priv_s *dev,
                                FAR timerfd_waiter_sem_t  *sem,
                                FAR timerfd_waiter_sem_t **slist);
 
-static unsigned int timerfd_get_unique_minor(void);
-static void timerfd_release_minor(unsigned int minor);
-
 static FAR struct timerfd_priv_s *timerfd_allocdev(void);
 static void timerfd_destroy(FAR struct timerfd_priv_s *dev);
 
@@ -132,6 +128,18 @@ static const struct file_operations g_timerfd_fops =
 #endif
 };
 
+static struct inode g_timerfd_inode =
+{
+  NULL,                   /* i_parent */
+  NULL,                   /* i_peer */
+  NULL,                   /* i_child */
+  1,                      /* i_crefs */
+  FSNODEFLAG_TYPE_DRIVER, /* i_flags */
+  {
+    &g_timerfd_fops       /* u */
+  }
+};
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -157,6 +165,7 @@ static void timerfd_destroy(FAR struct timerfd_priv_s *dev)
 {
   wd_cancel(&dev->wdog);
   work_cancel(TIMER_FD_WORK, &dev->work);
+  nxmutex_unlock(&dev->lock);
   nxmutex_destroy(&dev->lock);
   kmm_free(dev);
 }
@@ -173,21 +182,9 @@ static timerfd_t timerfd_get_counter(FAR struct timerfd_priv_s *dev)
   return counter;
 }
 
-static unsigned int timerfd_get_unique_minor(void)
-{
-  static unsigned int minor;
-
-  return minor++;
-}
-
-static void timerfd_release_minor(unsigned int minor)
-{
-}
-
 static int timerfd_open(FAR struct file *filep)
 {
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct timerfd_priv_s *priv = inode->i_private;
+  FAR struct timerfd_priv_s *priv = filep->f_priv;
   int ret;
 
   /* Get exclusive access to the device structures */
@@ -198,8 +195,6 @@ static int timerfd_open(FAR struct file *filep)
       return ret;
     }
 
-  finfo("crefs: %d <%s>\n", priv->crefs, inode->i_name);
-
   if (priv->crefs >= 255)
     {
       /* More than 255 opens; uint8_t would overflow to zero */
@@ -220,13 +215,8 @@ static int timerfd_open(FAR struct file *filep)
 
 static int timerfd_close(FAR struct file *filep)
 {
+  FAR struct timerfd_priv_s *priv = filep->f_priv;
   int ret;
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct timerfd_priv_s *priv = inode->i_private;
-
-  /* devpath: TIMER_FD_VFS_PATH + /tfd (4) + %u (10) + null char (1) */
-
-  char devpath[sizeof(CONFIG_TIMER_FD_VFS_PATH) + 4 + 10 + 1];
 
   /* Get exclusive access to the device structures */
 
@@ -236,8 +226,6 @@ static int timerfd_close(FAR struct file *filep)
       return ret;
     }
 
-  finfo("crefs: %d <%s>\n", priv->crefs, inode->i_name);
-
   /* Decrement the references to the driver.  If the reference count will
    * decrement to 0, then uninitialize the driver.
    */
@@ -254,16 +242,8 @@ static int timerfd_close(FAR struct file *filep)
   /* Re-create the path to the driver. */
 
   finfo("destroy\n");
-  sprintf(devpath, CONFIG_TIMER_FD_VFS_PATH "/tfd%u", priv->minor);
-
-  /* Will be unregistered later after close is done */
 
-  unregister_driver(devpath);
-
-  DEBUGASSERT(nxmutex_is_locked(&priv->lock));
-  timerfd_release_minor(priv->minor);
   timerfd_destroy(priv);
-
   return OK;
 }
 
@@ -272,6 +252,7 @@ static int timerfd_blocking_io(FAR struct timerfd_priv_s *dev,
                                FAR timerfd_waiter_sem_t **slist)
 {
   int ret;
+
   sem->next = *slist;
   *slist = sem;
 
@@ -318,8 +299,7 @@ static int timerfd_blocking_io(FAR struct timerfd_priv_s *dev,
 static ssize_t timerfd_read(FAR struct file *filep, FAR char *buffer,
                             size_t len)
 {
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct timerfd_priv_s *dev = inode->i_private;
+  FAR struct timerfd_priv_s *dev = filep->f_priv;
   irqstate_t intflags;
   ssize_t ret;
 
@@ -381,8 +361,7 @@ static ssize_t timerfd_read(FAR struct file *filep, FAR char *buffer,
 static int timerfd_poll(FAR struct file *filep, FAR struct pollfd *fds,
                         bool setup)
 {
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct timerfd_priv_s *dev = inode->i_private;
+  FAR struct timerfd_priv_s *dev = filep->f_priv;
   int ret;
   int i;
 
@@ -402,8 +381,8 @@ static int timerfd_poll(FAR struct file *filep, FAR struct pollfd *fds,
 
       /* Remove all memory of the poll setup */
 
-      *slot                = NULL;
-      fds->priv            = NULL;
+      *slot     = NULL;
+      fds->priv = NULL;
       goto out;
     }
 
@@ -518,18 +497,15 @@ int timerfd_create(int clockid, int flags)
 
   /* Sanity checks. */
 
-  if (clockid != CLOCK_REALTIME &&
-      clockid != CLOCK_MONOTONIC &&
-      clockid != CLOCK_BOOTTIME)
+  if ((clockid != CLOCK_REALTIME &&
+       clockid != CLOCK_MONOTONIC &&
+       clockid != CLOCK_BOOTTIME) ||
+      (flags & ~(TFD_NONBLOCK | TFD_CLOEXEC)) != 0)
     {
       ret = -EINVAL;
       goto errout;
     }
 
-  /* devpath: TIMER_FD_VFS_PATH + /tfd (4) + %u (10) + null char (1) */
-
-  char devpath[sizeof(CONFIG_TIMER_FD_VFS_PATH) + 4 + 10 + 1];
-
   /* Allocate instance data for this driver */
 
   new_dev = timerfd_allocdev();
@@ -544,46 +520,21 @@ int timerfd_create(int clockid, int flags)
   /* Initialize the timer instance */
 
   new_dev->clock = clockid;
-
-  /* Request a unique minor device number */
-
-  new_dev->minor = timerfd_get_unique_minor();
-
-  /* Get device path */
-
-  sprintf(devpath, CONFIG_TIMER_FD_VFS_PATH "/tfd%u", new_dev->minor);
-
-  /* Register the driver */
-
-  ret = register_driver(devpath, &g_timerfd_fops, 0444, new_dev);
-  if (ret < 0)
+  new_fd = file_allocate(&g_timerfd_inode, O_RDONLY | flags,
+                         0, new_dev, 0, true);
+  if (new_fd < 0)
     {
-      ferr("Failed to register new device %s: %d\n", devpath, ret);
-      ret = -ENODEV;
-      goto errout_release_minor;
+      ret = new_fd;
+      goto errout_with_dev;
     }
 
   /* Device is ready for use */
 
   nxmutex_unlock(&new_dev->lock);
 
-  /* Try open new device */
-
-  new_fd = nx_open(devpath, O_RDONLY |
-                   (flags & (TFD_NONBLOCK | TFD_CLOEXEC)));
-
-  if (new_fd < 0)
-    {
-      ret = new_fd;
-      goto errout_unregister_driver;
-    }
-
   return new_fd;
 
-errout_unregister_driver:
-  unregister_driver(devpath);
-errout_release_minor:
-  timerfd_release_minor(new_dev->minor);
+errout_with_dev:
   timerfd_destroy(new_dev);
 errout:
   set_errno(-ret);
@@ -594,8 +545,8 @@ int timerfd_settime(int fd, int flags,
                     FAR const struct itimerspec *new_value,
                     FAR struct itimerspec *old_value)
 {
-  FAR struct file *filep;
   FAR struct timerfd_priv_s *dev;
+  FAR struct file *filep;
   irqstate_t intflags;
   sclock_t delay;
   int ret;
@@ -630,7 +581,7 @@ int timerfd_settime(int fd, int flags,
       goto errout;
     }
 
-  dev = (FAR struct timerfd_priv_s *)filep->f_inode->i_private;
+  dev = (FAR struct timerfd_priv_s *)filep->f_priv;
 
   if (old_value)
     {
@@ -743,8 +694,8 @@ errout:
 
 int timerfd_gettime(int fd, FAR struct itimerspec *curr_value)
 {
-  FAR struct file *filep;
   FAR struct timerfd_priv_s *dev;
+  FAR struct file *filep;
   sclock_t ticks;
   int ret;
 
@@ -772,7 +723,7 @@ int timerfd_gettime(int fd, FAR struct itimerspec *curr_value)
       goto errout;
     }
 
-  dev = (FAR struct timerfd_priv_s *)filep->f_inode->i_private;
+  dev = (FAR struct timerfd_priv_s *)filep->f_priv;
 
   /* Get the number of ticks before the underlying watchdog expires */
 


[nuttx] 02/02: timerfd: remove timeout work and do notify in isr

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit d36b7fea455c0c194c1e5efb1388a42cfec71f43
Author: dongjiuzhu1 <do...@xiaomi.com>
AuthorDate: Fri Dec 23 14:37:39 2022 +0800

    timerfd: remove timeout work and do notify in isr
    
    1.Optimize notification speed
    2.using enter/leave critical to replace spin_lock to avoid race condition
    
    Signed-off-by: dongjiuzhu1 <do...@xiaomi.com>
---
 fs/vfs/fs_timerfd.c | 178 +++++++++++++++-------------------------------------
 1 file changed, 50 insertions(+), 128 deletions(-)

diff --git a/fs/vfs/fs_timerfd.c b/fs/vfs/fs_timerfd.c
index 6fe502c6d0..639ab63a7b 100644
--- a/fs/vfs/fs_timerfd.c
+++ b/fs/vfs/fs_timerfd.c
@@ -32,8 +32,6 @@
 #include <debug.h>
 
 #include <nuttx/wdog.h>
-#include <nuttx/wqueue.h>
-#include <nuttx/spinlock.h>
 #include <nuttx/mutex.h>
 
 #include <sys/ioctl.h>
@@ -46,8 +44,6 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define TIMER_FD_WORK LPWORK
-
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -68,9 +64,7 @@ struct timerfd_priv_s
   int                       delay;   /* If non-zero, used to reset repetitive
                                       * timers */
   struct wdog_s             wdog;    /* The watchdog that provides the timing */
-  struct work_s             work;    /* For deferred timeout operations */
   timerfd_t                 counter; /* timerfd counter */
-  spinlock_t                splock;  /* timerfd counter specific lock */
   uint8_t                   crefs;   /* References counts on timerfd (max: 255) */
 
   /* The following is a list if poll structures of threads waiting for
@@ -103,8 +97,7 @@ static int timerfd_blocking_io(FAR struct timerfd_priv_s *dev,
 static FAR struct timerfd_priv_s *timerfd_allocdev(void);
 static void timerfd_destroy(FAR struct timerfd_priv_s *dev);
 
-static void timerfd_timeout_work(FAR void *arg);
-static void timerfd_timeout(wdparm_t idev);
+static void timerfd_timeout(wdparm_t arg);
 
 /****************************************************************************
  * Private Data
@@ -164,24 +157,11 @@ static FAR struct timerfd_priv_s *timerfd_allocdev(void)
 static void timerfd_destroy(FAR struct timerfd_priv_s *dev)
 {
   wd_cancel(&dev->wdog);
-  work_cancel(TIMER_FD_WORK, &dev->work);
   nxmutex_unlock(&dev->lock);
   nxmutex_destroy(&dev->lock);
   kmm_free(dev);
 }
 
-static timerfd_t timerfd_get_counter(FAR struct timerfd_priv_s *dev)
-{
-  timerfd_t counter;
-  irqstate_t intflags;
-
-  intflags = spin_lock_irqsave(&dev->splock);
-  counter = dev->counter;
-  spin_unlock_irqrestore(&dev->splock, intflags);
-
-  return counter;
-}
-
 static int timerfd_open(FAR struct file *filep)
 {
   FAR struct timerfd_priv_s *priv = filep->f_priv;
@@ -256,22 +236,13 @@ static int timerfd_blocking_io(FAR struct timerfd_priv_s *dev,
   sem->next = *slist;
   *slist = sem;
 
-  nxmutex_unlock(&dev->lock);
-
   /* Wait for timerfd to notify */
 
   ret = nxsem_wait(&sem->sem);
-
   if (ret < 0)
     {
       FAR timerfd_waiter_sem_t *cur_sem;
 
-      /* Interrupted wait, unregister semaphore
-       * TODO ensure that lock wait does not fail (ECANCELED)
-       */
-
-      nxmutex_lock(&dev->lock);
-
       cur_sem = *slist;
       if (cur_sem == sem)
         {
@@ -288,12 +259,9 @@ static int timerfd_blocking_io(FAR struct timerfd_priv_s *dev,
                 }
             }
         }
-
-      nxmutex_unlock(&dev->lock);
-      return ret;
     }
 
-  return nxmutex_lock(&dev->lock);
+  return ret;
 }
 
 static ssize_t timerfd_read(FAR struct file *filep, FAR char *buffer,
@@ -308,21 +276,22 @@ static ssize_t timerfd_read(FAR struct file *filep, FAR char *buffer,
       return -EINVAL;
     }
 
-  ret = nxmutex_lock(&dev->lock);
-  if (ret < 0)
-    {
-      return ret;
-    }
+  /* Ensure that interrupts are disabled and we do not lose counts
+   * if expiration occurs after read, but before setting counter
+   * to zero
+   */
+
+  intflags = enter_critical_section();
 
   /* Wait for an incoming event */
 
-  if (timerfd_get_counter(dev) == 0)
+  if (dev->counter == 0)
     {
       timerfd_waiter_sem_t sem;
 
       if (filep->f_oflags & O_NONBLOCK)
         {
-          nxmutex_unlock(&dev->lock);
+          leave_critical_section(intflags);
           return -EAGAIN;
         }
 
@@ -332,28 +301,21 @@ static ssize_t timerfd_read(FAR struct file *filep, FAR char *buffer,
           ret = timerfd_blocking_io(dev, &sem, &dev->rdsems);
           if (ret < 0)
             {
+              leave_critical_section(intflags);
               nxsem_destroy(&sem.sem);
               return ret;
             }
         }
-      while (timerfd_get_counter(dev) == 0);
+      while (dev->counter == 0);
 
       nxsem_destroy(&sem.sem);
     }
 
-  /* Device ready for read.  Ensure that interrupts are disabled and we
-   * do not lose counts if expiration occurs after read, but before setting
-   * counter to zero
-   */
-
-  intflags = spin_lock_irqsave(&dev->splock);
-
   *(FAR timerfd_t *)buffer = dev->counter;
   dev->counter = 0;
 
-  spin_unlock_irqrestore(&dev->splock, intflags);
+  leave_critical_section(intflags);
 
-  nxmutex_unlock(&dev->lock);
   return sizeof(timerfd_t);
 }
 
@@ -362,17 +324,11 @@ static int timerfd_poll(FAR struct file *filep, FAR struct pollfd *fds,
                         bool setup)
 {
   FAR struct timerfd_priv_s *dev = filep->f_priv;
-  int ret;
+  irqstate_t intflags;
+  int ret = OK;
   int i;
 
-  ret = nxmutex_lock(&dev->lock);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  ret = OK;
-
+  intflags = enter_critical_section();
   if (!setup)
     {
       /* This is a request to tear down the poll. */
@@ -413,7 +369,7 @@ static int timerfd_poll(FAR struct file *filep, FAR struct pollfd *fds,
 
   /* Notify the POLLIN event if the counter is not zero */
 
-  if (timerfd_get_counter(dev) > 0)
+  if (dev->counter > 0)
     {
 #ifdef CONFIG_TIMER_FD_POLL
       poll_notify(dev->fds, CONFIG_TIMER_FD_NPOLLWAITERS, POLLIN);
@@ -421,22 +377,32 @@ static int timerfd_poll(FAR struct file *filep, FAR struct pollfd *fds,
     }
 
 out:
-  nxmutex_unlock(&dev->lock);
+  leave_critical_section(intflags);
   return ret;
 }
 #endif
 
-static void timerfd_timeout_work(FAR void *arg)
+static void timerfd_timeout(wdparm_t arg)
 {
   FAR struct timerfd_priv_s *dev = (FAR struct timerfd_priv_s *)arg;
   FAR timerfd_waiter_sem_t *cur_sem;
-  int ret;
+  irqstate_t intflags;
 
-  ret = nxmutex_lock(&dev->lock);
-  if (ret < 0)
+  /* Disable interrupts to ensure that expiration counter is accessed
+   * atomically
+   */
+
+  intflags = enter_critical_section();
+
+  /* Increment timer expiration counter */
+
+  dev->counter++;
+
+  /* If this is a repetitive timer, then restart the watchdog */
+
+  if (dev->delay > 0)
     {
-      wd_cancel(&dev->wdog);
-      return;
+      wd_start(&dev->wdog, dev->delay, timerfd_timeout, arg);
     }
 
 #ifdef CONFIG_TIMER_FD_POLL
@@ -455,34 +421,8 @@ static void timerfd_timeout_work(FAR void *arg)
     }
 
   dev->rdsems = NULL;
-  nxmutex_unlock(&dev->lock);
-}
 
-static void timerfd_timeout(wdparm_t idev)
-{
-  FAR struct timerfd_priv_s *dev = (FAR struct timerfd_priv_s *)idev;
-  irqstate_t intflags;
-
-  /* Disable interrupts to ensure that expiration counter is accessed
-   * atomically
-   */
-
-  intflags = spin_lock_irqsave(&dev->splock);
-
-  /* Increment timer expiration counter */
-
-  dev->counter++;
-
-  work_queue(TIMER_FD_WORK, &dev->work, timerfd_timeout_work, dev, 0);
-
-  /* If this is a repetitive timer, then restart the watchdog */
-
-  if (dev->delay)
-    {
-      wd_start(&dev->wdog, dev->delay, timerfd_timeout, idev);
-    }
-
-  spin_unlock_irqrestore(&dev->splock, intflags);
+  leave_critical_section(intflags);
 }
 
 /****************************************************************************
@@ -559,7 +499,7 @@ int timerfd_settime(int fd, int flags,
       goto errout;
     }
 
-  if (flags && (flags & TFD_TIMER_ABSTIME) == 0)
+  if ((flags & ~TFD_TIMER_ABSTIME) != 0)
     {
       ret = -EINVAL;
       goto errout;
@@ -583,6 +523,12 @@ int timerfd_settime(int fd, int flags,
 
   dev = (FAR struct timerfd_priv_s *)filep->f_priv;
 
+  /* Disable interrupts here to ensure that expiration counter is accessed
+   * atomicaly.
+   */
+
+  intflags = enter_critical_section();
+
   if (old_value)
     {
       /* Get the number of ticks before the underlying watchdog expires */
@@ -595,22 +541,12 @@ int timerfd_settime(int fd, int flags,
       clock_ticks2time(dev->delay, &old_value->it_interval);
     }
 
-  /* Disable interrupts here to ensure that expiration counter is accessed
-   * atomicaly and timeout work is canceled with the same sequence
-   */
-
-  intflags = spin_lock_irqsave(&dev->splock);
-
   /* Disarm the timer (in case the timer was already armed when
    * timerfd_settime() is called).
    */
 
   wd_cancel(&dev->wdog);
 
-  /* Cancel notification work */
-
-  work_cancel(TIMER_FD_WORK, &dev->work);
-
   /* Clear expiration counter */
 
   dev->counter = 0;
@@ -621,25 +557,14 @@ int timerfd_settime(int fd, int flags,
 
   if (new_value->it_value.tv_sec <= 0 && new_value->it_value.tv_nsec <= 0)
     {
-      spin_unlock_irqrestore(&dev->splock, intflags);
+      leave_critical_section(intflags);
       return OK;
     }
 
   /* Setup up any repetitive timer */
 
-  if (new_value->it_interval.tv_sec > 0 ||
-      new_value->it_interval.tv_nsec > 0)
-    {
-      clock_time2ticks(&new_value->it_interval, &delay);
-
-      /* REVISIT: Should delay be sclock_t? */
-
-      dev->delay = (int)delay;
-    }
-  else
-    {
-      dev->delay = 0;
-    }
+  clock_time2ticks(&new_value->it_interval, &delay);
+  dev->delay = delay;
 
   /* We need to disable timer interrupts through the following section so
    * that the system timer is stable.
@@ -674,17 +599,14 @@ int timerfd_settime(int fd, int flags,
 
   /* Then start the watchdog */
 
-  if (delay > 0)
+  ret = wd_start(&dev->wdog, delay, timerfd_timeout, (wdparm_t)dev);
+  if (ret < 0)
     {
-      ret = wd_start(&dev->wdog, delay, timerfd_timeout, (wdparm_t)dev);
-      if (ret < 0)
-        {
-          spin_unlock_irqrestore(&dev->splock, intflags);
-          goto errout;
-        }
+      leave_critical_section(intflags);
+      goto errout;
     }
 
-  spin_unlock_irqrestore(&dev->splock, intflags);
+  leave_critical_section(intflags);
   return OK;
 
 errout: