diff options
author | Kinsey Moore <kinsey.moore@oarcorp.com> | 2023-08-22 14:39:22 -0500 |
---|---|---|
committer | Joel Sherrill <joel@rtems.org> | 2023-09-06 08:53:02 -0500 |
commit | fa85760c99a72b8186c70c896b98efe0d7cde2b6 (patch) | |
tree | d3a6bf42f1ced41f904e134d6c3fdcfefd6a5ddd /cpukit/libfs/src/jffs2/src/fs-rtems.c | |
parent | microblaze: Add link options to dl07, dl08, and dl09 (diff) | |
download | rtems-fa85760c99a72b8186c70c896b98efe0d7cde2b6.tar.bz2 |
cpukit/jffs2: Avoid delayed work lock inversion
This moves delayed work to a temporary chain to prevent a locking
inversion between the delayed work lock and the alloc_sem lock. Delayed
work is now processed after the delayed work lock is released. Locking
order is any JFFS2 locks before the delayed work lock.
Diffstat (limited to '')
-rw-r--r-- | cpukit/libfs/src/jffs2/src/fs-rtems.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/cpukit/libfs/src/jffs2/src/fs-rtems.c b/cpukit/libfs/src/jffs2/src/fs-rtems.c index 59d03effe6..1a677c9772 100644 --- a/cpukit/libfs/src/jffs2/src/fs-rtems.c +++ b/cpukit/libfs/src/jffs2/src/fs-rtems.c @@ -1282,6 +1282,8 @@ static void process_delayed_work(void) rtems_chain_node* node; mutex_lock(&delayed_work_mutex); + rtems_chain_control process_work_chain; + rtems_chain_initialize_empty(&process_work_chain); if (rtems_chain_is_empty(&delayed_work_chain)) { mutex_unlock(&delayed_work_mutex); @@ -1294,12 +1296,22 @@ static void process_delayed_work(void) rtems_chain_node* next_node = rtems_chain_next(node); if (rtems_clock_get_uptime_nanoseconds() >= work->execution_time) { rtems_chain_extract(node); - work->callback(&work->work); + rtems_chain_append(&process_work_chain, node); } node = next_node; } mutex_unlock(&delayed_work_mutex); + + node = rtems_chain_first(&process_work_chain); + while (!rtems_chain_is_tail(&process_work_chain, node)) { + work = (struct delayed_work*) node; + rtems_chain_node* next_node = rtems_chain_next(node); + rtems_chain_extract(node); + work->callback(&work->work); + node = next_node; + } } + /* Task for processing delayed work */ static rtems_task delayed_work_task( rtems_task_argument unused |