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


The following commit(s) were added to refs/heads/master by this push:
     new 607792d452 fs_files.c: make sure that fs_getfilep is not interrupted 
when holding mutex
607792d452 is described below

commit 607792d4528a2cdc1d29c2692c304e11be397908
Author: raiden00pl <[email protected]>
AuthorDate: Fri Nov 3 14:16:43 2023 +0100

    fs_files.c: make sure that fs_getfilep is not interrupted when holding mutex
    
    this fixes the issue https://github.com/apache/nuttx/issues/6012
---
 fs/inode/fs_files.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c
index dec3488fd0..bcb7638288 100644
--- a/fs/inode/fs_files.c
+++ b/fs/inode/fs_files.c
@@ -547,6 +547,7 @@ void files_close_onexec(FAR struct tcb_s *tcb)
 int fs_getfilep(int fd, FAR struct file **filep)
 {
   FAR struct filelist *list;
+  irqstate_t flags;
   int ret;
 
 #ifdef CONFIG_FDCHECK
@@ -574,6 +575,27 @@ int fs_getfilep(int fd, FAR struct file **filep)
       return -EBADF;
     }
 
+  /* Protect this part with a critical section to make sure that we won't
+   * interrupt the mutex lock-unclock sequence below which may lead to the
+   * priority inversion. The case is as follows:
+   *
+   *   We have two threads: low-priority thread A and high-priority thread B,
+   *   both threads share the same task group data.
+   *
+   *   Thread A performs IO on files periodically. Thread B is woken up by a
+   *   high-frequency interrupts, and performs IO on files periodically.
+   *
+   *   There is a chance that thread B wakes up exactly when thread A holds
+   *   the mutex below, and consequently the file access in thread B will be
+   *   delayed due to thread A holding the list->fl_lock mutex and execution
+   *   will be returned to a thread with lower priority.
+   *
+   * The correct solution to this problem is to use the read-write lock,
+   * which is currently not supported by NuttX.
+   */
+
+  flags = enter_critical_section();
+
   /* The descriptor is in a valid range to file descriptor... Get the
    * thread-specific file list.
    */
@@ -583,6 +605,7 @@ int fs_getfilep(int fd, FAR struct file **filep)
   ret = nxmutex_lock(&list->fl_lock);
   if (ret < 0)
     {
+      leave_critical_section(flags);
       return ret;
     }
 
@@ -598,6 +621,7 @@ int fs_getfilep(int fd, FAR struct file **filep)
     }
 
   nxmutex_unlock(&list->fl_lock);
+  leave_critical_section(flags);
   return ret;
 }
 

Reply via email to