From aa673e7d16a67ebb1fa058c7e634e6e7342b5a7f Mon Sep 17 00:00:00 2001 From: chenrun1 Date: Tue, 23 Jul 2024 19:30:19 +0800 Subject: [PATCH 1/4] fs_inode:Change the type of i_crefs to atomic_int MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: 1.Modified the i_crefs from int16_t to atomic_int 2.Modified the i_crefs add, delete, read, and initialize interfaces to atomic operations The purpose of this change is to avoid deadlock in cross-core scenarios, where A Core blocks B Core’s request for a write operation to A Core when A Core requests a read operation to B Core. Signed-off-by: chenrun1 --- arch/arm/src/cxd56xx/cxd56_sph.c | 2 +- arch/arm/src/cxd56xx/cxd56_uart0.c | 4 ++-- crypto/cryptodev.c | 2 +- drivers/serial/pty.c | 2 +- fs/inode/fs_inodeaddref.c | 7 +----- fs/inode/fs_inodefind.c | 2 +- fs/inode/fs_inoderelease.c | 37 +----------------------------- fs/inode/fs_inoderemove.c | 4 ++-- fs/inode/fs_inodereserve.c | 2 +- fs/mount/fs_mount.c | 4 ++-- fs/mount/fs_umount2.c | 3 +-- fs/mqueue/mq_open.c | 4 ++-- fs/mqueue/mq_unlink.c | 2 +- fs/notify/inotify.c | 2 +- fs/semaphore/sem_close.c | 27 +--------------------- fs/semaphore/sem_open.c | 2 +- fs/shm/shm_open.c | 2 +- fs/shm/shmfs.c | 31 +++++++------------------ fs/socket/socket.c | 2 +- fs/vfs/fs_dir.c | 6 ++--- fs/vfs/fs_epoll.c | 2 +- fs/vfs/fs_eventfd.c | 2 +- fs/vfs/fs_pseudofile.c | 23 +++++++------------ fs/vfs/fs_signalfd.c | 2 +- fs/vfs/fs_timerfd.c | 2 +- include/nuttx/fs/fs.h | 3 ++- 26 files changed, 47 insertions(+), 134 deletions(-) diff --git a/arch/arm/src/cxd56xx/cxd56_sph.c b/arch/arm/src/cxd56xx/cxd56_sph.c index f770d7753f0c1..72e6b0cbb257c 100644 --- a/arch/arm/src/cxd56xx/cxd56_sph.c +++ b/arch/arm/src/cxd56xx/cxd56_sph.c @@ -104,7 +104,7 @@ static int sph_open(struct file *filep) { /* Exclusive access */ - if (filep->f_inode->i_crefs > 2) + if (atomic_load(&filep->f_inode->i_crefs) > 2) { return ERROR; } diff --git a/arch/arm/src/cxd56xx/cxd56_uart0.c b/arch/arm/src/cxd56xx/cxd56_uart0.c index 1f1841f2006e4..c0eeb97125331 100644 --- a/arch/arm/src/cxd56xx/cxd56_uart0.c +++ b/arch/arm/src/cxd56xx/cxd56_uart0.c @@ -115,7 +115,7 @@ static int uart0_open(struct file *filep) int stop; int ret; - if (inode->i_crefs > 2) + if (atomic_load(&inode->i_crefs) > 2) { return OK; } @@ -172,7 +172,7 @@ static int uart0_close(struct file *filep) { struct inode *inode = filep->f_inode; - if (inode->i_crefs == 2) + if (atomic_load(&inode->i_crefs) == 2) { fw_pd_uartdisable(0); fw_pd_uartuninit(0); diff --git a/crypto/cryptodev.c b/crypto/cryptodev.c index 2e6adcf09e71b..1e545de8f3670 100644 --- a/crypto/cryptodev.c +++ b/crypto/cryptodev.c @@ -154,7 +154,7 @@ static const struct file_operations g_cryptoops = static struct inode g_cryptoinode = { - .i_crefs = 1, + .i_crefs = ATOMIC_VAR_INIT(1), .u.i_ops = &g_cryptofops }; diff --git a/drivers/serial/pty.c b/drivers/serial/pty.c index 6e30277c5db47..bc37f9050de6a 100644 --- a/drivers/serial/pty.c +++ b/drivers/serial/pty.c @@ -336,7 +336,7 @@ static int pty_close(FAR struct file *filep) /* Check if the decremented inode reference count would go to zero */ - if (inode->i_crefs == 1) + if (atomic_load(&inode->i_crefs) == 1) { /* Did the (single) master just close its reference? */ diff --git a/fs/inode/fs_inodeaddref.c b/fs/inode/fs_inodeaddref.c index 896e7d1d389cb..9187a8fae0d81 100644 --- a/fs/inode/fs_inodeaddref.c +++ b/fs/inode/fs_inodeaddref.c @@ -47,12 +47,7 @@ int inode_addref(FAR struct inode *inode) if (inode) { - ret = inode_lock(); - if (ret >= 0) - { - inode->i_crefs++; - inode_unlock(); - } + atomic_fetch_add(&inode->i_crefs, 1); } return ret; diff --git a/fs/inode/fs_inodefind.c b/fs/inode/fs_inodefind.c index d8e3a9815cefe..47fe84df95275 100644 --- a/fs/inode/fs_inodefind.c +++ b/fs/inode/fs_inodefind.c @@ -71,7 +71,7 @@ int inode_find(FAR struct inode_search_s *desc) /* Increment the reference count on the inode */ - node->i_crefs++; + atomic_fetch_add(&node->i_crefs, 1); } inode_unlock(); diff --git a/fs/inode/fs_inoderelease.c b/fs/inode/fs_inoderelease.c index 0a32620316972..0c5a680c66c60 100644 --- a/fs/inode/fs_inoderelease.c +++ b/fs/inode/fs_inoderelease.c @@ -47,49 +47,14 @@ void inode_release(FAR struct inode *inode) { - int ret; - if (inode) { /* Decrement the references of the inode */ - do - { - ret = inode_lock(); - - /* This only possible error is due to cancellation of the thread. - * We need to try again anyway in this case, otherwise the - * reference count would be wrong. - */ - - DEBUGASSERT(ret == OK || ret == -ECANCELED); - } - while (ret < 0); - - if (inode->i_crefs) - { - inode->i_crefs--; - } - - /* If the subtree was previously deleted and the reference - * count has decrement to zero, then delete the inode - * now. - */ - - if (inode->i_crefs <= 0) + if (atomic_fetch_sub(&inode->i_crefs, 1) <= 1) { - /* If the inode has been properly unlinked, then the peer pointer - * should be NULL. - */ - - inode_unlock(); - DEBUGASSERT(inode->i_peer == NULL); inode_free(inode); } - else - { - inode_unlock(); - } } } diff --git a/fs/inode/fs_inoderemove.c b/fs/inode/fs_inoderemove.c index e5396df2a0d77..0006855153d67 100644 --- a/fs/inode/fs_inoderemove.c +++ b/fs/inode/fs_inoderemove.c @@ -96,7 +96,7 @@ static FAR struct inode *inode_unlink(FAR const char *path) node->i_peer = NULL; node->i_parent = NULL; - node->i_crefs--; + atomic_fetch_sub(&node->i_crefs, 1); } RELEASE_SEARCH(&desc); @@ -134,7 +134,7 @@ int inode_remove(FAR const char *path) * to it */ - if (node->i_crefs) + if (atomic_load(&node->i_crefs)) { return -EBUSY; } diff --git a/fs/inode/fs_inodereserve.c b/fs/inode/fs_inodereserve.c index f7ba4002e3826..33fdbfd043eb3 100644 --- a/fs/inode/fs_inodereserve.c +++ b/fs/inode/fs_inodereserve.c @@ -85,7 +85,7 @@ static FAR struct inode *inode_alloc(FAR const char *name, mode_t mode) if (node) { node->i_ino = g_ino++; - node->i_crefs = 1; + atomic_init(&node->i_crefs, 1); #ifdef CONFIG_PSEUDOFS_ATTRIBUTES node->i_mode = mode; clock_gettime(CLOCK_REALTIME, &node->i_atime); diff --git a/fs/mount/fs_mount.c b/fs/mount/fs_mount.c index 55c3cd25e6ddf..a23fdc364f4e3 100644 --- a/fs/mount/fs_mount.c +++ b/fs/mount/fs_mount.c @@ -449,7 +449,7 @@ int nx_mount(FAR const char *source, FAR const char *target, if (drvr_inode != NULL) #endif { - drvr_inode->i_crefs++; + atomic_fetch_add(&drvr_inode->i_crefs, 1); } #endif @@ -477,7 +477,7 @@ int nx_mount(FAR const char *source, FAR const char *target, if (drvr_inode != NULL) #endif { - drvr_inode->i_crefs--; + atomic_fetch_sub(&drvr_inode->i_crefs, 1); } #endif diff --git a/fs/mount/fs_umount2.c b/fs/mount/fs_umount2.c index 121be901a873b..76ee449ece854 100644 --- a/fs/mount/fs_umount2.c +++ b/fs/mount/fs_umount2.c @@ -145,8 +145,7 @@ int nx_umount2(FAR const char *target, unsigned int flags) { /* Just decrement the reference count (without deleting it) */ - DEBUGASSERT(mountpt_inode->i_crefs > 0); - mountpt_inode->i_crefs--; + atomic_fetch_sub(&mountpt_inode->i_crefs, 1); inode_unlock(); } else diff --git a/fs/mqueue/mq_open.c b/fs/mqueue/mq_open.c index 9c4bbbc326bf8..84d14545587b0 100644 --- a/fs/mqueue/mq_open.c +++ b/fs/mqueue/mq_open.c @@ -74,7 +74,7 @@ static int nxmq_file_close(FAR struct file *filep) { FAR struct inode *inode = filep->f_inode; - if (inode->i_crefs <= 0) + if (atomic_load(&inode->i_crefs) <= 0) { FAR struct mqueue_inode_s *msgq = inode->i_private; @@ -322,7 +322,7 @@ static int file_mq_vopen(FAR struct file *mq, FAR const char *mq_name, /* Set the initial reference count on this inode to one */ - inode->i_crefs++; + atomic_fetch_add(&inode->i_crefs, 1); if (created) { diff --git a/fs/mqueue/mq_unlink.c b/fs/mqueue/mq_unlink.c index c5280e51b1af2..d6a1c14e58dea 100644 --- a/fs/mqueue/mq_unlink.c +++ b/fs/mqueue/mq_unlink.c @@ -56,7 +56,7 @@ static void mq_inode_release(FAR struct inode *inode) { - if (inode->i_crefs <= 1) + if (atomic_load(&inode->i_crefs) <= 1) { FAR struct mqueue_inode_s *msgq = inode->i_private; diff --git a/fs/notify/inotify.c b/fs/notify/inotify.c index 5b22cfd8e376a..3f95180fd448b 100644 --- a/fs/notify/inotify.c +++ b/fs/notify/inotify.c @@ -131,7 +131,7 @@ static struct inode g_inotify_inode = NULL, NULL, NULL, - 1, + ATOMIC_VAR_INIT(1), FSNODEFLAG_TYPE_DRIVER, { &g_inotify_fops diff --git a/fs/semaphore/sem_close.c b/fs/semaphore/sem_close.c index fdab4694860f3..ae8bd1265200c 100644 --- a/fs/semaphore/sem_close.c +++ b/fs/semaphore/sem_close.c @@ -71,7 +71,6 @@ int nxsem_close(FAR sem_t *sem) { FAR struct nsem_inode_s *nsem; struct inode *inode; - int ret; DEBUGASSERT(sem); @@ -81,34 +80,13 @@ int nxsem_close(FAR sem_t *sem) DEBUGASSERT(nsem->ns_inode); inode = nsem->ns_inode; - /* Decrement the reference count on the inode */ - - do - { - ret = inode_lock(); - - /* The only error that is expected is due to thread cancellation. - * At this point, we must continue to free the semaphore anyway. - */ - - DEBUGASSERT(ret == OK || ret == -ECANCELED); - } - while (ret < 0); - - if (inode->i_crefs > 0) - { - inode->i_crefs--; - } - /* If the semaphore was previously unlinked and the reference count has * decremented to zero, then release the semaphore and delete the inode * now. */ - if (inode->i_crefs <= 0) + if (atomic_fetch_sub(&inode->i_crefs, 1) <= 1) { - /* Destroy the semaphore and free the container */ - nxsem_destroy(&nsem->ns_sem); group_free(NULL, nsem); @@ -116,16 +94,13 @@ int nxsem_close(FAR sem_t *sem) * unlinked, then the peer pointer should be NULL. */ - inode_unlock(); #ifdef CONFIG_FS_NOTIFY notify_close2(inode); #endif DEBUGASSERT(inode->i_peer == NULL); inode_free(inode); - return OK; } - inode_unlock(); return OK; } diff --git a/fs/semaphore/sem_open.c b/fs/semaphore/sem_open.c index 03232b6b6c4bd..406244b31d05c 100644 --- a/fs/semaphore/sem_open.c +++ b/fs/semaphore/sem_open.c @@ -211,7 +211,7 @@ int nxsem_open(FAR sem_t **sem, FAR const char *name, int oflags, ...) /* Initialize the inode */ INODE_SET_NAMEDSEM(inode); - inode->i_crefs++; + atomic_fetch_add(&inode->i_crefs, 1); /* Initialize the semaphore */ diff --git a/fs/shm/shm_open.c b/fs/shm/shm_open.c index 55ae338fba167..cf980497e74b0 100644 --- a/fs/shm/shm_open.c +++ b/fs/shm/shm_open.c @@ -137,7 +137,7 @@ static int file_shm_open(FAR struct file *shm, FAR const char *name, INODE_SET_SHM(inode); inode->u.i_ops = &g_shmfs_operations; inode->i_private = NULL; - inode->i_crefs++; + atomic_fetch_add(&inode->i_crefs, 1); } /* Associate the inode with a file structure */ diff --git a/fs/shm/shmfs.c b/fs/shm/shmfs.c index 48e54e41db1b6..cf826302c5264 100644 --- a/fs/shm/shmfs.c +++ b/fs/shm/shmfs.c @@ -185,21 +185,13 @@ static int shmfs_release(FAR struct inode *inode) * The inode is released after this call, hence checking if i_crefs <= 1. */ - int ret = inode_lock(); - if (ret >= 0) + if (inode->i_parent == NULL && atomic_load(&inode->i_crefs) <= 1) { - if (inode->i_parent == NULL && - inode->i_crefs <= 1) - { - shmfs_free_object(inode->i_private); - inode->i_private = NULL; - ret = OK; - } - - inode_unlock(); + shmfs_free_object(inode->i_private); + inode->i_private = NULL; } - return ret; + return OK; } /**************************************************************************** @@ -267,20 +259,13 @@ static int shmfs_truncate(FAR struct file *filep, off_t length) #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS static int shmfs_unlink(FAR struct inode *inode) { - int ret = inode_lock(); - - if (ret >= 0) + if (atomic_load(&inode->i_crefs) <= 1) { - if (inode->i_crefs <= 1) - { - shmfs_free_object(inode->i_private); - inode->i_private = NULL; - } - - inode_unlock(); + shmfs_free_object(inode->i_private); + inode->i_private = NULL; } - return ret; + return OK; } #endif diff --git a/fs/socket/socket.c b/fs/socket/socket.c index 3675988e7aef8..47fcf35bfa246 100644 --- a/fs/socket/socket.c +++ b/fs/socket/socket.c @@ -75,7 +75,7 @@ static struct inode g_sock_inode = NULL, /* i_parent */ NULL, /* i_peer */ NULL, /* i_child */ - 1, /* i_crefs */ + ATOMIC_VAR_INIT(1), /* i_crefs */ FSNODEFLAG_TYPE_SOCKET, /* i_flags */ { &g_sock_fileops /* u */ diff --git a/fs/vfs/fs_dir.c b/fs/vfs/fs_dir.c index fc78f619feb39..a59a8578fb2f9 100644 --- a/fs/vfs/fs_dir.c +++ b/fs/vfs/fs_dir.c @@ -80,7 +80,7 @@ static struct inode g_dir_inode = NULL, NULL, NULL, - 1, + ATOMIC_VAR_INIT(1), 0, { &g_dir_fileops }, }; @@ -216,7 +216,7 @@ static off_t seek_pseudodir(FAR struct file *filep, off_t offset) { /* Increment the reference count on this next node */ - curr->i_crefs++; + atomic_fetch_add(&curr->i_crefs, 1); } inode_unlock(); @@ -383,7 +383,7 @@ static int read_pseudodir(FAR struct fs_dirent_s *dir, { /* Increment the reference count on this next node */ - pdir->next->i_crefs++; + atomic_fetch_add(&pdir->next->i_crefs, 1); } inode_unlock(); diff --git a/fs/vfs/fs_epoll.c b/fs/vfs/fs_epoll.c index cf612b0a0a590..f53a002f2132e 100644 --- a/fs/vfs/fs_epoll.c +++ b/fs/vfs/fs_epoll.c @@ -123,7 +123,7 @@ static struct inode g_epoll_inode = NULL, /* i_parent */ NULL, /* i_peer */ NULL, /* i_child */ - 1, /* i_crefs */ + ATOMIC_VAR_INIT(1), /* i_crefs */ FSNODEFLAG_TYPE_DRIVER, /* i_flags */ { &g_epoll_ops /* u */ diff --git a/fs/vfs/fs_eventfd.c b/fs/vfs/fs_eventfd.c index d89abf1ded489..5bbd2286ed1d4 100644 --- a/fs/vfs/fs_eventfd.c +++ b/fs/vfs/fs_eventfd.c @@ -112,7 +112,7 @@ static struct inode g_eventfd_inode = NULL, /* i_parent */ NULL, /* i_peer */ NULL, /* i_child */ - 1, /* i_crefs */ + ATOMIC_VAR_INIT(1), /* i_crefs */ FSNODEFLAG_TYPE_DRIVER, /* i_flags */ { &g_eventfd_fops /* u */ diff --git a/fs/vfs/fs_pseudofile.c b/fs/vfs/fs_pseudofile.c index 23890ef0bf20e..c600fab724b57 100644 --- a/fs/vfs/fs_pseudofile.c +++ b/fs/vfs/fs_pseudofile.c @@ -353,24 +353,18 @@ static int pseudofile_munmap(FAR struct task_group_s *group, * The inode is released after this call, hence checking if i_crefs <= 1. */ - int ret = inode_lock(); - if (ret >= 0) + if (inode->i_parent == NULL && + atomic_load(&inode->i_crefs) <= 1) { - if (inode->i_parent == NULL && - inode->i_crefs <= 1) - { - /* Delete the inode metadata */ - - if (inode->i_private) - { - fs_heap_free(inode->i_private); - } + /* Delete the inode metadata */ - inode->i_private = NULL; - ret = OK; + if (inode->i_private) + { + fs_heap_free(inode->i_private); } - inode_unlock(); + inode->i_private = NULL; + ret = OK; } /* Unkeep the inode when unmapped, decrease refcount */ @@ -501,7 +495,6 @@ int pseudofile_create(FAR struct inode **node, FAR const char *path, goto reserve_err; } - (*node)->i_crefs = 0; (*node)->i_flags = 1; (*node)->u.i_ops = &g_pseudofile_ops; (*node)->i_private = pf; diff --git a/fs/vfs/fs_signalfd.c b/fs/vfs/fs_signalfd.c index 64f9cd61b390f..cdd006ca1a5b4 100644 --- a/fs/vfs/fs_signalfd.c +++ b/fs/vfs/fs_signalfd.c @@ -89,7 +89,7 @@ static struct inode g_signalfd_inode = NULL, /* i_parent */ NULL, /* i_peer */ NULL, /* i_child */ - 1, /* i_crefs */ + ATOMIC_VAR_INIT(1), /* i_crefs */ FSNODEFLAG_TYPE_DRIVER, /* i_flags */ { &g_signalfd_fileops /* u */ diff --git a/fs/vfs/fs_timerfd.c b/fs/vfs/fs_timerfd.c index 3b550d16be835..a2b939ef57b4f 100644 --- a/fs/vfs/fs_timerfd.c +++ b/fs/vfs/fs_timerfd.c @@ -123,7 +123,7 @@ static struct inode g_timerfd_inode = NULL, /* i_parent */ NULL, /* i_peer */ NULL, /* i_child */ - 1, /* i_crefs */ + ATOMIC_VAR_INIT(1), /* i_crefs */ FSNODEFLAG_TYPE_DRIVER, /* i_flags */ { &g_timerfd_fops /* u */ diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index 14a6b2280e586..905aaede6973c 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -410,7 +411,7 @@ struct inode FAR struct inode *i_parent; /* Link to parent level inode */ FAR struct inode *i_peer; /* Link to same level inode */ FAR struct inode *i_child; /* Link to lower level inode */ - int16_t i_crefs; /* References to inode */ + atomic_short i_crefs; /* References to inode */ uint16_t i_flags; /* Flags for inode */ union inode_ops_u u; /* Inode operations */ ino_t i_ino; /* Inode serial number */ From c306e3265d799ee07703015363e1403b0fc2b29e Mon Sep 17 00:00:00 2001 From: chenrun1 Date: Sat, 14 Sep 2024 16:42:04 +0800 Subject: [PATCH 2/4] nuttx/atomic.h:fix Fixed the pragma of ATOMIC_VAR_INIT in clang Error: vfs/fs_epoll.c:126:3: error: macro 'ATOMIC_VAR_INIT' has been marked as deprecated [-Werror,-Wdeprecated-pragma] ATOMIC_VAR_INIT(1), /* i_crefs */ ^ /Applications/Xcode_15.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include/stdatomic.h:54:41: note: macro marked 'deprecated' here ^ 1 error generated. make[1]: *** [fs_epoll.o] Error 1 Error: socket/socket.c:78:3: error: macro 'ATOMIC_VAR_INIT' has been marked as deprecated [-Werror,-Wdeprecated-pragma] ATOMIC_VAR_INIT(1), /* i_crefs */ Signed-off-by: chenrun1 --- crypto/cryptodev.c | 2 +- fs/notify/inotify.c | 2 +- fs/socket/socket.c | 2 +- fs/vfs/fs_dir.c | 2 +- fs/vfs/fs_epoll.c | 2 +- fs/vfs/fs_eventfd.c | 2 +- fs/vfs/fs_signalfd.c | 2 +- fs/vfs/fs_timerfd.c | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crypto/cryptodev.c b/crypto/cryptodev.c index 1e545de8f3670..2e6adcf09e71b 100644 --- a/crypto/cryptodev.c +++ b/crypto/cryptodev.c @@ -154,7 +154,7 @@ static const struct file_operations g_cryptoops = static struct inode g_cryptoinode = { - .i_crefs = ATOMIC_VAR_INIT(1), + .i_crefs = 1, .u.i_ops = &g_cryptofops }; diff --git a/fs/notify/inotify.c b/fs/notify/inotify.c index 3f95180fd448b..5b22cfd8e376a 100644 --- a/fs/notify/inotify.c +++ b/fs/notify/inotify.c @@ -131,7 +131,7 @@ static struct inode g_inotify_inode = NULL, NULL, NULL, - ATOMIC_VAR_INIT(1), + 1, FSNODEFLAG_TYPE_DRIVER, { &g_inotify_fops diff --git a/fs/socket/socket.c b/fs/socket/socket.c index 47fcf35bfa246..3675988e7aef8 100644 --- a/fs/socket/socket.c +++ b/fs/socket/socket.c @@ -75,7 +75,7 @@ static struct inode g_sock_inode = NULL, /* i_parent */ NULL, /* i_peer */ NULL, /* i_child */ - ATOMIC_VAR_INIT(1), /* i_crefs */ + 1, /* i_crefs */ FSNODEFLAG_TYPE_SOCKET, /* i_flags */ { &g_sock_fileops /* u */ diff --git a/fs/vfs/fs_dir.c b/fs/vfs/fs_dir.c index a59a8578fb2f9..a33c8e0f3bf89 100644 --- a/fs/vfs/fs_dir.c +++ b/fs/vfs/fs_dir.c @@ -80,7 +80,7 @@ static struct inode g_dir_inode = NULL, NULL, NULL, - ATOMIC_VAR_INIT(1), + 1, 0, { &g_dir_fileops }, }; diff --git a/fs/vfs/fs_epoll.c b/fs/vfs/fs_epoll.c index f53a002f2132e..cf612b0a0a590 100644 --- a/fs/vfs/fs_epoll.c +++ b/fs/vfs/fs_epoll.c @@ -123,7 +123,7 @@ static struct inode g_epoll_inode = NULL, /* i_parent */ NULL, /* i_peer */ NULL, /* i_child */ - ATOMIC_VAR_INIT(1), /* i_crefs */ + 1, /* i_crefs */ FSNODEFLAG_TYPE_DRIVER, /* i_flags */ { &g_epoll_ops /* u */ diff --git a/fs/vfs/fs_eventfd.c b/fs/vfs/fs_eventfd.c index 5bbd2286ed1d4..d89abf1ded489 100644 --- a/fs/vfs/fs_eventfd.c +++ b/fs/vfs/fs_eventfd.c @@ -112,7 +112,7 @@ static struct inode g_eventfd_inode = NULL, /* i_parent */ NULL, /* i_peer */ NULL, /* i_child */ - ATOMIC_VAR_INIT(1), /* i_crefs */ + 1, /* i_crefs */ FSNODEFLAG_TYPE_DRIVER, /* i_flags */ { &g_eventfd_fops /* u */ diff --git a/fs/vfs/fs_signalfd.c b/fs/vfs/fs_signalfd.c index cdd006ca1a5b4..64f9cd61b390f 100644 --- a/fs/vfs/fs_signalfd.c +++ b/fs/vfs/fs_signalfd.c @@ -89,7 +89,7 @@ static struct inode g_signalfd_inode = NULL, /* i_parent */ NULL, /* i_peer */ NULL, /* i_child */ - ATOMIC_VAR_INIT(1), /* i_crefs */ + 1, /* i_crefs */ FSNODEFLAG_TYPE_DRIVER, /* i_flags */ { &g_signalfd_fileops /* u */ diff --git a/fs/vfs/fs_timerfd.c b/fs/vfs/fs_timerfd.c index a2b939ef57b4f..3b550d16be835 100644 --- a/fs/vfs/fs_timerfd.c +++ b/fs/vfs/fs_timerfd.c @@ -123,7 +123,7 @@ static struct inode g_timerfd_inode = NULL, /* i_parent */ NULL, /* i_peer */ NULL, /* i_child */ - ATOMIC_VAR_INIT(1), /* i_crefs */ + 1, /* i_crefs */ FSNODEFLAG_TYPE_DRIVER, /* i_flags */ { &g_timerfd_fops /* u */ From 24767d25933e3ecdc93d5066d5263fd71314fedf Mon Sep 17 00:00:00 2001 From: chenrun1 Date: Sat, 14 Sep 2024 16:46:07 +0800 Subject: [PATCH 3/4] arch_atomic.c:Provide __sync_synchronize when the compiler does not support it Summary: Configuration/Tool: zp214xpa/nsh,CONFIG_ARM_TOOLCHAIN_GNU_EABI 2024-09-14 06:11:00 ------------------------------------------------------------------------------------ Cleaning... Configuring... Disabling CONFIG_ARM_TOOLCHAIN_GNU_EABI Enabling CONFIG_ARM_TOOLCHAIN_GNU_EABI Building NuttX... arm-none-eabi-ld: /github/workspace/sources/nuttx/staging/libfs.a(fs_inoderemove.o): in function `inode_remove': fs_inoderemove.c:(.text.inode_remove+0x94): undefined reference to `__sync_synchronize' arm-none-eabi-ld: fs_inoderemove.c:(.text.inode_remove+0x9c): undefined reference to `__sync_synchronize' make[1]: *** [Makefile:212: nuttx] Error 1 make: *** [tools/Unix.mk:548: nuttx] Error 2 make: Target 'all' not remade because of errors. Signed-off-by: chenrun1 --- libs/libc/machine/arch_atomic.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libs/libc/machine/arch_atomic.c b/libs/libc/machine/arch_atomic.c index 0db93e79b2ea2..fef258e718a05 100644 --- a/libs/libc/machine/arch_atomic.c +++ b/libs/libc/machine/arch_atomic.c @@ -753,17 +753,15 @@ SYNC_VAL_CMP_SWAP(4, uint32_t) SYNC_VAL_CMP_SWAP(8, uint64_t) -#endif /* __clang__ */ - -#ifdef __ghs__ - /**************************************************************************** * Name: __sync_synchronize ****************************************************************************/ void weak_function __sync_synchronize(void) { - asm volatile("" ::: "memory"); +#ifdef SP_DMB + SP_DMB(); +#endif } -#endif +#endif /* __clang__ */ From 0c56ffeeca27e89248507c3d82134552a6751b72 Mon Sep 17 00:00:00 2001 From: chenrun1 Date: Wed, 18 Sep 2024 14:51:11 +0800 Subject: [PATCH 4/4] arch/samd2l2:Ignore atomic warning when using clang compiler When the toolchain does not support atomic, it will use the version implemented by NuttX (low performance version). This scenario is consistent with the original design, so we can ignore it. see bug here: https://bugs.llvm.org/show_bug.cgi?id=43603 Error: inode/fs_inodeaddref.c:50:7: error: large atomic operation may incur significant performance penalty; the access size (4 bytes) exceeds the max lock-free size (0 bytes) [-Werror,-Watomic-alignment] 50 | atomic_fetch_add(&inode->i_crefs, 1); | ^ /tools/clang-arm-none-eabi/lib/clang/17/include/stdatomic.h:152:43: note: expanded from macro 'atomic_fetch_add' 152 | #define atomic_fetch_add(object, operand) __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST) | ^ 1 error generated. make[1]: *** [Makefile:83: fs_inodeaddref.o] Error 1 Error: inode/fs_inodefind.c:74:7: error: large atomic operation may incur significant performance penalty; the access size (4 bytes) exceeds the max lock-free size (0 bytes) [-Werror,-Watomic-alignment] 74 | atomic_fetch_add(&node->i_crefs, 1); Signed-off-by: chenrun1 --- arch/arm/src/cmake/Toolchain.cmake | 2 ++ arch/arm/src/common/Toolchain.defs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm/src/cmake/Toolchain.cmake b/arch/arm/src/cmake/Toolchain.cmake index 1c6deb6f1dcb2..34c61c58ac74d 100644 --- a/arch/arm/src/cmake/Toolchain.cmake +++ b/arch/arm/src/cmake/Toolchain.cmake @@ -61,6 +61,8 @@ if(CONFIG_ARCH_TOOLCHAIN_CLANG) # https://github.com/apache/incubator-nuttx/pull/5971 add_compile_options(-fno-builtin) + add_compile_options(-Wno-atomic-alignment) + add_compile_options(-Wno-atomic-alignment) else() set(TOOLCHAIN_PREFIX arm-none-eabi) set(CMAKE_LIBRARY_ARCHITECTURE ${TOOLCHAIN_PREFIX}) diff --git a/arch/arm/src/common/Toolchain.defs b/arch/arm/src/common/Toolchain.defs index d77c286b4b31c..10950fba7901a 100644 --- a/arch/arm/src/common/Toolchain.defs +++ b/arch/arm/src/common/Toolchain.defs @@ -324,6 +324,8 @@ endif ifeq ($(CONFIG_ARCH_TOOLCHAIN_CLANG),y) ARCHOPTIMIZATION += -fshort-enums + ARCHCFLAGS += -Wno-atomic-alignment + ARCHCXXFLAGS += -Wno-atomic-alignment endif # Architecture flags