--- zzzz-none-000/linux-4.19.183/fs/jffs2/gc.c 2021-03-24 10:07:39.000000000 +0000 +++ bcm63-7530ax-756/linux-4.19.183/fs/jffs2/gc.c 2023-06-28 08:54:20.000000000 +0000 @@ -923,6 +923,12 @@ for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) { + +#if defined(CONFIG_BCM_KF_JFFS) + if (!raw) + break; +#endif + cond_resched(); /* We only care about obsolete ones */ @@ -943,7 +949,21 @@ /* This is an obsolete node belonging to the same directory, and it's of the right length. We need to take a closer look...*/ + #if defined(CONFIG_BCM_KF_JFFS) + /* The lock, erase_free_sem, needs to be unlocked here in order to prevent a possible + * deadlock. Without doing this, the following condition can occur. + * thread 1: brcmnand_erase => brcmnand_get_device (gets and holds chip_lock) => + * jffs2_erase_pending_blocks (blocks trying to get erase_free_sem) + * thread 2: jffs2_garbage_collect_deletion_dirent (gets and holds erase_free_sem) => + * brcmnand_get_device (blocks trying to get chip_lock) + */ + mutex_unlock(&c->erase_free_sem); + ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)rd); + mutex_lock(&c->erase_free_sem); +#else + ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)rd); +#endif if (ret) { pr_warn("%s(): Read error (%d) reading obsolete node at %08x\n", __func__, ret, ref_offset(raw));